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_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 _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_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