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:
Bart Wensley
2019-11-21 11:54:04 -06:00
parent 32dc0ce0b4
commit 535879dfd0
39 changed files with 4160 additions and 94 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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'])

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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):

View File

@@ -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

View 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)

View 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")

View File

@@ -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,
]