diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..29f6bef5be7a6d93b4bb702c55ea3e7641335391 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,52 @@ +stages: + - build + - deploy + +before_script: + - export KOJI_TARGET=openstackclients7-stein + - export SPEC=python-magnumclient.spec + - export USE_SOURCE_TARBALL=1 + - export DIST='.el7.cern' + - export PKG=$(rpm -q --specfile python-magnumclient.spec --queryformat "%{name}-%{version}-%{release}\n" | head -n1) + +kojicheck: + stage: build + image: gitlab-registry.cern.ch/cloud/ciadm + except: + - cern-stein + - cern-stein-qa + - master + script: + - curl https://gitlab.cern.ch/cloud-infrastructure/cloud-dev/raw/master/gitlab/kojicheck.sh | bash + +kojiscratch: + stage: build + image: gitlab-registry.cern.ch/cloud/ciadm + except: + - cern-stein + - cern-stein-qa + - master + script: + - export SCRATCH=1 + - curl https://gitlab.cern.ch/cloud-infrastructure/cloud-dev/raw/master/gitlab/kojibuild.sh | bash + +deploy qa: + stage: deploy + image: gitlab-registry.cern.ch/cloud/ciadm + environment: qa + only: + - cern-stein-qa + script: + - curl https://gitlab.cern.ch/cloud-infrastructure/cloud-dev/raw/master/gitlab/kojibuild.sh | bash + - echo $SVCBUILD_PASSWORD | kinit svcbuild@CERN.CH + - koji tag ${KOJI_TARGET}-qa $PKG + +deploy production: + stage: deploy + image: gitlab-registry.cern.ch/cloud/ciadm + environment: production + only: + - cern-stein + script: + - echo $SVCBUILD_PASSWORD | kinit svcbuild@CERN.CH + - koji tag ${KOJI_TARGET}-stable $PKG diff --git a/0001-Update-UPPER_CONSTRAINTS_FILE-for-stable-stein.patch b/0001-Update-UPPER_CONSTRAINTS_FILE-for-stable-stein.patch new file mode 100644 index 0000000000000000000000000000000000000000..3bf8d53e3a6ad1c3468dedd308532a363ad6fb63 --- /dev/null +++ b/0001-Update-UPPER_CONSTRAINTS_FILE-for-stable-stein.patch @@ -0,0 +1,48 @@ +From 7c0e9a76f28df2a2c90170dda1cbc3d3c52a6383 Mon Sep 17 00:00:00 2001 +From: OpenStack Release Bot <infra-root@openstack.org> +Date: Mon, 18 Mar 2019 14:52:26 +0000 +Subject: [PATCH 1/4] Update UPPER_CONSTRAINTS_FILE for stable/stein + +Update the URL to the upper-constraints file to point to the redirect +rule on releases.openstack.org so that anyone working on this branch +will switch to the correct upper-constraints list automatically when +the requirements repository branches. + +Until the requirements repository has as stable/stein branch, tests will +continue to use the upper-constraints list on master. + +Change-Id: Ibf849d7f4dd7c59561828798713de0009e3233ff +--- + tox.ini | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tox.ini b/tox.ini +index 64159a8..98b8610 100644 +--- a/tox.ini ++++ b/tox.ini +@@ -11,7 +11,7 @@ setenv = + VIRTUAL_ENV={envdir} + PYTHONWARNINGS=default::DeprecationWarning + deps = +- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} ++ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein} + -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt + commands = +@@ -21,14 +21,14 @@ commands = + [testenv:bandit] + basepython = python3 + deps = +- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} ++ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein} + -r{toxinidir}/test-requirements.txt + commands = bandit -r magnumclient -x tests -n5 -ll + + [testenv:pypy] + basepython = python3 + deps = +- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} ++ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/stein} + setuptools<3.2 + -r{toxinidir}/requirements.txt + -r{toxinidir}/test-requirements.txt diff --git a/0002-python3-fixes.patch b/0002-python3-fixes.patch new file mode 100644 index 0000000000000000000000000000000000000000..1f6eb507ccd9f13154b7cda73bdd6e3c44de9f0e --- /dev/null +++ b/0002-python3-fixes.patch @@ -0,0 +1,126 @@ +From 939f72a2357ff594fa7a7a108faccc10ee0f34ab Mon Sep 17 00:00:00 2001 +From: Jake Yip <jake.yip@unimelb.edu.au> +Date: Wed, 20 Feb 2019 15:37:58 +1100 +Subject: [PATCH 2/4] python3 fixes + +Update uses of b64encode() as describe in OpenStack docs [1]. + +Also add tests. + +[1]: https://wiki.openstack.org/wiki/Python3#Serialization:_base64.2C_JSON.2C_etc. + +Change-Id: I5aa6ba509979e0532d2837153aa5363d1e13631e +(cherry picked from commit 3f7b994acd3eaac2321006b34cebfcb07d924934) +--- + magnumclient/common/utils.py | 10 +++++----- + magnumclient/tests/osc/unit/v1/fakes.py | 12 +++++++++++- + magnumclient/tests/osc/unit/v1/test_clusters.py | 9 ++++++++- + 3 files changed, 24 insertions(+), 7 deletions(-) + +diff --git a/magnumclient/common/utils.py b/magnumclient/common/utils.py +index ee7a2bd..c0d17a7 100644 +--- a/magnumclient/common/utils.py ++++ b/magnumclient/common/utils.py +@@ -15,7 +15,6 @@ + # License for the specific language governing permissions and limitations + # under the License. + +-import base64 + import os + + from cryptography.hazmat.backends import default_backend +@@ -24,6 +23,7 @@ from cryptography.hazmat.primitives import hashes + from cryptography.hazmat.primitives import serialization + from cryptography import x509 + from cryptography.x509.oid import NameOID ++from oslo_serialization import base64 + from oslo_serialization import jsonutils + + from magnumclient import exceptions as exc +@@ -215,9 +215,9 @@ def _config_cluster_kubernetes(cluster, cluster_template, cfg_dir, + " client-key-data: %(key)s\n" + % {'name': cluster.name, + 'api_address': cluster.api_address, +- 'key': base64.b64encode(certs['key']), +- 'cert': base64.b64encode(certs['cert']), +- 'ca': base64.b64encode(certs['ca'])}) ++ 'key': base64.encode_as_text(certs['key']), ++ 'cert': base64.encode_as_text(certs['cert']), ++ 'ca': base64.encode_as_text(certs['ca'])}) + else: + cfg = ("apiVersion: v1\n" + "clusters:\n" +@@ -250,7 +250,7 @@ def _config_cluster_kubernetes(cluster, cluster_template, cfg_dir, + " fi\n" + % {'name': cluster.name, + 'api_address': cluster.api_address, +- 'ca': base64.b64encode(certs['ca'])}) ++ 'ca': base64.encode_as_text(certs['ca'])}) + + if os.path.exists(cfg_file) and not force: + raise exc.CommandError("File %s exists, aborting." % cfg_file) +diff --git a/magnumclient/tests/osc/unit/v1/fakes.py b/magnumclient/tests/osc/unit/v1/fakes.py +index df11d41..3005547 100644 +--- a/magnumclient/tests/osc/unit/v1/fakes.py ++++ b/magnumclient/tests/osc/unit/v1/fakes.py +@@ -62,12 +62,17 @@ class FakeQuotasModelManager(object): + pass + + ++class FakeCertificatesModelManager(FakeBaseModelManager): ++ def get(self, cluster_uuid): ++ pass ++ ++ + class MagnumFakeContainerInfra(object): + def __init__(self): + self.cluster_templates = FakeBaseModelManager() + self.clusters = FakeBaseModelManager() + self.mservices = FakeBaseModelManager() +- self.certificates = FakeBaseModelManager() ++ self.certificates = FakeCertificatesModelManager() + self.stats = FakeStatsModelManager() + self.quotas = FakeQuotasModelManager() + +@@ -237,6 +242,11 @@ class FakeCluster(object): + return cluster + + ++class FakeCert(object): ++ def __init__(self, pem): ++ self.pem = pem ++ ++ + class FakeQuota(object): + """Fake one or more Quota""" + +diff --git a/magnumclient/tests/osc/unit/v1/test_clusters.py b/magnumclient/tests/osc/unit/v1/test_clusters.py +index 4783c13..d4cfd95 100644 +--- a/magnumclient/tests/osc/unit/v1/test_clusters.py ++++ b/magnumclient/tests/osc/unit/v1/test_clusters.py +@@ -37,6 +37,8 @@ class TestCluster(magnum_fakes.TestMagnumClientOSCV1): + super(TestCluster, self).setUp() + + self.clusters_mock = self.app.client_manager.container_infra.clusters ++ self.certificates_mock = \ ++ self.app.client_manager.container_infra.certificates + + + class TestClusterCreate(TestCluster): +@@ -360,10 +362,15 @@ class TestClusterConfig(TestCluster): + self.clusters_mock.get = mock.Mock() + self.clusters_mock.get.return_value = self._cluster + ++ cert = magnum_fakes.FakeCert(pem='foo bar') ++ self.certificates_mock.create = mock.Mock() ++ self.certificates_mock.create.return_value = cert ++ self.certificates_mock.get = mock.Mock() ++ self.certificates_mock.get.return_value = cert ++ + # Fake the cluster_template + attr = dict() + attr['name'] = 'fake-ct' +- attr['tls_disabled'] = True + self._cluster_template = \ + magnum_fakes.FakeClusterTemplate.create_one_cluster_template(attr) + diff --git a/0003-Support-health_status-on-client-side.patch b/0003-Support-health_status-on-client-side.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f8c6ecd99eac907c573d21c5632caec075699c5 --- /dev/null +++ b/0003-Support-health_status-on-client-side.patch @@ -0,0 +1,91 @@ +From 5fe5893b4d7d1e0b223bb26747f13db5257e2215 Mon Sep 17 00:00:00 2001 +From: Feilong Wang <flwang@catalyst.net.nz> +Date: Fri, 1 Mar 2019 11:36:31 +1300 +Subject: [PATCH 3/4] Support health_status on client side + +Task: 29762 +Story: 2002742 + +Depends-on: If702584fabe1402257b45db281561a5f5b83b972 +Change-Id: Iffce9a2cc422bbce70152be3a58d2573e80b104b +(cherry picked from commit 74c5f22c6ffb23154f2e0412ba43371f3c02f3b7) +--- + magnumclient/osc/v1/clusters.py | 5 ++++- + magnumclient/tests/osc/unit/v1/fakes.py | 2 ++ + magnumclient/tests/osc/unit/v1/test_clusters.py | 6 ++++-- + 3 files changed, 10 insertions(+), 3 deletions(-) + +diff --git a/magnumclient/osc/v1/clusters.py b/magnumclient/osc/v1/clusters.py +index d2829fa..fa2bdcb 100644 +--- a/magnumclient/osc/v1/clusters.py ++++ b/magnumclient/osc/v1/clusters.py +@@ -24,6 +24,7 @@ from osc_lib import utils + + CLUSTER_ATTRIBUTES = [ + 'status', ++ 'health_status', + 'cluster_template_id', + 'node_addresses', + 'uuid', +@@ -45,6 +46,7 @@ CLUSTER_ATTRIBUTES = [ + 'name', + 'master_flavor_id', + 'flavor_id', ++ 'health_status_reason', + ] + + +@@ -197,7 +199,8 @@ class ListCluster(command.Lister): + + mag_client = self.app.client_manager.container_infra + columns = [ +- 'uuid', 'name', 'keypair', 'node_count', 'master_count', 'status'] ++ 'uuid', 'name', 'keypair', 'node_count', 'master_count', 'status', ++ 'health_status'] + clusters = mag_client.clusters.list(limit=parsed_args.limit, + sort_key=parsed_args.sort_key, + sort_dir=parsed_args.sort_dir) +diff --git a/magnumclient/tests/osc/unit/v1/fakes.py b/magnumclient/tests/osc/unit/v1/fakes.py +index df11d41..593e0e5 100644 +--- a/magnumclient/tests/osc/unit/v1/fakes.py ++++ b/magnumclient/tests/osc/unit/v1/fakes.py +@@ -205,6 +205,7 @@ class FakeCluster(object): + # set default attributes. + cluster_info = { + 'status': 'CREATE_IN_PROGRESS', ++ 'health_status': 'HEALTHY', + 'cluster_template_id': 'fake-ct', + 'node_addresses': [], + 'uuid': '3a369884-b6ba-484f-a206-919b4b718aff', +@@ -227,6 +228,7 @@ class FakeCluster(object): + 'master_flavor_id': None, + 'flavor_id': 'm1.medium', + 'project_id': None, ++ 'health_status_reason': {'api': 'ok'} + } + + # Overwrite default attributes. +diff --git a/magnumclient/tests/osc/unit/v1/test_clusters.py b/magnumclient/tests/osc/unit/v1/test_clusters.py +index 4783c13..fcb895c 100644 +--- a/magnumclient/tests/osc/unit/v1/test_clusters.py ++++ b/magnumclient/tests/osc/unit/v1/test_clusters.py +@@ -181,7 +181,8 @@ class TestClusterList(TestCluster): + 'keypair', + 'node_count', + 'master_count', +- 'status' ++ 'status', ++ 'health_status' + ] + + datalist = ( +@@ -191,7 +192,8 @@ class TestClusterList(TestCluster): + _cluster.keypair, + _cluster.node_count, + _cluster.master_count, +- _cluster.status ++ _cluster.status, ++ _cluster.health_status, + ), + ) + diff --git a/0004-cern-Support-resize-api.patch b/0004-cern-Support-resize-api.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a85c2c9c39544e4727701cb175a61b6da4713d2 --- /dev/null +++ b/0004-cern-Support-resize-api.patch @@ -0,0 +1,173 @@ +From 9a4b58e088788542a14df9f550dae0bc2a9bbf01 Mon Sep 17 00:00:00 2001 +From: Spyros Trigazis <spyridon.trigazis@cern.ch> +Date: Thu, 20 Jun 2019 00:30:34 +0200 +Subject: [PATCH 4/4] [cern] Support resize api + +Task: 29572 +Story: 2005054 + +cern: drop setup.cfg + +Change-Id: Ic9ede21bbf87883d7dbdf9fde02e7dba24440ce7 +(cherry picked from commit 94380f9ad5e452eb176e7116182e024576db66df) + +Signed-off-by: Spyros Trigazis <spyridon.trigazis@cern.ch> +--- + magnumclient/osc/plugin.py | 10 +++--- + magnumclient/osc/v1/clusters.py | 43 ++++++++++++++++++++++++++ + magnumclient/tests/v1/test_clusters.py | 21 +++++++++++++ + magnumclient/v1/clusters.py | 15 +++++++++ + 4 files changed, 85 insertions(+), 4 deletions(-) + +diff --git a/magnumclient/osc/plugin.py b/magnumclient/osc/plugin.py +index dde56fd..49309c2 100644 +--- a/magnumclient/osc/plugin.py ++++ b/magnumclient/osc/plugin.py +@@ -17,7 +17,8 @@ from osc_lib import utils + + LOG = logging.getLogger(__name__) + +-DEFAULT_API_VERSION = '1' ++DEFAULT_MAJOR_API_VERSION = '1' ++DEFAULT_MAGNUM_API_VERSION = 'latest' + API_VERSION_OPTION = 'os_container_infra_api_version' + API_NAME = 'container_infra' + API_VERSIONS = { +@@ -37,7 +38,8 @@ def make_client(instance): + region_name=instance._region_name, + interface=instance._interface, + insecure=instance._insecure, +- ca_cert=instance._cacert) ++ ca_cert=instance._cacert, ++ api_version=DEFAULT_MAGNUM_API_VERSION) + return client + + +@@ -49,8 +51,8 @@ def build_option_parser(parser): + metavar='<container-infra-api-version>', + default=utils.env( + 'OS_CONTAINER_INFRA_API_VERSION', +- default=DEFAULT_API_VERSION), ++ default=DEFAULT_MAJOR_API_VERSION), + help='Container-Infra API version, default=' + +- DEFAULT_API_VERSION + ++ DEFAULT_MAJOR_API_VERSION + + ' (Env: OS_CONTAINER_INFRA_API_VERSION)') + return parser +diff --git a/magnumclient/osc/v1/clusters.py b/magnumclient/osc/v1/clusters.py +index fa2bdcb..3a34ab8 100644 +--- a/magnumclient/osc/v1/clusters.py ++++ b/magnumclient/osc/v1/clusters.py +@@ -370,3 +370,46 @@ class ConfigCluster(command.Command): + cluster, cluster_template, parsed_args.dir, + force=parsed_args.force, certs=tls, + use_keystone=parsed_args.use_keystone)) ++ ++ ++class ResizeCluster(command.Command): ++ _description = _("Resize a Cluster") ++ ++ def get_parser(self, prog_name): ++ parser = super(ResizeCluster, self).get_parser(prog_name) ++ parser.add_argument( ++ 'cluster', ++ metavar='<cluster>', ++ help=_('The name or UUID of cluster to update')) ++ ++ parser.add_argument( ++ 'node_count', ++ type=int, ++ help=_("Desired node count of the cluser.")) ++ ++ parser.add_argument( ++ '--nodes-to-remove', ++ metavar='<Server UUID>', ++ action='append', ++ help=_("Server ID of the nodes to be removed. Repeat to add" ++ "more server ID")) ++ ++ parser.add_argument( ++ '--nodegroup', ++ metavar='<nodegroup>', ++ help=_('The name or UUID of the nodegroup of current cluster.')) ++ ++ return parser ++ ++ def take_action(self, parsed_args): ++ self.log.debug("take_action(%s)", parsed_args) ++ ++ mag_client = self.app.client_manager.container_infra ++ cluster = mag_client.clusters.get(parsed_args.cluster) ++ ++ mag_client.clusters.resize(cluster.uuid, ++ parsed_args.node_count, ++ parsed_args.nodes_to_remove, ++ parsed_args.nodegroup) ++ print("Request to resize cluster %s has been accepted." % ++ parsed_args.cluster) +diff --git a/magnumclient/tests/v1/test_clusters.py b/magnumclient/tests/v1/test_clusters.py +index dc1a100..2f01745 100644 +--- a/magnumclient/tests/v1/test_clusters.py ++++ b/magnumclient/tests/v1/test_clusters.py +@@ -54,6 +54,10 @@ UPDATED_CLUSTER = copy.deepcopy(CLUSTER1) + NEW_NAME = 'newcluster' + UPDATED_CLUSTER['name'] = NEW_NAME + ++RESIZED_CLUSTER = copy.deepcopy(CLUSTER1) ++RESIZED_NODE_COUNT = 5 ++UPDATED_CLUSTER['node_count'] = RESIZED_NODE_COUNT ++ + fake_responses = { + '/v1/clusters': + { +@@ -145,6 +149,13 @@ fake_responses = { + {'clusters': [CLUSTER2, CLUSTER1]}, + ), + }, ++ '/v1/clusters/%s/actions/resize' % CLUSTER1['uuid']: ++ { ++ 'POST': ( ++ {}, ++ UPDATED_CLUSTER ++ ), ++ } + } + + +@@ -355,3 +366,13 @@ class ClusterManagerTest(testtools.TestCase): + ] + self.assertEqual(expect, self.api.calls) + self.assertEqual(NEW_NAME, cluster.name) ++ ++ def test_cluster_resize(self): ++ body = {'node_count': RESIZED_NODE_COUNT} ++ cluster = self.mgr.resize(CLUSTER1["uuid"], **body) ++ expect = [ ++ ('POST', '/v1/clusters/%s/actions/resize' % CLUSTER1['uuid'], ++ {}, body), ++ ] ++ self.assertEqual(expect, self.api.calls) ++ self.assertEqual(RESIZED_NODE_COUNT, cluster.node_count) +diff --git a/magnumclient/v1/clusters.py b/magnumclient/v1/clusters.py +index cdb599a..c045603 100644 +--- a/magnumclient/v1/clusters.py ++++ b/magnumclient/v1/clusters.py +@@ -32,3 +32,18 @@ class Cluster(baseunit.BaseTemplate): + class ClusterManager(baseunit.BaseTemplateManager): + resource_class = Cluster + template_name = 'clusters' ++ ++ def resize(self, cluster_uuid, node_count, ++ nodes_to_remove=[], nodegroup=None): ++ url = self._path(cluster_uuid) + "/actions/resize" ++ ++ post_body = {"node_count": node_count} ++ if nodes_to_remove: ++ post_body.update({"nodes_to_remove": nodes_to_remove}) ++ if nodegroup: ++ post_body.update({"nodegroup": nodegroup}) ++ ++ resp, resp_body = self.api.json_request("POST", url, body=post_body) ++ ++ if resp_body: ++ return self.resource_class(self, resp_body) diff --git a/python-magnumclient.spec b/python-magnumclient.spec index ea349b7b8e02735219e0ab4910fd95f6e484a294..070584139f408683e1b0ea994a8f5563f6271451 100644 --- a/python-magnumclient.spec +++ b/python-magnumclient.spec @@ -23,7 +23,7 @@ command-line tool (magnum). Name: python-%{pname} Version: 2.12.0 -Release: 1%{?dist} +Release: 1.1%{?dist} Summary: Client library for Magnum API License: ASL 2.0 @@ -31,6 +31,12 @@ URL: https://launchpad.net/python-magnumclient Source0: https://tarballs.openstack.org/%{sname}/%{sname}-%{upstream_version}.tar.gz BuildArch: noarch +Patch0: 0001-Update-UPPER_CONSTRAINTS_FILE-for-stable-stein.patch +Patch1: 0002-python3-fixes.patch +Patch2: 0003-Support-health_status-on-client-side.patch +Patch3: 0004-cern-Support-resize-api.patch + + %description %{common_desc} @@ -142,6 +148,9 @@ rm -rf doc/build/html/.{doctrees,buildinfo} %install %{pyver_install} +# Add resize entrypoint +echo "coe_cluster_resize = magnumclient.osc.v1.clusters:ResizeCluster" >> %{buildroot}/usr/lib/python2.7/site-packages/python_magnumclient-2.12.0-py2.7.egg-info/entry_points.txt + %check # tests are failing due to unicode not defined # we are skipping the test @@ -165,6 +174,9 @@ rm -rf doc/build/html/.{doctrees,buildinfo} %{pyver_sitelib}/%{pname}/tests %changelog +* Wed Jun 19 2019 Spyros Trigazis <spyridon.trigazis@cern.ch> 2.12.0-1.1 +- Rebuild at cern + * Mon Mar 11 2019 RDO <dev@lists.rdoproject.org> 2.12.0-1 - Update to 2.12.0