def extract_keypairs(self, keypair_ids, parent_name=None, parent_resources=None): keypair_objs = [] keypairResources = [] if not keypair_ids: LOG.debug('Extract resources of all keypairs.') keypair_objs = self.nova_api.keypair_list(self.context) else: LOG.debug('Extract resources of keypairs: %s', keypair_ids) # remove duplicate keypairs keypair_ids = {}.fromkeys(keypair_ids).keys() for keypair_id in keypair_ids: try: keypair = self.nova_api.get_keypair(self.context, keypair_id) keypair_objs.append(keypair) except Exception as e: msg = "Keypair resource <%s> could not be found. %s" \ % (keypair_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for keypair in keypair_objs: resource_id = keypair.get('id', '') keypair_res = self._collected_resources.get(resource_id) if keypair_res: keypairResources.append(keypair_res) continue name = keypair.get('name', '') properties = {'name': name, 'public_key': keypair.get('public_key', '') } resource_type = "OS::Nova::KeyPair" resource_name = "keypair_%d" \ % self._get_resource_num(resource_type) if parent_name and resource_id in parent_resources: resource_name = parent_name + '.' + resource_name keypair_res = resource.Resource(resource_name, resource_type, resource_id, properties=properties) keypair_dep = resource.ResourceDependency(resource_id, resource_name, name, resource_type) self._collected_resources[resource_id] = keypair_res self._collected_dependencies[resource_id] = keypair_dep keypairResources.append(keypair_res) if keypair_ids and not keypairResources: msg = "KeyPair resource extracted failed, \ can't find the keypair with id of %s." % keypair_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return keypairResources
def _get_interface_info(self, subnet_id, subnet_res, other_net_ids, parent_name=None, parent_resources=None): try: interfaces = \ self.neutron_api.port_list( self.context, device_owner="network:router_interface") except Exception as e: msg = "Interface resource extracted failed, \ can't find router port list. %s" % unicode(e) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for interface in interfaces: fixed_ips = interface.get("fixed_ips", []) for fip in fixed_ips: if fip.get("subnet_id", "") == subnet_id: router_id = interface.get('device_id') router_res = self.\ _generate_router_resource(router_id, other_net_ids, parent_name, parent_resources) if not router_id: return None self._generate_interface_resource(interface, subnet_res, router_res, parent_name, parent_resources)
def extract_stacks(self, stack_ids): stack_lists = [] stackResources = [] stack_resources_dicts = {} if not stack_ids: LOG.info('Extract resources of all stacks.') stack_lists = self.heat_api.stack_list(self.context) else: LOG.info('Extract resources of stacks: %s', stack_ids) # remove duplicate volume stack_ids = {}.fromkeys(stack_ids).keys() for stack_id in stack_ids: try: stack = self.heat_api.get_stack(self.context, stack_id) stack_lists.append(stack) except Exception as e: msg = "stack resource <%s> could not be found. %s" \ % (stack_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for stack in stack_lists: stack_id = stack['id'] stack_res = self._collected_resources.get(stack_id) if stack_res: stackResources.append(stack_res) continue # extract stack and return resource stack_resources_dicts[stack_id] = self._extract_stack_resources( self.context, stack) for _resources in stack_resources_dicts.values(): for _res in _resources: self._collected_resources.pop(_res.id)
def extract_instances(self, instance_ids=None, parent_name=None, parent_resources=None): instance_reses = [] servers = [] if not instance_ids: LOG.info('No instances to extract.') return instance_reses else: LOG.info('Get resources of instance: %s', instance_ids) for instance_id in instance_ids: try: server = self.nova_api.get_server(self.context, instance_id) servers.append(server) except Exception as e: msg = "Instance resource <%s> could not be found. %s" \ % (instance_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for server in servers: res = self._extract_single_instance(server, parent_name, parent_resources) instance_reses.append(res) return instance_reses
def _build_vm_bdm(self, server, instance_resources, instance_dependencies, parent_name=None, parent_resources=None): server_id = server.get('id', '') LOG.debug(_LE('Extract bdm resources of instance: %s.'), server_id) volumes = server.get('os-extended-volumes:volumes_attached', []) volume_ids = [] for v in volumes: if v.get('id'): volume_ids.append(v.get('id')) if len(volume_ids) == 0: return bdm_property = [] collected_dependencies = self._collected_dependencies vr = VolumeResource(self.context, collected_resources=self._collected_resources, collected_parameters=self._collected_parameters, collected_dependencies=collected_dependencies) volume_res = vr.extract_volumes(volume_ids, parent_name, parent_resources) index = 0 for v in volume_res: sys_boot_index = v.extra_properties.get('boot_index', None) if sys_boot_index == 0 or sys_boot_index == '0': boot_index = sys_boot_index else: boot_index = index + 1 index += 1 properties = {'volume_id': {'get_resource': v.name}, 'boot_index': boot_index} dep_res_name = v.properties.get('name', '') instance_dependencies.add_dependency(v.id, v.name, dep_res_name, v.type) try: volume_dict = self.cinder_api.get(self.context, v.id) except Exception as e: msg = "Instance volume <%s> could not be found. %s" \ % (v.id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) if volume_dict.get('mountpoint'): properties['device_name'] = volume_dict['mountpoint'] bdm_property.append(properties) instance_resources.add_property('block_device_mapping_v2', bdm_property)
def get_server(self, context, server_id): server = None try: server = self.call('get_server') except Exception as e: LOG.error(_LE('Query server %(id)s info error: %(err)s'), { 'id': server_id, 'err': e }) raise exception.ResourceNotFound(resource_type='Nova', resource_id=server_id) return server
def get_security_group(self, context, security_group_id, **_params): security_group = None try: security_group = self.call('get_security_group') except exc.HTTPNotFound: LOG.error(_LE('Can not find secgroup %s info'), security_group_id) raise neutronclient_exceptions.NotFound except Exception as e: LOG.error(_LE('Query security group %(id)s info error: %(err)s'), { 'id': security_group_id, 'err': e }) raise exception.ResourceNotFound(resource_type='Network', resource_id=security_group_id) return security_group
def _build_vm_secgroups(self, server, instance_resources, instance_dependencies, parent_name=None, parent_resources=None): server_id = server.get('id') LOG.debug('Extract security group of instance: %s.', server_id) try: secgroup_objs = \ self.nova_api.server_security_group_list(self.context, server) except Exception as e: msg = "Security groups of instance <%s> could not be found. %s" \ % (server_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) secgroup_id_list = [] for sec in secgroup_objs: secgroup_id_list.append(sec.get('id')) collected_dependencies = self._collected_dependencies nr = SecGroup(self.context, collected_resources=self._collected_resources, collected_parameters=self._collected_parameters, collected_dependencies=collected_dependencies) try: secgroups__res = nr.extract_secgroups(secgroup_id_list, parent_name, parent_resources) sec_property = [] for sec in secgroups__res: sec_property.append({'get_resource': sec.get('name')}) res_type = 'OS::Neutron::SecurityGroup' instance_dependencies.add_dependency(sec.get('id'), sec.get('name'), '', res_type) if sec_property: instance_resources.add_property('security_groups', sec_property) except Exception as e: msg = "Instance security group extracted failed. %s" % unicode(e) LOG.error(msg)
def extract_routers(self, router_ids, parent_name=None, parent_resources=None): router_objs = [] routerResources = [] if not router_ids: LOG.info('Extract resources of routers.') router_objs = filter(self._tenant_filter, self.neutron_api.router_list(self.context)) else: LOG.debug('Extract resources of routers: %s', router_ids) # remove duplicate routers router_ids = {}.fromkeys(router_ids).keys() for router_id in router_ids: try: router = self.neutron_api.get_router( self.context, router_id) router_objs.append(router) except Exception as e: msg = "Router resource <%s> could not be found. %s" \ % (router_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) # every router_obj is a dict for router in router_objs: router_id = router.get('id') router_res = self._collected_resources.get(router_id) if router_res: routerResources.append(router_res) continue properties = { 'name': router.get('name'), 'admin_state_up': router.get('admin_state_up') } dependencies = [] external_gateway_info = router.get('external_gateway_info') if external_gateway_info: network = external_gateway_info.get('network_id') if network: net_res = self.extract_nets( [network], with_subnets=True, parent_name=parent_name, parent_resources=parent_resources) if net_res: enable_snat = external_gateway_info.get('enable_snat') properties['external_gateway_info'] = \ {'network': {'get_resource': net_res[0].name}, 'enable_snat': enable_snat} dep_res_name = net_res[0].properties.get('name', '') dependencies.append({ 'id': net_res[0].id, 'name': net_res[0].name, 'name_in_template': dep_res_name, 'type': net_res[0].type }) resource_type = "OS::Neutron::Router" resource_name = 'router_%d' % self.\ _get_resource_num(resource_type) if parent_name and router_id in parent_resources: resource_name = parent_name + '.' + resource_name router_res = resource.Resource(resource_name, resource_type, router_id, properties=properties) # remove duplicate dependencies # dependencies = {}.fromkeys(dependencies).keys() router_dep = resource.ResourceDependency(router_id, resource_name, router.get('name'), resource_type, dependencies=dependencies) self._collected_resources[router_id] = router_res self._collected_dependencies[router_id] = router_dep routerResources.append(router_res) if router_ids and not routerResources: msg = "Router resource extracted failed, \ can't find the router with id of %s." % router_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return routerResources
def extract_floatingips(self, floatingip_ids, parent_name=None, parent_resources=None): floatingip_objs = [] floatingipResources = [] if not floatingip_ids: LOG.debug('Extract resources of floating ips.') floatingip_list = self.neutron_api.floatingip_list(self.context) floatingip_objs = filter(self._tenant_filter, floatingip_list) else: LOG.debug('Extract resources of floating ips: %s', floatingip_ids) # remove duplicate floatingips floatingip_ids = {}.fromkeys(floatingip_ids).keys() for floatingip_id in floatingip_ids: try: floatingip = self.neutron_api.get_floatingip( self.context, floatingip_id) floatingip_objs.append(floatingip) except Exception as e: msg = "FloatingIp resource <%s> could not be found. %s" \ % (floatingip_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for floatingip in floatingip_objs: floatingip_id = floatingip.get('id') floatingip_res = self._collected_resources.get(floatingip_id) if floatingip_res: floatingipResources.append(floatingip_res) continue properties = {} dependencies = [] floating_network_id = floatingip.get('floating_network_id') floating_ip_address = floatingip.get('floating_ip_address') if not floating_network_id or not floating_ip_address: msg = "FloatingIp information is abnormal. \ 'floating_network_id' or 'floating_ip_address' " \ "is None" LOG.error(msg) raise exception.ResourceAttributesException(message=msg) net_res = self.extract_nets([floating_network_id], with_subnets=True, parent_name=parent_name, parent_resources=parent_resources) properties['floating_network_id'] = \ {'get_resource': net_res[0].name} dep_res_name = net_res[0].properties.get('name', '') dependencies.append({ 'id': net_res[0].id, 'name': net_res[0].name, 'name_in_template': dep_res_name, 'type': net_res[0].type }) router_id = floatingip.get('router_id') router_res = None if router_id: router_res = self.extract_routers([router_id], parent_name, parent_resources) port_id = floatingip.get('port_id') resource_type = "OS::Neutron::FloatingIP" resource_name = 'floatingip_%d' % \ self._get_resource_num(resource_type) if parent_name and port_id in parent_resources: resource_name = parent_name + '.' + resource_name if port_id: kwargs = {} kwargs['id'] = port_id kwargs['type'] = resource_type kwargs['name_in_template'] = '' self._extract_associate(floatingip, router_res, port_id, resource_name, parent_name, parent_resources, **kwargs) floatingip_res = resource.Resource(resource_name, resource_type, floatingip_id, properties=properties) # remove duplicate dependencies # dependencies = {}.fromkeys(dependencies).keys() floatingip_dep = resource.ResourceDependency( floatingip_id, resource_name, '', resource_type, dependencies=dependencies) self._collected_resources[floatingip_id] = floatingip_res self._collected_dependencies[floatingip_id] = floatingip_dep floatingipResources.append(floatingip_res) if floatingip_ids and not floatingipResources: msg = "FloatingIp resource extracted failed, \ can't find the floatingip with id of %s." % floatingip_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return floatingipResources
def extract_nets(self, net_ids, with_subnets=False, parent_name=None, parent_resources=None): net_objs = [] netResources = [] if not net_ids: LOG.info('Extract resources of all networks.') network_list = self.neutron_api.network_list(self.context) net_objs = filter(self._tenant_filter, network_list) else: LOG.info('Extract resources of networks: %s', net_ids) # remove duplicate nets net_ids = {}.fromkeys(net_ids).keys() for net_id in net_ids: try: net = self.neutron_api.get_network(self.context, net_id) net_objs.append(net) except Exception as e: msg = "Network resource <%s> could not be found. %s" \ % (net_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) # every net_obj is a dict for net in net_objs: net_id = net.get('id') net_res = self._collected_resources.get(net_id) if net_res: netResources.append(net_res) continue properties = { 'name': net.get('name'), 'admin_state_up': net.get('admin_state_up'), 'shared': net.get('shared') } value_specs = {} if net.get('provider:physical_network') is not None: value_specs['provider:physical_network'] = \ net.get('provider:physical_network') if net.get('provider:network_type') is not None: value_specs['provider:network_type'] = \ net.get('provider:network_type') if net.get('provider:segmentation_id') is not None: value_specs['provider:segmentation_id'] = \ net.get('provider:segmentation_id') if net.get('router:external') is not None: value_specs['router:external'] = net.get('router:external') if value_specs: properties['value_specs'] = value_specs resource_type = "OS::Neutron::Net" resource_name = 'network_%d' % \ self._get_resource_num(resource_type) if parent_name and net_id in parent_resources: resource_name = parent_name + '.' + resource_name if with_subnets: kwargs = {} kwargs['id'] = net_id kwargs['type'] = resource_type kwargs['name_in_template'] = net.get('name') self.extract_subnets_of_network(resource_name, net.get('subnets'), parent_name, parent_resources, **kwargs) net_res = resource.Resource(resource_name, resource_type, net_id, properties=properties) net_dep = resource.ResourceDependency(net_id, resource_name, net.get('name'), resource_type) self._collected_resources[net_id] = net_res self._collected_dependencies[net_id] = net_dep netResources.append(net_res) if net_ids and not netResources: msg = "Network resource extracted failed, \ can't find the network with id of %s." % net_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return netResources
def extract_ports(self, port_ids, parent_name=None, parent_resources=None): port_objs = [] portResources = [] if not port_ids: LOG.debug('Extract resources of all ports.') port_objs = filter(self._tenant_filter, self.neutron_api.port_list(self.context)) else: LOG.debug('Extract resources of ports: %s', port_ids) # remove duplicate ports port_ids = {}.fromkeys(port_ids).keys() for port_id in port_ids: try: port = self.neutron_api.get_port(self.context, port_id) port_objs.append(port) except Exception as e: msg = "Port resource <%s> could not be found. %s" \ % (port_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) # every port_obj is a dict for port in port_objs: port_id = port.get('id') port_res = self._collected_resources.get(port_id) if port_res: portResources.append(port_res) continue properties = { 'name': port.get('name', ''), 'mac_address': port.get('mac_address', ''), 'admin_state_up': port.get('admin_state_up', True), } dependencies = [] if port.get('allowed_address_pairs'): properties['allowed_address_pairs'] = \ port.get('allowed_address_pairs') value_specs = {} if port.get('binding:profile') is not None: value_specs['binding:profile'] = port.get('binding:profile') # fsp 6.1 add(wanggang) if port.get('binding:vnic_type', None): properties['binding:vnic_type'] = \ port.get('binding:vnic_type') if port.get('qos_policy_id', None): properties['qos_policy'] = \ port.get('qos_policy_id') # properties['device_owner'] = port.get('device_owner', '') # properties['device_id'] = port.get('device_id', '') if value_specs: properties['value_specs'] = value_specs if port.get('security_groups'): secgroup_ids = port.get('security_groups') secgroup_res = self.extract_secgroups(secgroup_ids, parent_name, parent_resources) secgroup_properties = [] for sec in secgroup_res: secgroup_properties.append({'get_resource': sec.name}) dep_res_name = sec.properties.get('name', '') dependencies.append({ 'id': sec.id, 'name': sec.name, 'name_in_template': dep_res_name, 'type': sec.type }) properties['security_groups'] = secgroup_properties fixed_ips_properties = [] fixed_ips = port.get('fixed_ips', []) for opt in fixed_ips: subnet_id = opt.get('subnet_id') ip_address = opt.get('ip_address') if not subnet_id or not ip_address: msg = "Port information is abnormal. \ 'subnet_id' or 'ip_address' attribute is None" LOG.error(msg) raise exception.ResourceAttributesException(message=msg) subnet_res = self.extract_subnets([subnet_id], parent_name, parent_resources) if not subnet_res: LOG.error("Subnet %s could not be found.", subnet_id) raise exception.ResourceNotFound(resource_type='Subnet', resource_id=subnet_id) sub_name = subnet_res[0].name fixed_ips_properties.append({ 'subnet_id': { 'get_resource': sub_name }, 'ip_address': ip_address }) sub_properties = subnet_res[0].properties network_name = \ sub_properties.get('network_id').get('get_resource') properties['network_id'] = {"get_resource": network_name} net_res = None for r_k, r_s in self._collected_resources.items(): if r_s.name == network_name: net_res = r_s break if net_res: dep_net_name = net_res.properties.get('name', '') dependencies.append({ 'id': net_res.id, 'name': net_res.name, 'name_in_template': dep_net_name, 'type': net_res.type }) dep_sub_name = sub_properties.get('name', '') dependencies.append({ 'id': subnet_res[0].id, 'name': subnet_res[0].name, 'name_in_template': dep_sub_name, 'type': subnet_res[0].type }) properties['fixed_ips'] = fixed_ips_properties resource_type = "OS::Neutron::Port" resource_name = 'port_%d' % self._get_resource_num(resource_type) if parent_name and port_id in parent_resources: resource_name = parent_name + '.' + resource_name port_res = resource.Resource(resource_name, resource_type, port_id, properties=properties) # remove duplicate dependencies # dependencies = {}.fromkeys(dependencies).keys() port_dep = resource.ResourceDependency(port_id, resource_name, port.get('name'), resource_type, dependencies=dependencies) self._collected_resources[port_id] = port_res self._collected_dependencies[port_id] = port_dep portResources.append(port_res) if port_ids and not portResources: msg = "Port resource extracted failed, \ can't find the port with id of %s." % port_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return portResources
def extract_subnets_of_network(self, network_resource_name, subnet_ids, parent_name=None, parent_resources=None, **kwargs): LOG.debug('Extract resources of subnets %s ', subnet_ids) if not network_resource_name or not subnet_ids: return # remove duplicate subnets subnet_ids = {}.fromkeys(subnet_ids).keys() for subnet_id in subnet_ids: try: subnet = self.neutron_api.get_subnet(self.context, subnet_id) except Exception as e: msg = "Subnet resource <%s> could not be found. %s" \ % (subnet_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) subnet_id = subnet.get('id') subnet_res = self._collected_resources.get(subnet_id) if subnet_res: continue properties = { 'name': subnet.get('name', ''), 'allocation_pools': subnet.get('allocation_pools', []), 'cidr': subnet.get('cidr', ''), 'gateway_ip': subnet.get('gateway_ip', ''), 'enable_dhcp': subnet.get('enable_dhcp', False), 'ip_version': subnet.get('ip_version'), 'network_id': { 'get_resource': network_resource_name } } if subnet.get('dns_nameservers'): properties['dns_nameservers'] = subnet.get('dns_nameservers') if subnet.get('host_routes'): properties['host_routes'] = subnet.get('host_routes') resource_type = "OS::Neutron::Subnet" resource_name = 'subnet_%d' % self.\ _get_resource_num(resource_type) if parent_name and subnet_id in parent_resources: resource_name = parent_name + '.' + resource_name subnet_res = resource.Resource(resource_name, resource_type, subnet_id, properties=properties) net_name = network_resource_name subnet_dep = resource.ResourceDependency(subnet_id, resource_name, subnet.get('name'), resource_type) subnet_dep.add_dependency(kwargs.get('id', ''), net_name, kwargs.get('name_in_template', ''), kwargs.get('type', '')) self._collected_resources[subnet_id] = subnet_res self._collected_dependencies[subnet_id] = subnet_dep
def extract_subnets(self, subnet_ids, parent_name=None, parent_resources=None): subnet_objs = [] subnetResources = [] if not subnet_ids: LOG.debug('Extract resources of all subnets.') subnet_objs = filter(self._tenant_filter, self.neutron_api.subnet_list(self.context)) else: LOG.debug('Extract resources of subnets: %s', subnet_ids) # remove duplicate nets subnet_ids = {}.fromkeys(subnet_ids).keys() for subnet_id in subnet_ids: try: subnet = self.neutron_api.get_subnet( self.context, subnet_id) subnet_objs.append(subnet) except Exception as e: msg = "Subnet resource <%s> could not be found. %s" \ % (subnet_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for subnet in subnet_objs: subnet_id = subnet.get('id') subnet_res = self._collected_resources.get(subnet_id) if subnet_res: subnetResources.append(subnet_res) continue properties = { 'name': subnet.get('name', ''), 'allocation_pools': subnet.get('allocation_pools', []), 'cidr': subnet.get('cidr', ''), 'gateway_ip': subnet.get('gateway_ip', ''), 'enable_dhcp': subnet.get('enable_dhcp', False), 'ip_version': subnet.get('ip_version'), } if subnet.get('dns_nameservers'): properties['dns_nameservers'] = subnet.get('dns_nameservers') if subnet.get('host_routes'): properties['host_routes'] = subnet.get('host_routes') net_id = subnet.get('network_id') network_res = None if net_id: network_res = self.extract_nets([net_id], False, parent_name, parent_resources) if not network_res: LOG.error("Network resource %s could not be found.", net_id) raise exception.ResourceNotFound(resource_type='Network', resource_id=net_id) properties['network_id'] = {'get_resource': network_res[0].name} resource_type = "OS::Neutron::Subnet" resource_name = 'subnet_%d' % self._get_resource_num(resource_type) if parent_name and subnet_id in parent_resources: resource_name = parent_name + '.' + resource_name subnet_res = resource.Resource(resource_name, resource_type, subnet_id, properties=properties) nres_name = network_res[0].name subnet_dep = resource.ResourceDependency(subnet_id, resource_name, subnet.get('name'), resource_type) dep_res_name = network_res[0].properties.get('name', '') subnet_dep.add_dependency(network_res[0].id, nres_name, dep_res_name, network_res[0].type) self._collected_resources[subnet_id] = subnet_res self._collected_dependencies[subnet_id] = subnet_dep subnetResources.append(subnet_res) if subnet_ids and not subnetResources: msg = "Subnet resource extracted failed, \ can't find the subnet with id of %s." % subnet_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return subnetResources
def extract_flavors(self, flavor_ids, parent_name=None, parent_resources=None): flavor_objs = [] flavorResources = [] if not flavor_ids: LOG.debug('Extract resources of all flavors.') flavor_objs = self.nova_api.flavor_list(self.context) else: LOG.debug('Extract resources of flavors: %s', flavor_ids) # remove duplicate flavors flavor_ids = {}.fromkeys(flavor_ids).keys() for flavor_id in flavor_ids: try: flavor = self.nova_api.get_flavor(self.context, flavor_id) flavor_objs.append(flavor) except Exception as e: msg = "Flavor resource <%s> could not be found. %s" \ % (flavor_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for flavor in flavor_objs: resource_id = flavor.get('id', '') flavor_res = self._collected_resources.get(resource_id) if flavor_res: flavorResources.append(flavor_res) continue ram = flavor.get('ram', '') vcpus = flavor.get('vcpus', '') disk = flavor.get('disk', '') ephemeral = flavor.get('OS-FLV-EXT-DATA:ephemeral', '') rxtx_factor = flavor.get('rxtx_factor', '') is_public = flavor.get('os-flavor-access:is_public', '') properties = {'ram': ram, 'vcpus': vcpus, 'disk': disk, 'ephemeral': ephemeral, 'rxtx_factor': rxtx_factor, 'is_public': is_public } keys = flavor.get('keys', '') if keys: properties['extra_specs'] = keys swap = flavor.get('swap', '') if swap: properties['swap'] = swap resource_type = "OS::Nova::Flavor" resource_name = "flavor_%d" % self._get_resource_num(resource_type) if parent_name and resource_id in parent_resources: resource_name = parent_name + '.' + resource_name flavor_res = resource.Resource(resource_name, resource_type, resource_id, properties=properties) name = flavor.get('name', "") flavor_dep = resource.ResourceDependency(resource_id, resource_name, name, resource_type) self._collected_resources[resource_id] = flavor_res self._collected_dependencies[resource_id] = flavor_dep flavorResources.append(flavor_res) if flavor_ids and not flavorResources: msg = "Flavor resource extracted failed, \ can't find the flavor with id of %s." % flavor_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return flavorResources
def _extract_single_instance(self, server, parent_name=None, parent_resources=None): if not server: return instance_id = server.get('id', '') LOG.debug('Extract resources of instance %s.', instance_id) vm_state = server.get('OS-EXT-STS:vm_state', None) if vm_state not in resource_state.INSTANCE_CLONE_STATE: LOG.error("Instance %(id)s state is %(state)s not active or stop", {'id': instance_id, 'state': vm_state}) raise exception.PlanCreateFailed # If this server resource has been extracted, ignore it. instance_resources = self._collected_resources.get(instance_id) if instance_resources: return instance_resources resource_type = "OS::Nova::Server" resource_name = "server_%d" % self._get_resource_num(resource_type) if parent_name and instance_id in parent_resources: resource_name = parent_name + '.' + resource_name instance_resources = resource.Resource(resource_name, resource_type, instance_id, properties={}) name = server.get('name', None) instance_dependencies = resource.ResourceDependency(instance_id, resource_name, name, resource_type) instance_resources.add_property('name', name) availability_zone = server.get('OS-EXT-AZ:availability_zone', '') instance_resources.add_property('availability_zone', availability_zone) # extract metadata parameter. # If metadata is None, ignore this parameter. metadata = server.get('metadata', {}) if metadata: instance_resources.add_property('metadata', metadata) # extract userdata parameter. # If userdata is None, ignore this parameter. user_data = server.get('OS-EXT-SRV-ATTR:user_data', '') if user_data: instance_resources.add_property('user_data', user_data) instance_resources.add_property('user_data_format', 'RAW') # extract flavor resource, if failed, raise exception flavor = server.get('flavor', {}) if flavor and flavor.get('id'): flavor_id = flavor.get('id') try: flavor_res = self.extract_flavors([flavor_id], parent_name, parent_resources) instance_resources.add_property('flavor', {'get_resource': flavor_res[0].name}) dep_res_name = flavor_res[0].properties.get('name', '') instance_dependencies.add_dependency(flavor_res[0].id, flavor_res[0].name, dep_res_name, flavor_res[0].type) except Exception as e: msg = "Instance flavor extracted failed. %s" % unicode(e) LOG.error(msg) raise exception.ResourceNotFound(message=msg) # extract keypair resource, if failed, give up this resource keypair_name = server.get('key_name', '') if keypair_name: try: keypair_res = self.extract_keypairs([keypair_name], parent_name, parent_resources) instance_resources.add_property('key_name', {'get_resource': keypair_res[0].name}) dep_res_name = keypair_res[0].properties.get('name', '') instance_dependencies.add_dependency(keypair_res[0].id, keypair_res[0].name, dep_res_name, keypair_res[0].type) except Exception as e: msg = "Instance keypair extracted failed. %s" % unicode(e) LOG.error(msg) raise exception.ResourceNotFound(message=msg) # extract image parameter image = server.get('image', '') if image and image.get('id'): image_id = image.get('id') image_para_name = self.extract_image(image_id, parent_name, parent_resources) description = ("Image to use to boot server or volume") constraints = [{'custom_constraint': "glance.image"}] instance_resources.add_parameter(image_para_name, description, default=image_id, constraints=constraints) instance_resources.add_property('image', {'get_param': image_para_name}) # extract bdm resources volumes_attached = server.get('os-extended-volumes:volumes_attached', '') if volumes_attached: self._build_vm_bdm(server, instance_resources, instance_dependencies, parent_name, parent_resources) # extract network resources addresses = server.get('addresses', {}) if addresses: self._build_vm_networks(server, instance_resources, instance_dependencies, parent_name, parent_resources) else: msg = "Instance addresses information is abnormal. \ 'addresses' attribute is None" LOG.error(msg) raise exception.ResourceAttributesException(message=msg) # add extra properties instance_resources.add_extra_property('vm_state', vm_state) power_state = server.get('OS-EXT-STS:power_state', None) instance_resources.add_extra_property('power_state', power_state) LOG.info('Extracting instance %s has finished', instance_id) self._collected_resources[instance_id] = instance_resources self._collected_dependencies[instance_id] = instance_dependencies return instance_resources
def extract_floatingips(self, floatingip_ids, parent_name=None, parent_resources=None): # 1. get floating ips info floatingip_objs = [] floatingipResources = [] if not floatingip_ids: LOG.debug('Extract resources of floating ips.') floatingip_list = self.neutron_api.floatingip_list(self.context) floatingip_objs = filter(self._tenant_filter, floatingip_list) else: LOG.debug('Extract resources of floating ips: %s', floatingip_ids) # remove duplicate floatingips floatingip_ids = {}.fromkeys(floatingip_ids).keys() for floatingip_id in floatingip_ids: try: floatingip = self.neutron_api.get_floatingip( self.context, floatingip_id) floatingip_objs.append(floatingip) except Exception as e: msg = "FloatingIp resource <%s> could not be found. %s" \ % (floatingip_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for floatingip in floatingip_objs: floatingip_id = floatingip.get('id') floatingip_res = self._collected_resources.get(floatingip_id) if floatingip_res: floatingipResources.append(floatingip_res) continue properties = {} dependencies = [] floating_network_id = floatingip.get('floating_network_id') floating_ip_address = floatingip.get('floating_ip_address') if not floating_network_id or not floating_ip_address: msg = "FloatingIp information is abnormal. \ 'floating_network_id' or 'floating_ip_address' is None" LOG.error(msg) raise exception.ResourceAttributesException(message=msg) # 2.get network and subnetwork for floating ip col_res = self._collected_resources cold_eps = self._collected_dependencies network_cls = \ networks.NetworkResource(self.context, collected_resources=col_res, collected_dependencies=cold_eps) net_res = \ network_cls.extract_nets([floating_network_id], with_subnets=True, parent_name=parent_name, parent_resources=parent_resources) # refresh collected resource in order # to add network and subnet resource self._collected_resources = \ network_cls.get_collected_resources() self._collected_dependencies = \ network_cls.get_collected_dependencies() properties['floating_network_id'] = \ {'get_resource': net_res[0].name} resource_type = "OS::Neutron::FloatingIP" resource_name = 'floatingip_%d' % \ self._get_resource_num(resource_type) if parent_name and floatingip_id in parent_resources: resource_name = parent_name + '.' + resource_name floatingip_res = resource.Resource(resource_name, resource_type, floatingip_id, properties=properties) # remove duplicate dependencies dependencies = {}.fromkeys(dependencies).keys() floatingip_dep = \ resource.ResourceDependency(floatingip_id, resource_name, '', resource_type) dep_res_name = net_res[0].properties.get('name', '') floatingip_dep.add_dependency(net_res[0].id, dep_res_name, net_res[0].name, net_res[0].type) self._collected_resources[floatingip_id] = floatingip_res self._collected_dependencies[floatingip_id] = floatingip_dep floatingipResources.append(floatingip_res) if floatingip_ids and not floatingipResources: msg = "FloatingIp resource extracted failed, \ can't find the floatingip with id of %s." % floatingip_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return floatingipResources
def extract_volume(self, volume_id, parent_name=None, parent_resources=None): LOG.debug('Create volume resource start: %s', volume_id) # 1.query volume info try: volume = self.cinder_api.get(self.context, volume_id) except Exception as e: msg = "Volume resource <%s> could not be found. %s" \ % (volume_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) volume_id = volume.get('id') vol_state = volume.get('status', None) if vol_state not in resource_state.VOLUME_CLONE_STATE: LOG.error("Volume %(id)s state is %(state)s not available \ or in-use", {'id': volume_id, 'state': vol_state}) raise exception.PlanCreateFailed v_res = self._collected_resources.get(volume_id) # check volume resource is existing or not if v_res: return v_res # 2. bulid volume resource properties = { 'size': volume['size'], 'name': volume['display_name'], 'availability_zone': volume['availability_zone'] } if volume.get('display_description'): properties['description'] = volume['display_description'] vol_metadata = volume.get('volume_metadata', None) if vol_metadata: vol_metadata.pop('__hc_vol_id', None) vol_metadata.pop('__openstack_region_name', None) properties['metadata'] = vol_metadata resource_type = "OS::Cinder::Volume" resource_name = 'volume_%d' % self._get_resource_num(resource_type) if parent_name and volume_id in parent_resources: resource_name = parent_name + '.' + resource_name volume_res = resource.Resource(resource_name, resource_type, volume_id, properties=properties) volume_dep = resource.ResourceDependency(volume_id, resource_name, volume['display_name'], resource_type) self._collected_resources[volume_id] = volume_res self._collected_dependencies[volume_id] = volume_dep volume_res.add_extra_property('status', vol_state) volume_res.add_extra_property('copy_data', True) # 3. if volume has volume type, building volume type resource # and updating dependences volume_type_name = volume.get('volume_type') if volume_type_name: volume_types = self.cinder_api.volume_type_list(self.context) type_id = None for vtype in volume_types: if vtype['name'] == volume_type_name: type_id = vtype['id'] break if type_id: type_driver = \ VolumeType( self.context, collected_resources=self._collected_resources, collected_parameters=self._collected_parameters, collected_dependencies=self._collected_dependencies) volume_type_res = type_driver.extract_volume_type( type_id, parent_name, parent_resources) if volume_type_res: t_name = volume_type_res.name volume_res.add_property('volume_type', {'get_resource': t_name}) dep_res_name = volume_type_res.properties.get('name', '') volume_dep.add_dependency(volume_type_res.id, volume_type_res.name, dep_res_name, volume_type_res.type) self._collected_resources = \ type_driver.get_collected_resources() self._collected_dependencies = \ type_driver.get_collected_dependencies() # 4. if volume has image or not, add image info to volume resource if volume['bootable'] == 'true' and \ volume.get('volume_image_metadata'): image_id = volume['volume_image_metadata'].get('image_id') if image_id: image_para_name = self.extract_image(image_id, parent_name, parent_resources) description = ("Image to use to boot server or volume") constraints = [{'custom_constraint': "glance.image"}] volume_res.add_parameter(image_para_name, description, default=image_id, constraints=constraints) volume_res.add_property('image', {'get_param': image_para_name}) # 5.if volume in consistency group, collect consistency group resource cg_id = volume.get('consistencygroup_id') if cg_id: from conveyor.resource.driver.consistencygroup import \ ConsistencyGroup consisgroup_driver = \ ConsistencyGroup( self.context, collected_resources=self._collected_resources, collected_parameters=self._collected_parameters, collected_dependencies=self._collected_dependencies) cons_res = consisgroup_driver.extract_consistency_group( cg_id, parent_name, parent_resources) volume_res.add_property('consistencygroup_id', {'get_resource': cons_res.name}) dep_res_name = cons_res.properties.get('name', '') volume_dep.add_dependency(cons_res.id, cons_res.name, dep_res_name, cons_res.type) self._collected_resources = \ consisgroup_driver.get_collected_resources() self._collected_dependencies = \ consisgroup_driver.get_collected_dependencies() LOG.debug('Create volume resource end: %s', volume_id) return volume_res
def extract_volumes(self, volume_ids, parent_name=None, parent_resources=None): volume_dicts = [] volumeResources = [] if not volume_ids: LOG.info('Extract resources of all volumes.') volume_dicts = self.cinder_api.get_all(self.context) else: LOG.info('Extract resources of volumes: %s', volume_ids) # remove duplicate volume volume_ids = {}.fromkeys(volume_ids).keys() for volume_id in volume_ids: try: volume = self.cinder_api.get(self.context, volume_id) volume_dicts.append(volume) except Exception as e: msg = "Volume resource <%s> could not be found. %s" \ % (volume_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for volume in volume_dicts: volume_id = volume['id'] vol_state = volume.get('status', None) if vol_state not in resource_state.VOLUME_CLONE_STATE: LOG.error("Volume %(id)s state is %(state)s not available \ or in-use", {'id': volume_id, 'state': vol_state}) raise exception.PlanCreateFailed volume_res = self._collected_resources.get(volume_id) if volume_res: volumeResources.append(volume_res) continue properties = { 'size': volume['size'], 'name': volume['display_name'], 'availability_zone': volume['availability_zone'] } if volume.get('display_description'): properties['description'] = volume['display_description'] vol_metadata = volume.get('volume_metadata', None) if vol_metadata: vol_metadata.pop('__hc_vol_id', None) vol_metadata.pop('__openstack_region_name', None) properties['metadata'] = vol_metadata resource_type = "OS::Cinder::Volume" resource_name = 'volume_%d' % self.\ _get_resource_num(resource_type) if parent_name and volume_id in parent_resources: resource_name = parent_name + '.' + resource_name volume_res = resource.Resource(resource_name, resource_type, volume_id, properties=properties) volume_dep = resource.ResourceDependency(volume_id, resource_name, volume['display_name'], resource_type) volume_res.add_extra_property('status', vol_state) volume_res.add_extra_property('copy_data', True) volume_type_name = volume['volume_type'] if volume_type_name: volume_types = self.cinder_api.volume_type_list(self.context) volume_type_id = None for vtype in volume_types: if vtype['name'] == volume_type_name: volume_type_id = vtype['id'] break if volume_type_id: volume_type_res = \ self.extract_volume_types([volume_type_id], parent_name, parent_resources) if volume_type_res: t_name = volume_type_res[0].name volume_res.add_property('volume_type', {'get_resource': t_name}) dep_res_name = \ volume_type_res[0].properties.get('name', '') volume_dep.add_dependency(volume_type_res[0].id, volume_type_res[0].name, dep_res_name, volume_type_res[0].type) if volume['bootable'] and volume.get('volume_image_metadata'): image_id = volume['volume_image_metadata'].get('image_id') if image_id: image_para_name = self.extract_image(image_id, parent_name, parent_resources) description = ("Image to use to boot server or volume") constraints = [{'custom_constraint': "glance.image"}] volume_res.add_parameter(image_para_name, description, default=image_id, constraints=constraints) volume_res.add_property('image', {'get_param': image_para_name}) volume_res.add_extra_property('boot_index', 0) self._collected_resources[volume_id] = volume_res self._collected_dependencies[volume_id] = volume_dep volumeResources.append(volume_res) if volume_ids and not volumeResources: msg = "Volume resource extracted failed, \ can't find the volume with id of %s." % volume_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) LOG.info('Extracting volume resources has finished') return volumeResources
def extract_volume_types(self, volume_type_ids, parent_name=None, parent_resources=None): volume_type_dicts = [] volumeTypeResources = [] if not volume_type_ids: LOG.debug('Extract resources of all volume_types.') volume_type_dicts = self.cinder_api.volume_type_list(self.context) else: LOG.debug('Extract resources of volume_types: %s', volume_type_ids) # remove duplicate volume_type volume_type_ids = {}.fromkeys(volume_type_ids).keys() for volume_type_id in volume_type_ids: try: volume_type = \ self.cinder_api.get_volume_type(self.context, volume_type_id) volume_type_dicts.append(volume_type) except Exception as e: msg = "VolumeType resource <%s> could not be found. %s" \ % (volume_type_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for volume_type in volume_type_dicts: volume_type_id = volume_type['id'] volume_type_res = self._collected_resources.get(volume_type_id) if volume_type_res: volumeTypeResources.append(volume_type_res) continue properties = { 'name': volume_type['name'] } dependencies = [] # 2. check volume has qos or not, if having, build qos resource qos_id = volume_type.get('qos_specs_id', None) if qos_id: qos_driver = \ QosResource( self.context, collected_resources=self._collected_resources, collected_parameters=self._collected_parameters, collected_dependencies=self._collected_dependencies) qos_res = qos_driver.extract_qos(qos_id, parent_name, parent_resources) properties['qos_specs_id'] = {'get_resource': qos_res.name} dependencies.append({'id': qos_res.id, 'name': qos_res.name, 'name_in_template': '', 'type': qos_res.type}) self._collected_resources = \ qos_driver.get_collected_resources() self._collected_dependencies = \ qos_driver.get_collected_dependencies() if volume_type.get('extra_specs'): properties['metadata'] = volume_type['extra_specs'] resource_type = "OS::Cinder::VolumeType" resource_name = 'volume_type_%d' % \ self._get_resource_num(resource_type) if parent_name and volume_type_id in parent_resources: resource_name = parent_name + '.' + resource_name volume_type_res = resource.Resource(resource_name, resource_type, volume_type_id, properties=properties) volume_type_dep = resource.ResourceDependency( volume_type_id, resource_name, volume_type['name'], resource_type, dependencies=dependencies) self._collected_resources[volume_type_id] = volume_type_res self._collected_dependencies[volume_type_id] = volume_type_dep volumeTypeResources.append(volume_type_res) if volume_type_ids and not volumeTypeResources: msg = "VolumeType resource extracted failed, \ can't find the volume type with id of %s." % \ volume_type_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return volumeTypeResources
def _get_network_info(self, net_id, parent_name=None, parent_resources=None): # 1. get net info from neutron api try: net = self.neutron_api.get_network(self.context, net_id) except Exception as e: msg = "Network resource <%s> could not be found. %s" \ % (net_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) if not net: msg = "Network resource <%s> could not be found. " % net_id LOG.error(msg) raise exception.ResourceNotFound(message=msg) # 2. check net resource exist or not net_res = self._collected_resources.get(net_id) if net_res: return net.get('subnets'), net_res properties = { 'name': net.get('name'), 'admin_state_up': net.get('admin_state_up'), 'shared': net.get('shared') } value_specs = {} if net.get('provider:physical_network') is not None: value_specs['provider:physical_network'] = \ net.get('provider:physical_network') if net.get('provider:network_type') is not None: value_specs['provider:network_type'] = \ net.get('provider:network_type') if net.get('provider:segmentation_id') is not None: value_specs['provider:segmentation_id'] = \ net.get('provider:segmentation_id') if net.get('router:external') is not None: value_specs['router:external'] = net.get('router:external') if value_specs: properties['value_specs'] = value_specs resource_type = "OS::Neutron::Net" resource_name = 'network_%d' % self._get_resource_num(resource_type) if parent_name and net_id in parent_resources: resource_name = parent_name + '.' + resource_name net_res = resource.Resource(resource_name, resource_type, net_id, properties=properties) net_dep = resource.ResourceDependency(net_id, resource_name, net.get('name'), resource_type) self._collected_resources[net_id] = net_res self._collected_dependencies[net_id] = net_dep return net.get('subnets'), net_res
def _generate_router_resource(self, router_id, other_net_ids, parent_name=None, parent_resources=None): # 1. get router info from neutron api # routers = None try: router = self.neutron_api.get_router(self.context, router_id) except Exception as e: msg = "Router resource extracted failed, \ can't find router with id: %s. %s" % \ (router_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) if not router: msg = "Router resource <%s> could not be found." \ % router_id LOG.error(msg) raise exception.ResourceNotFound(message=msg) # 2. check this router resource is exist or not router_id = router.get('id') router_res = self._collected_resources.get(router_id) if router_res: return router_res.name # 3. generate new router resource properties = { 'name': router.get('name'), 'admin_state_up': router.get('admin_state_up') } dependencies = [] external_gateway_info = router.get('external_gateway_info') if external_gateway_info: network = external_gateway_info.get('network_id') if (network in other_net_ids): if network: net_res = self.extract_nets( [network], with_subnets=True, parent_name=parent_name, parent_resources=parent_resources) if net_res: enable_snat = external_gateway_info.get('enable_snat') properties['external_gateway_info'] = \ {'network': {'get_resource': net_res[0].name}, 'enable_snat': enable_snat} dep_res_name = net_res[0].properties.get('name', '') dependencies.append({ 'id': net_res[0].id, 'name': net_res[0].name, 'name_in_template': dep_res_name, 'type': net_res[0].type }) else: # if router relate public network not in clone list, # do not copy router return None else: # if router does not have public network, do not clone router return None resource_type = "OS::Neutron::Router" resource_name = 'router_%d' % self._get_resource_num(resource_type) if parent_name and router_id in parent_resources: resource_name = parent_name + '.' + resource_name router_res = resource.Resource(resource_name, resource_type, router_id, properties=properties) # remove duplicate dependencies # dependencies = {}.fromkeys(dependencies).keys() router_dep = resource.ResourceDependency(router_id, resource_name, router.get('name'), resource_type, dependencies=dependencies) self._collected_resources[router_id] = router_res self._collected_dependencies[router_id] = router_dep return router_res
def extract_volume_type(self, volume_type_id, parent_name=None, parent_resources=None): LOG.debug('Create volume type resource start: %s', volume_type_id) properties = {} dependencies = [] # 1. query volume type info try: volume_type = self.cinder_api.get_volume_type(self.context, volume_type_id) except Exception as e: msg = "VolumeType resource <%s> could not be found. %s" \ % (volume_type_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) volume_type_id = volume_type['id'] # check volume type resource is existing or not volume_type_res = self._collected_resources.get(volume_type_id) if volume_type_res: return volume_type_res # 2. check volume has qos or not, if having, build qos resource qos_id = volume_type.get('qos_specs_id') if qos_id: qos_driver = \ QosResource( self.context, collected_resources=self._collected_resources, collected_parameters=self._collected_parameters, collected_dependencies=self._collected_dependencies) qos_res = qos_driver.extract_qos(qos_id, parent_name, parent_resources) self._collected_resources = qos_driver.get_collected_resources() self._collected_dependencies = \ qos_driver.get_collected_dependencies() properties['qos_specs_id'] = {'get_resource': qos_res.name} dependencies.append({'id': qos_res.id, 'name': qos_res.name, 'name_in_template': '', 'type': qos_res.type}) # 3. bulid volume type resource properties['name'] = volume_type.get('name') if volume_type.get('extra_specs'): properties['metadata'] = volume_type['extra_specs'] resource_type = "OS::Cinder::VolumeType" resource_name = 'volume_type_%d' % \ self._get_resource_num(resource_type) if parent_name and volume_type_id in parent_resources: resource_name = parent_name + '.' + resource_name volume_type_res = resource.Resource(resource_name, resource_type, volume_type_id, properties=properties) type_dep = resource.ResourceDependency(volume_type_id, resource_name, volume_type['name'], resource_type, dependencies=dependencies) self._collected_resources[volume_type_id] = volume_type_res self._collected_dependencies[volume_type_id] = type_dep LOG.debug('Create volume type resource end: %s', volume_type_id) return volume_type_res
def _build_vm_networks(self, server, instance_resources, instance_dependencies, parent_name=None, parent_resources=None): server_id = server.get('id', '') LOG.debug('Extract network resources of instance: %s.', server_id) addresses = server.get('addresses', {}) network_properties = [] fixed_ip_macs = [] for addrs in addresses.values(): for addr_info in addrs: addr = addr_info.get('addr') mac = addr_info.get('OS-EXT-IPS-MAC:mac_addr') ip_type = addr_info.get('OS-EXT-IPS:type') if not addr or not mac or not ip_type: msg = "Instance addresses information is abnormal. \ 'addr' or 'mac' or 'type' attribute is None" LOG.error(msg) raise exception.ResourceAttributesException(message=msg) nr = NetworkResource(self.context, collected_resources= self._collected_resources, collected_parameters= self._collected_parameters, collected_dependencies= self._collected_dependencies) if ip_type == 'fixed': # Avoid the port with different ips was extract many times. if mac in fixed_ip_macs: continue else: fixed_ip_macs.append(mac) port = self.neutron_api.port_list(self.context, mac_address=mac) if not port: msg = "Instance network extracted failed, can't find \ the port with mac_address of %s." % mac LOG.error(msg) raise exception.ResourceNotFound(message=msg) port_id = port[0].get('id') port_res = nr.extract_ports([port_id], parent_name, parent_resources) network_properties.append({"port": {"get_resource": port_res[0].name}}) dep_res_name = port_res[0].properties.get('name', '') instance_dependencies.add_dependency(port_res[0].id, port_res[0].name, dep_res_name, port_res[0].type) elif ip_type == 'floating': floatingip = \ self.neutron_api.floatingip_list( self.context, floating_ip_address=addr) if not floatingip: msg = "Instance floatingip extracted failed,can't \ find floatingip with address of %s." % addr LOG.error(msg) raise exception.ResourceNotFound(message=msg) floatingip_id = floatingip[0].get('id') nr.extract_floatingips([floatingip_id], parent_name, parent_resources) instance_resources.add_property('networks', network_properties)
def extract_secgroups(self, secgroup_ids, parent_name=None, parent_resources=None): secgroup_objs = [] secgroupResources = [] if not secgroup_ids: LOG.debug('Extract resources of security groups') secgroup_list = self.neutron_api.secgroup_list(self.context) secgroup_objs = filter(self._tenant_filter, secgroup_list) else: LOG.debug('Extract resources of security groups: %s', secgroup_ids) # remove duplicate secgroups secgroup_ids = {}.fromkeys(secgroup_ids).keys() for sec_id in secgroup_ids: try: sec = self.neutron_api.get_security_group( self.context, sec_id) secgroup_objs.append(sec) except Exception as e: msg = "SecurityGroup resource <%s> could " \ "not be found. %s" % (sec_id, unicode(e)) LOG.error(msg) raise exception.ResourceNotFound(message=msg) for sec in secgroup_objs: sec_id = sec.get('id') sec_res = self._collected_resources.get(sec_id) if sec_res: secgroupResources.append(sec_res) continue if sec.get('name') == 'default': sec['name'] = '_default' properties = { 'description': sec.get('description'), 'name': sec.get('name'), } resource_type = "OS::Neutron::SecurityGroup" resource_name = 'security_group_%d' % \ self._get_resource_num(resource_type) if parent_name and sec_id in parent_resources: resource_name = parent_name + '.' + resource_name sec_res = resource.Resource(resource_name, resource_type, sec_id, properties=properties) # Put secgroup into collected_resources first before # extracting rules to avoid recycle dependencies. self._collected_resources[sec_id] = sec_res # Extract secgroup rules. rules, dependencies = \ self._build_rules(sec.get('security_group_rules')) self._collected_resources[sec_id].add_property('rules', rules) # remove duplicate dependencies dependencies = {}.fromkeys(dependencies).keys() sec_dep = resource.ResourceDependency(sec_id, resource_name, sec.get('name'), resource_type, dependencies=dependencies) self._collected_dependencies[sec_id] = sec_dep secgroupResources.append(sec_res) if secgroup_ids and not secgroupResources: msg = "Security group resource extracted failed, \ can't find the Security group with id of %s." % \ secgroup_ids LOG.error(msg) raise exception.ResourceNotFound(message=msg) return secgroupResources