diff -Nru python-novaclient-10.3.0/AUTHORS python-novaclient-11.0.0/AUTHORS --- python-novaclient-10.3.0/AUTHORS 2018-06-08 14:28:23.000000000 +0000 +++ python-novaclient-11.0.0/AUTHORS 2018-07-26 22:34:23.000000000 +0000 @@ -61,6 +61,7 @@ Brian Elliott Brian Lamar Brian Waldon +Brianna Poulos Cao ShuFeng Cao Shufeng Carlos Goncalves @@ -68,6 +69,7 @@ Chang Bo Guo ChangBo Guo(gcb) Chaozhe.Chen +Chen Chen Hanxiao Chmouel Boudjnah Chmouel Boudjnah @@ -160,6 +162,7 @@ Istvan Imre JUN JIE NAN Jacek Tomasiak +Jackie Truong Jake Dahn Jake Yip Jakub Ruzicka @@ -375,6 +378,7 @@ Vincent Untz Vishvananda Ishaya Vitaliy Kolosov +Vu Cong Tuan Wang Wei William Wolf Wu Wenxiang @@ -459,6 +463,7 @@ sampathP sathish-nagappan shihanzhang +shilpa.devharakar shu-mutou sonu.kumar sridhargaddam @@ -470,6 +475,7 @@ vnathan wangxiyuan wingwj +wu.chunyang xiexs yamini sardana yanghuichan diff -Nru python-novaclient-10.3.0/ChangeLog python-novaclient-11.0.0/ChangeLog --- python-novaclient-10.3.0/ChangeLog 2018-06-08 14:28:23.000000000 +0000 +++ python-novaclient-11.0.0/ChangeLog 2018-07-26 22:34:22.000000000 +0000 @@ -1,6 +1,25 @@ CHANGES ======= +11.0.0 +------ + +* Fix the help text for server-group-create +* Fix inconsistency +* Add support for microversion 2.65 +* Microversion 2.64 - Use new format policy in server group +* Switch to stestr +* Rename --endpoint-override to --os-endpoint-override +* Add release note link in README +* Fix help text in server-group-create +* Fix trusted-image-certificate-id help text +* Microversion 2.63 - Add trusted\_image\_certificates +* Add CLI docs reference for flavor-update +* Remove doc/build when building docs +* Modify novaclient to support basic attributes +* Remove PyPI downloads +* fix tox python3 overrides + 10.3.0 ------ diff -Nru python-novaclient-10.3.0/debian/changelog python-novaclient-11.0.0/debian/changelog --- python-novaclient-10.3.0/debian/changelog 2018-06-12 15:17:24.000000000 +0000 +++ python-novaclient-11.0.0/debian/changelog 2018-08-01 18:53:28.000000000 +0000 @@ -1,3 +1,9 @@ +python-novaclient (2:11.0.0-0ubuntu1) cosmic; urgency=medium + + * New upstream release for OpenStack Rocky. + + -- Corey Bryant Wed, 01 Aug 2018 14:53:28 -0400 + python-novaclient (2:10.3.0-0ubuntu1) cosmic; urgency=low * Merge from Debian unstable. Remaining changes: diff -Nru python-novaclient-10.3.0/doc/source/cli/nova.rst python-novaclient-11.0.0/doc/source/cli/nova.rst --- python-novaclient-10.3.0/doc/source/cli/nova.rst 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/doc/source/cli/nova.rst 2018-07-26 22:31:29.000000000 +0000 @@ -33,7 +33,7 @@ [--service-name ] [--os-endpoint-type ] [--os-compute-api-version ] - [--endpoint-override ] [--profile HMAC_KEY] + [--os-endpoint-override ] [--profile HMAC_KEY] [--insecure] [--os-cacert ] [--os-cert ] [--os-key ] [--timeout ] [--os-auth-type ] [--os-auth-url OS_AUTH_URL] @@ -218,7 +218,7 @@ Evacuate all instances from failed host. ``host-evacuate-live`` - Live migrate all instances of the specified + Live migrate all instances off the specified host to other available hosts. ``host-list`` @@ -678,10 +678,10 @@ minor part) or "X.latest", defaults to ``env[OS_COMPUTE_API_VERSION]``. -``--endpoint-override `` +``--os-endpoint-override `` Use this API endpoint instead of the Service Catalog. Defaults to - ``env[NOVACLIENT_ENDPOINT_OVERRIDE]``. + ``env[OS_ENDPOINT_OVERRIDE]``. ``--profile HMAC_KEY`` HMAC key to use for encrypting context data @@ -1011,6 +1011,7 @@ [--config-drive ] [--poll] [--admin-pass ] [--access-ip-v4 ] [--access-ip-v6 ] [--description ] + [--trusted-image-certificate-id ] Boot a new server. @@ -1164,6 +1165,13 @@ Description for the server. (Supported by API versions '2.19' - '2.latest') +``--trusted-image-certificate-id `` + Trusted image certificate IDs used to validate certificates + during the image signature verification process. + Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. + May be specified multiple times to pass multiple trusted image + certificate IDs. (Supported by API versions '2.63' - '2.latest') + .. _nova_cell-capacities: nova cell-capacities @@ -1499,6 +1507,29 @@ ```` Name or ID of flavor. +nova flavor-update +------------------ + +.. code-block:: console + + usage: nova flavor-update + +Update the description of an existing flavor. +(Supported by API versions '2.55' - '2.latest') +[hint: use '--os-compute-api-version' flag to show help message for proper +version] + +.. versionadded:: 10.0.0 + +**Positional arguments** + +```` + Name or ID of the flavor to update. + +```` + A free form description of the flavor. Limited to 65535 + characters in length. Only printable characters are allowed. + .. _nova_force-delete: nova force-delete @@ -1672,7 +1703,7 @@ [--max-servers ] [--force] -Live migrate all instances of the specified host to other available hosts. +Live migrate all instances off the specified host to other available hosts. **Positional arguments:** @@ -2290,6 +2321,10 @@ '2.latest') [hint: use '--os-compute-api-version' flag to show help message for proper version] +For microversions from 2.24 to 2.64 the migration status must be ``running``; +for microversion 2.65 and greater, the migration status can also be ``queued`` +and ``preparing``. + **Positional arguments:** ```` @@ -2660,6 +2695,8 @@ [--minimal] [--preserve-ephemeral] [--name ] [--description ] [--meta ] [--file ] + [--trusted-image-certificate-id ] + [--trusted-image-certificates-unset] Shutdown, re-image, and re-boot a server. @@ -2707,6 +2744,18 @@ to on the new server. You may store up to 5 files. +``--trusted-image-certificate-id `` + Trusted image certificate IDs used to validate certificates + during the image signature verification process. + Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. + May be specified multiple times to pass multiple trusted image + certificate IDs. (Supported by API versions '2.63' - '2.latest') + +``--trusted-image-certificates-unset`` + Unset trusted_image_certificates in the server. Cannot be + specified with the ``--trusted-image-certificate-id`` option. + (Supported by API versions '2.63' - '2.latest') + .. _nova_refresh-network: nova refresh-network @@ -2906,7 +2955,7 @@ .. code-block:: console - usage: nova server-group-create [ ...] + usage: nova server-group-create [--rules ] Create a new server group with the specified details. @@ -2916,7 +2965,15 @@ Server group name. ```` - Policies for the server groups. + Policy for the server groups. + +``--rule`` + Policy rules for the server groups. (Supported by API versions + '2.64' - '2.latest'). Currently, only the ``max_server_per_host`` rule + is supported for the ``anti-affinity`` policy. The ``max_server_per_host`` + rule allows specifying how many members of the anti-affinity group can + reside on the same compute host. If not specified, only one member from + the same anti-affinity group can reside on a given host. .. _nova_server-group-delete: diff -Nru python-novaclient-10.3.0/doc/source/user/shell.rst python-novaclient-11.0.0/doc/source/user/shell.rst --- python-novaclient-10.3.0/doc/source/user/shell.rst 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/doc/source/user/shell.rst 2018-07-26 22:31:29.000000000 +0000 @@ -60,6 +60,16 @@ The Keystone region name. Defaults to the first region if multiple regions are available. +.. envvar:: OS_TRUSTED_IMAGE_CERTIFICATE_IDS + + A comma-delimited list of trusted image certificate IDs. Only used + with the ``nova boot`` and ``nova rebuild`` commands starting with the + 2.63 microversion. + + For example:: + + export OS_TRUSTED_IMAGE_CERTIFICATE_IDS=trusted-cert-id1,trusted-cert-id2 + For example, in Bash you'd use:: export OS_USERNAME=yourname diff -Nru python-novaclient-10.3.0/lower-constraints.txt python-novaclient-11.0.0/lower-constraints.txt --- python-novaclient-10.3.0/lower-constraints.txt 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/lower-constraints.txt 2018-07-26 22:31:29.000000000 +0000 @@ -10,6 +10,7 @@ contextlib2==0.4.0 coverage==4.0 cryptography==2.1 +ddt==1.0.1 debtcollector==1.2.0 decorator==3.4.0 deprecation==1.0 @@ -47,7 +48,6 @@ openstacksdk==0.11.2 os-client-config==1.28.0 os-service-types==1.2.0 -os-testr==1.0.0 osc-lib==1.8.0 oslo.concurrency==3.25.0 oslo.config==5.2.0 @@ -87,7 +87,7 @@ PyYAML==3.12 repoze.lru==0.7 requests==2.14.2 -requests-mock==1.1.0 +requests-mock==1.2.0 requestsexceptions==1.2.0 rfc3986==0.3.1 Routes==2.3.1 @@ -95,11 +95,10 @@ six==1.10.0 smmap==0.9.0 statsd==3.2.1 -stestr==1.0.0 stevedore==1.20.0 tempest==17.1.0 tenacity==3.2.1 -testrepository==0.0.18 +stestr==2.0.0 testscenarios==0.4 testtools==2.2.0 traceback2==1.4.0 diff -Nru python-novaclient-10.3.0/novaclient/__init__.py python-novaclient-11.0.0/novaclient/__init__.py --- python-novaclient-10.3.0/novaclient/__init__.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/__init__.py 2018-07-26 22:31:29.000000000 +0000 @@ -25,4 +25,4 @@ # when client supported the max version, and bumped sequentially, otherwise # the client may break due to server side new version may include some # backward incompatible change. -API_MAX_VERSION = api_versions.APIVersion("2.62") +API_MAX_VERSION = api_versions.APIVersion("2.65") diff -Nru python-novaclient-10.3.0/novaclient/shell.py python-novaclient-11.0.0/novaclient/shell.py --- python-novaclient-10.3.0/novaclient/shell.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/shell.py 2018-07-26 22:31:29.000000000 +0000 @@ -270,6 +270,14 @@ 'OS_PROJECT_NAME', 'OS_TENANT_NAME', 'NOVA_PROJECT_ID')) parser.set_defaults(os_project_id=utils.env( 'OS_PROJECT_ID', 'OS_TENANT_ID')) + parser.set_defaults( + os_project_domain_id=utils.env('OS_PROJECT_DOMAIN_ID')) + parser.set_defaults( + os_project_domain_name=utils.env('OS_PROJECT_DOMAIN_NAME')) + parser.set_defaults( + os_user_domain_id=utils.env('OS_USER_DOMAIN_ID')) + parser.set_defaults( + os_user_domain_name=utils.env('OS_USER_DOMAIN_NAME')) def get_base_parser(self, argv): parser = NovaClientArgumentParser( @@ -350,19 +358,32 @@ '"X.latest", defaults to env[OS_COMPUTE_API_VERSION].')) parser.add_argument( - '--endpoint-override', + '--os-endpoint-override', metavar='', dest='endpoint_override', - default=utils.env('NOVACLIENT_ENDPOINT_OVERRIDE', + default=utils.env('OS_ENDPOINT_OVERRIDE', + 'NOVACLIENT_ENDPOINT_OVERRIDE', 'NOVACLIENT_BYPASS_URL'), help=_("Use this API endpoint instead of the Service Catalog. " - "Defaults to env[NOVACLIENT_ENDPOINT_OVERRIDE].")) + "Defaults to env[OS_ENDPOINT_OVERRIDE].")) + + # NOTE(takashin): This dummy '--end' argument was added + # to avoid misinterpreting command line arguments. + # If there is not this dummy argument, the '--end' is interpreted to + # the '--endpoint-override'. + # TODO(takashin): Remove this dummy '--end' argument + # when the deprecated '--endpoint-override' argument is removed. + parser.add_argument( + '--end', + metavar='', + nargs='?', + help=argparse.SUPPRESS) parser.add_argument( - '--bypass-url', + '--endpoint-override', action=DeprecatedAction, - use=_('use "%s"; this option will be removed after Pike OpenStack ' - 'release.') % '--os-endpoint-override', + use=_('use "%s"; this option will be removed after Rocky ' + 'OpenStack release.') % '--os-endpoint-override', dest='endpoint_override', help=argparse.SUPPRESS) @@ -596,6 +617,26 @@ _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL].")) + # TODO(Shilpasd): need to provide support in python - novaclient + # for required options for below default auth type plugins: + # 1. v3oidcclientcredential + # 2. v3oidcpassword + # 3. v3oidcauthcode + # 4. v3oidcaccesstoken + # 5. v3oauth1 + # 6. v3fedkerb + # 7. v3adfspassword + # 8. v3samlpassword + # 9. v3applicationcredential + # TODO(Shilpasd): need to provide support in python - novaclient + # for below extra keystoneauth auth type plugins: + # We will need to add code to support discovering of versions + # supported by the keystone service based on the auth_url similar + # to the one supported by glanceclient. + # 1. v3password + # 2. v3token + # 3. v3kerberos + # 4. v3totp with utils.record_time(self.times, args.timings, 'auth_url', args.os_auth_url): keystone_session = ( diff -Nru python-novaclient-10.3.0/novaclient/tests/functional/v2/legacy/test_readonly_nova.py python-novaclient-11.0.0/novaclient/tests/functional/v2/legacy/test_readonly_nova.py --- python-novaclient-10.3.0/novaclient/tests/functional/v2/legacy/test_readonly_nova.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/functional/v2/legacy/test_readonly_nova.py 2018-07-26 22:31:29.000000000 +0000 @@ -124,4 +124,4 @@ self.assertRaises(exceptions.CommandFailed, self.nova, 'list', - flags='--endpoint-override badurl') + flags='--os-endpoint-override badurl') diff -Nru python-novaclient-10.3.0/novaclient/tests/functional/v2/test_server_groups.py python-novaclient-11.0.0/novaclient/tests/functional/v2/test_server_groups.py --- python-novaclient-10.3.0/novaclient/tests/functional/v2/test_server_groups.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/functional/v2/test_server_groups.py 2018-07-26 22:31:29.000000000 +0000 @@ -17,7 +17,9 @@ class TestServerGroupClientV213(test_server_groups.TestServerGroupClient): """Server groups v2.13 functional tests.""" - COMPUTE_API_VERSION = "2.latest" + COMPUTE_API_VERSION = "2.13" + expected_metadata = True + expected_policy_rules = False def test_create_server_group(self): sg_id = self._create_sg("affinity") @@ -29,6 +31,11 @@ self._get_column_value_from_single_row_table( sg, "Project Id") self.assertEqual(sg_id, result) + self._get_column_value_from_single_row_table(sg, "Metadata") + self.assertIn( + 'affinity', + self._get_column_value_from_single_row_table(sg, 'Policies')) + self.assertNotIn('Rules', sg) def test_list_server_groups(self): sg_id = self._create_sg("affinity") @@ -40,6 +47,22 @@ self._get_column_value_from_single_row_table( sg, "Project Id") self.assertEqual(sg_id, result) + if self.expected_metadata: + self._get_column_value_from_single_row_table(sg, "Metadata") + else: + self.assertNotIn(sg, 'Metadata') + if self.expected_policy_rules: + self.assertEqual( + 'affinity', + self._get_column_value_from_single_row_table(sg, "Policy")) + self.assertEqual( + '{}', + self._get_column_value_from_single_row_table(sg, "Rules")) + else: + self.assertIn( + 'affinity', + self._get_column_value_from_single_row_table(sg, 'Policies')) + self.assertNotIn('Rules', sg) def test_get_server_group(self): sg_id = self._create_sg("affinity") @@ -51,3 +74,47 @@ self._get_column_value_from_single_row_table( sg, "Project Id") self.assertEqual(sg_id, result) + if self.expected_metadata: + self._get_column_value_from_single_row_table(sg, "Metadata") + else: + self.assertNotIn(sg, 'Metadata') + if self.expected_policy_rules: + self.assertEqual( + 'affinity', + self._get_column_value_from_single_row_table(sg, "Policy")) + self.assertEqual( + '{}', + self._get_column_value_from_single_row_table(sg, "Rules")) + else: + self.assertIn( + 'affinity', + self._get_column_value_from_single_row_table(sg, 'Policies')) + self.assertNotIn('Rules', sg) + + +class TestServerGroupClientV264(TestServerGroupClientV213): + """Server groups v2.64 functional tests.""" + + COMPUTE_API_VERSION = "2.64" + expected_metadata = False + expected_policy_rules = True + + def test_create_server_group(self): + output = self.nova('server-group-create complex-anti-affinity-group ' + 'anti-affinity --rule max_server_per_host=3') + sg_id = self._get_column_value_from_single_row_table(output, "Id") + self.addCleanup(self.nova, 'server-group-delete %s' % sg_id) + sg = self.nova('server-group-get %s' % sg_id) + result = self._get_column_value_from_single_row_table(sg, "Id") + self.assertEqual(sg_id, result) + self._get_column_value_from_single_row_table( + sg, "User Id") + self._get_column_value_from_single_row_table( + sg, "Project Id") + self.assertNotIn('Metadata', sg) + self.assertEqual( + 'anti-affinity', + self._get_column_value_from_single_row_table(sg, "Policy")) + self.assertIn( + 'max_server_per_host', + self._get_column_value_from_single_row_table(sg, "Rules")) diff -Nru python-novaclient-10.3.0/novaclient/tests/unit/test_shell.py python-novaclient-11.0.0/novaclient/tests/unit/test_shell.py --- python-novaclient-10.3.0/novaclient/tests/unit/test_shell.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/unit/test_shell.py 2018-07-26 22:31:29.000000000 +0000 @@ -16,6 +16,7 @@ import re import sys +import ddt import fixtures from keystoneauth1 import fixture import mock @@ -35,7 +36,11 @@ 'OS_PASSWORD': 'password', 'OS_TENANT_NAME': 'tenant_name', 'OS_AUTH_URL': 'http://no.where/v2.0', - 'OS_COMPUTE_API_VERSION': '2'} + 'OS_COMPUTE_API_VERSION': '2', + 'OS_PROJECT_DOMAIN_ID': 'default', + 'OS_PROJECT_DOMAIN_NAME': 'default', + 'OS_USER_DOMAIN_ID': 'default', + 'OS_USER_DOMAIN_NAME': 'default'} FAKE_ENV2 = {'OS_USER_ID': 'user_id', 'OS_PASSWORD': 'password', @@ -349,6 +354,7 @@ self.assertTrue(args.tic_tac) +@ddt.ddt class ShellTest(utils.TestCase): _msg_no_tenant_project = ("You must provide a project name or project" @@ -521,6 +527,23 @@ else: self.fail('CommandError not raised') + @ddt.data( + (None, 'project_domain_id', FAKE_ENV['OS_PROJECT_DOMAIN_ID']), + ('OS_PROJECT_DOMAIN_ID', 'project_domain_id', ''), + (None, 'project_domain_name', FAKE_ENV['OS_PROJECT_DOMAIN_NAME']), + ('OS_PROJECT_DOMAIN_NAME', 'project_domain_name', ''), + (None, 'user_domain_id', FAKE_ENV['OS_USER_DOMAIN_ID']), + ('OS_USER_DOMAIN_ID', 'user_domain_id', ''), + (None, 'user_domain_name', FAKE_ENV['OS_USER_DOMAIN_NAME']), + ('OS_USER_DOMAIN_NAME', 'user_domain_name', '') + ) + @ddt.unpack + def test_basic_attributes(self, exclude, client_arg, env_var): + self.make_env(exclude=exclude, fake_env=FAKE_ENV) + self.shell('list') + client_kwargs = self.mock_client.call_args_list[0][1] + self.assertEqual(env_var, client_kwargs[client_arg]) + @requests_mock.Mocker() def test_nova_endpoint_type(self, m_requests): self.make_env(fake_env=FAKE_ENV3) diff -Nru python-novaclient-10.3.0/novaclient/tests/unit/v2/fakes.py python-novaclient-11.0.0/novaclient/tests/unit/v2/fakes.py --- python-novaclient-10.3.0/novaclient/tests/unit/v2/fakes.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/unit/v2/fakes.py 2018-07-26 22:31:29.000000000 +0000 @@ -2236,8 +2236,13 @@ return (200, {}, {"server_groups": server_groups}) def _return_server_group(self): - r = {'server_group': - self.get_os_server_groups()[2]['server_groups'][0]} + if self.api_version < api_versions.APIVersion("2.64"): + r = {'server_group': + self.get_os_server_groups()[2]['server_groups'][0]} + else: + r = {"members": [], "id": "2cbd51f4-fafe-4cdb-801b-cf913a6f288b", + 'server_group': {'name': 'ig1', 'policy': 'anti-affinity', + 'rules': {'max_server_per_host': 3}}} return (200, {}, r) def post_os_server_groups(self, body, **kw): diff -Nru python-novaclient-10.3.0/novaclient/tests/unit/v2/test_server_groups.py python-novaclient-11.0.0/novaclient/tests/unit/v2/test_server_groups.py --- python-novaclient-10.3.0/novaclient/tests/unit/v2/test_server_groups.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/unit/v2/test_server_groups.py 2018-07-26 22:31:29.000000000 +0000 @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. +from novaclient import api_versions from novaclient import exceptions from novaclient.tests.unit.fixture_data import client from novaclient.tests.unit.fixture_data import server_groups as data @@ -106,3 +107,36 @@ self.cs.server_groups.find, **kwargs) self.assert_called('GET', '/os-server-groups') + + +class ServerGroupsTestV264(ServerGroupsTest): + def setUp(self): + super(ServerGroupsTestV264, self).setUp() + self.cs.api_version = api_versions.APIVersion("2.64") + + def test_create_server_group(self): + name = 'ig1' + policy = 'anti-affinity' + server_group = self.cs.server_groups.create(name, policy) + self.assert_request_id(server_group, fakes.FAKE_REQUEST_ID_LIST) + body = {'server_group': {'name': name, 'policy': policy}} + self.assert_called('POST', '/os-server-groups', body) + self.assertIsInstance(server_group, + server_groups.ServerGroup) + + def test_create_server_group_with_rules(self): + kwargs = {'name': 'ig1', + 'policy': 'anti-affinity', + 'rules': {'max_server_per_host': 3}} + server_group = self.cs.server_groups.create(**kwargs) + self.assert_request_id(server_group, fakes.FAKE_REQUEST_ID_LIST) + body = { + 'server_group': { + 'name': 'ig1', + 'policy': 'anti-affinity', + 'rules': {'max_server_per_host': 3} + } + } + self.assert_called('POST', '/os-server-groups', body) + self.assertIsInstance(server_group, + server_groups.ServerGroup) diff -Nru python-novaclient-10.3.0/novaclient/tests/unit/v2/test_servers.py python-novaclient-11.0.0/novaclient/tests/unit/v2/test_servers.py --- python-novaclient-10.3.0/novaclient/tests/unit/v2/test_servers.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/unit/v2/test_servers.py 2018-07-26 22:31:29.000000000 +0000 @@ -1542,3 +1542,70 @@ exceptions.UnsupportedAttribute, s.rebuild, image=1, name='new', meta={'foo': 'bar'}, files=files) self.assertIn('files', six.text_type(ex)) + + +class ServersV263Test(ServersV257Test): + + api_version = "2.63" + + def test_create_server_with_trusted_image_certificates(self): + self.cs.servers.create( + name="My server", + image=1, + flavor=1, + meta={'foo': 'bar'}, + userdata="hello moto", + key_name="fakekey", + nics=self._get_server_create_default_nics(), + trusted_image_certificates=['id1', 'id2'], + ) + self.assert_called('POST', '/servers', + {'server': { + 'flavorRef': '1', + 'imageRef': '1', + 'key_name': 'fakekey', + 'max_count': 1, + 'metadata': {'foo': 'bar'}, + 'min_count': 1, + 'name': 'My server', + 'networks': 'auto', + 'trusted_image_certificates': ['id1', 'id2'], + 'user_data': 'aGVsbG8gbW90bw==' + }} + ) + + def test_create_server_with_trusted_image_certificates_pre_263_fails(self): + self.cs.api_version = api_versions.APIVersion('2.62') + ex = self.assertRaises( + exceptions.UnsupportedAttribute, self.cs.servers.create, + name="My server", image=1, flavor=1, meta={'foo': 'bar'}, + userdata="hello moto", key_name="fakekey", + nics=self._get_server_create_default_nics(), + trusted_image_certificates=['id1', 'id2']) + self.assertIn('trusted_image_certificates', six.text_type(ex)) + + def test_rebuild_server_with_trusted_image_certificates(self): + s = self.cs.servers.get(1234) + ret = s.rebuild(image="1", trusted_image_certificates=['id1', 'id2']) + self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': { + 'imageRef': '1', + 'trusted_image_certificates': ['id1', 'id2']}}) + + def test_rebuild_server_with_trusted_image_certificates_none(self): + s = self.cs.servers.get(1234) + ret = s.rebuild(image="1", trusted_image_certificates=None) + self.assert_request_id(ret, fakes.FAKE_REQUEST_ID_LIST) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': { + 'imageRef': '1', + 'trusted_image_certificates': None}}) + + def test_rebuild_with_trusted_image_certificates_pre_263_fails(self): + self.cs.api_version = api_versions.APIVersion('2.62') + ex = self.assertRaises(exceptions.UnsupportedAttribute, + self.cs.servers.rebuild, + '1234', fakes.FAKE_IMAGE_UUID_1, + trusted_image_certificates=['id1', 'id2']) + self.assertIn('trusted_image_certificates', six.text_type(ex)) diff -Nru python-novaclient-10.3.0/novaclient/tests/unit/v2/test_shell.py python-novaclient-11.0.0/novaclient/tests/unit/v2/test_shell.py --- python-novaclient-10.3.0/novaclient/tests/unit/v2/test_shell.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/tests/unit/v2/test_shell.py 2018-07-26 22:31:29.000000000 +0000 @@ -1155,6 +1155,113 @@ self.assertRaises(SystemExit, self.run_command, cmd, api_version='2.51') + def test_boot_with_single_trusted_image_certificates(self): + self.run_command('boot --flavor 1 --image %s --nic auto some-server ' + '--trusted-image-certificate-id id1' + % FAKE_UUID_1, api_version='2.63') + self.assert_called_anytime( + 'POST', '/servers', + {'server': { + 'flavorRef': '1', + 'name': 'some-server', + 'imageRef': FAKE_UUID_1, + 'min_count': 1, + 'max_count': 1, + 'networks': 'auto', + 'trusted_image_certificates': ['id1'] + }}, + ) + + def test_boot_with_multiple_trusted_image_certificates(self): + self.run_command('boot --flavor 1 --image %s --nic auto some-server ' + '--trusted-image-certificate-id id1 ' + '--trusted-image-certificate-id id2' + % FAKE_UUID_1, api_version='2.63') + self.assert_called_anytime( + 'POST', '/servers', + {'server': { + 'flavorRef': '1', + 'name': 'some-server', + 'imageRef': FAKE_UUID_1, + 'min_count': 1, + 'max_count': 1, + 'networks': 'auto', + 'trusted_image_certificates': ['id1', 'id2'] + }}, + ) + + def test_boot_with_trusted_image_certificates_envar(self): + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2')) + self.run_command('boot --flavor 1 --image %s --nic auto some-server' + % FAKE_UUID_1, api_version='2.63') + self.assert_called_anytime( + 'POST', '/servers', + {'server': { + 'flavorRef': '1', + 'name': 'some-server', + 'imageRef': FAKE_UUID_1, + 'min_count': 1, + 'max_count': 1, + 'networks': 'auto', + 'trusted_image_certificates': ['var_id1', 'var_id2'] + }}, + ) + + def test_boot_without_trusted_image_certificates_v263(self): + self.run_command('boot --flavor 1 --image %s --nic auto some-server' + % FAKE_UUID_1, api_version='2.63') + self.assert_called_anytime( + 'POST', '/servers', + {'server': { + 'flavorRef': '1', + 'name': 'some-server', + 'imageRef': FAKE_UUID_1, + 'min_count': 1, + 'max_count': 1, + 'networks': 'auto', + }}, + ) + + def test_boot_with_trusted_image_certificates_pre_v263(self): + cmd = ('boot --flavor 1 --image %s some-server ' + '--trusted-image-certificate-id id1 ' + '--trusted-image-certificate-id id2' % FAKE_UUID_1) + self.assertRaises(SystemExit, self.run_command, + cmd, api_version='2.62') + + # OS_TRUSTED_IMAGE_CERTIFICATE_IDS environment variable is not supported in + # microversions < 2.63 (should result in an UnsupportedAttribute exception) + def test_boot_with_trusted_image_certificates_envar_pre_v263(self): + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2')) + cmd = ('boot --flavor 1 --image %s --nic auto some-server ' + % FAKE_UUID_1) + self.assertRaises(exceptions.UnsupportedAttribute, self.run_command, + cmd, api_version='2.62') + + def test_boot_with_trusted_image_certificates_arg_and_envvar(self): + """Tests that if both the environment variable and argument are + specified, the argument takes precedence. + """ + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'cert1')) + self.run_command('boot --flavor 1 --image %s --nic auto ' + '--trusted-image-certificate-id cert2 some-server' + % FAKE_UUID_1, api_version='2.63') + self.assert_called_anytime( + 'POST', '/servers', + {'server': { + 'flavorRef': '1', + 'name': 'some-server', + 'imageRef': FAKE_UUID_1, + 'min_count': 1, + 'max_count': 1, + 'networks': 'auto', + 'trusted_image_certificates': ['cert2'] + }}, + ) + def test_flavor_list(self): out, _ = self.run_command('flavor-list') self.assert_called_anytime('GET', '/flavors/detail') @@ -1664,6 +1771,148 @@ self.assertIn("Cannot specify '--user-data-unset' with " "'--user-data'.", six.text_type(ex)) + def test_rebuild_with_single_trusted_image_certificates(self): + self.run_command('rebuild sample-server %s ' + '--trusted-image-certificate-id id1' + % FAKE_UUID_1, api_version='2.63') + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + 'trusted_image_certificates': ['id1'] + } + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + + def test_rebuild_with_multiple_trusted_image_certificate_ids(self): + self.run_command('rebuild sample-server %s ' + '--trusted-image-certificate-id id1 ' + '--trusted-image-certificate-id id2' + % FAKE_UUID_1, api_version='2.63') + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + 'trusted_image_certificates': ['id1', + 'id2'] + } + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + + def test_rebuild_with_trusted_image_certificates_envar(self): + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2')) + self.run_command('rebuild sample-server %s' + % FAKE_UUID_1, api_version='2.63') + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + 'trusted_image_certificates': + ['var_id1', 'var_id2']} + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + + def test_rebuild_without_trusted_image_certificates_v263(self): + self.run_command('rebuild sample-server %s' % FAKE_UUID_1, + api_version='2.63') + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + } + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + + def test_rebuild_with_trusted_image_certificates_pre_v263(self): + cmd = ('rebuild sample-server %s' + '--trusted-image-certificate-id id1 ' + '--trusted-image-certificate-id id2' % FAKE_UUID_1) + self.assertRaises(SystemExit, self.run_command, + cmd, api_version='2.62') + + # OS_TRUSTED_IMAGE_CERTIFICATE_IDS environment variable is not supported in + # microversions < 2.63 (should result in an UnsupportedAttribute exception) + def test_rebuild_with_trusted_image_certificates_envar_pre_v263(self): + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1,var_id2')) + cmd = ('rebuild sample-server %s' % FAKE_UUID_1) + self.assertRaises(exceptions.UnsupportedAttribute, self.run_command, + cmd, api_version='2.62') + + def test_rebuild_with_trusted_image_certificates_unset(self): + """Tests explicitly unsetting the existing server trusted image + certificate IDs. + """ + self.run_command('rebuild sample-server %s ' + '--trusted-image-certificates-unset' + % FAKE_UUID_1, api_version='2.63') + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + 'trusted_image_certificates': None + } + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + + def test_rebuild_with_trusted_image_certificates_unset_arg_conflict(self): + """Tests the error condition that trusted image certs are both unset + and set via argument during rebuild. + """ + ex = self.assertRaises( + exceptions.CommandError, self.run_command, + 'rebuild sample-server %s --trusted-image-certificate-id id1 ' + '--trusted-image-certificates-unset' % FAKE_UUID_1, + api_version='2.63') + self.assertIn("Cannot specify '--trusted-image-certificates-unset' " + "with '--trusted-image-certificate-id'", + six.text_type(ex)) + + def test_rebuild_with_trusted_image_certificates_unset_env_conflict(self): + """Tests the error condition that trusted image certs are both unset + and set via environment variable during rebuild. + """ + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'var_id1')) + ex = self.assertRaises( + exceptions.CommandError, self.run_command, + 'rebuild sample-server %s --trusted-image-certificates-unset' % + FAKE_UUID_1, api_version='2.63') + self.assertIn("Cannot specify '--trusted-image-certificates-unset' " + "with '--trusted-image-certificate-id'", + six.text_type(ex)) + + def test_rebuild_with_trusted_image_certificates_arg_and_envar(self): + """Tests that if both the environment variable and argument are + specified, the argument takes precedence. + """ + self.useFixture(fixtures.EnvironmentVariable( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS', 'cert1')) + self.run_command('rebuild sample-server ' + '--trusted-image-certificate-id cert2 %s' + % FAKE_UUID_1, api_version='2.63') + self.assert_called('GET', '/servers?name=sample-server', pos=0) + self.assert_called('GET', '/servers/1234', pos=1) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_1, pos=2) + self.assert_called('POST', '/servers/1234/action', + {'rebuild': {'imageRef': FAKE_UUID_1, + 'description': None, + 'trusted_image_certificates': + ['cert2']} + }, pos=3) + self.assert_called('GET', '/v2/images/%s' % FAKE_UUID_2, pos=4) + def test_start(self): self.run_command('start sample-server') self.assert_called('POST', '/servers/1234/action', {'os-start': None}) @@ -3479,6 +3728,48 @@ {'server_group': {'name': 'wjsg', 'policies': ['affinity']}}) + def test_create_server_group_v2_64(self): + self.run_command('server-group-create sg1 affinity', + api_version='2.64') + self.assert_called('POST', '/os-server-groups', + {'server_group': { + 'name': 'sg1', + 'policy': 'affinity' + }}) + + def test_create_server_group_with_rules(self): + self.run_command('server-group-create sg1 anti-affinity ' + '--rule max_server_per_host=3', api_version='2.64') + self.assert_called('POST', '/os-server-groups', + {'server_group': { + 'name': 'sg1', + 'policy': 'anti-affinity', + 'rules': {'max_server_per_host': 3} + }}) + + def test_create_server_group_with_multi_rules(self): + self.run_command('server-group-create sg1 anti-affinity ' + '--rule a=b --rule c=d', api_version='2.64') + self.assert_called('POST', '/os-server-groups', + {'server_group': { + 'name': 'sg1', + 'policy': 'anti-affinity', + 'rules': {'a': 'b', 'c': 'd'} + }}) + + def test_create_server_group_with_invalid_value(self): + result = self.assertRaises( + exceptions.CommandError, self.run_command, + 'server-group-create sg1 anti-affinity ' + '--rule max_server_per_host=foo', api_version='2.64') + self.assertIn("Invalid 'max_server_per_host' value: foo", + six.text_type(result)) + + def test_create_server_group_with_rules_pre_264(self): + self.assertRaises(SystemExit, self.run_command, + 'server-group-create sg1 anti-affinity ' + '--rule max_server_per_host=3', api_version='2.63') + def test_create_server_group_with_multiple_policies(self): self.assertRaises(SystemExit, self.run_command, 'server-group-create wjsg affinity anti-affinity') @@ -3509,6 +3800,9 @@ 7, # doesn't require any changes in novaclient 9, # doesn't require any changes in novaclient 12, # no longer supported + 13, # 13 adds information ``project_id`` and ``user_id`` to + # ``os-server-groups``, but is not explicitly tested + # via wraps and _SUBSTITUTIONS. 15, # doesn't require any changes in novaclient 16, # doesn't require any changes in novaclient 18, # NOTE(andreykurilin): this microversion requires changes in @@ -3547,6 +3841,8 @@ 60, # There are no client-side changes for volume multiattach. 61, # There are no version-wrapped shell method changes for this. 62, # There are no version-wrapped shell method changes for this. + 63, # There are no version-wrapped shell method changes for this. + 65, # There are no version-wrapped shell method changes for this. ]) versions_supported = set(range(0, novaclient.API_MAX_VERSION.ver_minor + 1)) diff -Nru python-novaclient-10.3.0/novaclient/v2/server_groups.py python-novaclient-11.0.0/novaclient/v2/server_groups.py --- python-novaclient-10.3.0/novaclient/v2/server_groups.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/v2/server_groups.py 2018-07-26 22:31:29.000000000 +0000 @@ -17,7 +17,10 @@ Server group interface. """ +from novaclient import api_versions from novaclient import base +from novaclient import exceptions +from novaclient.i18n import _ class ServerGroup(base.Resource): @@ -80,6 +83,7 @@ """ return self._delete('/os-server-groups/%s' % id) + @api_versions.wraps("2.0", "2.63") def create(self, name, policies): """Create (allocate) a server group. @@ -92,3 +96,29 @@ body = {'server_group': {'name': name, 'policies': policies}} return self._create('/os-server-groups', body, 'server_group') + + @api_versions.wraps("2.64") + def create(self, name, policy, rules=None): + """Create (allocate) a server group. + + :param name: The name of the server group. + :param policy: Policy name to associate with the server group. + :param rules: The rules of policy which is a dict, can be applied to + the policy, now only ``max_server_per_host`` for ``anti-affinity`` + policy would be supported (optional). + :rtype: list of :class:`ServerGroup` + """ + body = {'server_group': { + 'name': name, 'policy': policy + }} + if rules: + key = 'max_server_per_host' + try: + if key in rules: + rules[key] = int(rules[key]) + except ValueError: + msg = _("Invalid '%(key)s' value: %(value)s") + raise exceptions.CommandError(msg % { + 'key': key, 'value': rules[key]}) + body['server_group']['rules'] = rules + return self._create('/os-server-groups', body, 'server_group') diff -Nru python-novaclient-10.3.0/novaclient/v2/servers.py python-novaclient-11.0.0/novaclient/v2/servers.py --- python-novaclient-10.3.0/novaclient/v2/servers.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/v2/servers.py 2018-07-26 22:31:29.000000000 +0000 @@ -650,7 +650,7 @@ block_device_mapping_v2=None, nics=None, scheduler_hints=None, config_drive=None, admin_pass=None, disk_config=None, access_ip_v4=None, access_ip_v6=None, description=None, - tags=None, **kwargs): + tags=None, trusted_image_certificates=None, **kwargs): """ Create (boot) a new server. """ @@ -768,6 +768,10 @@ if tags: body['server']['tags'] = tags + if trusted_image_certificates: + body['server']['trusted_image_certificates'] = ( + trusted_image_certificates) + return self._create('/servers', body, response_key, return_raw=return_raw, **kwargs) @@ -1191,7 +1195,8 @@ block_device_mapping=None, block_device_mapping_v2=None, nics=None, scheduler_hints=None, config_drive=None, disk_config=None, admin_pass=None, - access_ip_v4=None, access_ip_v6=None, **kwargs): + access_ip_v4=None, access_ip_v6=None, + trusted_image_certificates=None, **kwargs): # TODO(anthony): indicate in doc string if param is an extension # and/or optional """ @@ -1252,6 +1257,8 @@ microversion 2.19) :param tags: A list of arbitrary strings to be added to the server as tags (allowed since microversion 2.52) + :param trusted_image_certificates: A list of trusted certificate IDs + (allowed since microversion 2.63) """ if not min_count: min_count = 1 @@ -1292,6 +1299,12 @@ if files and self.api_version >= personality_files_deprecation: raise exceptions.UnsupportedAttribute('files', '2.0', '2.56') + trusted_certs_microversion = api_versions.APIVersion("2.63") + if (trusted_image_certificates and + self.api_version < trusted_certs_microversion): + raise exceptions.UnsupportedAttribute("trusted_image_certificates", + "2.63") + boot_kwargs = dict( meta=meta, files=files, userdata=userdata, reservation_id=reservation_id, min_count=min_count, @@ -1299,7 +1312,8 @@ key_name=key_name, availability_zone=availability_zone, scheduler_hints=scheduler_hints, config_drive=config_drive, disk_config=disk_config, admin_pass=admin_pass, - access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, **kwargs) + access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, + trusted_image_certificates=trusted_image_certificates, **kwargs) if block_device_mapping: boot_kwargs['block_device_mapping'] = block_device_mapping @@ -1416,6 +1430,9 @@ well or a string. If None is specified, the existing user_data is unset. (starting from microversion 2.57) + :param trusted_image_certificates: A list of trusted certificate IDs + or None to unset/reset the servers trusted image + certificates (allowed since microversion 2.63) :returns: :class:`Server` """ descr_microversion = api_versions.APIVersion("2.19") @@ -1436,6 +1453,15 @@ if 'userdata' in kwargs and self.api_version < files_and_userdata: raise exceptions.UnsupportedAttribute('userdata', '2.57') + trusted_certs_microversion = api_versions.APIVersion("2.63") + # trusted_image_certificates is intentionally *not* a named kwarg + # so that trusted_image_certificates=None is not confused with an + # intentional unset/reset request. + if ("trusted_image_certificates" in kwargs and + self.api_version < trusted_certs_microversion): + raise exceptions.UnsupportedAttribute("trusted_image_certificates", + "2.63") + body = {'imageRef': base.getid(image)} if password is not None: body['adminPass'] = password @@ -1449,6 +1475,9 @@ body["description"] = kwargs["description"] if 'key_name' in kwargs: body['key_name'] = kwargs['key_name'] + if "trusted_image_certificates" in kwargs: + body["trusted_image_certificates"] = kwargs[ + "trusted_image_certificates"] if meta: body['metadata'] = meta if files: diff -Nru python-novaclient-10.3.0/novaclient/v2/shell.py python-novaclient-11.0.0/novaclient/v2/shell.py --- python-novaclient-10.3.0/novaclient/v2/shell.py 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/novaclient/v2/shell.py 2018-07-26 22:31:29.000000000 +0000 @@ -510,6 +510,19 @@ if include_files: boot_kwargs['files'] = files + if ('trusted_image_certificates' in args and + args.trusted_image_certificates): + boot_kwargs['trusted_image_certificates'] = ( + args.trusted_image_certificates) + elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'): + if cs.api_version >= api_versions.APIVersion('2.63'): + boot_kwargs["trusted_image_certificates"] = utils.env( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS').split(',') + else: + raise exceptions.UnsupportedAttribute( + "OS_TRUSTED_IMAGE_CERTIFICATE_IDS", + "2.63") + return boot_args, boot_kwargs @@ -874,6 +887,18 @@ action="store_true", default=False, help=_("Return a reservation id bound to created servers.")) +@utils.arg( + '--trusted-image-certificate-id', + metavar='', + action='append', + dest='trusted_image_certificates', + default=[], + help=_('Trusted image certificate IDs used to validate certificates ' + 'during the image signature verification process. ' + 'Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. ' + 'May be specified multiple times to pass multiple trusted image ' + 'certificate IDs.'), + start_version="2.63") def do_boot(cs, args): """Boot a new server.""" boot_args, boot_kwargs = _boot(cs, args) @@ -1807,6 +1832,25 @@ help=_("Unset user_data in the server. Cannot be specified with the " "'--user-data' option."), start_version='2.57') +@utils.arg( + '--trusted-image-certificate-id', + metavar='', + action='append', + dest='trusted_image_certificates', + default=[], + help=_('Trusted image certificate IDs used to validate certificates ' + 'during the image signature verification process. ' + 'Defaults to env[OS_TRUSTED_IMAGE_CERTIFICATE_IDS]. ' + 'May be specified multiple times to pass multiple trusted image ' + 'certificate IDs.'), + start_version="2.63") +@utils.arg( + '--trusted-image-certificates-unset', + action='store_true', + default=False, + help=_("Unset trusted_image_certificates in the server. Cannot be " + "specified with the '--trusted-image-certificate-id' option."), + start_version="2.63") def do_rebuild(cs, args): """Shutdown, re-image, and re-boot a server.""" server = _find_server(cs, args.server) @@ -1861,6 +1905,34 @@ elif args.key_name: kwargs['key_name'] = args.key_name + if cs.api_version >= api_versions.APIVersion('2.63'): + # First determine if the user specified anything via the command line + # or the environment variable. + trusted_image_certificates = None + if ('trusted_image_certificates' in args and + args.trusted_image_certificates): + trusted_image_certificates = args.trusted_image_certificates + elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'): + trusted_image_certificates = utils.env( + 'OS_TRUSTED_IMAGE_CERTIFICATE_IDS').split(',') + + if args.trusted_image_certificates_unset: + kwargs['trusted_image_certificates'] = None + # Check for conflicts in option usage. + if trusted_image_certificates: + raise exceptions.CommandError( + _("Cannot specify '--trusted-image-certificates-unset' " + "with '--trusted-image-certificate-id' or with " + "OS_TRUSTED_IMAGE_CERTIFICATE_IDS env variable set.")) + elif trusted_image_certificates: + # Only specify the kwarg if there is a value specified to avoid + # confusion with unsetting the value. + kwargs['trusted_image_certificates'] = trusted_image_certificates + elif utils.env('OS_TRUSTED_IMAGE_CERTIFICATE_IDS'): + raise exceptions.UnsupportedAttribute( + "OS_TRUSTED_IMAGE_CERTIFICATE_IDS", + "2.63") + server = server.rebuild(image, _password, **kwargs) _print_server(cs, args, server) @@ -4453,16 +4525,15 @@ sortby_index=None) -@api_versions.wraps("2.0", "2.12") def _print_server_group_details(cs, server_group): - columns = ['Id', 'Name', 'Policies', 'Members', 'Metadata'] - utils.print_list(server_group, columns) - - -@api_versions.wraps("2.13") -def _print_server_group_details(cs, server_group): # noqa - columns = ['Id', 'Name', 'Project Id', 'User Id', - 'Policies', 'Members', 'Metadata'] + if cs.api_version < api_versions.APIVersion('2.13'): + columns = ['Id', 'Name', 'Policies', 'Members', 'Metadata'] + elif cs.api_version < api_versions.APIVersion('2.64'): + columns = ['Id', 'Name', 'Project Id', 'User Id', + 'Policies', 'Members', 'Metadata'] + else: + columns = ['Id', 'Name', 'Project Id', 'User Id', + 'Policy', 'Rules', 'Members'] utils.print_list(server_group, columns) @@ -4497,6 +4568,7 @@ _print_server_group_details(cs, server_groups) +@api_versions.wraps("2.0", "2.63") @utils.arg('name', metavar='', help=_('Server group name.')) @utils.arg( 'policy', @@ -4509,6 +4581,30 @@ _print_server_group_details(cs, [server_group]) +@api_versions.wraps("2.64") +@utils.arg('name', metavar='', help=_('Server group name.')) +@utils.arg( + 'policy', + metavar='', + help=_('Policy for the server group.')) +@utils.arg( + '--rule', + metavar="", + dest='rules', + action='append', + default=[], + help=_('A rule for the policy. Currently, only the ' + '"max_server_per_host" rule is supported for the ' + '"anti-affinity" policy.')) +def do_server_group_create(cs, args): + """Create a new server group with the specified details.""" + rules = _meta_parsing(args.rules) + server_group = cs.server_groups.create(name=args.name, + policy=args.policy, + rules=rules) + _print_server_group_details(cs, [server_group]) + + @utils.arg( 'id', metavar='', @@ -4815,7 +4911,7 @@ default=False, help=_('live Evacuate host with exact hypervisor hostname match')) def do_host_evacuate_live(cs, args): - """Live migrate all instances of the specified host + """Live migrate all instances off the specified host to other available hosts. """ response = [] diff -Nru python-novaclient-10.3.0/PKG-INFO python-novaclient-11.0.0/PKG-INFO --- python-novaclient-10.3.0/PKG-INFO 2018-06-08 14:28:27.000000000 +0000 +++ python-novaclient-11.0.0/PKG-INFO 2018-07-26 22:34:25.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-novaclient -Version: 10.3.0 +Version: 11.0.0 Summary: Client library for OpenStack Compute API Home-page: https://docs.openstack.org/python-novaclient/latest Author: OpenStack @@ -23,10 +23,6 @@ :target: https://pypi.org/project/python-novaclient/ :alt: Latest Version - .. image:: https://img.shields.io/pypi/dm/python-novaclient.svg - :target: https://pypi.org/project/python-novaclient/ - :alt: Downloads - This is a client for the OpenStack Compute API. It provides a Python API (the ``novaclient`` module) and a command-line script (``nova``). Each implements 100% of the OpenStack Compute API. @@ -40,6 +36,7 @@ * `Source`_ * `Specs`_ * `How to Contribute`_ + * `Release Notes`_ .. _PyPi: https://pypi.org/project/python-novaclient .. _Online Documentation: https://docs.openstack.org/python-novaclient/latest @@ -49,6 +46,7 @@ .. _Source: https://git.openstack.org/cgit/openstack/python-novaclient .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html .. _Specs: http://specs.openstack.org/openstack/nova-specs/ + .. _Release Notes: https://docs.openstack.org/releasenotes/python-novaclient Platform: UNKNOWN diff -Nru python-novaclient-10.3.0/python_novaclient.egg-info/pbr.json python-novaclient-11.0.0/python_novaclient.egg-info/pbr.json --- python-novaclient-10.3.0/python_novaclient.egg-info/pbr.json 2018-06-08 14:28:23.000000000 +0000 +++ python-novaclient-11.0.0/python_novaclient.egg-info/pbr.json 2018-07-26 22:34:23.000000000 +0000 @@ -1 +1 @@ -{"git_version": "0cb0ffa", "is_release": true} \ No newline at end of file +{"git_version": "f1005ce", "is_release": true} \ No newline at end of file diff -Nru python-novaclient-10.3.0/python_novaclient.egg-info/PKG-INFO python-novaclient-11.0.0/python_novaclient.egg-info/PKG-INFO --- python-novaclient-10.3.0/python_novaclient.egg-info/PKG-INFO 2018-06-08 14:28:23.000000000 +0000 +++ python-novaclient-11.0.0/python_novaclient.egg-info/PKG-INFO 2018-07-26 22:34:23.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: python-novaclient -Version: 10.3.0 +Version: 11.0.0 Summary: Client library for OpenStack Compute API Home-page: https://docs.openstack.org/python-novaclient/latest Author: OpenStack @@ -23,10 +23,6 @@ :target: https://pypi.org/project/python-novaclient/ :alt: Latest Version - .. image:: https://img.shields.io/pypi/dm/python-novaclient.svg - :target: https://pypi.org/project/python-novaclient/ - :alt: Downloads - This is a client for the OpenStack Compute API. It provides a Python API (the ``novaclient`` module) and a command-line script (``nova``). Each implements 100% of the OpenStack Compute API. @@ -40,6 +36,7 @@ * `Source`_ * `Specs`_ * `How to Contribute`_ + * `Release Notes`_ .. _PyPi: https://pypi.org/project/python-novaclient .. _Online Documentation: https://docs.openstack.org/python-novaclient/latest @@ -49,6 +46,7 @@ .. _Source: https://git.openstack.org/cgit/openstack/python-novaclient .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html .. _Specs: http://specs.openstack.org/openstack/nova-specs/ + .. _Release Notes: https://docs.openstack.org/releasenotes/python-novaclient Platform: UNKNOWN diff -Nru python-novaclient-10.3.0/python_novaclient.egg-info/requires.txt python-novaclient-11.0.0/python_novaclient.egg-info/requires.txt --- python-novaclient-10.3.0/python_novaclient.egg-info/requires.txt 2018-06-08 14:28:23.000000000 +0000 +++ python-novaclient-11.0.0/python_novaclient.egg-info/requires.txt 2018-07-26 22:34:23.000000000 +0000 @@ -4,7 +4,7 @@ oslo.i18n>=3.15.3 oslo.serialization!=2.19.1,>=2.18.0 oslo.utils>=3.33.0 -PrettyTable<0.8,>=0.7.1 +PrettyTable<0.8,>=0.7.2 simplejson>=3.5.1 six>=1.10.0 Babel!=2.4.0,>=2.3.4 diff -Nru python-novaclient-10.3.0/python_novaclient.egg-info/SOURCES.txt python-novaclient-11.0.0/python_novaclient.egg-info/SOURCES.txt --- python-novaclient-10.3.0/python_novaclient.egg-info/SOURCES.txt 2018-06-08 14:28:25.000000000 +0000 +++ python-novaclient-11.0.0/python_novaclient.egg-info/SOURCES.txt 2018-07-26 22:34:23.000000000 +0000 @@ -1,6 +1,6 @@ .coveragerc .mailmap -.testr.conf +.stestr.conf .zuul.yaml AUTHORS CONTRIBUTING.rst @@ -196,8 +196,10 @@ releasenotes/notes/add-user-agent-string-db77210dfd3ec671.yaml releasenotes/notes/bp-cold-migration-with-target-queens-e361d4ae977aa396.yaml releasenotes/notes/bp-deprecate-image-meta-proxy-api-1483b75cf73b021e.yaml +releasenotes/notes/bug-1744118-0b064d7062117317.yaml releasenotes/notes/bug-1764420-flavor-delete-output-7b80f73deee5a869.yaml releasenotes/notes/bug-1767287-cc28d60d9e59f9bd.yaml +releasenotes/notes/bug-1778536-a1b5d65a0d4ad622.yaml releasenotes/notes/clarify-project-id-variable-5832698315000438.yaml releasenotes/notes/deprecate-baremetal-d67f58a2986b3565.yaml releasenotes/notes/deprecate-certs-1558d8e3b7888938.yaml @@ -246,6 +248,9 @@ releasenotes/notes/microversion-v2_59-4160c852d7d8812d.yaml releasenotes/notes/microversion-v2_61-9a8faa02fddf9ed6.yaml releasenotes/notes/microversion-v2_62-479a23f0d4307500.yaml +releasenotes/notes/microversion-v2_63-cd058a9145550cae.yaml +releasenotes/notes/microversion-v2_64-66366829ec65bea4.yaml.yaml +releasenotes/notes/microversion-v2_65-3c89c5932f4391cb.yaml releasenotes/notes/no-glance-proxy-5c13001a4b13e8ce.yaml releasenotes/notes/no-neutron-proxy-18fd54febe939a6b.yaml releasenotes/notes/pike-rm-deprecated-img-d58e9ae2d774cbfc.yaml @@ -286,5 +291,4 @@ releasenotes/source/_templates/.placeholder releasenotes/source/locale/fr/LC_MESSAGES/releasenotes.po tools/nova.bash_completion -tools/nova.zsh_completion -tools/pretty_tox.sh \ No newline at end of file +tools/nova.zsh_completion \ No newline at end of file diff -Nru python-novaclient-10.3.0/README.rst python-novaclient-11.0.0/README.rst --- python-novaclient-10.3.0/README.rst 2018-06-08 14:26:14.000000000 +0000 +++ python-novaclient-11.0.0/README.rst 2018-07-26 22:31:29.000000000 +0000 @@ -15,10 +15,6 @@ :target: https://pypi.org/project/python-novaclient/ :alt: Latest Version -.. image:: https://img.shields.io/pypi/dm/python-novaclient.svg - :target: https://pypi.org/project/python-novaclient/ - :alt: Downloads - This is a client for the OpenStack Compute API. It provides a Python API (the ``novaclient`` module) and a command-line script (``nova``). Each implements 100% of the OpenStack Compute API. @@ -32,6 +28,7 @@ * `Source`_ * `Specs`_ * `How to Contribute`_ +* `Release Notes`_ .. _PyPi: https://pypi.org/project/python-novaclient .. _Online Documentation: https://docs.openstack.org/python-novaclient/latest @@ -41,3 +38,4 @@ .. _Source: https://git.openstack.org/cgit/openstack/python-novaclient .. _How to Contribute: https://docs.openstack.org/infra/manual/developers.html .. _Specs: http://specs.openstack.org/openstack/nova-specs/ +.. _Release Notes: https://docs.openstack.org/releasenotes/python-novaclient diff -Nru python-novaclient-10.3.0/releasenotes/notes/bug-1744118-0b064d7062117317.yaml python-novaclient-11.0.0/releasenotes/notes/bug-1744118-0b064d7062117317.yaml --- python-novaclient-10.3.0/releasenotes/notes/bug-1744118-0b064d7062117317.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-novaclient-11.0.0/releasenotes/notes/bug-1744118-0b064d7062117317.yaml 2018-07-26 22:31:29.000000000 +0000 @@ -0,0 +1,15 @@ +--- +fixes: + - | + A fix is made for `bug 1744118`_ which adds the below missing CLI + arguments. + + * OS_PROJECT_DOMAIN_ID + + * OS_PROJECT_DOMAIN_NAME + + * OS_USER_DOMAIN_ID + + * OS_USER_DOMAIN_NAME + + .. _bug 1744118: https://bugs.launchpad.net/python-novaclient/+bug/1744118 \ No newline at end of file diff -Nru python-novaclient-10.3.0/releasenotes/notes/bug-1778536-a1b5d65a0d4ad622.yaml python-novaclient-11.0.0/releasenotes/notes/bug-1778536-a1b5d65a0d4ad622.yaml --- python-novaclient-10.3.0/releasenotes/notes/bug-1778536-a1b5d65a0d4ad622.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-novaclient-11.0.0/releasenotes/notes/bug-1778536-a1b5d65a0d4ad622.yaml 2018-07-26 22:31:29.000000000 +0000 @@ -0,0 +1,12 @@ +--- +upgrade: + - The deprecated ``--bypass-url`` command line argument has been removed. +deprecations: + - | + The ``--endpoint-override`` command line argument has been deprecated. + It is renamed to ``--os-endpoint-override`` to avoid misinterpreting + command line arguments. + It defaults to the ``OS_ENDPOINT_OVERRIDE`` environment variable. + See `bug 1778536`_ for more details. + + .. _bug 1778536: https://bugs.launchpad.net/python-novaclient/+bug/1778536 diff -Nru python-novaclient-10.3.0/releasenotes/notes/microversion-v2_63-cd058a9145550cae.yaml python-novaclient-11.0.0/releasenotes/notes/microversion-v2_63-cd058a9145550cae.yaml --- python-novaclient-10.3.0/releasenotes/notes/microversion-v2_63-cd058a9145550cae.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-novaclient-11.0.0/releasenotes/notes/microversion-v2_63-cd058a9145550cae.yaml 2018-07-26 22:31:29.000000000 +0000 @@ -0,0 +1,17 @@ +--- +features: + - | + Added support for `microversion 2.63`_, which includes the following + changes: + + - New environment variable called ``OS_TRUSTED_IMAGE_CERTIFICATE_IDS`` + - New ``nova boot`` option called ``--trusted-image-certificate-id`` + - New ``nova rebuild`` options called ``--trusted-image-certificate-id`` + and ``--trusted-image-certificates-unset`` + - New kwarg called ``trusted_image_certificates`` added to python API + bindings: + + - ``novaclient.v2.servers.ServerManager.create()`` + - ``novaclient.v2.servers.ServerManager.rebuild()`` + + .. _microversion 2.63: https://docs.openstack.org/nova/latest/api_microversion_history.html#id57 diff -Nru python-novaclient-10.3.0/releasenotes/notes/microversion-v2_64-66366829ec65bea4.yaml.yaml python-novaclient-11.0.0/releasenotes/notes/microversion-v2_64-66366829ec65bea4.yaml.yaml --- python-novaclient-10.3.0/releasenotes/notes/microversion-v2_64-66366829ec65bea4.yaml.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-novaclient-11.0.0/releasenotes/notes/microversion-v2_64-66366829ec65bea4.yaml.yaml 2018-07-26 22:31:29.000000000 +0000 @@ -0,0 +1,15 @@ +--- +features: + - | + Added support for `microversion 2.64`_, which includes the following + changes: + + * The ``--rule`` options is added to the ``nova server-group-create`` + CLI that enables user to create server group with specific policy rules. + * Remove ``metadata`` column in the output of ``nova server-group-create``, + ``nova server-group-get``, ``nova server-group-list``. + * Remove ``policies`` column, add ``policy`` and ``rules`` columns in + the output of ``nova server-group-create``, ``nova server-group-get``, + ``nova server-group-list``. + + .. _microversion 2.64: https://docs.openstack.org/nova/latest/api_microversion_history.html#id58 diff -Nru python-novaclient-10.3.0/releasenotes/notes/microversion-v2_65-3c89c5932f4391cb.yaml python-novaclient-11.0.0/releasenotes/notes/microversion-v2_65-3c89c5932f4391cb.yaml --- python-novaclient-10.3.0/releasenotes/notes/microversion-v2_65-3c89c5932f4391cb.yaml 1970-01-01 00:00:00.000000000 +0000 +++ python-novaclient-11.0.0/releasenotes/notes/microversion-v2_65-3c89c5932f4391cb.yaml 2018-07-26 22:31:29.000000000 +0000 @@ -0,0 +1,9 @@ +--- +features: + - | + Support has been added for the compute API `2.65`_ microversion. This + allows calling ``nova live-migration-abort`` on live migrations that are + in ``queued`` or ``preparing`` status in addition to the already accepted + ``running`` status. + + .. _2.65: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id59 diff -Nru python-novaclient-10.3.0/releasenotes/notes/reno.cache python-novaclient-11.0.0/releasenotes/notes/reno.cache --- python-novaclient-10.3.0/releasenotes/notes/reno.cache 2018-06-08 14:28:27.000000000 +0000 +++ python-novaclient-11.0.0/releasenotes/notes/reno.cache 2018-07-26 22:34:25.000000000 +0000 @@ -1,105 +1,3 @@ --- -file-contents: - releasenotes/notes/bug-1764420-flavor-delete-output-7b80f73deee5a869.yaml: - upgrade: ['The ``flavor-delete`` command no longer prints out the details of the - - deleted flavor. On successful deletion, there is no output. - - '] - releasenotes/notes/bug-1767287-cc28d60d9e59f9bd.yaml: - upgrade: ['The ``nova server-group-create`` command now only supports specifying - - a single policy name when creating the server group. This is to match - - the server-side API validation. - - '] - releasenotes/notes/get-rid-off-redundant-methods-47e679c13e88f28a.yaml: - deprecations: ['``novaclient.utils.add_resource_manager_extra_kwargs_hook`` and - - ``novaclient.utils.get_resource_manager_extra_kwargs`` were designed for - - supporting extensions in nova/novaclient. Nowadays, this "extensions" - - feature is abandoned and both ``add_resource_manager_extra_kwargs_hook``, - - ``add_resource_manager_extra_kwargs_hook`` are not used in novaclient''s - - code. These methods are not documented, so we are removing them without - - standard deprecation cycle. - - '] - releasenotes/notes/microversion-v2_61-9a8faa02fddf9ed6.yaml: - other: ['Starting from microversion 2.61, the responses of the ''Flavor'' APIs - - include the ''extra_specs'' parameter. Therefore ''Flavors extra-specs'' - - (os-extra_specs) API calls have been removed in the following commands - - since microversion 2.61. - - - * ``nova flavor-list`` - - * ``nova flavor-show`` - - - There are no behavior changes in the CLI. This is just a performance - - optimization. - - '] - releasenotes/notes/microversion-v2_62-479a23f0d4307500.yaml: - features: ['Adds support for microversion 2.62 which adds ``host`` (hostname) - - and ``hostId`` (an obfuscated hashed host id string) fields to the - - instance action ``GET /servers/{server_id}/os-instance-actions/{req_id}`` - - API. - - - The event columns are already included in the result of - - "nova instance-action " command, therefore does not - - have any CLI or python API binding impacts in the client. - - '] - releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml: - features: ['Added new client API and CLI (``nova instance-usage-audit-log``) to - get server usage audit logs. By default, it lists usage audits for all servers - on all compute hosts where usage auditing is configured. If you specify the - ``--before`` option, the result is filtered by the date and time before which - to list server usage audits.'] - releasenotes/notes/strict_hostname_match-f37243f0520a09a2.yaml: - features: ['Provides "--strict" option for "nova host-servers-migrate", "nova - host-evacuate", - - "nova host-evacuate-live" and "nova host-meta" commands. When "--strict" option - is - - used, the action will be applied to a single compute with the exact hypervisor - - hostname string match rather than to the computes with hostname substring - match. - - When the specified hostname does not exist in the system, "NotFound" error - code - - will be returned. - - '] -notes: -- files: - - [releasenotes/notes/bug-1767287-cc28d60d9e59f9bd.yaml, 57e9a5d34cde8cef319487cb56eca383cff76059] - - [releasenotes/notes/microversion-v2_62-479a23f0d4307500.yaml, 5483be7fe74a90e3a38428cfb436864ffeee4c54] - version: 10.3.0 -- files: - - [releasenotes/notes/bug-1764420-flavor-delete-output-7b80f73deee5a869.yaml, bcc7d8f1138ea22207ac0d31c5be132d6f274b34] - - [releasenotes/notes/get-rid-off-redundant-methods-47e679c13e88f28a.yaml, ca27736810a41080761e604e09c6763aaed07ed7] - - [releasenotes/notes/microversion-v2_61-9a8faa02fddf9ed6.yaml, 229d0df752702700dd30ddbe6d94d5efd5477318] - - [releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml, d418b5f245f4cef4d35b8795aa6af8b98cd60141] - - [releasenotes/notes/strict_hostname_match-f37243f0520a09a2.yaml, 9213ec2d32fa173ec9943c28fb6c3ba5c196015d] - version: 10.2.0 +file-contents: {} +notes: [] diff -Nru python-novaclient-10.3.0/RELEASENOTES.rst python-novaclient-11.0.0/RELEASENOTES.rst --- python-novaclient-10.3.0/RELEASENOTES.rst 2018-06-08 14:28:27.000000000 +0000 +++ python-novaclient-11.0.0/RELEASENOTES.rst 2018-07-26 22:34:25.000000000 +0000 @@ -1,107 +1,3 @@ ================= python-novaclient ================= - -.. _python-novaclient_10.3.0: - -10.3.0 -====== - -.. _python-novaclient_10.3.0_New Features: - -New Features ------------- - -.. releasenotes/notes/microversion-v2_62-479a23f0d4307500.yaml @ 5483be7fe74a90e3a38428cfb436864ffeee4c54 - -- Adds support for microversion 2.62 which adds ``host`` (hostname) - and ``hostId`` (an obfuscated hashed host id string) fields to the - instance action ``GET /servers/{server_id}/os-instance-actions/{req_id}`` - API. - - The event columns are already included in the result of - "nova instance-action " command, therefore does not - have any CLI or python API binding impacts in the client. - - -.. _python-novaclient_10.3.0_Upgrade Notes: - -Upgrade Notes -------------- - -.. releasenotes/notes/bug-1767287-cc28d60d9e59f9bd.yaml @ 57e9a5d34cde8cef319487cb56eca383cff76059 - -- The ``nova server-group-create`` command now only supports specifying - a single policy name when creating the server group. This is to match - the server-side API validation. - - -.. _python-novaclient_10.2.0: - -10.2.0 -====== - -.. _python-novaclient_10.2.0_New Features: - -New Features ------------- - -.. releasenotes/notes/show-instance-usage-audit-logs-7826b411fac1283b.yaml @ d418b5f245f4cef4d35b8795aa6af8b98cd60141 - -- Added new client API and CLI (``nova instance-usage-audit-log``) to get server usage audit logs. By default, it lists usage audits for all servers on all compute hosts where usage auditing is configured. If you specify the ``--before`` option, the result is filtered by the date and time before which to list server usage audits. - -.. releasenotes/notes/strict_hostname_match-f37243f0520a09a2.yaml @ 9213ec2d32fa173ec9943c28fb6c3ba5c196015d - -- Provides "--strict" option for "nova host-servers-migrate", "nova host-evacuate", - "nova host-evacuate-live" and "nova host-meta" commands. When "--strict" option is - used, the action will be applied to a single compute with the exact hypervisor - hostname string match rather than to the computes with hostname substring match. - When the specified hostname does not exist in the system, "NotFound" error code - will be returned. - - -.. _python-novaclient_10.2.0_Upgrade Notes: - -Upgrade Notes -------------- - -.. releasenotes/notes/bug-1764420-flavor-delete-output-7b80f73deee5a869.yaml @ bcc7d8f1138ea22207ac0d31c5be132d6f274b34 - -- The ``flavor-delete`` command no longer prints out the details of the - deleted flavor. On successful deletion, there is no output. - - -.. _python-novaclient_10.2.0_Deprecation Notes: - -Deprecation Notes ------------------ - -.. releasenotes/notes/get-rid-off-redundant-methods-47e679c13e88f28a.yaml @ ca27736810a41080761e604e09c6763aaed07ed7 - -- ``novaclient.utils.add_resource_manager_extra_kwargs_hook`` and - ``novaclient.utils.get_resource_manager_extra_kwargs`` were designed for - supporting extensions in nova/novaclient. Nowadays, this "extensions" - feature is abandoned and both ``add_resource_manager_extra_kwargs_hook``, - ``add_resource_manager_extra_kwargs_hook`` are not used in novaclient's - code. These methods are not documented, so we are removing them without - standard deprecation cycle. - - -.. _python-novaclient_10.2.0_Other Notes: - -Other Notes ------------ - -.. releasenotes/notes/microversion-v2_61-9a8faa02fddf9ed6.yaml @ 229d0df752702700dd30ddbe6d94d5efd5477318 - -- Starting from microversion 2.61, the responses of the 'Flavor' APIs - include the 'extra_specs' parameter. Therefore 'Flavors extra-specs' - (os-extra_specs) API calls have been removed in the following commands - since microversion 2.61. - - * ``nova flavor-list`` - * ``nova flavor-show`` - - There are no behavior changes in the CLI. This is just a performance - optimization. - diff -Nru python-novaclient-10.3.0/requirements.txt python-novaclient-11.0.0/requirements.txt --- python-novaclient-10.3.0/requirements.txt 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/requirements.txt 2018-07-26 22:31:29.000000000 +0000 @@ -7,7 +7,7 @@ oslo.i18n>=3.15.3 # Apache-2.0 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 oslo.utils>=3.33.0 # Apache-2.0 -PrettyTable<0.8,>=0.7.1 # BSD +PrettyTable<0.8,>=0.7.2 # BSD simplejson>=3.5.1 # MIT six>=1.10.0 # MIT Babel!=2.4.0,>=2.3.4 # BSD diff -Nru python-novaclient-10.3.0/.stestr.conf python-novaclient-11.0.0/.stestr.conf --- python-novaclient-10.3.0/.stestr.conf 1970-01-01 00:00:00.000000000 +0000 +++ python-novaclient-11.0.0/.stestr.conf 2018-07-26 22:31:29.000000000 +0000 @@ -0,0 +1,3 @@ +[DEFAULT] +test_path=${OS_TEST_PATH:-./novaclient/tests/unit} +top_dir=./ diff -Nru python-novaclient-10.3.0/.testr.conf python-novaclient-11.0.0/.testr.conf --- python-novaclient-10.3.0/.testr.conf 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/.testr.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-300} \ - ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./novaclient/tests/unit} $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff -Nru python-novaclient-10.3.0/test-requirements.txt python-novaclient-11.0.0/test-requirements.txt --- python-novaclient-10.3.0/test-requirements.txt 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/test-requirements.txt 2018-07-26 22:31:29.000000000 +0000 @@ -5,6 +5,7 @@ bandit>=1.1.0 # Apache-2.0 coverage!=4.4,>=4.0 # Apache-2.0 +ddt>=1.0.1 # MIT fixtures>=3.0.0 # Apache-2.0/BSD keyring>=5.5.1 # MIT/PSF mock>=2.0.0 # BSD @@ -14,9 +15,8 @@ python-neutronclient>=6.7.0 # Apache-2.0 requests-mock>=1.2.0 # Apache-2.0 os-client-config>=1.28.0 # Apache-2.0 -os-testr>=1.0.0 # Apache-2.0 osprofiler>=1.4.0 # Apache-2.0 -testrepository>=0.0.18 # Apache-2.0/BSD +stestr>=2.0.0 # Apache-2.0 testscenarios>=0.4 # Apache-2.0/BSD testtools>=2.2.0 # MIT tempest>=17.1.0 # Apache-2.0 diff -Nru python-novaclient-10.3.0/tools/pretty_tox.sh python-novaclient-11.0.0/tools/pretty_tox.sh --- python-novaclient-10.3.0/tools/pretty_tox.sh 2018-06-08 14:26:01.000000000 +0000 +++ python-novaclient-11.0.0/tools/pretty_tox.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -set -o pipefail - -TESTRARGS=$1 - -# --until-failure is not compatible with --subunit see: -# -# https://bugs.launchpad.net/testrepository/+bug/1411804 -# -# this work around exists until that is addressed -if [[ "$TESTARGS" =~ "until-failure" ]]; then - python setup.py testr --slowest --testr-args="$TESTRARGS" -else - python setup.py testr --slowest --testr-args="--subunit $TESTRARGS" | subunit-trace -f -fi diff -Nru python-novaclient-10.3.0/tox.ini python-novaclient-11.0.0/tox.ini --- python-novaclient-10.3.0/tox.ini 2018-06-08 14:26:14.000000000 +0000 +++ python-novaclient-11.0.0/tox.ini 2018-07-26 22:31:29.000000000 +0000 @@ -7,8 +7,9 @@ [testenv] usedevelop = True # tox is silly... these need to be separated by a newline.... -whitelist_externals = find - bash +whitelist_externals = + find + rm passenv = ZUUL_CACHE_DIR REQUIREMENTS_PIP_LOCATION install_command = pip install {opts} {packages} @@ -18,17 +19,18 @@ -r{toxinidir}/requirements.txt commands = find . -type f -name "*.pyc" -delete - bash tools/pretty_tox.sh '{posargs}' - # there is also secret magic in pretty_tox.sh which lets you run in a fail only - # mode. To do this define the TRACE_FAILONLY environmental variable. + stestr run {posargs} [testenv:pep8] +basepython = python3 commands = flake8 {posargs} [testenv:bandit] +basepython = python3 commands = bandit -r novaclient -n5 -x tests [testenv:venv] +basepython = python3 deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -r{toxinidir}/test-requirements.txt @@ -37,14 +39,17 @@ commands = {posargs} [testenv:docs] +basepython = python3 deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -r{toxinidir}/requirements.txt -r{toxinidir}/doc/requirements.txt commands = + rm -rf doc/build sphinx-build -b html doc/source doc/build/html [testenv:releasenotes] +basepython = python3 deps = -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} -r{toxinidir}/requirements.txt @@ -55,25 +60,27 @@ [testenv:functional] basepython = python2.7 passenv = OS_NOVACLIENT_TEST_NETWORK -setenv = - OS_TEST_PATH = ./novaclient/tests/functional commands = - bash tools/pretty_tox.sh '--concurrency=1 {posargs}' + stestr --test-path=./novaclient/tests/functional run --concurrency=1 {posargs} python novaclient/tests/functional/hooks/check_resources.py [testenv:functional-py35] basepython = python3.5 passenv = OS_NOVACLIENT_TEST_NETWORK -setenv = - OS_TEST_PATH = ./novaclient/tests/functional commands = - bash tools/pretty_tox.sh '--concurrency=1 {posargs}' + stestr --test-path=./novaclient/tests/functional run --concurrency=1 {posargs} python novaclient/tests/functional/hooks/check_resources.py [testenv:cover] +basepython = python3 +setenv = + PYTHON=coverage run --source novaclient --parallel-mode commands = - python setup.py testr --coverage --testr-args='{posargs}' - coverage report + stestr run {posargs} + coverage combine + coverage html -d cover + coverage xml -o cover/coverage.xml + coverage report [flake8] # Following checks should be enabled in the future. @@ -92,6 +99,7 @@ import_exceptions = novaclient.i18n [testenv:bindep] +basepython = python3 # Do not install any requirements. We want this to be fast and work even if # system dependencies are missing, since it's used to tell you what system # dependencies are missing! This also means that bindep must be installed