diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py index c49c181559..50299d65d0 100644 --- a/openstackclient/compute/v2/server.py +++ b/openstackclient/compute/v2/server.py @@ -3472,18 +3472,35 @@ class SetServer(command.Command): metavar='', help=_('New server name'), ) - parser.add_argument( + password_group = parser.add_mutually_exclusive_group() + password_group.add_argument( + '--password', + help=_('Set the server password'), + ) + password_group.add_argument( + '--no-password', + action='store_true', + help=_( + 'Clear the admin password for the server from the metadata ' + 'service; note that this action does not actually change the ' + 'server password' + ), + ) + # TODO(stephenfin): Remove this in a future major version + password_group.add_argument( '--root-password', action="store_true", - help=_('Set new root password (interactive only)'), + help=argparse.SUPPRESS, ) parser.add_argument( '--property', metavar='', action=parseractions.KeyValueAction, dest='properties', - help=_('Property to add/change for this server ' - '(repeat option to set multiple properties)'), + help=_( + 'Property to add/change for this server ' + '(repeat option to set multiple properties)' + ), ) parser.add_argument( '--state', @@ -3494,8 +3511,10 @@ class SetServer(command.Command): parser.add_argument( '--description', metavar='', - help=_('New server description (supported by ' - '--os-compute-api-version 2.19 or above)'), + help=_( + 'New server description ' + '(supported by --os-compute-api-version 2.19 or above)' + ), ) parser.add_argument( '--tag', @@ -3519,6 +3538,22 @@ class SetServer(command.Command): parsed_args.server, ) + if parsed_args.description: + if server.api_version < api_versions.APIVersion("2.19"): + msg = _( + '--os-compute-api-version 2.19 or greater is required to ' + 'support the --description option' + ) + raise exceptions.CommandError(msg) + + if parsed_args.tags: + if server.api_version < api_versions.APIVersion('2.26'): + msg = _( + '--os-compute-api-version 2.26 or greater is required to ' + 'support the --tag option' + ) + raise exceptions.CommandError(msg) + if parsed_args.name: server.update(name=parsed_args.name) @@ -3536,22 +3571,15 @@ class SetServer(command.Command): else: msg = _("Passwords do not match, password unchanged") raise exceptions.CommandError(msg) + elif parsed_args.password: + server.change_password(parsed_args.password) + elif parsed_args.no_password: + server.clear_password() if parsed_args.description: - if server.api_version < api_versions.APIVersion("2.19"): - msg = _("Description is not supported for " - "--os-compute-api-version less than 2.19") - raise exceptions.CommandError(msg) server.update(description=parsed_args.description) if parsed_args.tags: - if server.api_version < api_versions.APIVersion('2.26'): - msg = _( - '--os-compute-api-version 2.26 or greater is required to ' - 'support the --tag option' - ) - raise exceptions.CommandError(msg) - for tag in parsed_args.tags: server.add_tag(tag=tag) diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py index f046925af1..0f33dd7047 100644 --- a/openstackclient/tests/unit/compute/v2/test_server.py +++ b/openstackclient/tests/unit/compute/v2/test_server.py @@ -6207,6 +6207,7 @@ class TestServerSet(TestServer): 'update': None, 'reset_state': None, 'change_password': None, + 'clear_password': None, 'add_tag': None, 'set_tags': None, } @@ -6290,6 +6291,37 @@ class TestServerSet(TestServer): self.fake_servers[0], parsed_args.properties) self.assertIsNone(result) + def test_server_set_with_password(self): + arglist = [ + '--password', 'foo', + 'foo_vm', + ] + verifylist = [ + ('password', 'foo'), + ('server', 'foo_vm'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.fake_servers[0].change_password.assert_called_once_with('foo') + + def test_server_set_with_no_password(self): + arglist = [ + '--no-password', + 'foo_vm', + ] + verifylist = [ + ('no_password', True), + ('server', 'foo_vm'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + self.fake_servers[0].clear_password.assert_called_once_with() + + # TODO(stephenfin): Remove this in a future major version @mock.patch.object(getpass, 'getpass', return_value=mock.sentinel.fake_pass) def test_server_set_with_root_password(self, mock_getpass): diff --git a/releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml b/releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml new file mode 100644 index 0000000000..ccffaa1fe7 --- /dev/null +++ b/releasenotes/notes/add-missing-server-set-opts-e1b4300f5f42e863.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Add ``--no-password`` option to ``server set`` command, allowing users + to clear the admin password from the metadata service. Note that this does + not actually change the server password. +upgrade: + - | + The ``server set --root-password`` option has been deprecated in favour of + a non-interactive ``--password`` option.