def take_action(self, parsed_args): volume_client = self.app.client_manager.volume volume_type = volume_client.volume_types.create(parsed_args.name) volume_type._info.pop('extra_specs') if parsed_args.property: result = volume_type.set_keys(parsed_args.property) volume_type._info.update({'properties': utils.format_dict(result)}) if (parsed_args.encryption_provider or parsed_args.encryption_cipher or parsed_args.encryption_key_size or parsed_args.encryption_control_location): try: # create new encryption encryption = _create_encryption_type( volume_client, volume_type, parsed_args) except Exception as e: LOG.error(_("Failed to set encryption information for this " "volume type: %s"), e) # add encryption info in result encryption._info.pop("volume_type_id", None) volume_type._info.update( {'encryption': utils.format_dict(encryption._info)}) volume_type._info.pop("os-volume-type-access:is_public", None) return zip(*sorted(six.iteritems(volume_type._info)))
def test_format_dict(self): expected = "a='b', c='d', e='f'" self.assertEqual(expected, utils.format_dict({'a': 'b', 'c': 'd', 'e': 'f'})) self.assertEqual(expected, utils.format_dict({'e': 'f', 'c': 'd', 'a': 'b'})) self.assertIsNone(utils.format_dict(None))
def _get_common_cols_data(self, fake_port): columns = ( "admin_state_up", "allowed_address_pairs", "binding_host_id", "binding_profile", "binding_vif_details", "binding_vif_type", "binding_vnic_type", "description", "device_id", "device_owner", "dns_assignment", "dns_name", "extra_dhcp_opts", "fixed_ips", "id", "mac_address", "name", "network_id", "port_security_enabled", "project_id", "security_groups", "status", ) data = ( port._format_admin_state(fake_port.admin_state_up), utils.format_list_of_dicts(fake_port.allowed_address_pairs), fake_port.binding_host_id, utils.format_dict(fake_port.binding_profile), utils.format_dict(fake_port.binding_vif_details), fake_port.binding_vif_type, fake_port.binding_vnic_type, fake_port.description, fake_port.device_id, fake_port.device_owner, utils.format_list_of_dicts(fake_port.dns_assignment), fake_port.dns_name, utils.format_list_of_dicts(fake_port.extra_dhcp_opts), utils.format_list_of_dicts(fake_port.fixed_ips), fake_port.id, fake_port.mac_address, fake_port.name, fake_port.network_id, fake_port.port_security_enabled, fake_port.project_id, utils.format_list(fake_port.security_groups), fake_port.status, ) return columns, data
def _get_common_cols_data(self, fake_port): columns = ( 'admin_state_up', 'allowed_address_pairs', 'binding_host_id', 'binding_profile', 'binding_vif_details', 'binding_vif_type', 'binding_vnic_type', 'device_id', 'device_owner', 'dns_assignment', 'dns_name', 'extra_dhcp_opts', 'fixed_ips', 'id', 'mac_address', 'name', 'network_id', 'port_security_enabled', 'project_id', 'security_groups', 'status', ) data = ( port._format_admin_state(fake_port.admin_state_up), utils.format_list_of_dicts(fake_port.allowed_address_pairs), fake_port.binding_host_id, utils.format_dict(fake_port.binding_profile), utils.format_dict(fake_port.binding_vif_details), fake_port.binding_vif_type, fake_port.binding_vnic_type, fake_port.device_id, fake_port.device_owner, utils.format_list_of_dicts(fake_port.dns_assignment), fake_port.dns_name, utils.format_list_of_dicts(fake_port.extra_dhcp_opts), utils.format_list_of_dicts(fake_port.fixed_ips), fake_port.id, fake_port.mac_address, fake_port.name, fake_port.network_id, fake_port.port_security_enabled, fake_port.project_id, utils.format_list(fake_port.security_groups), fake_port.status, ) return columns, data
def test_qos_list(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.list.assert_called_with() collist = ( 'ID', 'Name', 'Consumer', 'Associations', 'Specs', ) self.assertEqual(collist, columns) datalist = (( volume_fakes.qos_id, volume_fakes.qos_name, volume_fakes.qos_consumer, volume_fakes.type_name, utils.format_dict(volume_fakes.qos_specs), ), ) self.assertEqual(datalist, tuple(data))
def test_type_show_with_list_access_exec(self): arglist = [ self.volume_type.id ] verifylist = [ ("volume_type", self.volume_type.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) private_type = volume_fakes.FakeType.create_one_type( attrs={'is_public': False}) with mock.patch.object(self.types_mock, 'get', return_value=private_type): with mock.patch.object(self.types_access_mock, 'list', side_effect=Exception()): columns, data = self.cmd.take_action(parsed_args) self.types_mock.get.assert_called_once_with( self.volume_type.id) self.types_access_mock.list.assert_called_once_with( private_type.id) self.assertEqual(self.columns, columns) private_type_data = ( None, private_type.description, private_type.id, private_type.is_public, private_type.name, utils.format_dict(private_type.extra_specs) ) self.assertEqual(private_type_data, data)
def test_qos_show(self): arglist = [ self.qos_spec.id ] verifylist = [ ('qos_spec', self.qos_spec.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.get.assert_called_with( self.qos_spec.id ) collist = ( 'associations', 'consumer', 'id', 'name', 'properties' ) self.assertEqual(collist, columns) datalist = ( self.qos_association.name, self.qos_spec.consumer, self.qos_spec.id, self.qos_spec.name, utils.format_dict(self.qos_spec.specs), ) self.assertEqual(datalist, tuple(data))
def test_type_create_with_encryption(self): encryption_info = { 'provider': 'LuksEncryptor', 'cipher': 'aes-xts-plain64', 'key_size': '128', 'control_location': 'front-end', } encryption_type = volume_fakes.FakeType.create_one_encryption_type( attrs=encryption_info ) self.new_volume_type = volume_fakes.FakeType.create_one_type( attrs={'encryption': encryption_info}) self.types_mock.create.return_value = self.new_volume_type self.encryption_types_mock.create.return_value = encryption_type encryption_columns = ( 'description', 'encryption', 'id', 'is_public', 'name', ) encryption_data = ( self.new_volume_type.description, utils.format_dict(encryption_info), self.new_volume_type.id, True, self.new_volume_type.name, ) arglist = [ '--encryption-provider', 'LuksEncryptor', '--encryption-cipher', 'aes-xts-plain64', '--encryption-key-size', '128', '--encryption-control-location', 'front-end', self.new_volume_type.name, ] verifylist = [ ('encryption_provider', 'LuksEncryptor'), ('encryption_cipher', 'aes-xts-plain64'), ('encryption_key_size', 128), ('encryption_control_location', 'front-end'), ('name', self.new_volume_type.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.create.assert_called_with( self.new_volume_type.name, ) body = { 'provider': 'LuksEncryptor', 'cipher': 'aes-xts-plain64', 'key_size': 128, 'control_location': 'front-end', } self.encryption_types_mock.create.assert_called_with( self.new_volume_type, body, ) self.assertEqual(encryption_columns, columns) self.assertEqual(encryption_data, data)
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume volume = parsed_args.volume if not parsed_args.volume: volume = parsed_args.snapshot_name volume_id = utils.find_resource( volume_client.volumes, volume).id if parsed_args.remote_source: # Create a new snapshot from an existing remote snapshot source if parsed_args.force: msg = (_("'--force' option will not work when you create " "new volume snapshot from an existing remote " "volume snapshot")) LOG.warning(msg) snapshot = volume_client.volume_snapshots.manage( volume_id=volume_id, ref=parsed_args.remote_source, name=parsed_args.snapshot_name, description=parsed_args.description, metadata=parsed_args.property, ) else: # create a new snapshot from scratch snapshot = volume_client.volume_snapshots.create( volume_id, force=parsed_args.force, name=parsed_args.snapshot_name, description=parsed_args.description, metadata=parsed_args.property, ) snapshot._info.update( {'properties': utils.format_dict(snapshot._info.pop('metadata'))} ) return zip(*sorted(six.iteritems(snapshot._info)))
def test_qos_show(self): arglist = [ volume_fakes.qos_id ] verifylist = [ ('qos_spec', volume_fakes.qos_id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.get.assert_called_with( volume_fakes.qos_id ) collist = ( 'associations', 'consumer', 'id', 'name', 'specs' ) self.assertEqual(collist, columns) datalist = ( volume_fakes.type_name, volume_fakes.qos_consumer, volume_fakes.qos_id, volume_fakes.qos_name, utils.format_dict(volume_fakes.qos_specs), ) self.assertEqual(datalist, tuple(data))
def test_assert_item_formattable_columns_vs_legacy_formatter(self): expected = [format_columns.DictColumn({'a': 1, 'b': 2}), format_columns.ListColumn(['x', 'y', 'z'])] actual = [utils.format_dict({'a': 1, 'b': 2}), utils.format_list(['x', 'y', 'z'])] self.assertRaises(AssertionError, self.assertItemEqual, expected, actual)
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute resource_flavor = _find_flavor(compute_client, parsed_args.flavor) access_projects = None # get access projects list of this flavor if not resource_flavor.is_public: try: flavor_access = compute_client.flavor_access.list( flavor=resource_flavor.id) projects = [utils.get_field(access, 'tenant_id') for access in flavor_access] # TODO(Huanxuan Ao): This format case can be removed after # patch https://review.openstack.org/#/c/330223/ merged. access_projects = utils.format_list(projects) except Exception as e: msg = _("Failed to get access projects list " "for flavor '%(flavor)s': %(e)s") LOG.error(msg % {'flavor': parsed_args.flavor, 'e': e}) flavor = resource_flavor._info.copy() flavor.update({ 'access_project_ids': access_projects }) flavor.pop("links", None) flavor['properties'] = utils.format_dict(resource_flavor.get_keys()) return zip(*sorted(six.iteritems(flavor)))
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume volume_type = utils.find_resource( volume_client.volume_types, parsed_args.volume_type) properties = utils.format_dict(volume_type._info.pop('extra_specs')) volume_type._info.update({'properties': properties}) return zip(*sorted(six.iteritems(volume_type._info)))
def _format_image(image): """Format an image to make it more consistent with OSC operations.""" info = {} properties = {} # the only fields we're not including is "links", "tags" and the properties fields_to_show = ['status', 'name', 'container_format', 'created_at', 'size', 'disk_format', 'updated_at', 'visibility', 'min_disk', 'protected', 'id', 'file', 'checksum', 'owner', 'virtual_size', 'min_ram', 'schema'] # split out the usual key and the properties which are top-level for key in six.iterkeys(image): if key in fields_to_show: info[key] = image.get(key) elif key == 'tags': continue # handle this later else: properties[key] = image.get(key) # format the tags if they are there info['tags'] = utils.format_list(image.get('tags')) # add properties back into the dictionary as a top-level key if properties: info['properties'] = utils.format_dict(properties) return info
def test_qos_list_no_association(self): self.qos_mock.reset_mock() self.qos_mock.get_associations.side_effect = [ [self.qos_association], exceptions.NotFound("NotFound"), ] arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.list.assert_called_with() self.assertEqual(self.columns, columns) ex_data = copy.deepcopy(self.data) ex_data[1] = ( self.qos_specs[1].id, self.qos_specs[1].name, self.qos_specs[1].consumer, None, utils.format_dict(self.qos_specs[1].specs), ) self.assertEqual(ex_data, list(data))
def test_baremetal_port_list_long(self): arglist = ['--long'] verifylist = [('detail', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) kwargs = { 'detail': True, 'marker': None, 'limit': None, } self.baremetal_mock.port.list.assert_called_with(**kwargs) collist = ('UUID', 'Address', 'Created At', 'Extra', 'Node UUID', 'Local Link Connection', 'Portgroup UUID', 'PXE boot enabled', 'Updated At', 'Internal Info') self.assertEqual(collist, columns) datalist = (( baremetal_fakes.baremetal_port_uuid, baremetal_fakes.baremetal_port_address, '', oscutils.format_dict(baremetal_fakes.baremetal_port_extra), baremetal_fakes.baremetal_uuid, '', '', '', '', '' ), ) self.assertEqual(datalist, tuple(data))
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, parsed_args.server, ) # Set sane defaults as this API wants all mouths to be fed if parsed_args.name is None: backup_name = server.name else: backup_name = parsed_args.name if parsed_args.type is None: backup_type = "" else: backup_type = parsed_args.type if parsed_args.rotate is None: backup_rotation = 1 else: backup_rotation = parsed_args.rotate compute_client.servers.backup( server.id, backup_name, backup_type, backup_rotation, ) image_client = self.app.client_manager.image image = utils.find_resource( image_client.images, backup_name, ) if parsed_args.wait: if utils.wait_for_status( image_client.images.get, image.id, callback=_show_progress, ): sys.stdout.write('\n') else: msg = _('Error creating server backup: %s') % parsed_args.name raise exceptions.CommandError(msg) if self.app.client_manager._api_version['image'] == '1': info = {} info.update(image._info) info['properties'] = utils.format_dict(info.get('properties', {})) else: # Get the right image module to format the output image_module = importutils.import_module( self.IMAGE_API_VERSIONS[ self.app.client_manager._api_version['image'] ] ) info = image_module._format_image(image) return zip(*sorted(six.iteritems(info)))
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume snapshot = utils.find_resource( volume_client.volume_snapshots, parsed_args.snapshot) snapshot._info.update( {'properties': utils.format_dict(snapshot._info.pop('metadata'))} ) return zip(*sorted(six.iteritems(snapshot._info)))
def take_action(self, parsed_args): _check_size_arg(parsed_args) identity_client = self.app.client_manager.identity image_client = self.app.client_manager.image volume_client = self.app.client_manager.volume source_volume = None if parsed_args.source: source_volume = utils.find_resource( volume_client.volumes, parsed_args.source, ).id project = None if parsed_args.project: project = utils.find_resource( identity_client.tenants, parsed_args.project, ).id user = None if parsed_args.user: user = utils.find_resource( identity_client.users, parsed_args.user, ).id image = None if parsed_args.image: image = utils.find_resource( image_client.images, parsed_args.image, ).id snapshot = parsed_args.snapshot or parsed_args.snapshot_id volume = volume_client.volumes.create( parsed_args.size, snapshot, source_volume, parsed_args.name, parsed_args.description, parsed_args.type, user, project, parsed_args.availability_zone, parsed_args.property, image, ) # Map 'metadata' column to 'properties' volume._info.update( { 'properties': utils.format_dict(volume._info.pop('metadata')), 'type': volume._info.pop('volume_type'), }, ) return zip(*sorted(six.iteritems(volume._info)))
def take_action(self, parsed_args): data = self.app.client_manager.object_store.container_show( container=parsed_args.container, ) if 'properties' in data: data['properties'] = utils.format_dict(data.pop('properties')) return zip(*sorted(six.iteritems(data)))
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute resource_flavor = _find_flavor(compute_client, parsed_args.flavor) flavor = resource_flavor._info.copy() flavor.pop("links", None) flavor['properties'] = utils.format_dict(resource_flavor.get_keys()) return zip(*sorted(six.iteritems(flavor)))
def take_action(self, parsed_args): identity_client = self.app.client_manager.identity volume_client = self.app.client_manager.volume image_client = self.app.client_manager.image source_volume = None if parsed_args.source: source_volume = utils.find_resource( volume_client.volumes, parsed_args.source).id image = None if parsed_args.image: image = utils.find_resource( image_client.images, parsed_args.image).id snapshot = None if parsed_args.snapshot: snapshot = utils.find_resource( volume_client.volume_snapshots, parsed_args.snapshot).id project = None if parsed_args.project: project = utils.find_resource( identity_client.projects, parsed_args.project).id user = None if parsed_args.user: user = utils.find_resource( identity_client.users, parsed_args.user).id volume = volume_client.volumes.create( size=parsed_args.size, snapshot_id=snapshot, name=parsed_args.name, description=parsed_args.description, volume_type=parsed_args.type, user_id=user, project_id=project, availability_zone=parsed_args.availability_zone, metadata=parsed_args.property, imageRef=image, source_volid=source_volume ) # Remove key links from being displayed volume._info.update( { 'properties': utils.format_dict(volume._info.pop('metadata')), 'type': volume._info.pop('volume_type') } ) volume._info.pop("links", None) return zip(*sorted(six.iteritems(volume._info)))
def take_action(self, parsed_args): LOG_DEP.warning(_('This command has been deprecated. ' 'Please use "volume snapshot show" instead.')) volume_client = self.app.client_manager.volume snapshot = utils.find_resource( volume_client.volume_snapshots, parsed_args.snapshot) snapshot._info.update( {'properties': utils.format_dict(snapshot._info.pop('metadata'))} ) return zip(*sorted(six.iteritems(snapshot._info)))
def test_type_show_with_encryption(self): encryption_type = volume_fakes.FakeType.create_one_encryption_type() encryption_info = { 'provider': 'LuksEncryptor', 'cipher': None, 'key_size': None, 'control_location': 'front-end', } self.volume_type = volume_fakes.FakeType.create_one_type( attrs={'encryption': encryption_info}) self.types_mock.get.return_value = self.volume_type self.encryption_types_mock.get.return_value = encryption_type encryption_columns = ( 'description', 'encryption', 'id', 'is_public', 'name', 'properties', ) encryption_data = ( self.volume_type.description, utils.format_dict(encryption_info), self.volume_type.id, True, self.volume_type.name, utils.format_dict(self.volume_type.extra_specs) ) arglist = [ '--encryption-type', self.volume_type.id ] verifylist = [ ('encryption_type', True), ("volume_type", self.volume_type.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.get.assert_called_with(self.volume_type.id) self.encryption_types_mock.get.assert_called_with(self.volume_type.id) self.assertEqual(encryption_columns, columns) self.assertEqual(encryption_data, data)
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume volume_type = volume_client.volume_types.create(parsed_args.name) volume_type._info.pop('extra_specs') if parsed_args.property: result = volume_type.set_keys(parsed_args.property) volume_type._info.update({'properties': utils.format_dict(result)}) volume_type._info.pop("os-volume-type-access:is_public", None) return zip(*sorted(six.iteritems(volume_type._info)))
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume volume_type = utils.find_resource( volume_client.volume_types, parsed_args.volume_type) properties = utils.format_dict(volume_type._info.pop('extra_specs')) volume_type._info.update({'properties': properties}) if parsed_args.encryption_type: # show encryption type information for this volume type try: encryption = volume_client.volume_encryption_types.get( volume_type.id) encryption._info.pop("volume_type_id", None) volume_type._info.update( {'encryption': utils.format_dict(encryption._info)}) except Exception as e: LOG.error(_("Failed to display the encryption information " "of this volume type: %s"), e) volume_type._info.pop("os-volume-type-access:is_public", None) return zip(*sorted(six.iteritems(volume_type._info)))
def take_action(self, parsed_args): volume_client = self.app.client_manager.volume qos_spec = utils.find_resource(volume_client.qos_specs, parsed_args.qos_spec) qos_associations = volume_client.qos_specs.get_associations(qos_spec) if qos_associations: associations = [association.name for association in qos_associations] qos_spec._info.update({"associations": utils.format_list(associations)}) qos_spec._info.update({"specs": utils.format_dict(qos_spec.specs)}) return zip(*sorted(six.iteritems(qos_spec._info)))
def take_action(self, parsed_args): def _show_progress(progress): if progress: self.app.stdout.write('\rProgress: %s' % progress) self.app.stdout.flush() compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, parsed_args.server, ) if parsed_args.name: image_name = parsed_args.name else: image_name = server.name image_id = compute_client.servers.create_image( server.id, image_name, ) image_client = self.app.client_manager.image image = utils.find_resource( image_client.images, image_id, ) if parsed_args.wait: if utils.wait_for_status( image_client.images.get, image_id, callback=_show_progress, ): self.app.stdout.write('\n') else: LOG.error(_('Error creating server image: %s'), parsed_args.server) raise exceptions.CommandError if self.app.client_manager._api_version['image'] == '1': info = {} info.update(image._info) info['properties'] = utils.format_dict(info.get('properties', {})) else: # Get the right image module to format the output image_module = importutils.import_module( self.IMAGE_API_VERSIONS[ self.app.client_manager._api_version['image'] ] ) info = image_module._format_image(image) return zip(*sorted(six.iteritems(info)))
def take_action(self, parsed_args): image_client = self.app.client_manager.image image = utils.find_resource( image_client.images, parsed_args.image, ) info = {} info.update(image._info) info['properties'] = utils.format_dict(info.get('properties', {})) return zip(*sorted(six.iteritems(info)))
def setUp(self): super(TestQosCreate, self).setUp() self.new_qos_spec = volume_fakes.FakeQos.create_one_qos() self.datalist = ( self.new_qos_spec.consumer, self.new_qos_spec.id, self.new_qos_spec.name, utils.format_dict(self.new_qos_spec.specs) ) self.qos_mock.create.return_value = self.new_qos_spec # Get the command object to test self.cmd = qos_specs.CreateQos(self.app, None)
class TestImageShow(TestImage): _image = image_fakes.FakeImage.create_one_image(attrs={'size': 2000}) columns = ( 'container_format', 'disk_format', 'id', 'is_public', 'min_disk', 'min_ram', 'name', 'owner', 'properties', 'protected', 'size', ) data = ( _image.container_format, _image.disk_format, _image.id, _image.is_public, _image.min_disk, _image.min_ram, _image.name, _image.owner, utils.format_dict(_image.properties), _image.protected, _image.size, ) def setUp(self): super(TestImageShow, self).setUp() self.images_mock.get.return_value = self._image # Get the command object to test self.cmd = image.ShowImage(self.app, None) def test_image_show(self): arglist = [ self._image.id, ] verifylist = [ ('image', self._image.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.images_mock.get.assert_called_with(self._image.id, ) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_image_show_human_readable(self): arglist = [ '--human-readable', self._image.id, ] verifylist = [ ('human_readable', True), ('image', self._image.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.images_mock.get.assert_called_with(self._image.id, ) size_index = columns.index('size') self.assertEqual(data[size_index], '2K')
class TestImageCreate(TestImage): new_image = image_fakes.FakeImage.create_one_image() columns = ( 'container_format', 'disk_format', 'id', 'is_public', 'min_disk', 'min_ram', 'name', 'owner', 'properties', 'protected', ) data = ( new_image.container_format, new_image.disk_format, new_image.id, new_image.is_public, new_image.min_disk, new_image.min_ram, new_image.name, new_image.owner, utils.format_dict(new_image.properties), new_image.protected, ) def setUp(self): super(TestImageCreate, self).setUp() self.images_mock.create.return_value = self.new_image # This is the return value for utils.find_resource() self.images_mock.get.return_value = self.new_image self.images_mock.update.return_value = self.new_image # Get the command object to test self.cmd = image.CreateImage(self.app, None) def test_image_reserve_no_options(self): mock_exception = { 'find.side_effect': exceptions.CommandError('x'), 'get.side_effect': exceptions.CommandError('x'), } self.images_mock.configure_mock(**mock_exception) arglist = [ self.new_image.name, ] verifylist = [ ('container_format', image.DEFAULT_CONTAINER_FORMAT), ('disk_format', image.DEFAULT_DISK_FORMAT), ('name', self.new_image.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) self.images_mock.create.assert_called_with( name=self.new_image.name, container_format=image.DEFAULT_CONTAINER_FORMAT, disk_format=image.DEFAULT_DISK_FORMAT, data=mock.ANY, ) # Verify update() was not called, if it was show the args self.assertEqual(self.images_mock.update.call_args_list, []) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_image_reserve_options(self): mock_exception = { 'find.side_effect': exceptions.CommandError('x'), 'get.side_effect': exceptions.CommandError('x'), } self.images_mock.configure_mock(**mock_exception) arglist = [ '--container-format', 'ovf', '--disk-format', 'ami', '--min-disk', '10', '--min-ram', '4', '--protected', '--private', '--project', 'q', self.new_image.name, ] verifylist = [ ('container_format', 'ovf'), ('disk_format', 'ami'), ('min_disk', 10), ('min_ram', 4), ('protected', True), ('unprotected', False), ('public', False), ('private', True), ('project', 'q'), ('name', self.new_image.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) # ImageManager.create(name=, **) self.images_mock.create.assert_called_with( name=self.new_image.name, container_format='ovf', disk_format='ami', min_disk=10, min_ram=4, protected=True, is_public=False, owner='q', data=mock.ANY, ) # Verify update() was not called, if it was show the args self.assertEqual(self.images_mock.update.call_args_list, []) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @mock.patch('openstackclient.image.v1.image.io.open', name='Open') def test_image_create_file(self, mock_open): mock_file = mock.Mock(name='File') mock_open.return_value = mock_file mock_open.read.return_value = self.data mock_exception = { 'find.side_effect': exceptions.CommandError('x'), 'get.side_effect': exceptions.CommandError('x'), } self.images_mock.configure_mock(**mock_exception) arglist = [ '--file', 'filer', '--unprotected', '--public', '--property', 'Alpha=1', '--property', 'Beta=2', self.new_image.name, ] verifylist = [ ('file', 'filer'), ('protected', False), ('unprotected', True), ('public', True), ('private', False), ('properties', { 'Alpha': '1', 'Beta': '2' }), ('name', self.new_image.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) # In base command class ShowOne in cliff, abstract method take_action() # returns a two-part tuple with a tuple of column names and a tuple of # data to be shown. columns, data = self.cmd.take_action(parsed_args) # Ensure input file is opened mock_open.assert_called_with('filer', 'rb') # Ensure the input file is closed mock_file.close.assert_called_with() # ImageManager.get(name) not to be called since update action exists self.images_mock.get.assert_not_called() # ImageManager.create(name=, **) self.images_mock.create.assert_called_with( name=self.new_image.name, container_format=image.DEFAULT_CONTAINER_FORMAT, disk_format=image.DEFAULT_DISK_FORMAT, protected=False, is_public=True, properties={ 'Alpha': '1', 'Beta': '2', }, data=mock_file, ) # Verify update() was not called, if it was show the args self.assertEqual(self.images_mock.update.call_args_list, []) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data)
def take_action(self, parsed_args): _check_size_arg(parsed_args) identity_client = self.app.client_manager.identity volume_client = self.app.client_manager.volume image_client = self.app.client_manager.image source_volume = None if parsed_args.source: source_volume = utils.find_resource(volume_client.volumes, parsed_args.source).id replicated_source_volume = None if parsed_args.source_replicated: replicated_source_volume = utils.find_resource( volume_client.volumes, parsed_args.source_replicated).id consistency_group = None if parsed_args.consistency_group: consistency_group = utils.find_resource( volume_client.consistencygroups, parsed_args.consistency_group).id image = None if parsed_args.image: image = utils.find_resource(image_client.images, parsed_args.image).id snapshot = None if parsed_args.snapshot: snapshot = utils.find_resource(volume_client.volume_snapshots, parsed_args.snapshot).id project = None if parsed_args.project: project = utils.find_resource(identity_client.projects, parsed_args.project).id user = None if parsed_args.user: user = utils.find_resource(identity_client.users, parsed_args.user).id volume = volume_client.volumes.create( size=parsed_args.size, snapshot_id=snapshot, name=parsed_args.name, description=parsed_args.description, volume_type=parsed_args.type, user_id=user, project_id=project, availability_zone=parsed_args.availability_zone, metadata=parsed_args.property, imageRef=image, source_volid=source_volume, consistencygroup_id=consistency_group, source_replica=replicated_source_volume, multiattach=parsed_args.multi_attach, scheduler_hints=parsed_args.hint, ) # Remove key links from being displayed volume._info.update({ 'properties': utils.format_dict(volume._info.pop('metadata')), 'type': volume._info.pop('volume_type') }) volume._info.pop("links", None) return zip(*sorted(six.iteritems(volume._info)))
def _test_create_fake_server(self, mock_create, mock_find, name, flavor_id, image_id, networks, description=None, availability_zone=None, properties=None): arglist = [name, '--flavor', flavor_id, '--image', image_id] verifylist = [('name', name), ('flavor', flavor_id), ('image', image_id)] called_networks = copy.deepcopy(networks) for nic in called_networks: if 'port-type' in nic: nic['port_type'] = nic['port-type'] del nic['port-type'] if 'net-id' in nic: nic['net_id'] = nic['net-id'] del nic['net-id'] called_data = { 'server': { 'name': name, 'image_uuid': image_id, 'flavor_uuid': flavor_id, 'networks': called_networks, 'min_count': 1, 'max_count': 1 } } for network in networks: network_id = network.get('net-id') port_type = network.get('port-type') if port_type: arglist.extend([ '--nic', 'net-id=' + network_id + ',port-type=' + port_type ]) verifylist.append(('nic', [{ 'net-id': network_id, 'port-type': port_type }])) else: arglist.extend(['--nic', 'net-id=' + network_id]) verifylist.append(('nic', [{'net-id': network_id}])) if description: arglist.extend(['--description', description]) verifylist.append(('description', description)) called_data['server']['description'] = description if availability_zone: arglist.extend(['--availability-zone', availability_zone]) verifylist.append(('availability_zone', availability_zone)) called_data['server']['availability_zone'] = availability_zone if properties: arglist.extend(['--property', properties]) verifylist.append(('property', {'key1': 'test'})) called_data['server']['metadata'] = {'key1': 'test'} flavor_obj = mock.Mock() flavor_obj.uuid = flavor_id flavor_obj.name = 'test-flavor' image_obj = mock.Mock() image_obj.id = image_id image_obj.name = 'test-image' mock_find.side_effect = [flavor_obj, image_obj] fk_server = fakes.FakeServer.create_one_server(called_data['server']) mock_create.return_value = fk_server parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) mock_create.assert_called_once_with('/servers', data=called_data) self.assertEqual(self.columns, columns) expected_data = (fk_server.addresses, fk_server.availability_zone, fk_server.created_at, fk_server.description, 'test-flavor (%s)' % fk_server.flavor_uuid, 'test-image (%s)' % fk_server.image_uuid, fk_server.links, 1, 1, fk_server.name, utils.format_dict(fk_server.metadata), fk_server.updated_at, fk_server.uuid) self.assertEqual(expected_data, data)
class TestQosList(TestQos): qos_specs = volume_fakes.FakeQos.create_qoses(count=2) qos_association = volume_fakes.FakeQos.create_one_qos_association() columns = ( 'ID', 'Name', 'Consumer', 'Associations', 'Properties', ) data = [] for q in qos_specs: data.append(( q.id, q.name, q.consumer, qos_association.name, utils.format_dict(q.specs), )) def setUp(self): super(TestQosList, self).setUp() self.qos_mock.list.return_value = self.qos_specs self.qos_mock.get_associations.return_value = [self.qos_association] # Get the command object to test self.cmd = qos_specs.ListQos(self.app, None) def test_qos_list(self): arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.list.assert_called_with() self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_qos_list_no_association(self): self.qos_mock.reset_mock() self.qos_mock.get_associations.side_effect = [ [self.qos_association], exceptions.NotFound("NotFound"), ] arglist = [] verifylist = [] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.list.assert_called_with() self.assertEqual(self.columns, columns) ex_data = copy.deepcopy(self.data) ex_data[1] = ( self.qos_specs[1].id, self.qos_specs[1].name, self.qos_specs[1].consumer, None, utils.format_dict(self.qos_specs[1].specs), ) self.assertEqual(ex_data, list(data))
class TestFlavorShow(TestFlavor): # Return value of self.flavors_mock.find(). flavor_access = compute_fakes.FakeFlavorAccess.create_one_flavor_access() flavor = compute_fakes.FakeFlavor.create_one_flavor() columns = ( 'OS-FLV-DISABLED:disabled', 'OS-FLV-EXT-DATA:ephemeral', 'access_project_ids', 'disk', 'id', 'name', 'os-flavor-access:is_public', 'properties', 'ram', 'rxtx_factor', 'swap', 'vcpus', ) data = ( flavor.disabled, flavor.ephemeral, None, flavor.disk, flavor.id, flavor.name, flavor.is_public, utils.format_dict(flavor.get_keys()), flavor.ram, flavor.rxtx_factor, flavor.swap, flavor.vcpus, ) def setUp(self): super(TestFlavorShow, self).setUp() # Return value of _find_resource() self.flavors_mock.find.return_value = self.flavor self.flavors_mock.get.side_effect = exceptions.NotFound(None) self.flavor_access_mock.list.return_value = [self.flavor_access] self.cmd = flavor.ShowFlavor(self.app, None) def test_show_no_options(self): arglist = [] verifylist = [] # Missing required args should boil here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) def test_public_flavor_show(self): arglist = [ self.flavor.name, ] verifylist = [ ('flavor', self.flavor.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_private_flavor_show(self): private_flavor = compute_fakes.FakeFlavor.create_one_flavor( attrs={ 'os-flavor-access:is_public': False, } ) self.flavors_mock.find.return_value = private_flavor arglist = [ private_flavor.name, ] verifylist = [ ('flavor', private_flavor.name), ] data_with_project = ( private_flavor.disabled, private_flavor.ephemeral, self.flavor_access.tenant_id, private_flavor.disk, private_flavor.id, private_flavor.name, private_flavor.is_public, utils.format_dict(private_flavor.get_keys()), private_flavor.ram, private_flavor.rxtx_factor, private_flavor.swap, private_flavor.vcpus, ) parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.flavor_access_mock.list.assert_called_with( flavor=private_flavor.id) self.assertEqual(self.columns, columns) self.assertEqual(data_with_project, data)
def take_action(self, parsed_args): image_client = self.app.client_manager.image if getattr(parsed_args, 'owner', None) is not None: LOG.warning( _('The --owner option is deprecated, ' 'please use --project instead.')) # Build an attribute dict from the parsed args, only include # attributes that were actually set on the command line kwargs = {} copy_attrs = ('name', 'id', 'store', 'container_format', 'disk_format', 'owner', 'size', 'min_disk', 'min_ram', 'location', 'copy_from', 'volume', 'force', 'checksum', 'properties') for attr in copy_attrs: if attr in parsed_args: val = getattr(parsed_args, attr, None) if val: # Only include a value in kwargs for attributes that are # actually present on the command line kwargs[attr] = val # Special case project option back to API attribute name 'owner' val = getattr(parsed_args, 'project', None) if val: kwargs['owner'] = val # Handle exclusive booleans with care # Avoid including attributes in kwargs if an option is not # present on the command line. These exclusive booleans are not # a single value for the pair of options because the default must be # to do nothing when no options are present as opposed to always # setting a default. if parsed_args.protected: kwargs['protected'] = True if parsed_args.unprotected: kwargs['protected'] = False if parsed_args.public: kwargs['is_public'] = True if parsed_args.private: kwargs['is_public'] = False info = {} if not parsed_args.location and not parsed_args.copy_from: if parsed_args.volume: volume_client = self.app.client_manager.volume source_volume = utils.find_resource( volume_client.volumes, parsed_args.volume, ) response, body = volume_client.volumes.upload_to_image( source_volume.id, parsed_args.force, parsed_args.name, parsed_args.container_format, parsed_args.disk_format, ) info = body['os-volume_upload_image'] elif parsed_args.file: # Send an open file handle to glanceclient so it will # do a chunked transfer kwargs["data"] = io.open(parsed_args.file, "rb") else: # Read file from stdin if sys.stdin.isatty() is not True: if msvcrt: msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) # Send an open file handle to glanceclient so it will # do a chunked transfer kwargs["data"] = sys.stdin if not parsed_args.volume: # Wrap the call to catch exceptions in order to close files try: image = image_client.images.create(**kwargs) finally: # Clean up open files - make sure data isn't a string if ('data' in kwargs and hasattr(kwargs['data'], 'close') and kwargs['data'] != sys.stdin): kwargs['data'].close() info.update(image._info) info['properties'] = utils.format_dict(info.get('properties', {})) return zip(*sorted(six.iteritems(info)))
def test_nuage_floating_ip_option(self): """Create, delete a port with a nuage floating ip""" # Create Nuage floating ip shared_subnet = self._create_shared_fip_subnet(self.session, '1.1.1.0', '255.255.255.0') floating_ip_str = '1.1.1.10' floating_ip = self.l3domain.create_child( vspk.NUFloatingIp( associated_shared_network_resource_id=shared_subnet.id, address=floating_ip_str))[0] self.addCleanup(floating_ip.delete) # Create a port with the Nuage floating ip in the VSD managed subnet port_name = utils.get_random_name() cmd_create = ('port create -f json --nuage-floatingip {floating_ip} ' '--network {network} {name}'.format( floating_ip=floating_ip_str, network=self.NETWORK_NAME, name=port_name)) cmd_output = json.loads(self.openstack(cmd_create)) self.addCleanup(self.openstack, 'port delete {}'.format(port_name)) # Verify create self.assertIsNotNone(cmd_output.get('nuage_floatingip')) self.assertEqual(observed=cmd_output['nuage_floatingip'], expected=osc_utils.format_dict({ 'id': floating_ip.id, 'floating_ip_address': floating_ip_str })) # Verify show cmd_output = self._port_show(port_name) self.assertEqual(observed=cmd_output['nuage_floatingip'], expected=osc_utils.format_dict({ 'id': floating_ip.id, 'floating_ip_address': floating_ip_str })) # Try to create again, expect failure cmd_create = ('port create -f json --nuage-floatingip {floating_ip} ' '--network {network} {name}'.format( floating_ip=floating_ip_str, network=self.NETWORK_NAME, name=utils.get_random_name())) self.assertRaisesRegex(Exception, "Floating IP .* is already in use", self.openstack, cmd_create) # Verify set / unset cmd_set = 'port set --nuage-floatingip 1.1.1.99 {}'.format(port_name) self.assertRaisesRegex( Exception, 'No Nuage Floating IP available with' ' IP 1.1.1.99', self.openstack, cmd_set) port_name_2 = utils.get_random_name() self.openstack('port create -f json --network {network} {name}'.format( network=self.NETWORK_NAME, name=port_name_2)) cmd_set = 'port set --nuage-floatingip {} {}'.format( floating_ip_str, port_name_2) self.assertRaisesRegex( Exception, 'Floating IP {} is already in use'.format(floating_ip_str), self.openstack, cmd_set) cmd_unset = 'port unset --nuage-floatingip {}'.format(port_name) self.openstack(cmd_unset) # Verify show (No Nuage floating ip) cmd_output = self._port_show(port_name) self.assertIsNone(cmd_output['nuage_floatingip']) # the set should work now, since we unsetted the previous fip self.openstack(cmd_set) # Verify delete utils.delete_and_verify(self, 'port', port_name_2)
def test_type_create_with_encryption(self): encryption_info = { 'provider': 'LuksEncryptor', 'cipher': 'aes-xts-plain64', 'key_size': '128', 'control_location': 'front-end', } encryption_type = volume_fakes.FakeType.create_one_encryption_type( attrs=encryption_info ) self.new_volume_type = volume_fakes.FakeType.create_one_type( attrs={'encryption': encryption_info}) self.types_mock.create.return_value = self.new_volume_type self.encryption_types_mock.create.return_value = encryption_type encryption_columns = ( 'description', 'encryption', 'id', 'is_public', 'name', ) encryption_data = ( self.new_volume_type.description, utils.format_dict(encryption_info), self.new_volume_type.id, True, self.new_volume_type.name, ) arglist = [ '--encryption-provider', 'LuksEncryptor', '--encryption-cipher', 'aes-xts-plain64', '--encryption-key-size', '128', '--encryption-control-location', 'front-end', self.new_volume_type.name, ] verifylist = [ ('encryption_provider', 'LuksEncryptor'), ('encryption_cipher', 'aes-xts-plain64'), ('encryption_key_size', 128), ('encryption_control_location', 'front-end'), ('name', self.new_volume_type.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.create.assert_called_with( self.new_volume_type.name, description=None, ) body = { 'provider': 'LuksEncryptor', 'cipher': 'aes-xts-plain64', 'key_size': 128, 'control_location': 'front-end', } self.encryption_types_mock.create.assert_called_with( self.new_volume_type, body, ) self.assertEqual(encryption_columns, columns) self.assertEqual(encryption_data, data)
class TestTypeList(TestType): volume_types = volume_fakes.FakeType.create_types() columns = [ "ID", "Name", "Is Public", ] columns_long = columns + [ "Description", "Properties" ] data_with_default_type = [( volume_types[0].id, volume_types[0].name, True )] data = [] for t in volume_types: data.append(( t.id, t.name, t.is_public, )) data_long = [] for t in volume_types: data_long.append(( t.id, t.name, t.is_public, t.description, utils.format_dict(t.extra_specs), )) def setUp(self): super(TestTypeList, self).setUp() self.types_mock.list.return_value = self.volume_types self.types_mock.default.return_value = self.volume_types[0] # get the command to test self.cmd = volume_type.ListVolumeType(self.app, None) def test_type_list_without_options(self): arglist = [] verifylist = [ ("long", False), ("private", False), ("public", False), ("default", False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=None) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_type_list_with_options(self): arglist = [ "--long", "--public", ] verifylist = [ ("long", True), ("private", False), ("public", True), ("default", False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=True) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) def test_type_list_with_private_option(self): arglist = [ "--private", ] verifylist = [ ("long", False), ("private", True), ("public", False), ("default", False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=False) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_type_list_with_default_option(self): arglist = [ "--default", ] verifylist = [ ("encryption_type", False), ("long", False), ("private", False), ("public", False), ("default", True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.default.assert_called_once_with() self.assertEqual(self.columns, columns) self.assertEqual(self.data_with_default_type, list(data)) def test_type_list_with_encryption(self): encryption_type = volume_fakes.FakeType.create_one_encryption_type( attrs={'volume_type_id': self.volume_types[0].id}) encryption_info = { 'provider': 'LuksEncryptor', 'cipher': None, 'key_size': None, 'control_location': 'front-end', } encryption_columns = self.columns + [ "Encryption", ] encryption_data = [] encryption_data.append(( self.volume_types[0].id, self.volume_types[0].name, self.volume_types[0].is_public, utils.format_dict(encryption_info), )) encryption_data.append(( self.volume_types[1].id, self.volume_types[1].name, self.volume_types[1].is_public, '-', )) self.encryption_types_mock.list.return_value = [encryption_type] arglist = [ "--encryption-type", ] verifylist = [ ("encryption_type", True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.encryption_types_mock.list.assert_called_once_with() self.types_mock.list.assert_called_once_with(is_public=None) self.assertEqual(encryption_columns, columns) self.assertEqual(encryption_data, list(data))
def take_action(self, parsed_args): def _show_progress(progress): if progress: self.app.stderr.write('\rProgress: %s' % progress) self.app.stderr.flush() compute_client = self.app.client_manager.compute server = utils.find_resource( compute_client.servers, parsed_args.server, ) # Set sane defaults as this API wants all mouths to be fed if parsed_args.name is None: backup_name = server.name else: backup_name = parsed_args.name if parsed_args.type is None: backup_type = "" else: backup_type = parsed_args.type if parsed_args.rotate is None: backup_rotation = 1 else: backup_rotation = parsed_args.rotate compute_client.servers.backup( server.id, backup_name, backup_type, backup_rotation, ) image_client = self.app.client_manager.image image = utils.find_resource( image_client.images, backup_name, ) if parsed_args.wait: if utils.wait_for_status( image_client.images.get, image.id, callback=_show_progress, ): self.app.stdout.write('\n') else: msg = _('Error creating server backup: %s') % parsed_args.name raise exceptions.CommandError(msg) if self.app.client_manager._api_version['image'] == '1': info = {} info.update(image._info) info['properties'] = utils.format_dict(info.get('properties', {})) else: # Get the right image module to format the output image_module = importutils.import_module(self.IMAGE_API_VERSIONS[ self.app.client_manager._api_version['image']]) info = image_module._format_image(image) return zip(*sorted(six.iteritems(info)))
def human_readable(self): return utils.format_dict(self._value)
def take_action(self, parsed_args): data = self.app.client_manager.object_store.account_show() if 'properties' in data: data['properties'] = utils.format_dict(data.pop('properties')) return zip(*sorted(six.iteritems(data)))
def take_action(self, parsed_args): _check_size_arg(parsed_args) identity_client = self.app.client_manager.identity image_client = self.app.client_manager.image volume_client = self.app.client_manager.volume source_volume = None if parsed_args.source: source_volume = utils.find_resource( volume_client.volumes, parsed_args.source, ).id project = None if parsed_args.project: project = utils.find_resource( identity_client.tenants, parsed_args.project, ).id user = None if parsed_args.user: user = utils.find_resource( identity_client.users, parsed_args.user, ).id image = None if parsed_args.image: image = utils.find_resource( image_client.images, parsed_args.image, ).id snapshot = parsed_args.snapshot or parsed_args.snapshot_id volume = volume_client.volumes.create( parsed_args.size, snapshot, source_volume, parsed_args.name, parsed_args.description, parsed_args.type, user, project, parsed_args.availability_zone, parsed_args.property, image, ) if parsed_args.bootable or parsed_args.non_bootable: try: volume_client.volumes.set_bootable(volume.id, parsed_args.bootable) except Exception as e: LOG.error(_("Failed to set volume bootable property: %s"), e) if parsed_args.read_only or parsed_args.read_write: try: volume_client.volumes.update_readonly_flag( volume.id, parsed_args.read_only) except Exception as e: LOG.error( _("Failed to set volume read-only access " "mode flag: %s"), e) # Map 'metadata' column to 'properties' volume._info.update( { 'properties': utils.format_dict(volume._info.pop('metadata')), 'type': volume._info.pop('volume_type'), }, ) # Replace "display_name" by "name", keep consistent in v1 and v2 if 'display_name' in volume._info: volume._info.update({'name': volume._info.pop('display_name')}) volume_info = utils.backward_compat_col_showone( volume._info, parsed_args.columns, {'display_name': 'name'}) return zip(*sorted(six.iteritems(volume_info)))
class TestSnapshotList(TestSnapshot): volume = volume_fakes.FakeVolume.create_one_volume() snapshots = volume_fakes.FakeSnapshot.create_snapshots( attrs={'volume_id': volume.display_name}, count=3) columns = [ "ID", "Name", "Description", "Status", "Size" ] columns_long = columns + [ "Created At", "Volume", "Properties" ] data = [] for s in snapshots: data.append(( s.id, s.display_name, s.display_description, s.status, s.size, )) data_long = [] for s in snapshots: data_long.append(( s.id, s.display_name, s.display_description, s.status, s.size, s.created_at, s.volume_id, utils.format_dict(s.metadata), )) def setUp(self): super(TestSnapshotList, self).setUp() self.volumes_mock.list.return_value = [self.volume] self.snapshots_mock.list.return_value = self.snapshots # Get the command to test self.cmd = snapshot.ListSnapshot(self.app, None) def test_snapshot_list_without_options(self): arglist = [] verifylist = [ ('all_projects', False), ("long", False) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with( search_opts={'all_tenants': False}) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_snapshot_list_with_long(self): arglist = [ "--long", ] verifylist = [ ("long", True), ('all_projects', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with( search_opts={'all_tenants': False} ) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) def test_snapshot_list_all_projects(self): arglist = [ '--all-projects', ] verifylist = [ ('long', False), ('all_projects', True) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with( search_opts={'all_tenants': True}) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data))
class TestFlavorCreate(TestFlavor): flavor = compute_fakes.FakeFlavor.create_one_flavor( attrs={'links': 'flavor-links'}) project = identity_fakes.FakeProject.create_one_project() columns = ( 'OS-FLV-DISABLED:disabled', 'OS-FLV-EXT-DATA:ephemeral', 'disk', 'id', 'name', 'os-flavor-access:is_public', 'properties', 'ram', 'rxtx_factor', 'swap', 'vcpus', ) data = ( flavor.disabled, flavor.ephemeral, flavor.disk, flavor.id, flavor.name, flavor.is_public, utils.format_dict(flavor.properties), flavor.ram, flavor.rxtx_factor, flavor.swap, flavor.vcpus, ) def setUp(self): super(TestFlavorCreate, self).setUp() # Return a project self.projects_mock.get.return_value = self.project self.flavors_mock.create.return_value = self.flavor self.cmd = flavor.CreateFlavor(self.app, None) def test_flavor_create_default_options(self): arglist = [ self.flavor.name ] verifylist = [ ('name', self.flavor.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) default_args = ( self.flavor.name, 256, 1, 0, 'auto', 0, 0, 1.0, True ) columns, data = self.cmd.take_action(parsed_args) self.flavors_mock.create.assert_called_once_with(*default_args) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_flavor_create_all_options(self): arglist = [ '--id', self.flavor.id, '--ram', str(self.flavor.ram), '--disk', str(self.flavor.disk), '--ephemeral', str(self.flavor.ephemeral), '--swap', str(self.flavor.swap), '--vcpus', str(self.flavor.vcpus), '--rxtx-factor', str(self.flavor.rxtx_factor), '--public', '--property', 'property=value', self.flavor.name, ] verifylist = [ ('id', self.flavor.id), ('ram', self.flavor.ram), ('disk', self.flavor.disk), ('ephemeral', self.flavor.ephemeral), ('swap', self.flavor.swap), ('vcpus', self.flavor.vcpus), ('rxtx_factor', self.flavor.rxtx_factor), ('public', True), ('property', {'property': 'value'}), ('name', self.flavor.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) args = ( self.flavor.name, self.flavor.ram, self.flavor.vcpus, self.flavor.disk, self.flavor.id, self.flavor.ephemeral, self.flavor.swap, self.flavor.rxtx_factor, self.flavor.is_public, ) columns, data = self.cmd.take_action(parsed_args) self.flavors_mock.create.assert_called_once_with(*args) self.flavor.set_keys.assert_called_once_with({'property': 'value'}) self.flavor.get_keys.assert_called_once_with() self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_flavor_create_other_options(self): self.flavor.is_public = False arglist = [ '--id', 'auto', '--ram', str(self.flavor.ram), '--disk', str(self.flavor.disk), '--ephemeral', str(self.flavor.ephemeral), '--swap', str(self.flavor.swap), '--vcpus', str(self.flavor.vcpus), '--rxtx-factor', str(self.flavor.rxtx_factor), '--private', '--project', self.project.id, '--property', 'key1=value1', '--property', 'key2=value2', self.flavor.name, ] verifylist = [ ('ram', self.flavor.ram), ('disk', self.flavor.disk), ('ephemeral', self.flavor.ephemeral), ('swap', self.flavor.swap), ('vcpus', self.flavor.vcpus), ('rxtx_factor', self.flavor.rxtx_factor), ('public', False), ('project', self.project.id), ('property', {'key1': 'value1', 'key2': 'value2'}), ('name', self.flavor.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) args = ( self.flavor.name, self.flavor.ram, self.flavor.vcpus, self.flavor.disk, 'auto', self.flavor.ephemeral, self.flavor.swap, self.flavor.rxtx_factor, self.flavor.is_public, ) columns, data = self.cmd.take_action(parsed_args) self.flavors_mock.create.assert_called_once_with(*args) self.flavor_access_mock.add_tenant_access.assert_called_with( self.flavor.id, self.project.id, ) self.flavor.set_keys.assert_called_with( {'key1': 'value1', 'key2': 'value2'}) self.flavor.get_keys.assert_called_with() self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_public_flavor_create_with_project(self): arglist = [ '--project', self.project.id, self.flavor.name, ] verifylist = [ ('project', self.project.id), ('name', self.flavor.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(exceptions.CommandError, self.cmd.take_action, parsed_args) def test_flavor_create_no_options(self): arglist = [] verifylist = None self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist)
class TestSnapshotList(TestSnapshot): volume = volume_fakes.FakeVolume.create_one_volume() project = project_fakes.FakeProject.create_one_project() snapshots = volume_fakes.FakeSnapshot.create_snapshots( attrs={'volume_id': volume.name}, count=3) columns = ["ID", "Name", "Description", "Status", "Size"] columns_long = columns + ["Created At", "Volume", "Properties"] data = [] for s in snapshots: data.append(( s.id, s.name, s.description, s.status, s.size, )) data_long = [] for s in snapshots: data_long.append(( s.id, s.name, s.description, s.status, s.size, s.created_at, s.volume_id, utils.format_dict(s.metadata), )) def setUp(self): super(TestSnapshotList, self).setUp() self.volumes_mock.list.return_value = [self.volume] self.volumes_mock.get.return_value = self.volume self.project_mock.get.return_value = self.project self.snapshots_mock.list.return_value = self.snapshots # Get the command to test self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None) def test_snapshot_list_without_options(self): arglist = [] verifylist = [('all_projects', False), ('long', False)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with(limit=None, marker=None, search_opts={ 'all_tenants': False, 'name': None, 'status': None, 'project_id': None, 'volume_id': None }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_snapshot_list_with_options(self): arglist = [ "--long", "--limit", "2", "--project", self.project.id, "--marker", self.snapshots[0].id, ] verifylist = [ ("long", True), ("limit", 2), ("project", self.project.id), ("marker", self.snapshots[0].id), ('all_projects', False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with( limit=2, marker=self.snapshots[0].id, search_opts={ 'all_tenants': True, 'project_id': self.project.id, 'name': None, 'status': None, 'volume_id': None }) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) def test_snapshot_list_all_projects(self): arglist = [ '--all-projects', ] verifylist = [('long', False), ('all_projects', True)] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with(limit=None, marker=None, search_opts={ 'all_tenants': True, 'name': None, 'status': None, 'project_id': None, 'volume_id': None }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_snapshot_list_name_option(self): arglist = [ '--name', self.snapshots[0].name, ] verifylist = [ ('all_projects', False), ('long', False), ('name', self.snapshots[0].name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with( limit=None, marker=None, search_opts={ 'all_tenants': False, 'name': self.snapshots[0].name, 'status': None, 'project_id': None, 'volume_id': None }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_snapshot_list_status_option(self): arglist = [ '--status', self.snapshots[0].status, ] verifylist = [ ('all_projects', False), ('long', False), ('status', self.snapshots[0].status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with( limit=None, marker=None, search_opts={ 'all_tenants': False, 'name': None, 'status': self.snapshots[0].status, 'project_id': None, 'volume_id': None }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_snapshot_list_volumeid_option(self): arglist = [ '--volume', self.volume.id, ] verifylist = [ ('all_projects', False), ('long', False), ('volume', self.volume.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.list.assert_called_once_with(limit=None, marker=None, search_opts={ 'all_tenants': False, 'name': None, 'status': None, 'project_id': None, 'volume_id': self.volume.id }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_snapshot_list_negative_limit(self): arglist = [ "--limit", "-2", ] verifylist = [ ("limit", -2), ] self.assertRaises(argparse.ArgumentTypeError, self.check_parser, self.cmd, arglist, verifylist)
class TestTypeList(TestType): volume_types = volume_fakes.FakeType.create_types() columns = ["ID", "Name"] columns_long = columns + ["Description", "Properties"] data = [] for t in volume_types: data.append(( t.id, t.name, )) data_long = [] for t in volume_types: data_long.append(( t.id, t.name, t.description, utils.format_dict(t.extra_specs), )) def setUp(self): super(TestTypeList, self).setUp() self.types_mock.list.return_value = self.volume_types # get the command to test self.cmd = volume_type.ListVolumeType(self.app, None) def test_type_list_without_options(self): arglist = [] verifylist = [ ("long", False), ("private", False), ("public", False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=None) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data)) def test_type_list_with_options(self): arglist = [ "--long", "--public", ] verifylist = [ ("long", True), ("private", False), ("public", True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=True) self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) def test_type_list_with_private_option(self): arglist = [ "--private", ] verifylist = [ ("long", False), ("private", True), ("public", False), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.list.assert_called_once_with(is_public=False) self.assertEqual(self.columns, columns) self.assertEqual(self.data, list(data))
def take_action(self, parsed_args): bc_client = self.app.client_manager.baremetal_compute flavor_data = utils.find_resource(bc_client.flavor, parsed_args.flavor) image_data = utils.find_resource(self.app.client_manager.image.images, parsed_args.image) for nic in parsed_args.nic: if 'port-type' in nic: nic['port_type'] = nic['port-type'] del nic['port-type'] if 'net-id' in nic: nic['net_id'] = nic['net-id'] del nic['net-id'] files = {} for f in parsed_args.file: dst, src = f.split('=', 1) try: files[dst] = io.open(src, 'rb') except IOError as e: msg = _("Can't open '%(source)s': %(exception)s") raise exceptions.CommandError(msg % { "source": src, "exception": e }) if parsed_args.min > parsed_args.max: msg = _("min servers should be <= max servers") raise exceptions.CommandError(msg) if parsed_args.min < 1: msg = _("min servers should be > 0") raise exceptions.CommandError(msg) if parsed_args.max < 1: msg = _("max servers should be > 0") raise exceptions.CommandError(msg) userdata = None if parsed_args.user_data: try: userdata = io.open(parsed_args.user_data) except IOError as e: msg = _("Can't open '%(data)s': %(exception)s") raise exceptions.CommandError(msg % { "data": parsed_args.user_data, "exception": e }) boot_kwargs = dict(name=parsed_args.name, image_uuid=image_data.id, flavor_uuid=flavor_data.uuid, description=parsed_args.description, networks=parsed_args.nic, availability_zone=parsed_args.availability_zone, userdata=userdata, files=files, key_name=parsed_args.key_name, metadata=parsed_args.property, min_count=parsed_args.min, max_count=parsed_args.max, hint=parsed_args.hint) try: data = bc_client.server.create(**boot_kwargs) finally: # Clean up open files - make sure they are not strings for f in files: if hasattr(f, 'close'): f.close() if hasattr(userdata, 'close'): userdata.close() # Special mapping for columns to make the output easier to read: # 'metadata' --> 'properties' # 'image_uuid' --> '<image_name> (<image_uuid>)' # 'flavor_uuid' --> '<flavor_name> (<flavor_uuid>)' data._info.update( { 'properties': utils.format_dict(data._info.pop('metadata')), 'image': '%s (%s)' % (image_data.name, image_data.id), 'flavor': '%s (%s)' % (flavor_data.name, flavor_data.uuid) }, ) data._info.pop('flavor_uuid') data._info.pop('image_uuid') info = {} info.update(data._info) return zip(*sorted(info.items()))
def scaling_reason(self): desc = json.loads(self.description) return '\n\n'.join(formatter.format_dict(i) for i in desc["reason"])
def take_action(self, parsed_args): _check_size_arg(parsed_args) volume_client = self.app.client_manager.volume image_client = self.app.client_manager.image source_volume = None if parsed_args.source: source_volume = utils.find_resource(volume_client.volumes, parsed_args.source).id consistency_group = None if parsed_args.consistency_group: consistency_group = utils.find_resource( volume_client.consistencygroups, parsed_args.consistency_group).id image = None if parsed_args.image: image = utils.find_resource(image_client.images, parsed_args.image).id size = parsed_args.size snapshot = None if parsed_args.snapshot: snapshot_obj = utils.find_resource(volume_client.volume_snapshots, parsed_args.snapshot) snapshot = snapshot_obj.id # Cinder requires a value for size when creating a volume # even if creating from a snapshot. Cinder will create the # volume with at least the same size as the snapshot anyway, # so since we have the object here, just override the size # value if it's either not given or is smaller than the # snapshot size. size = max(size or 0, snapshot_obj.size) # NOTE(abishop): Cinder's volumes.create() has 'project_id' and # 'user_id' args, but they're not wired up to anything. The only way # to specify an alternate project or user for the volume is to use # the identity overrides (e.g. "--os-project-id"). # # Now, if the project or user arg is specified then the command is # rejected. Otherwise, Cinder would actually create a volume, but # without the specified property. if parsed_args.project: raise exceptions.CommandError( _("ERROR: --project is deprecated, please use" " --os-project-name or --os-project-id instead.")) if parsed_args.user: raise exceptions.CommandError( _("ERROR: --user is deprecated, please use" " --os-username instead.")) if parsed_args.multi_attach: LOG.warning( _("'--multi-attach' option is no longer supported by " "the block storage service.")) volume = volume_client.volumes.create( size=size, snapshot_id=snapshot, name=parsed_args.name, description=parsed_args.description, volume_type=parsed_args.type, availability_zone=parsed_args.availability_zone, metadata=parsed_args.property, imageRef=image, source_volid=source_volume, consistencygroup_id=consistency_group, scheduler_hints=parsed_args.hint, ) if parsed_args.bootable or parsed_args.non_bootable: try: volume_client.volumes.set_bootable(volume.id, parsed_args.bootable) except Exception as e: LOG.error(_("Failed to set volume bootable property: %s"), e) if parsed_args.read_only or parsed_args.read_write: try: volume_client.volumes.update_readonly_flag( volume.id, parsed_args.read_only) except Exception as e: LOG.error( _("Failed to set volume read-only access " "mode flag: %s"), e) # Remove key links from being displayed volume._info.update({ 'properties': utils.format_dict(volume._info.pop('metadata')), 'type': volume._info.pop('volume_type') }) volume._info.pop("links", None) return zip(*sorted(six.iteritems(volume._info)))
def human_readable(self): encryption_info = self._get_encryption_info() if encryption_info: return utils.format_dict(encryption_info) else: return '-'
def take_action(self, parsed_args): _check_size_arg(parsed_args) identity_client = self.app.client_manager.identity volume_client = self.app.client_manager.volume image_client = self.app.client_manager.image source_volume = None if parsed_args.source: source_volume = utils.find_resource(volume_client.volumes, parsed_args.source).id consistency_group = None if parsed_args.consistency_group: consistency_group = utils.find_resource( volume_client.consistencygroups, parsed_args.consistency_group).id image = None if parsed_args.image: image = utils.find_resource(image_client.images, parsed_args.image).id size = parsed_args.size snapshot = None if parsed_args.snapshot: snapshot_obj = utils.find_resource(volume_client.volume_snapshots, parsed_args.snapshot) snapshot = snapshot_obj.id # Cinder requires a value for size when creating a volume # even if creating from a snapshot. Cinder will create the # volume with at least the same size as the snapshot anyway, # so since we have the object here, just override the size # value if it's either not given or is smaller than the # snapshot size. size = max(size or 0, snapshot_obj.size) project = None if parsed_args.project: project = utils.find_resource(identity_client.projects, parsed_args.project).id user = None if parsed_args.user: user = utils.find_resource(identity_client.users, parsed_args.user).id volume = volume_client.volumes.create( size=size, snapshot_id=snapshot, name=parsed_args.name, description=parsed_args.description, volume_type=parsed_args.type, user_id=user, project_id=project, availability_zone=parsed_args.availability_zone, metadata=parsed_args.property, imageRef=image, source_volid=source_volume, consistencygroup_id=consistency_group, multiattach=parsed_args.multi_attach, scheduler_hints=parsed_args.hint, ) if parsed_args.bootable or parsed_args.non_bootable: try: volume_client.volumes.set_bootable(volume.id, parsed_args.bootable) except Exception as e: LOG.error(_("Failed to set volume bootable property: %s"), e) if parsed_args.read_only or parsed_args.read_write: try: volume_client.volumes.update_readonly_flag( volume.id, parsed_args.read_only) except Exception as e: LOG.error( _("Failed to set volume read-only access " "mode flag: %s"), e) # Remove key links from being displayed volume._info.update({ 'properties': utils.format_dict(volume._info.pop('metadata')), 'type': volume._info.pop('volume_type') }) volume._info.pop("links", None) return zip(*sorted(six.iteritems(volume._info)))