def test_cache_no_cloud_name(self, glance_mock): class FakeImage(object): status = 'active' name = 'None Test Image' def __init__(self, id): self.id = id fi = FakeImage(id=1) glance_mock.images.list.return_value = [fi] self.cloud.name = None self.assertEqual( meta.obj_list_to_dict([fi]), self.cloud.list_images()) # Now test that the list was cached fi2 = FakeImage(id=2) glance_mock.images.list.return_value = [fi, fi2] self.assertEqual( meta.obj_list_to_dict([fi]), self.cloud.list_images()) # Invalidation too self.cloud.list_images.invalidate(self.cloud) self.assertEqual( meta.obj_list_to_dict([fi, fi2]), self.cloud.list_images())
def test_list_projects_v2(self, keystone_mock): project = fakes.FakeProject('project_a') keystone_mock.tenants.list.return_value = [project] self.cloud.cloud_config.config['identity_api_version'] = '2' self.assertEqual( meta.obj_list_to_dict([project]), self.cloud.list_projects()) project_b = fakes.FakeProject('project_b') keystone_mock.tenants.list.return_value = [project, project_b] self.assertEqual( meta.obj_list_to_dict([project]), self.cloud.list_projects()) self.cloud.list_projects.invalidate(self.cloud) self.assertEqual( meta.obj_list_to_dict([project, project_b]), self.cloud.list_projects())
def wait(self, raw): self._finished.wait() if self._exception: six.reraise(type(self._exception), self._exception, self._traceback) if raw: # Do NOT convert the result. return self._result # NOTE(Shrews): Since the client API might decide to subclass one # of these result types, we use isinstance() here instead of type(). if (isinstance(self._result, list) or isinstance(self._result, types.GeneratorType)): return meta.obj_list_to_dict( self._result, request_id=self._request_id) elif (not isinstance(self._result, bool) and not isinstance(self._result, int) and not isinstance(self._result, float) and not isinstance(self._result, str) and not isinstance(self._result, set) and not isinstance(self._result, tuple) and not isinstance(self._result, types.GeneratorType)): return meta.obj_to_dict(self._result, request_id=self._request_id) else: return self._result
def normalize_roles(roles): """Normalize Identity roles.""" ret = [ dict( id=role.get('id'), name=role.get('name'), ) for role in roles ] return meta.obj_list_to_dict(ret)
def test_search_stacks(self, mock_heat): fake_stacks = [ fakes.FakeStack('001', 'stack1'), fakes.FakeStack('002', 'stack2'), ] mock_heat.stacks.list.return_value = fake_stacks stacks = self.cloud.search_stacks() mock_heat.stacks.list.assert_called_once_with() self.assertEqual(meta.obj_list_to_dict(fake_stacks), stacks)
def normalize_domains(domains): ret = [ dict( id=domain.get('id'), name=domain.get('name'), description=domain.get('description'), enabled=domain.get('enabled'), ) for domain in domains ] return meta.obj_list_to_dict(ret)
def test_search_stacks_filters(self, mock_heat): fake_stacks = [ fakes.FakeStack('001', 'stack1', status='GOOD'), fakes.FakeStack('002', 'stack2', status='BAD'), ] mock_heat.stacks.list.return_value = fake_stacks filters = {'stack_status': 'GOOD'} stacks = self.cloud.search_stacks(filters=filters) mock_heat.stacks.list.assert_called_once_with() self.assertEqual(meta.obj_list_to_dict(fake_stacks[:1]), stacks)
def test_list_nics(self, mock_client): port1 = fakes.FakeMachinePort(1, "aa:bb:cc:dd", "node1") port2 = fakes.FakeMachinePort(2, "dd:cc:bb:aa", "node2") port_list = [port1, port2] port_dict_list = meta.obj_list_to_dict(port_list) mock_client.port.list.return_value = port_list nics = self.cloud.list_nics() self.assertTrue(mock_client.port.list.called) self.assertEqual(port_dict_list, nics)
def normalize_groups(domains): """Normalize Identity groups.""" ret = [ dict( id=domain.get('id'), name=domain.get('name'), description=domain.get('description'), domain_id=domain.get('domain_id'), ) for domain in domains ] return meta.obj_list_to_dict(ret)
def wait(self): self._finished.wait() # TODO(mordred): We store the raw requests response if there is # one now. So we should probably do an error handler to throw # some exceptions if it's not 200 if self._exception: six.reraise(type(self._exception), self._exception, self._traceback) if type(self._result) == list: return meta.obj_list_to_dict(self._result) else: return meta.obj_to_dict(self._result)
def test_obj_list_to_dict(self): """Test conversion of a list of objects to a list of dictonaries""" class obj0(object): value = 0 class obj1(object): value = 1 list = [obj0, obj1] new_list = meta.obj_list_to_dict(list) self.assertEqual(new_list[0]['value'], 0) self.assertEqual(new_list[1]['value'], 1)
def wait(self, raw=False): super(Task, self).wait() if raw: # Do NOT convert the result. return self._result if _is_listlike(self._result): return meta.obj_list_to_dict(self._result) elif _is_objlike(self._result): return meta.obj_to_dict(self._result) else: return self._result
def normalize_users(users): ret = [ dict(id=user.get('id'), email=user.get('email'), name=user.get('name'), username=user.get('username'), default_project_id=user.get('default_project_id', user.get('tenantId')), domain_id=user.get('domain_id'), enabled=user.get('enabled'), description=user.get('description')) for user in users ] return meta.obj_list_to_dict(ret)
def normalize_users(users): ret = [ dict( id=user.get('id'), email=user.get('email'), name=user.get('name'), username=user.get('username'), default_project_id=user.get('default_project_id', user.get('tenantId')), domain_id=user.get('domain_id'), enabled=user.get('enabled'), ) for user in users ] return meta.obj_list_to_dict(ret)
def wait(self): self._finished.wait() # TODO(mordred): We store the raw requests response if there is # one now. So we should probably do an error handler to throw # some exceptions if it's not 200 if self._exception: six.reraise(type(self._exception), self._exception, self._traceback) if type(self._result) == list: return meta.obj_list_to_dict(self._result) elif type(self._result) not in (bool, int, float, str, set, tuple, types.GeneratorType): return meta.obj_to_dict(self._result) else: return self._result
def test_search_volume_backups(self): name = 'Volume1' vol1 = {'name': name, 'availability_zone': 'az1'} vol2 = {'name': name, 'availability_zone': 'az1'} vol3 = {'name': 'Volume2', 'availability_zone': 'az2'} self.register_uris([ dict(method='GET', uri=self.get_mock_url('volumev2', 'public', append=['backups', 'detail']), json={"backups": [vol1, vol2, vol3]}) ]) result = self.cloud.search_volume_backups(name, {'availability_zone': 'az1'}) self.assertEqual(len(result), 2) self.assertEqual(meta.obj_list_to_dict([vol1, vol2]), result) self.assert_calls()
def normalize_neutron_floating_ips(ips): """Normalize the structure of Neutron floating IPs Unfortunately, not all the Neutron floating_ip attributes are available with Nova and not all Nova floating_ip attributes are available with Neutron. This function extract attributes that are common to Nova and Neutron floating IP resource. If the whole structure is needed inside shade, shade provides private methods that returns "original" objects (e.g. _neutron_allocate_floating_ip) :param list ips: A list of Neutron floating IPs. :returns: A list of normalized dicts with the following attributes:: [ { "id": "this-is-a-floating-ip-id", "fixed_ip_address": "192.0.2.10", "floating_ip_address": "198.51.100.10", "network": "this-is-a-net-or-pool-id", "attached": True, "status": "ACTIVE" }, ... ] """ ret = [] for ip in ips: network_id = ip.get('floating_network_id', ip.get('network')) ret.append( dict( id=ip['id'], fixed_ip_address=ip.get('fixed_ip_address'), floating_ip_address=ip['floating_ip_address'], network=network_id, floating_network_id=network_id, port_id=ip.get('port_id'), router_id=ip.get('router_id'), attached=(ip.get('port_id') is not None and ip.get('port_id') != ''), status=ip['status'], )) return meta.obj_list_to_dict(ret)
def normalize_nova_secgroups(groups): """Normalize the structure of nova security groups This makes security group dicts, as returned from nova, look like the security group dicts as returned from neutron. This does not make them look exactly the same, but it's pretty close. :param list groups: A list of security group dicts. :returns: A list of normalized dicts. """ ret = [{'id': g['id'], 'name': g['name'], 'description': g['description'], 'security_group_rules': normalize_nova_secgroup_rules(g['rules']) } for g in groups] return meta.obj_list_to_dict(ret)
def normalize_neutron_floating_ips(ips): """Normalize the structure of Neutron floating IPs Unfortunately, not all the Neutron floating_ip attributes are available with Nova and not all Nova floating_ip attributes are available with Neutron. This function extract attributes that are common to Nova and Neutron floating IP resource. If the whole structure is needed inside shade, shade provides private methods that returns "original" objects (e.g. _neutron_allocate_floating_ip) :param list ips: A list of Neutron floating IPs. :returns: A list of normalized dicts with the following attributes:: [ { "id": "this-is-a-floating-ip-id", "fixed_ip_address": "192.0.2.10", "floating_ip_address": "198.51.100.10", "network": "this-is-a-net-or-pool-id", "attached": True, "status": "ACTIVE" }, ... ] """ ret = [] for ip in ips: network_id = ip.get('floating_network_id', ip.get('network')) ret.append(dict( id=ip['id'], fixed_ip_address=ip.get('fixed_ip_address'), floating_ip_address=ip['floating_ip_address'], network=network_id, floating_network_id=network_id, port_id=ip.get('port_id'), router_id=ip.get('router_id'), attached=(ip.get('port_id') is not None and ip.get('port_id') != ''), status=ip['status'], )) return meta.obj_list_to_dict(ret)
def setUp(self): super(TestFloatingIP, self).setUp() self.floating_ips = [ fakes.FakeFloatingIP(**ip) for ip in self.mock_floating_ip_list_rep ] self.fake_server = meta.obj_to_dict( fakes.FakeServer( 'server-id', '', 'ACTIVE', addresses={u'test_pnztt_net': [{ u'OS-EXT-IPS:type': u'fixed', u'addr': '192.0.2.129', u'version': 4, u'OS-EXT-IPS-MAC:mac_addr': u'fa:16:3e:ae:7d:42'}]})) self.floating_ip = _utils.normalize_nova_floating_ips( meta.obj_list_to_dict(self.floating_ips))[0]
def test_list_volume_backups(self): backup = { 'id': '6ff16bdf-44d5-4bf9-b0f3-687549c76414', 'status': 'available' } search_opts = {'status': 'available'} self.register_uris([ dict(method='GET', uri=self.get_mock_url( 'volumev2', 'public', append=['backups', 'detail'], qs_elements=['='.join(i) for i in search_opts.items()]), json={"backups": [backup]}) ]) result = self.cloud.list_volume_backups(True, search_opts) self.assertEqual(len(result), 1) self.assertEqual(meta.obj_list_to_dict([backup]), result) self.assert_calls()
def normalize_nova_secgroup_rules(rules): """Normalize the structure of nova security group rules Note that nova uses -1 for non-specific port values, but neutron represents these with None. :param list rules: A list of security group rule dicts. :returns: A list of normalized dicts. """ ret = [{ 'id': r['id'], 'direction': 'ingress', 'ethertype': 'IPv4', 'port_range_min': None if r['from_port'] == -1 else r['from_port'], 'port_range_max': None if r['to_port'] == -1 else r['to_port'], 'protocol': r['ip_protocol'], 'remote_ip_prefix': r['ip_range'].get('cidr', None), 'security_group_id': r['parent_group_id'] } for r in rules] return meta.obj_list_to_dict(ret)
def setUp(self): super(TestFloatingIP, self).setUp() config = os_client_config.OpenStackConfig() self.client = OpenStackCloud( cloud_config=config.get_one_cloud(validate=False)) self.floating_ips = [ fakes.FakeFloatingIP(**ip) for ip in self.mock_floating_ip_list_rep ] self.fake_server = meta.obj_to_dict( fakes.FakeServer( 'server-id', '', 'ACTIVE', addresses={u'test_pnztt_net': [{ u'OS-EXT-IPS:type': u'fixed', u'addr': '192.0.2.129', u'version': 4, u'OS-EXT-IPS-MAC:mac_addr': u'fa:16:3e:ae:7d:42'}]})) self.floating_ip = _utils.normalize_nova_floating_ips( meta.obj_list_to_dict(self.floating_ips))[0]
def normalize_keystone_services(services): """Normalize the structure of keystone services In keystone v2, there is a field called "service_type". In v3, it's "type". Just make the returned dict have both. :param list services: A list of keystone service dicts :returns: A list of normalized dicts. """ ret = [] for service in services: service_type = service.get('type', service.get('service_type')) new_service = { 'id': service['id'], 'name': service['name'], 'description': service.get('description', None), 'type': service_type, 'service_type': service_type, } ret.append(new_service) return meta.obj_list_to_dict(ret)
def normalize_nova_secgroup_rules(rules): """Normalize the structure of nova security group rules Note that nova uses -1 for non-specific port values, but neutron represents these with None. :param list rules: A list of security group rule dicts. :returns: A list of normalized dicts. """ ret = [{'id': r['id'], 'direction': 'ingress', 'ethertype': 'IPv4', 'port_range_min': None if r['from_port'] == -1 else r['from_port'], 'port_range_max': None if r['to_port'] == -1 else r['to_port'], 'protocol': r['ip_protocol'], 'remote_ip_prefix': r['ip_range'].get('cidr', None), 'security_group_id': r['parent_group_id'] } for r in rules] return meta.obj_list_to_dict(ret)
def normalize_volumes(volumes): ret = [] for vol in volumes: new_vol = vol.copy() name = vol.get('name', vol.get('display_name')) description = vol.get('description', vol.get('display_description')) new_vol['name'] = name new_vol['display_name'] = name new_vol['description'] = description new_vol['display_description'] = description # For some reason, cinder v1 uses strings for bools for these fields. # Cinder v2 uses booleans. for field in ('bootable', 'multiattach'): if field in new_vol and isinstance(new_vol[field], six.string_types): if new_vol[field] is not None: if new_vol[field].lower() == 'true': new_vol[field] = True elif new_vol[field].lower() == 'false': new_vol[field] = False ret.append(new_vol) return meta.obj_list_to_dict(ret)
def wait(self): self._finished.wait() # TODO(mordred): We store the raw requests response if there is # one now. So we should probably do an error handler to throw # some exceptions if it's not 200 if self._exception: six.reraise(type(self._exception), self._exception, self._traceback) # NOTE(Shrews): Since the client API might decide to subclass one # of these result types, we use isinstance() here instead of type(). if isinstance(self._result, list): return meta.obj_list_to_dict(self._result) elif (not isinstance(self._result, bool) and not isinstance(self._result, int) and not isinstance(self._result, float) and not isinstance(self._result, str) and not isinstance(self._result, set) and not isinstance(self._result, tuple) and not isinstance(self._result, types.GeneratorType)): return meta.obj_to_dict(self._result) else: return self._result