Provide infrastructure for kubernetes upgrades
This commit provides the CLI and REST API infrastructure for kubernetes upgrades. It also includes support for: - starting a kubernetes upgrade - upgrading the kubernetes control plane components - upgrading the kubelets Note that these capabilities cannot be exercised in a standard load - they require a new kubernetes version to be defined in the load and patches created for the new kubernetes version. Change-Id: I0c2755fca89e93583e43fc5ace93bef8fc181766 Story: 2006781 Task: 37306 Task: 37579 Task: 37580 Task: 37581 Depends-On: https://review.opendev.org/#/c/695542 Signed-off-by: Bart Wensley <barton.wensley@windriver.com>
This commit is contained in:
@@ -91,10 +91,10 @@ fixtures = {
|
||||
}
|
||||
|
||||
|
||||
class ihostManagerTest(testtools.TestCase):
|
||||
class HostManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ihostManagerTest, self).setUp()
|
||||
super(HostManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.mgr = cgtsclient.v1.ihost.ihostManager(self.api)
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import mock
|
||||
|
||||
from cgtsclient.tests import test_shell
|
||||
from cgtsclient.v1.ihost import ihost
|
||||
from cgtsclient.v1.kube_host_upgrade import KubeHostUpgrade
|
||||
|
||||
FAKE_KUBE_HOST_UPGRADE = {
|
||||
'id': 100,
|
||||
'uuid': '65d3fa7e-1414-4a1d-83b1-42c6bcac48bf',
|
||||
'target_version': 'v1.42.3',
|
||||
'status': 'fake status',
|
||||
'control_plane_version': 'v1.42.2',
|
||||
'kubelet_version': 'v1.42.2',
|
||||
'host_id': 67,
|
||||
}
|
||||
|
||||
FAKE_KUBE_HOST_UPGRADE_2 = {
|
||||
'id': 101,
|
||||
'uuid': '2044b22a-9fb3-4b62-9894-dcc6c0d0f791',
|
||||
'target_version': 'v1.42.3',
|
||||
'status': 'fake status',
|
||||
'control_plane_version': 'v1.42.3',
|
||||
'kubelet_version': 'v1.42.2',
|
||||
'host_id': 68,
|
||||
}
|
||||
|
||||
FAKE_KUBE_HOST_UPGRADE_3 = {
|
||||
'id': 102,
|
||||
'uuid': '0061fd45-0545-48e5-aa1b-fc3c809dfd3c',
|
||||
'target_version': None,
|
||||
'status': None,
|
||||
'control_plane_version': 'N/A',
|
||||
'kubelet_version': 'N/A',
|
||||
'host_id': 69,
|
||||
}
|
||||
|
||||
FAKE_IHOST = {
|
||||
'id': 67,
|
||||
'uuid': '7c4b5408-7097-4ab8-88fe-b8db156b1a8a',
|
||||
'hostname': 'controller-0',
|
||||
'personality': 'controller',
|
||||
}
|
||||
|
||||
FAKE_IHOST_2 = {
|
||||
'id': 68,
|
||||
'uuid': '62adea84-4fd5-4c78-b59a-a8eda2f2861c',
|
||||
'hostname': 'controller-1',
|
||||
'personality': 'controller',
|
||||
}
|
||||
|
||||
FAKE_IHOST_3 = {
|
||||
'id': 69,
|
||||
'uuid': '3a966002-14b9-4b96-bcf5-345ff50086b8',
|
||||
'hostname': 'storage-0',
|
||||
'personality': 'storage',
|
||||
}
|
||||
|
||||
|
||||
class HostTest(test_shell.ShellTest):
|
||||
|
||||
def setUp(self):
|
||||
super(HostTest, self).setUp()
|
||||
|
||||
# Mock the client
|
||||
p = mock.patch('cgtsclient.client._get_endpoint')
|
||||
self.mock_cgtsclient_client_get_endpoint = p.start()
|
||||
self.mock_cgtsclient_client_get_endpoint.return_value = \
|
||||
'http://fakelocalhost:6385/v1'
|
||||
self.addCleanup(p.stop)
|
||||
p = mock.patch('cgtsclient.client._get_ksclient')
|
||||
self.mock_cgtsclient_client_get_ksclient = p.start()
|
||||
self.addCleanup(p.stop)
|
||||
|
||||
# Mock the KubeHostUpgradeManager
|
||||
self.kube_host_upgrade_manager_list_result = [
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE, True)]
|
||||
|
||||
def mock_kube_host_upgrade_manager_list(obj):
|
||||
return self.kube_host_upgrade_manager_list_result
|
||||
self.mocked_kube_host_upgrade_manager_list = mock.patch(
|
||||
'cgtsclient.v1.kube_host_upgrade.KubeHostUpgradeManager.list',
|
||||
mock_kube_host_upgrade_manager_list)
|
||||
self.mocked_kube_host_upgrade_manager_list.start()
|
||||
self.addCleanup(self.mocked_kube_host_upgrade_manager_list.stop)
|
||||
|
||||
# Mock the ihostManager
|
||||
self.ihost_manager_list_result = [ihost(None, FAKE_IHOST, True)]
|
||||
|
||||
def mock_ihost_manager_list(obj):
|
||||
return self.ihost_manager_list_result
|
||||
self.mocked_ihost_manager_list = mock.patch(
|
||||
'cgtsclient.v1.ihost.ihostManager.list',
|
||||
mock_ihost_manager_list)
|
||||
self.mocked_ihost_manager_list.start()
|
||||
self.addCleanup(self.mocked_ihost_manager_list.stop)
|
||||
|
||||
self.ihost_manager_kube_upgrade_control_plane_result = \
|
||||
[ihost(None, FAKE_IHOST, True)]
|
||||
|
||||
def mock_ihost_manager_kube_upgrade_control_plane(obj, hostid):
|
||||
return self.ihost_manager_kube_upgrade_control_plane_result
|
||||
self.mocked_ihost_manager_kube_upgrade_control_plane = mock.patch(
|
||||
'cgtsclient.v1.ihost.ihostManager.kube_upgrade_control_plane',
|
||||
mock_ihost_manager_kube_upgrade_control_plane)
|
||||
self.mocked_ihost_manager_kube_upgrade_control_plane.start()
|
||||
self.addCleanup(
|
||||
self.mocked_ihost_manager_kube_upgrade_control_plane.stop)
|
||||
|
||||
def mock_ihost_manager_kube_upgrade_kubelet(obj, hostid):
|
||||
return self.ihost_manager_kube_upgrade_kubelet_result
|
||||
|
||||
self.mocked_ihost_manager_kube_upgrade_kubelet = mock.patch(
|
||||
'cgtsclient.v1.ihost.ihostManager.kube_upgrade_kubelet',
|
||||
mock_ihost_manager_kube_upgrade_kubelet)
|
||||
self.mocked_ihost_manager_kube_upgrade_kubelet.start()
|
||||
self.addCleanup(
|
||||
self.mocked_ihost_manager_kube_upgrade_kubelet.stop)
|
||||
|
||||
def test_kube_host_upgrade_list(self):
|
||||
self.make_env()
|
||||
|
||||
# Use --nowrap to prevent failure when test run with small terminal
|
||||
results = self.shell("kube-host-upgrade-list --nowrap")
|
||||
self.assertIn(str(FAKE_IHOST['id']), results)
|
||||
self.assertIn(str(FAKE_IHOST['hostname']), results)
|
||||
self.assertIn(str(FAKE_IHOST['personality']), results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE['target_version']), results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE['control_plane_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE['kubelet_version']), results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE['status']), results)
|
||||
|
||||
def test_kube_host_upgrade_list_multiple(self):
|
||||
self.make_env()
|
||||
self.kube_host_upgrade_manager_list_result = [
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE, True),
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE_2, True),
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE_3, True),
|
||||
]
|
||||
self.ihost_manager_list_result = [
|
||||
ihost(None, FAKE_IHOST, True),
|
||||
ihost(None, FAKE_IHOST_2, True),
|
||||
ihost(None, FAKE_IHOST_3, True),
|
||||
]
|
||||
|
||||
# Use --nowrap to prevent failure when test run with small terminal
|
||||
results = self.shell("kube-host-upgrade-list --nowrap")
|
||||
|
||||
for fake_ihost in [FAKE_IHOST, FAKE_IHOST_2, FAKE_IHOST_3]:
|
||||
self.assertIn(str(fake_ihost['id']), results)
|
||||
self.assertIn(str(fake_ihost['hostname']), results)
|
||||
self.assertIn(str(fake_ihost['personality']), results)
|
||||
|
||||
for fake_kube_host_upgrade in [FAKE_KUBE_HOST_UPGRADE,
|
||||
FAKE_KUBE_HOST_UPGRADE_2,
|
||||
FAKE_KUBE_HOST_UPGRADE_3]:
|
||||
self.assertIn(str(fake_kube_host_upgrade['target_version']),
|
||||
results)
|
||||
self.assertIn(str(fake_kube_host_upgrade['control_plane_version']),
|
||||
results)
|
||||
self.assertIn(str(fake_kube_host_upgrade['kubelet_version']),
|
||||
results)
|
||||
self.assertIn(str(fake_kube_host_upgrade['status']),
|
||||
results)
|
||||
|
||||
def test_kube_host_upgrade_control_plane(self):
|
||||
self.make_env()
|
||||
self.kube_host_upgrade_manager_list_result = [
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE, True),
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE_2, True),
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE_3, True),
|
||||
]
|
||||
self.ihost_manager_kube_upgrade_control_plane_result = \
|
||||
ihost(None, FAKE_IHOST_2, True)
|
||||
|
||||
results = self.shell("kube-host-upgrade controller-1 control-plane")
|
||||
|
||||
self.assertIn(str(FAKE_IHOST_2['id']), results)
|
||||
self.assertIn(str(FAKE_IHOST_2['hostname']), results)
|
||||
self.assertIn(str(FAKE_IHOST_2['personality']), results)
|
||||
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['target_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['control_plane_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['kubelet_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['status']),
|
||||
results)
|
||||
|
||||
def test_kube_host_upgrade_kubelet(self):
|
||||
self.make_env()
|
||||
self.kube_host_upgrade_manager_list_result = [
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE, True),
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE_2, True),
|
||||
KubeHostUpgrade(None, FAKE_KUBE_HOST_UPGRADE_3, True),
|
||||
]
|
||||
self.ihost_manager_kube_upgrade_kubelet_result = \
|
||||
ihost(None, FAKE_IHOST_2, True)
|
||||
|
||||
results = self.shell("kube-host-upgrade controller-1 kubelet")
|
||||
|
||||
self.assertIn(str(FAKE_IHOST_2['id']), results)
|
||||
self.assertIn(str(FAKE_IHOST_2['hostname']), results)
|
||||
self.assertIn(str(FAKE_IHOST_2['personality']), results)
|
||||
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['target_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['control_plane_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['kubelet_version']),
|
||||
results)
|
||||
self.assertIn(str(FAKE_KUBE_HOST_UPGRADE_2['status']),
|
||||
results)
|
||||
@@ -0,0 +1,80 @@
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
|
||||
import testtools
|
||||
|
||||
from cgtsclient.tests import utils
|
||||
import cgtsclient.v1.kube_host_upgrade
|
||||
|
||||
|
||||
KUBE_HOST_UPGRADE = {'id': 1,
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'target_version': 'v1.42.3',
|
||||
'status': 'fake status',
|
||||
'control_plane_version': 'v1.42.2',
|
||||
'kubelet_version': 'v1.42.2',
|
||||
'host_id': 1,
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
|
||||
|
||||
fixtures = {
|
||||
'/v1/kube_host_upgrades':
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
{"kube_host_upgrades": [KUBE_HOST_UPGRADE]},
|
||||
),
|
||||
},
|
||||
'/v1/kube_host_upgrades/%s' % KUBE_HOST_UPGRADE['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
KUBE_HOST_UPGRADE,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class KubeHostUpgradeManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(KubeHostUpgradeManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.mgr = cgtsclient.v1.kube_host_upgrade.KubeHostUpgradeManager(
|
||||
self.api)
|
||||
|
||||
def test_list(self):
|
||||
kube_host_upgrade_list = self.mgr.list()
|
||||
expect = [
|
||||
('GET', '/v1/kube_host_upgrades', {}, None),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(len(kube_host_upgrade_list), 1)
|
||||
|
||||
def test_get(self):
|
||||
kube_host_upgrade_list = self.mgr.get(KUBE_HOST_UPGRADE['uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/kube_host_upgrades/%s' % KUBE_HOST_UPGRADE['uuid'],
|
||||
{}, None),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(kube_host_upgrade_list.uuid,
|
||||
KUBE_HOST_UPGRADE['uuid'])
|
||||
@@ -0,0 +1,148 @@
|
||||
#
|
||||
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
|
||||
|
||||
import testtools
|
||||
|
||||
from cgtsclient.tests import utils
|
||||
import cgtsclient.v1.kube_upgrade
|
||||
import cgtsclient.v1.kube_upgrade_shell
|
||||
|
||||
|
||||
KUBE_UPGRADE = {'from_version': 'v1.42.1',
|
||||
'to_version': 'v1.42.2',
|
||||
'state': 'upgrade-started',
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
|
||||
CREATE_KUBE_UPGRADE = {'to_version': 'v1.42.2',
|
||||
'force': False}
|
||||
|
||||
UPDATED_KUBE_UPGRADE = {'from_version': 'v1.42.1',
|
||||
'to_version': 'v1.42.2',
|
||||
'state': 'upgrading-networking',
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
|
||||
|
||||
fixtures = {
|
||||
'/v1/kube_upgrade':
|
||||
{
|
||||
'POST': (
|
||||
{},
|
||||
KUBE_UPGRADE,
|
||||
),
|
||||
'GET': (
|
||||
{},
|
||||
{"kube_upgrades": [KUBE_UPGRADE]},
|
||||
),
|
||||
'DELETE': (
|
||||
{},
|
||||
None,
|
||||
),
|
||||
'PATCH': (
|
||||
{},
|
||||
UPDATED_KUBE_UPGRADE,
|
||||
),
|
||||
},
|
||||
'/v1/kube_upgrade/%s' % KUBE_UPGRADE['uuid']:
|
||||
{
|
||||
'GET': (
|
||||
{},
|
||||
KUBE_UPGRADE,
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class KubeUpgradeManagerTest(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(KubeUpgradeManagerTest, self).setUp()
|
||||
self.api = utils.FakeAPI(fixtures)
|
||||
self.mgr = cgtsclient.v1.kube_upgrade.KubeUpgradeManager(self.api)
|
||||
|
||||
def test_list(self):
|
||||
kube_upgrade_list = self.mgr.list()
|
||||
expect = [
|
||||
('GET', '/v1/kube_upgrade', {}, None),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(len(kube_upgrade_list), 1)
|
||||
|
||||
def test_get(self):
|
||||
kube_upgrade = self.mgr.get(KUBE_UPGRADE['uuid'])
|
||||
expect = [
|
||||
('GET', '/v1/kube_upgrade/%s' % KUBE_UPGRADE['uuid'], {}, None),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(kube_upgrade.from_version,
|
||||
KUBE_UPGRADE['from_version'])
|
||||
self.assertEqual(kube_upgrade.to_version,
|
||||
KUBE_UPGRADE['to_version'])
|
||||
self.assertEqual(kube_upgrade.state,
|
||||
KUBE_UPGRADE['state'])
|
||||
self.assertEqual(kube_upgrade.uuid,
|
||||
KUBE_UPGRADE['uuid'])
|
||||
self.assertEqual(kube_upgrade.created_at,
|
||||
KUBE_UPGRADE['created_at'])
|
||||
self.assertEqual(kube_upgrade.updated_at,
|
||||
KUBE_UPGRADE['updated_at'])
|
||||
|
||||
def test_create(self):
|
||||
kube_upgrade = self.mgr.create(**CREATE_KUBE_UPGRADE)
|
||||
expect = [
|
||||
('POST', '/v1/kube_upgrade', {}, CREATE_KUBE_UPGRADE),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(kube_upgrade.from_version,
|
||||
KUBE_UPGRADE['from_version'])
|
||||
self.assertEqual(kube_upgrade.to_version,
|
||||
KUBE_UPGRADE['to_version'])
|
||||
self.assertEqual(kube_upgrade.state,
|
||||
KUBE_UPGRADE['state'])
|
||||
self.assertEqual(kube_upgrade.uuid,
|
||||
KUBE_UPGRADE['uuid'])
|
||||
self.assertEqual(kube_upgrade.created_at,
|
||||
KUBE_UPGRADE['created_at'])
|
||||
self.assertEqual(kube_upgrade.updated_at,
|
||||
KUBE_UPGRADE['updated_at'])
|
||||
|
||||
def test_delete(self):
|
||||
self.mgr.delete()
|
||||
expect = [
|
||||
('DELETE', '/v1/kube_upgrade', {}, None),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
|
||||
def test_update(self):
|
||||
patch = {'op': 'replace',
|
||||
'value': 'upgrading-networking',
|
||||
'path': '/state'}
|
||||
kube_upgrade = self.mgr.update(patch=patch)
|
||||
expect = [
|
||||
('PATCH', '/v1/kube_upgrade', {}, patch),
|
||||
]
|
||||
self.assertEqual(self.api.calls, expect)
|
||||
self.assertEqual(kube_upgrade.state,
|
||||
cgtsclient.v1.kube_upgrade_shell.
|
||||
KUBE_UPGRADE_STATE_UPGRADING_NETWORKING)
|
||||
@@ -0,0 +1,133 @@
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
import mock
|
||||
|
||||
from cgtsclient.tests import test_shell
|
||||
from cgtsclient.v1.kube_upgrade import KubeUpgrade
|
||||
|
||||
|
||||
class KubeUpgradeTest(test_shell.ShellTest):
|
||||
|
||||
def setUp(self):
|
||||
super(KubeUpgradeTest, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
super(KubeUpgradeTest, self).tearDown()
|
||||
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.list')
|
||||
@mock.patch('cgtsclient.client._get_ksclient')
|
||||
@mock.patch('cgtsclient.client._get_endpoint')
|
||||
def test_kube_upgrade_show(self, mock_get_endpoint, mock_get_client,
|
||||
mock_list):
|
||||
mock_get_endpoint.return_value = 'http://fakelocalhost:6385/v1'
|
||||
fake_kube_upgrade = {'from_version': 'v1.42.1',
|
||||
'to_version': 'v1.42.2',
|
||||
'state': 'upgrade-started',
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
fake_kube_upgrade_list = [KubeUpgrade(None, fake_kube_upgrade, True)]
|
||||
mock_list.return_value = fake_kube_upgrade_list
|
||||
|
||||
self.make_env()
|
||||
results = self.shell("kube-upgrade-show")
|
||||
self.assertIn(fake_kube_upgrade['from_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['to_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['state'], results)
|
||||
self.assertIn(fake_kube_upgrade['uuid'], results)
|
||||
self.assertIn(fake_kube_upgrade['created_at'], results)
|
||||
self.assertIn(fake_kube_upgrade['updated_at'], results)
|
||||
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.create')
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.get')
|
||||
@mock.patch('cgtsclient.client._get_ksclient')
|
||||
@mock.patch('cgtsclient.client._get_endpoint')
|
||||
def test_kube_upgrade_start(self, mock_get_endpoint, mock_get_client,
|
||||
mock_get, mock_create):
|
||||
mock_get_endpoint.return_value = 'http://fakelocalhost:6385/v1'
|
||||
fake_kube_upgrade = {'from_version': 'v1.42.1',
|
||||
'to_version': 'v1.42.2',
|
||||
'state': 'upgrade-started',
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
mock_create.return_value = KubeUpgrade(None, fake_kube_upgrade, True)
|
||||
mock_get.return_value = KubeUpgrade(None, fake_kube_upgrade, True)
|
||||
|
||||
self.make_env()
|
||||
results = self.shell("kube-upgrade-start %s" %
|
||||
fake_kube_upgrade['to_version'])
|
||||
self.assertIn(fake_kube_upgrade['from_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['to_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['state'], results)
|
||||
self.assertIn(fake_kube_upgrade['uuid'], results)
|
||||
self.assertIn(fake_kube_upgrade['created_at'], results)
|
||||
self.assertIn(fake_kube_upgrade['updated_at'], results)
|
||||
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.create')
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.get')
|
||||
@mock.patch('cgtsclient.client._get_ksclient')
|
||||
@mock.patch('cgtsclient.client._get_endpoint')
|
||||
def test_kube_upgrade_start_force(self, mock_get_endpoint, mock_get_client,
|
||||
mock_get, mock_create):
|
||||
mock_get_endpoint.return_value = 'http://fakelocalhost:6385/v1'
|
||||
fake_kube_upgrade = {'from_version': 'v1.42.1',
|
||||
'to_version': 'v1.42.2',
|
||||
'state': 'upgrade-started',
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
mock_create.return_value = KubeUpgrade(None, fake_kube_upgrade, True)
|
||||
mock_get.return_value = KubeUpgrade(None, fake_kube_upgrade, True)
|
||||
|
||||
self.make_env()
|
||||
results = self.shell("kube-upgrade-start %s --force" %
|
||||
fake_kube_upgrade['to_version'])
|
||||
self.assertIn(fake_kube_upgrade['from_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['to_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['state'], results)
|
||||
self.assertIn(fake_kube_upgrade['uuid'], results)
|
||||
self.assertIn(fake_kube_upgrade['created_at'], results)
|
||||
self.assertIn(fake_kube_upgrade['updated_at'], results)
|
||||
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.update')
|
||||
@mock.patch('cgtsclient.client._get_ksclient')
|
||||
@mock.patch('cgtsclient.client._get_endpoint')
|
||||
def test_kube_upgrade_networking(self, mock_get_endpoint, mock_get_client,
|
||||
mock_update):
|
||||
mock_get_endpoint.return_value = 'http://fakelocalhost:6385/v1'
|
||||
fake_kube_upgrade = {'from_version': 'v1.42.1',
|
||||
'to_version': 'v1.42.2',
|
||||
'state': 'upgrading-networking',
|
||||
'uuid': 'cb737aba-1820-4184-b0dc-9b073822af48',
|
||||
'created_at': 'fake-created-time',
|
||||
'updated_at': 'fake-updated-time',
|
||||
}
|
||||
mock_update.return_value = KubeUpgrade(None, fake_kube_upgrade, True)
|
||||
|
||||
self.make_env()
|
||||
results = self.shell("kube-upgrade-networking")
|
||||
self.assertIn(fake_kube_upgrade['from_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['to_version'], results)
|
||||
self.assertIn(fake_kube_upgrade['state'], results)
|
||||
self.assertIn(fake_kube_upgrade['uuid'], results)
|
||||
self.assertIn(fake_kube_upgrade['created_at'], results)
|
||||
self.assertIn(fake_kube_upgrade['updated_at'], results)
|
||||
|
||||
@mock.patch('cgtsclient.v1.kube_upgrade.KubeUpgradeManager.delete')
|
||||
@mock.patch('cgtsclient.client._get_ksclient')
|
||||
@mock.patch('cgtsclient.client._get_endpoint')
|
||||
def test_kube_upgrade_delete(self, mock_get_endpoint, mock_get_client,
|
||||
mock_delete):
|
||||
mock_get_endpoint.return_value = 'http://fakelocalhost:6385/v1'
|
||||
|
||||
self.make_env()
|
||||
results = self.shell("kube-upgrade-delete")
|
||||
self.assertIn("Kubernetes upgrade deleted", results)
|
||||
@@ -53,6 +53,8 @@ from cgtsclient.v1 import istor
|
||||
from cgtsclient.v1 import isystem
|
||||
from cgtsclient.v1 import itrapdest
|
||||
from cgtsclient.v1 import iuser
|
||||
from cgtsclient.v1 import kube_host_upgrade
|
||||
from cgtsclient.v1 import kube_upgrade
|
||||
from cgtsclient.v1 import kube_version
|
||||
from cgtsclient.v1 import label
|
||||
from cgtsclient.v1 import license
|
||||
@@ -161,3 +163,5 @@ class Client(http.HTTPClient):
|
||||
self.app = app.AppManager(self)
|
||||
self.host_fs = host_fs.HostFsManager(self)
|
||||
self.kube_version = kube_version.KubeVersionManager(self)
|
||||
self.kube_upgrade = kube_upgrade.KubeUpgradeManager(self)
|
||||
self.kube_host_upgrade = kube_host_upgrade.KubeHostUpgradeManager(self)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
|
||||
from collections import OrderedDict
|
||||
import datetime
|
||||
import os
|
||||
|
||||
@@ -64,6 +65,22 @@ def _print_ihost_show(ihost, columns=None, output_format=None):
|
||||
utils.print_dict_with_format(data, wrap=72, output_format=output_format)
|
||||
|
||||
|
||||
def _get_kube_host_upgrade_details(cc):
|
||||
# Get the list of kubernetes host upgrades
|
||||
kube_host_upgrades = cc.kube_host_upgrade.list()
|
||||
|
||||
# Map the host_id to hostname and personality
|
||||
kube_host_upgrade_details = dict()
|
||||
for kube_host_upgrade in kube_host_upgrades:
|
||||
kube_host_upgrade_details[kube_host_upgrade.host_id] = {
|
||||
'target_version': kube_host_upgrade.target_version,
|
||||
'control_plane_version': kube_host_upgrade.control_plane_version,
|
||||
'kubelet_version': kube_host_upgrade.kubelet_version,
|
||||
'status': kube_host_upgrade.status}
|
||||
|
||||
return kube_host_upgrade_details
|
||||
|
||||
|
||||
@utils.arg('hostnameorid', metavar='<hostname or id>',
|
||||
help="Name or ID of host")
|
||||
@utils.arg('--column',
|
||||
@@ -110,6 +127,31 @@ def do_host_upgrade_list(cc, args):
|
||||
utils.print_list(ihosts, fields, field_labels, sortby=0)
|
||||
|
||||
|
||||
def do_kube_host_upgrade_list(cc, args):
|
||||
"""List kubernetes upgrade info for hosts."""
|
||||
|
||||
# Get the list of hosts
|
||||
ihosts = cc.ihost.list()
|
||||
# Get the kubernetes host upgrades
|
||||
kube_host_upgrade_details = _get_kube_host_upgrade_details(cc)
|
||||
|
||||
for host in ihosts:
|
||||
host.target_version = \
|
||||
kube_host_upgrade_details[host.id]['target_version']
|
||||
host.control_plane_version = \
|
||||
kube_host_upgrade_details[host.id]['control_plane_version']
|
||||
host.kubelet_version = \
|
||||
kube_host_upgrade_details[host.id]['kubelet_version']
|
||||
host.status = \
|
||||
kube_host_upgrade_details[host.id]['status']
|
||||
|
||||
field_labels = ['id', 'hostname', 'personality', 'target_version',
|
||||
'control_plane_version', 'kubelet_version', 'status']
|
||||
fields = ['id', 'hostname', 'personality', 'target_version',
|
||||
'control_plane_version', 'kubelet_version', 'status']
|
||||
utils.print_list(ihosts, fields, field_labels, sortby=0)
|
||||
|
||||
|
||||
@utils.arg('-n', '--hostname',
|
||||
metavar='<hostname>',
|
||||
help='Hostname of the host')
|
||||
@@ -763,3 +805,41 @@ def do_host_upgrade(cc, args):
|
||||
|
||||
ihost = cc.ihost.upgrade(args.hostid, args.force)
|
||||
_print_ihost_show(ihost)
|
||||
|
||||
|
||||
@utils.arg('hostid',
|
||||
metavar='<hostname or id>',
|
||||
help="Name or ID of host")
|
||||
@utils.arg('component',
|
||||
metavar='<component>',
|
||||
choices=['control-plane', 'kubelet'],
|
||||
help='kubernetes component to upgrade')
|
||||
def do_kube_host_upgrade(cc, args):
|
||||
"""Perform kubernetes upgrade for a host."""
|
||||
|
||||
if args.component == 'control-plane':
|
||||
host = cc.ihost.kube_upgrade_control_plane(args.hostid)
|
||||
elif args.component == 'kubelet':
|
||||
host = cc.ihost.kube_upgrade_kubelet(args.hostid)
|
||||
else:
|
||||
raise exc.CommandError('Invalid component value: %s' % args.component)
|
||||
|
||||
# Get the kubernetes host upgrades
|
||||
kube_host_upgrade_details = _get_kube_host_upgrade_details(cc)
|
||||
|
||||
host.target_version = \
|
||||
kube_host_upgrade_details[host.id]['target_version']
|
||||
host.control_plane_version = \
|
||||
kube_host_upgrade_details[host.id]['control_plane_version']
|
||||
host.kubelet_version = \
|
||||
kube_host_upgrade_details[host.id]['kubelet_version']
|
||||
host.status = \
|
||||
kube_host_upgrade_details[host.id]['status']
|
||||
|
||||
fields = ['id', 'hostname', 'personality', 'target_version',
|
||||
'control_plane_version', 'kubelet_version', 'status']
|
||||
|
||||
data_list = [(f, getattr(host, f, '')) for f in fields]
|
||||
data = dict(data_list)
|
||||
ordereddata = OrderedDict(sorted(data.items(), key=lambda t: t[0]))
|
||||
utils.print_dict(ordereddata, wrap=72)
|
||||
|
||||
@@ -122,6 +122,16 @@ class ihostManager(base.Manager):
|
||||
result = self._json_get(self._path('bulk_export'))
|
||||
return result
|
||||
|
||||
def kube_upgrade_control_plane(self, hostid):
|
||||
resp, body = self.api.json_request(
|
||||
'POST', self._path(hostid) + "/kube_upgrade_control_plane")
|
||||
return self.resource_class(self, body)
|
||||
|
||||
def kube_upgrade_kubelet(self, hostid):
|
||||
resp, body = self.api.json_request(
|
||||
'POST', self._path(hostid) + "/kube_upgrade_kubelet")
|
||||
return self.resource_class(self, body)
|
||||
|
||||
|
||||
def _find_ihost(cc, ihost):
|
||||
if ihost.isdigit() or utils.is_uuid_like(ihost):
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from cgtsclient.common import base
|
||||
|
||||
|
||||
class KubeHostUpgrade(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<kube_host_upgrade %s>" % self._info
|
||||
|
||||
|
||||
class KubeHostUpgradeManager(base.Manager):
|
||||
resource_class = KubeHostUpgrade
|
||||
|
||||
@staticmethod
|
||||
def _path(uuid=None):
|
||||
return '/v1/kube_host_upgrades/%s' % uuid if uuid \
|
||||
else '/v1/kube_host_upgrades'
|
||||
|
||||
def list(self):
|
||||
"""Retrieve the list of kubernetes host upgrades known to the system."""
|
||||
|
||||
return self._list(self._path(), "kube_host_upgrades")
|
||||
|
||||
def get(self, uuid):
|
||||
"""Retrieve the details of a given kubernetes host upgrade.
|
||||
|
||||
:param uuid: uuid of kubernetes host upgrade
|
||||
"""
|
||||
|
||||
try:
|
||||
return self._list(self._path(uuid))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
59
sysinv/cgts-client/cgts-client/cgtsclient/v1/kube_upgrade.py
Normal file
59
sysinv/cgts-client/cgts-client/cgtsclient/v1/kube_upgrade.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from cgtsclient.common import base
|
||||
|
||||
|
||||
class KubeUpgrade(base.Resource):
|
||||
def __repr__(self):
|
||||
return "<kube_upgrade %s>" % self._info
|
||||
|
||||
|
||||
class KubeUpgradeManager(base.Manager):
|
||||
resource_class = KubeUpgrade
|
||||
|
||||
@staticmethod
|
||||
def _path(uuid=None):
|
||||
return '/v1/kube_upgrade/%s' % uuid if uuid else '/v1/kube_upgrade'
|
||||
|
||||
def list(self):
|
||||
"""Retrieve the list of kubernetes upgrades known to the system."""
|
||||
|
||||
return self._list(self._path(), "kube_upgrades")
|
||||
|
||||
def get(self, uuid):
|
||||
"""Retrieve the details of a given kubernetes upgrade.
|
||||
|
||||
:param uuid: uuid of upgrade
|
||||
"""
|
||||
|
||||
try:
|
||||
return self._list(self._path(uuid))[0]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
def create(self, to_version, force):
|
||||
"""Create a new kubernetes upgrade.
|
||||
|
||||
:param to_version: target kubernetes version
|
||||
:param force: ignore non management-affecting alarms
|
||||
"""
|
||||
new = {}
|
||||
new['to_version'] = to_version
|
||||
new['force'] = force
|
||||
return self._create(self._path(), new)
|
||||
|
||||
def delete(self):
|
||||
"""Delete a kubernetes upgrade."""
|
||||
|
||||
res, body = self.api.json_request('DELETE', self._path())
|
||||
if body:
|
||||
return self.resource_class(self, body)
|
||||
|
||||
def update(self, patch):
|
||||
"""Update a kubernetes upgrade."""
|
||||
|
||||
return self._update(self._path(), patch)
|
||||
75
sysinv/cgts-client/cgts-client/cgtsclient/v1/kube_upgrade_shell.py
Executable file
75
sysinv/cgts-client/cgts-client/cgtsclient/v1/kube_upgrade_shell.py
Executable file
@@ -0,0 +1,75 @@
|
||||
#
|
||||
# Copyright (c) 2019 Wind River Systems, Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
from cgtsclient.common import utils
|
||||
from cgtsclient import exc
|
||||
|
||||
# Kubernetes constants
|
||||
KUBE_UPGRADE_STATE_UPGRADING_NETWORKING = 'upgrading-networking'
|
||||
|
||||
|
||||
def _print_kube_upgrade_show(obj):
|
||||
fields = ['uuid', 'from_version', 'to_version', 'state', 'created_at',
|
||||
'updated_at']
|
||||
data = [(f, getattr(obj, f, '')) for f in fields]
|
||||
utils.print_tuple_list(data)
|
||||
|
||||
|
||||
def do_kube_upgrade_show(cc, args):
|
||||
"""Show kubernetes upgrade details and attributes."""
|
||||
|
||||
kube_upgrades = cc.kube_upgrade.list()
|
||||
if kube_upgrades:
|
||||
_print_kube_upgrade_show(kube_upgrades[0])
|
||||
else:
|
||||
print('A kubernetes upgrade is not in progress')
|
||||
|
||||
|
||||
@utils.arg('to_version', metavar='<target kubernetes version>',
|
||||
help="target Kubernetes version")
|
||||
@utils.arg('-f', '--force',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="Ignore non management-affecting alarms")
|
||||
def do_kube_upgrade_start(cc, args):
|
||||
"""Start a kubernetes upgrade. """
|
||||
|
||||
kube_upgrade = cc.kube_upgrade.create(args.to_version, args.force)
|
||||
uuid = getattr(kube_upgrade, 'uuid', '')
|
||||
try:
|
||||
kube_upgrade = cc.kube_upgrade.get(uuid)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError('Created kubernetes upgrade UUID not found: %s'
|
||||
% uuid)
|
||||
_print_kube_upgrade_show(kube_upgrade)
|
||||
|
||||
|
||||
def do_kube_upgrade_networking(cc, args):
|
||||
"""Upgrade kubernetes networking."""
|
||||
|
||||
data = dict()
|
||||
data['state'] = KUBE_UPGRADE_STATE_UPGRADING_NETWORKING
|
||||
|
||||
patch = []
|
||||
for (k, v) in data.items():
|
||||
patch.append({'op': 'replace', 'path': '/' + k, 'value': v})
|
||||
try:
|
||||
kube_upgrade = cc.kube_upgrade.update(patch)
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError('Kubernetes upgrade UUID not found')
|
||||
|
||||
_print_kube_upgrade_show(kube_upgrade)
|
||||
|
||||
|
||||
def do_kube_upgrade_delete(cc, args):
|
||||
"""Delete a kubernetes upgrade."""
|
||||
|
||||
try:
|
||||
cc.kube_upgrade.delete()
|
||||
except exc.HTTPNotFound:
|
||||
raise exc.CommandError('Kubernetes upgrade not found')
|
||||
|
||||
print("Kubernetes upgrade deleted")
|
||||
@@ -41,6 +41,7 @@ from cgtsclient.v1 import isystem_shell
|
||||
from cgtsclient.v1 import itrapdest_shell
|
||||
from cgtsclient.v1 import iuser_shell
|
||||
|
||||
from cgtsclient.v1 import kube_upgrade_shell
|
||||
from cgtsclient.v1 import kube_version_shell
|
||||
from cgtsclient.v1 import label_shell
|
||||
from cgtsclient.v1 import license_shell
|
||||
@@ -121,6 +122,7 @@ COMMAND_MODULES = [
|
||||
app_shell,
|
||||
host_fs_shell,
|
||||
kube_version_shell,
|
||||
kube_upgrade_shell,
|
||||
]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user