示例#1
0
    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
示例#2
0
    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
示例#3
0
    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)
示例#4
0
    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
示例#5
0
    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