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