Esempio n. 1
0
    def _update_instance_cache(self):
        """Collect instance_id, project_id, and AZ for all instance UUIDs
        """
        from novaclient import client
        from novaclient.exceptions import NotFound

        id_cache = {}
        flavor_cache = {}
        port_cache = None
        netns = None
        # Get a list of all instances from the Nova API
        nova_client = client.Client(2, self.init_config.get('admin_user'),
                                    self.init_config.get('admin_password'),
                                    self.init_config.get('admin_tenant_name'),
                                    self.init_config.get('identity_uri'),
                                    endpoint_type='internalURL',
                                    service_type="compute",
                                    region_name=self.init_config.get('region_name'))
        instances = nova_client.servers.list(search_opts={'all_tenants': 1,
                                                          'host': self.hostname})
        # Lay the groundwork for fetching VM IPs and network namespaces
        if self.init_config.get('ping_check'):
            from neutronclient.v2_0 import client
            nu = client.Client(username=self.init_config.get('admin_user'),
                               password=self.init_config.get('admin_password'),
                               tenant_name=self.init_config.get('admin_tenant_name'),
                               auth_url=self.init_config.get('identity_uri'),
                               endpoint_type='internalURL',
                               region_name=self.init_config.get('region_name'))
            port_cache = nu.list_ports()['ports']
            # Finding existing network namespaces is an indication that either
            # DVR agent_mode is enabled, or this is all-in-one (like devstack)
            netns = subprocess.check_output(['ip', 'netns', 'list'])
            if netns == '':
                self.log.warn("Unable to ping VMs, no network namespaces found." +
                              "Either no VMs are present, or routing is centralized.")

        #
        # Only make the keystone call to get the tenant list
        # if we are configured to publish tenant names.
        #
        tenants = []
        if self.init_config.get('metadata') and 'tenant_name' in self.init_config.get('metadata'):
            tenants = utils.get_tenant_list(self.init_config, self.log)

        for instance in instances:
            instance_ports = []
            inst_name = instance.__getattr__('OS-EXT-SRV-ATTR:instance_name')
            inst_az = instance.__getattr__('OS-EXT-AZ:availability_zone')
            if instance.flavor['id'] in flavor_cache:
                inst_flavor = flavor_cache[instance.flavor['id']]
            else:
                try:
                    inst_flavor = nova_client.flavors.get(instance.flavor['id'])
                except NotFound as e:
                    self.log.error('Skipping VM {}: {}'.format(inst_name, e))
                    continue
                flavor_cache[instance.flavor['id']] = inst_flavor
            if port_cache:
                instance_ports = [p['id'] for p in port_cache if p['device_id'] == instance.id]
            id_cache[inst_name] = {'instance_uuid': instance.id,
                                   'hostname': instance.name,
                                   'zone': inst_az,
                                   'created': instance.created,
                                   'tenant_id': instance.tenant_id,
                                   'vcpus': inst_flavor.vcpus,
                                   'ram': inst_flavor.ram,
                                   'disk': inst_flavor.disk,
                                   'instance_ports': instance_ports}

            tenant_name = utils.get_tenant_name(tenants, instance.tenant_id)
            if tenant_name:
                id_cache[inst_name]['tenant_name'] = tenant_name

            for config_var in ['metadata', 'customer_metadata']:
                if self.init_config.get(config_var):
                    for metadata in self.init_config.get(config_var):
                        if instance.metadata.get(metadata):
                            id_cache[inst_name][metadata] = (instance.metadata.
                                                             get(metadata))

            # Build a list of pingable IP addresses attached to this VM and the
            # appropriate namespace, for use in ping tests
            if netns:
                secgroup_cache = nu.list_security_groups()['security_groups']
                self._build_ip_list(instance, inst_name,
                                    secgroup_cache, port_cache, id_cache)

        id_cache['last_update'] = int(time.time())

        # Write the updated cache
        try:
            with open(self.instance_cache_file, 'w') as cache_json:
                json.dump(id_cache, cache_json)
            if stat.S_IMODE(os.stat(self.instance_cache_file).st_mode) != 0o600:
                os.chmod(self.instance_cache_file, 0o600)
        except IOError as e:
            self.log.error("Cannot write to {0}: {1}".format(self.instance_cache_file, e))

        return id_cache
Esempio n. 2
0
    def _update_port_cache(self):
        """Collect port_uuid, device_uuid, router_name, and tenant_id
        for all routers.
        """
        if not hasattr(self, 'neutron_client'):
            self.neutron_client = self._get_neutron_client()
        port_cache = {}

        try:
            self.log.debug("Retrieving Neutron port data")
            all_ports_data = self.neutron_client.list_ports()
            self.log.debug("Retrieving Neutron router data")
            all_routers_data = self.neutron_client.list_routers()
        except Exception as e:
            self.log.exception("Unable to get neutron data: %s", str(e))
            return port_cache

        all_ports_data = all_ports_data['ports']
        all_routers_data = all_routers_data['routers']

        #
        # Only make the keystone call to get the tenant list
        # if we are configured to publish tenant names.
        #
        if self.init_config.get(
                'metadata') and 'tenant_name' in self.init_config.get(
                    'metadata'):
            tenants = utils.get_tenant_list(self.init_config, self.log)
        else:
            tenants = []

        for port_data in all_ports_data:
            port_uuid = port_data['id']
            device_uuid = port_data['device_id']
            router_info = self._get_os_info(device_uuid, all_routers_data)
            if router_info:
                tenant_id = router_info['tenant_id']
                is_router_port = True
                router_name = router_info['name']
            else:
                tenant_id = port_data['tenant_id']
                is_router_port = False
                router_name = ""
            port_cache[port_uuid] = {
                'device_uuid': device_uuid,
                'router_name': router_name,
                'is_router_port': is_router_port,
                'tenant_id': tenant_id
            }

            tenant_name = utils.get_tenant_name(tenants, tenant_id)
            if tenant_name:
                port_cache[port_uuid]['tenant_name'] = tenant_name

        port_cache = self._add_max_bw_to_port_cache(port_cache, all_ports_data)
        port_cache['last_update'] = int(time.time())

        # Write the updated cache
        try:
            with open(self.port_cache_file, 'w') as cache_json:
                json.dump(port_cache, cache_json)
            if stat.S_IMODE(os.stat(self.port_cache_file).st_mode) != 0o600:
                os.chmod(self.port_cache_file, 0o600)
        except IOError as e:
            self.log.error("Cannot write to {0}: {1}".format(
                self.port_cache_file, e))
        return port_cache
Esempio n. 3
0
    def _update_instance_cache(self):
        """Collect instance_id, project_id, and AZ for all instance UUIDs
        """
        from novaclient import client
        from novaclient.exceptions import NotFound

        id_cache = {}
        flavor_cache = {}
        port_cache = None
        netns = None
        # Get a list of all instances from the Nova API
        nova_client = client.Client(2,
                                    username=self.init_config.get('admin_user'),
                                    password=self.init_config.get('admin_password'),
                                    project_name=self.init_config.get('admin_tenant_name'),
                                    auth_url=self.init_config.get('identity_uri'),
                                    endpoint_type='internalURL',
                                    service_type="compute",
                                    region_name=self.init_config.get('region_name'))
        instances = nova_client.servers.list(search_opts={'all_tenants': 1,
                                                          'host': self.hostname})
        # Lay the groundwork for fetching VM IPs and network namespaces
        if self.init_config.get('ping_check'):
            from neutronclient.v2_0 import client
            nu = client.Client(username=self.init_config.get('admin_user'),
                               password=self.init_config.get('admin_password'),
                               tenant_name=self.init_config.get('admin_tenant_name'),
                               auth_url=self.init_config.get('identity_uri'),
                               endpoint_type='internalURL',
                               region_name=self.init_config.get('region_name'))
            port_cache = nu.list_ports()['ports']
            # Finding existing network namespaces is an indication that either
            # DVR agent_mode is enabled, or this is all-in-one (like devstack)
            netns = subprocess.check_output(['ip', 'netns', 'list'])
            if netns == '':
                self.log.warn("Unable to ping VMs, no network namespaces found." +
                              "Either no VMs are present, or routing is centralized.")

        #
        # Only make the keystone call to get the tenant list
        # if we are configured to publish tenant names.
        #
        tenants = []
        if self.init_config.get('metadata') and 'tenant_name' in self.init_config.get('metadata'):
            tenants = utils.get_tenant_list(self.init_config, self.log)

        for instance in instances:
            instance_ports = []
            inst_name = instance.__getattr__('OS-EXT-SRV-ATTR:instance_name')
            inst_az = instance.__getattr__('OS-EXT-AZ:availability_zone')
            if instance.flavor['id'] in flavor_cache:
                inst_flavor = flavor_cache[instance.flavor['id']]
            else:
                try:
                    inst_flavor = nova_client.flavors.get(instance.flavor['id'])
                except NotFound as e:
                    self.log.error('Skipping VM {}: {}'.format(inst_name, e))
                    continue
                flavor_cache[instance.flavor['id']] = inst_flavor
            if port_cache:
                instance_ports = [p['id'] for p in port_cache if p['device_id'] == instance.id]
            id_cache[inst_name] = {'instance_uuid': instance.id,
                                   'hostname': instance.name,
                                   'zone': inst_az,
                                   'created': instance.created,
                                   'tenant_id': instance.tenant_id,
                                   'vcpus': inst_flavor.vcpus,
                                   'ram': inst_flavor.ram,
                                   'disk': inst_flavor.disk,
                                   'instance_ports': instance_ports}

            tenant_name = utils.get_tenant_name(tenants, instance.tenant_id)
            if tenant_name:
                id_cache[inst_name]['tenant_name'] = tenant_name

            for config_var in ['metadata', 'customer_metadata']:
                if self.init_config.get(config_var):
                    for metadata in self.init_config.get(config_var):
                        if instance.metadata.get(metadata):
                            id_cache[inst_name][metadata] = (instance.metadata.
                                                             get(metadata))

            # Build a list of pingable IP addresses attached to this VM and the
            # appropriate namespace, for use in ping tests
            if netns:
                secgroup_cache = nu.list_security_groups()['security_groups']
                self._build_ip_list(instance, inst_name,
                                    secgroup_cache, port_cache, id_cache)

        id_cache['last_update'] = int(time.time())

        # Write the updated cache
        try:
            with open(self.instance_cache_file, 'w') as cache_json:
                json.dump(id_cache, cache_json)
            if stat.S_IMODE(os.stat(self.instance_cache_file).st_mode) != 0o600:
                os.chmod(self.instance_cache_file, 0o600)
        except IOError as e:
            self.log.error("Cannot write to {0}: {1}".format(self.instance_cache_file, e))

        return id_cache
Esempio n. 4
0
    def _update_port_cache(self):
        """Collect port_uuid, device_uuid, router_name, and tenant_id
        for all routers.
        """
        if not hasattr(self, 'neutron_client'):
            self.neutron_client = self._get_neutron_client()
        port_cache = {}

        try:
            self.log.debug("Retrieving Neutron port data")
            all_ports_data = self.neutron_client.list_ports()
            self.log.debug("Retrieving Neutron router data")
            all_routers_data = self.neutron_client.list_routers()
        except Exception as e:
            self.log.exception("Unable to get neutron data: %s", str(e))
            return port_cache

        all_ports_data = all_ports_data['ports']
        all_routers_data = all_routers_data['routers']

        #
        # Only make the keystone call to get the tenant list
        # if we are configured to publish tenant names.
        #
        if self.init_config.get('metadata') and 'tenant_name' in self.init_config.get('metadata'):
            tenants = utils.get_tenant_list(self.init_config, self.log)
        else:
            tenants = []

        for port_data in all_ports_data:
            port_uuid = port_data['id']
            device_uuid = port_data['device_id']
            router_info = self._get_os_info(device_uuid, all_routers_data)
            if router_info:
                tenant_id = router_info['tenant_id']
                is_router_port = True
                router_name = router_info['name']
            else:
                tenant_id = port_data['tenant_id']
                is_router_port = False
                router_name = ""
            port_cache[port_uuid] = {'device_uuid': device_uuid,
                                     'router_name': router_name,
                                     'is_router_port': is_router_port,
                                     'tenant_id': tenant_id}

            tenant_name = utils.get_tenant_name(tenants, tenant_id)
            if tenant_name:
                port_cache[port_uuid]['tenant_name'] = tenant_name

        port_cache = self._add_max_bw_to_port_cache(port_cache,
                                                    all_ports_data)
        port_cache['last_update'] = int(time.time())

        # Write the updated cache
        try:
            with open(self.port_cache_file, 'w') as cache_json:
                json.dump(port_cache, cache_json)
            if stat.S_IMODE(os.stat(self.port_cache_file).st_mode) != 0o600:
                os.chmod(self.port_cache_file, 0o600)
        except IOError as e:
            self.log.error("Cannot write to {0}: {1}".
                           format(self.port_cache_file, e))
        return port_cache