diff --git a/openstackclient/api/compute_v2.py b/openstackclient/api/compute_v2.py index 1ad572b133..7429a859d7 100644 --- a/openstackclient/api/compute_v2.py +++ b/openstackclient/api/compute_v2.py @@ -19,7 +19,7 @@ from osc_lib import exceptions from osc_lib.i18n import _ -# TODO(dtroyer): Mingrate this to osc-lib +# TODO(dtroyer): Migrate this to osc-lib class InvalidValue(Exception): """An argument value is not valid: wrong type, out of range, etc""" @@ -269,80 +269,6 @@ class APIv2(api.BaseAPI): return self.list(url)["floating_ip_pools"] - # Hosts - - def host_list( - self, - zone=None, - ): - """Lists hypervisor Hosts - - https://docs.openstack.org/api-ref/compute/#list-hosts - Valid for Compute 2.0 - 2.42 - - :param string zone: - Availability zone - :returns: A dict of the floating IP attributes - """ - - url = "/os-hosts" - if zone: - url = '/os-hosts?zone=%s' % zone - - return self.list(url)["hosts"] - - def host_set( - self, host=None, status=None, maintenance_mode=None, **params - ): - """Modify host properties - - https://docs.openstack.org/api-ref/compute/#update-host-status - Valid for Compute 2.0 - 2.42 - - status - maintenance_mode - """ - - url = "/os-hosts" - - params = {} - if status: - params['status'] = status - if maintenance_mode: - params['maintenance_mode'] = maintenance_mode - if params == {}: - # Don't bother calling if nothing given - return None - else: - return self._request( - "PUT", - f"/{url}/{host}", - json=params, - ).json() - - def host_show( - self, - host=None, - ): - """Show host - - https://docs.openstack.org/api-ref/compute/#show-host-details - Valid for Compute 2.0 - 2.42 - """ - - url = "/os-hosts" - - r_host = self.find( - url, - attr='host_name', - value=host, - ) - - data = [] - for h in r_host: - data.append(h['resource']) - return data - # Networks def network_create( diff --git a/openstackclient/compute/v2/host.py b/openstackclient/compute/v2/host.py index 20925682d5..27e8e2705a 100644 --- a/openstackclient/compute/v2/host.py +++ b/openstackclient/compute/v2/host.py @@ -15,6 +15,7 @@ """Host action implementations""" +from openstack import exceptions as sdk_exceptions from osc_lib.command import command from osc_lib import utils @@ -35,34 +36,26 @@ class ListHost(command.Lister): def take_action(self, parsed_args): compute_client = self.app.client_manager.sdk_connection.compute - columns = ("Host Name", "Service", "Zone") self.log.warning( - "API has been deprecated. " - "Please consider using 'hypervisor list' instead." + "API has been deprecated; " + "consider using 'hypervisor list' instead." ) # doing this since openstacksdk has decided not to support this # deprecated command - hosts = ( - compute_client.get('/os-hosts', microversion='2.1') - .json() - .get('hosts') - ) - + response = compute_client.get('/os-hosts', microversion='2.1') + sdk_exceptions.raise_from_response(response) + hosts = response.json().get('hosts') if parsed_args.zone is not None: - filtered_hosts = [] - for host in hosts: - if host['zone'] == parsed_args.zone: - filtered_hosts.append(host) - - hosts = filtered_hosts + hosts = [h for h in hosts if h['zone'] == parsed_args.zone] + columns = ("Host Name", "Service", "Zone") return columns, (utils.get_dict_properties(s, columns) for s in hosts) class SetHost(command.Command): - _description = _("Set host properties") + _description = _("DEPRECATED: Set host properties") def get_parser(self, prog_name): parser = super().get_parser(prog_name) @@ -90,20 +83,33 @@ class SetHost(command.Command): return parser def take_action(self, parsed_args): - kwargs = {} + compute_client = self.app.client_manager.sdk_connection.compute + self.log.warning( + "API has been deprecated; " + "consider using 'compute service set' instead." + ) + + data = {} if parsed_args.enable: - kwargs['status'] = 'enable' + data['status'] = 'enable' if parsed_args.disable: - kwargs['status'] = 'disable' + data['status'] = 'disable' if parsed_args.enable_maintenance: - kwargs['maintenance_mode'] = 'enable' + data['maintenance_mode'] = 'enable' if parsed_args.disable_maintenance: - kwargs['maintenance_mode'] = 'disable' + data['maintenance_mode'] = 'disable' - compute_client = self.app.client_manager.compute + if not data: + # don't bother calling if nothing given + return - compute_client.api.host_set(parsed_args.host, **kwargs) + # doing this since openstacksdk has decided not to support this + # deprecated command + response = compute_client.put( + f'/os-hosts/{parsed_args.host}', json=data, microversion='2.1' + ) + sdk_exceptions.raise_from_response(response) class ShowHost(command.Lister): @@ -116,26 +122,25 @@ class ShowHost(command.Lister): def take_action(self, parsed_args): compute_client = self.app.client_manager.sdk_connection.compute - columns = ("Host", "Project", "CPU", "Memory MB", "Disk GB") self.log.warning( - "API has been deprecated. " - "Please consider using 'hypervisor show' instead." + "API has been deprecated; " + "consider using 'hypervisor show' instead." ) # doing this since openstacksdk has decided not to support this # deprecated command - resources = ( - compute_client.get( - '/os-hosts/' + parsed_args.host, microversion='2.1' - ) - .json() - .get('host') + response = compute_client.get( + f'/os-hosts/{parsed_args.host}', microversion='2.1' ) + sdk_exceptions.raise_from_response(response) + resources = response.json().get('host') data = [] if resources is not None: for resource in resources: data.append(resource['resource']) + columns = ("Host", "Project", "CPU", "Memory MB", "Disk GB") + return columns, (utils.get_dict_properties(s, columns) for s in data) diff --git a/openstackclient/tests/unit/api/test_compute_v2.py b/openstackclient/tests/unit/api/test_compute_v2.py index 3856a77007..3bcd2a912a 100644 --- a/openstackclient/tests/unit/api/test_compute_v2.py +++ b/openstackclient/tests/unit/api/test_compute_v2.py @@ -227,114 +227,6 @@ class TestFloatingIPPool(TestComputeAPIv2): self.assertEqual(self.LIST_FLOATING_IP_POOL_RESP, ret) -class TestHost(TestComputeAPIv2): - FAKE_HOST_RESP_1 = { - "zone": "internal", - "host_name": "myhost", - "service": "conductor", - } - - FAKE_HOST_RESP_2 = { - "zone": "internal", - "host_name": "myhost", - "service": "scheduler", - } - - FAKE_HOST_RESP_3 = { - "zone": "nova", - "host_name": "myhost", - "service": "compute", - } - - LIST_HOST_RESP = [ - FAKE_HOST_RESP_1, - FAKE_HOST_RESP_2, - FAKE_HOST_RESP_3, - ] - - def test_host_list_no_options(self): - self.requests_mock.register_uri( - 'GET', - FAKE_URL + '/os-hosts', - json={'hosts': self.LIST_HOST_RESP}, - status_code=200, - ) - ret = self.api.host_list() - self.assertEqual(self.LIST_HOST_RESP, ret) - - def test_host_list_zone(self): - self.requests_mock.register_uri( - 'GET', - FAKE_URL + '/os-hosts?zone=nova', - json={'hosts': [self.FAKE_HOST_RESP_3]}, - status_code=200, - ) - self.requests_mock.register_uri( - 'GET', - FAKE_URL + '/os-hosts', - json={'hosts': [self.FAKE_HOST_RESP_3]}, - status_code=200, - ) - ret = self.api.host_list(zone='nova') - self.assertEqual([self.FAKE_HOST_RESP_3], ret) - - def test_host_set_none(self): - ret = self.api.host_set(host='myhost') - self.assertIsNone(ret) - - def test_host_set(self): - self.requests_mock.register_uri( - 'PUT', - FAKE_URL + '/os-hosts/myhost', - json={}, - status_code=200, - ) - ret = self.api.host_set(host='myhost', status='enabled') - self.assertEqual({}, ret) - - def test_host_show(self): - FAKE_RESOURCE_1 = { - "cpu": 2, - "disk_gb": 1028, - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "memory_mb": 8192, - "project": "(total)", - } - FAKE_RESOURCE_2 = { - "cpu": 0, - "disk_gb": 0, - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "memory_mb": 512, - "project": "(used_now)", - } - FAKE_RESOURCE_3 = { - "cpu": 0, - "disk_gb": 0, - "host": "c1a7de0ac9d94e4baceae031d05caae3", - "memory_mb": 0, - "project": "(used_max)", - } - FAKE_HOST_RESP = [ - {'resource': FAKE_RESOURCE_1}, - {'resource': FAKE_RESOURCE_2}, - {'resource': FAKE_RESOURCE_3}, - ] - FAKE_HOST_LIST = [ - FAKE_RESOURCE_1, - FAKE_RESOURCE_2, - FAKE_RESOURCE_3, - ] - - self.requests_mock.register_uri( - 'GET', - FAKE_URL + '/os-hosts/myhost', - json={'host': FAKE_HOST_RESP}, - status_code=200, - ) - ret = self.api.host_show(host='myhost') - self.assertEqual(FAKE_HOST_LIST, ret) - - class TestNetwork(TestComputeAPIv2): FAKE_NETWORK_RESP = { 'id': '1', diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py index 6c201db464..f3042f32b2 100644 --- a/openstackclient/tests/unit/compute/v2/fakes.py +++ b/openstackclient/tests/unit/compute/v2/fakes.py @@ -127,9 +127,6 @@ class FakeComputev2Client: self.keypairs = mock.Mock() self.keypairs.resource_class = fakes.FakeResource(None, {}) - self.hosts = mock.Mock() - self.hosts.resource_class = fakes.FakeResource(None, {}) - self.server_groups = mock.Mock() self.server_groups.resource_class = fakes.FakeResource(None, {}) @@ -1012,56 +1009,6 @@ def get_networks(networks=None, count=2): return mock.Mock(side_effect=networks) -def create_one_host(attrs=None): - """Create a fake host. - - :param dict attrs: - A dictionary with all attributes - :return: - A FakeResource object, with uuid and other attributes - """ - attrs = attrs or {} - - # Set default attributes. - host_info = { - "service_id": 1, - "host": "host1", - "uuid": 'host-id-' + uuid.uuid4().hex, - "vcpus": 10, - "memory_mb": 100, - "local_gb": 100, - "vcpus_used": 5, - "memory_mb_used": 50, - "local_gb_used": 10, - "hypervisor_type": "xen", - "hypervisor_version": 1, - "hypervisor_hostname": "devstack1", - "free_ram_mb": 50, - "free_disk_gb": 50, - "current_workload": 10, - "running_vms": 1, - "cpu_info": "", - "disk_available_least": 1, - "host_ip": "10.10.10.10", - "supported_instances": "", - "metrics": "", - "pci_stats": "", - "extra_resources": "", - "stats": "", - "numa_topology": "", - "ram_allocation_ratio": 1.0, - "cpu_allocation_ratio": 1.0, - "zone": 'zone-' + uuid.uuid4().hex, - "host_name": 'name-' + uuid.uuid4().hex, - "service": 'service-' + uuid.uuid4().hex, - "cpu": 4, - "disk_gb": 100, - 'project': 'project-' + uuid.uuid4().hex, - } - host_info.update(attrs) - return host_info - - def create_one_usage(attrs=None): """Create a fake usage. diff --git a/openstackclient/tests/unit/compute/v2/test_host.py b/openstackclient/tests/unit/compute/v2/test_host.py index 0ad83289c9..afda8e9589 100644 --- a/openstackclient/tests/unit/compute/v2/test_host.py +++ b/openstackclient/tests/unit/compute/v2/test_host.py @@ -11,9 +11,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -from unittest import mock +import uuid from openstackclient.compute.v2 import host from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes @@ -21,19 +20,51 @@ from openstackclient.tests.unit import fakes from openstackclient.tests.unit import utils as tests_utils -@mock.patch('openstackclient.api.compute_v2.APIv2.host_list') +def _generate_fake_host(): + return { + 'service_id': 1, + 'host': 'host1', + 'uuid': 'host-id-' + uuid.uuid4().hex, + 'vcpus': 10, + 'memory_mb': 100, + 'local_gb': 100, + 'vcpus_used': 5, + 'memory_mb_used': 50, + 'local_gb_used': 10, + 'hypervisor_type': 'xen', + 'hypervisor_version': 1, + 'hypervisor_hostname': 'devstack1', + 'free_ram_mb': 50, + 'free_disk_gb': 50, + 'current_workload': 10, + 'running_vms': 1, + 'cpu_info': '', + 'disk_available_least': 1, + 'host_ip': '10.10.10.10', + 'supported_instances': '', + 'metrics': '', + 'pci_stats': '', + 'extra_resources': '', + 'stats': '', + 'numa_topology': '', + 'ram_allocation_ratio': 1.0, + 'cpu_allocation_ratio': 1.0, + 'zone': 'zone-' + uuid.uuid4().hex, + 'host_name': 'name-' + uuid.uuid4().hex, + 'service': 'service-' + uuid.uuid4().hex, + 'cpu': 4, + 'disk_gb': 100, + 'project': 'project-' + uuid.uuid4().hex, + } + + class TestHostList(compute_fakes.TestComputev2): - _host = compute_fakes.create_one_host() def setUp(self): super().setUp() - self.compute_sdk_client.get.return_value = fakes.FakeResponse( - data={'hosts': [self._host]} - ) - + self._host = _generate_fake_host() self.columns = ('Host Name', 'Service', 'Zone') - self.data = [ ( self._host['host_name'], @@ -42,10 +73,12 @@ class TestHostList(compute_fakes.TestComputev2): ) ] + self.compute_sdk_client.get.return_value = fakes.FakeResponse( + data={'hosts': [self._host]} + ) self.cmd = host.ListHost(self.app, None) - def test_host_list_no_option(self, h_mock): - h_mock.return_value = [self._host] + def test_host_list_no_option(self): arglist = [] verifylist = [] @@ -59,8 +92,7 @@ class TestHostList(compute_fakes.TestComputev2): self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) - def test_host_list_with_option(self, h_mock): - h_mock.return_value = [self._host] + def test_host_list_with_option(self): arglist = [ '--zone', self._host['zone'], @@ -80,76 +112,60 @@ class TestHostList(compute_fakes.TestComputev2): self.assertEqual(self.data, list(data)) -@mock.patch('openstackclient.api.compute_v2.APIv2.host_set') class TestHostSet(compute_fakes.TestComputev2): def setUp(self): super().setUp() - self.host = compute_fakes.create_one_host() + self._host = _generate_fake_host() + self.compute_sdk_client.put.return_value = fakes.FakeResponse() self.cmd = host.SetHost(self.app, None) - def test_host_set_no_option(self, h_mock): - h_mock.return_value = self.host - h_mock.update.return_value = None + def test_host_set_no_option(self): arglist = [ - self.host['host'], + self._host['host'], ] verifylist = [ - ('host', self.host['host']), + ('host', self._host['host']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) + self.compute_sdk_client.put.assert_not_called() - h_mock.assert_called_with(self.host['host']) - - def test_host_set(self, h_mock): - h_mock.return_value = self.host - h_mock.update.return_value = None + def test_host_set(self): arglist = [ '--enable', '--disable-maintenance', - self.host['host'], + self._host['host'], ] verifylist = [ ('enable', True), ('enable_maintenance', False), - ('host', self.host['host']), + ('host', self._host['host']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.assertIsNone(result) - - h_mock.assert_called_with( - self.host['host'], status='enable', maintenance_mode='disable' + self.compute_sdk_client.put.assert_called_with( + f'/os-hosts/{self._host["host"]}', + json={ + 'maintenance_mode': 'disable', + 'status': 'enable', + }, + microversion='2.1', ) -@mock.patch('openstackclient.api.compute_v2.APIv2.host_show') class TestHostShow(compute_fakes.TestComputev2): - _host = compute_fakes.create_one_host() - def setUp(self): super().setUp() - output_data = { - "resource": { - "host": self._host['host'], - "project": self._host['project'], - "cpu": self._host['cpu'], - "memory_mb": self._host['memory_mb'], - "disk_gb": self._host['disk_gb'], - } - } - - self.compute_sdk_client.get.return_value = fakes.FakeResponse( - data={'host': [output_data]} - ) + self._host = _generate_fake_host() self.columns = ( 'Host', @@ -158,7 +174,6 @@ class TestHostShow(compute_fakes.TestComputev2): 'Memory MB', 'Disk GB', ) - self.data = [ ( self._host['host'], @@ -169,10 +184,25 @@ class TestHostShow(compute_fakes.TestComputev2): ) ] + self.compute_sdk_client.get.return_value = fakes.FakeResponse( + data={ + 'host': [ + { + 'resource': { + 'host': self._host['host'], + 'project': self._host['project'], + 'cpu': self._host['cpu'], + 'memory_mb': self._host['memory_mb'], + 'disk_gb': self._host['disk_gb'], + } + } + ], + } + ) + self.cmd = host.ShowHost(self.app, None) - def test_host_show_no_option(self, h_mock): - h_mock.host_show.return_value = [self._host] + def test_host_show_no_option(self): arglist = [] verifylist = [] @@ -185,8 +215,7 @@ class TestHostShow(compute_fakes.TestComputev2): verifylist, ) - def test_host_show_with_option(self, h_mock): - h_mock.return_value = [self._host] + def test_host_show_with_option(self): arglist = [ self._host['host_name'], ] diff --git a/releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml b/releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml new file mode 100644 index 0000000000..f935660919 --- /dev/null +++ b/releasenotes/notes/migrate-host-set-438997eb6f81f2b1.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - | + The ``host set`` command has been migrated to SDK.