def host_passes(self, host_state, spec_obj): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ image_props = spec_obj.image.properties if spec_obj.image else {} agg_metadata = utils.aggregate_metadata_get_by_host(host_state) for key, prop in six.iteritems(image_props.cim_properties): agg_vals = agg_metadata.get(key, None) if not agg_vals: LOG.debug("%(host_state)s fails image properties " "requirements. Image propertiy %(key)s is not in " "aggregate.", {'host_state': host_state, 'key': key}) return False for agg_val in agg_vals: if not extra_specs_ops.match(agg_val, prop): break else: LOG.debug("%(host_state)s fails image properties " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'", {'host_state': host_state, 'aggregate_vals': agg_vals, 'req': prop}) return False return True
def _satisfies_extra_specs(self, host_state, instance_type): """Check that the host_state provided by the compute service satisfy the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): # Either not scope format, or in capabilities scope scope = key.split(':') if len(scope) > 1: if scope[0] != "capabilities": continue else: del scope[0] cap = self._get_capabilities(host_state, scope) if cap is None: return False if not extra_specs_ops.match(str(cap), req): LOG.debug( "%(host_state)s fails extra_spec requirements. " "'%(req)s' does not match '%(cap)s'", { 'host_state': host_state, 'req': req, 'cap': cap }) return False return True
def _satisfies_extra_specs(self, host_state, instance_type): """Check that the host_state provided by the compute service satisfy the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): # Either not scope format, or in capabilities scope scope = key.split(':') if len(scope) > 1: if scope[0] != "capabilities": continue else: del scope[0] cap = host_state for index in range(0, len(scope)): try: if not isinstance(cap, dict): if getattr(cap, scope[index], None) is None: # If can't find, check stats dict cap = cap.stats.get(scope[index], None) else: cap = getattr(cap, scope[index], None) else: cap = cap.get(scope[index], None) except AttributeError: return False if cap is None: return False if not extra_specs_ops.match(str(cap), req): return False return True
def host_passes(self, host_state, filter_properties): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = filter_properties.get('instance_type') if 'extra_specs' not in instance_type: return True context = filter_properties['context'].elevated() metadata = db.aggregate_metadata_get_by_host(context, host_state.host) for key, req in instance_type['extra_specs'].iteritems(): if key.count(':'): continue aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug(_("%(host_state)s fails instance_type extra_specs " "requirements"), locals()) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug(_("%(host_state)s fails instance_type extra_specs " "requirements"), locals()) return False return True
def _satisfies_extra_specs(self, capabilities, instance_type): """Check that the capabilities provided by the compute service satisfy the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): # Either not scope format, or in capabilities scope scope = key.split(':') if len(scope) > 1: if scope[0] != "capabilities": continue else: del scope[0] cap = capabilities for index in range(0, len(scope)): try: cap = cap.get(scope[index], None) except AttributeError: return False if cap is None: return False if not extra_specs_ops.match(str(cap), req): return False return True
def _satisfies_extra_specs(self, host_state, instance_type): """Check that the host_state provided by the compute service satisfy the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): # Either not scope format, or in capabilities scope scope = key.split(':') if len(scope) > 1: if scope[0] != "capabilities": continue else: del scope[0] cap = host_state for index in range(0, len(scope)): try: if not isinstance(cap, dict): if getattr(cap, scope[index], None) is None: # If can't find, check stats dict cap = cap.stats.get(scope[index], None) else: cap = getattr(cap, scope[index], None) else: cap = cap.get(scope[index], None) except AttributeError: return False if cap is None: return False if not extra_specs_ops.match(str(cap), req): LOG.debug(_("extra_spec requirement '%(req)s' does not match " "'%(cap)s'"), {'req': req, 'cap': cap}) return False return True
def _satisfies_extra_specs(self, host_state, instance_type): """Check that the host_state provided by the compute service satisfy the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in six.iteritems(instance_type['extra_specs']): # Either not scope format, or in capabilities scope scope = key.split(':') if len(scope) > 1: if scope[0] != "capabilities": continue else: del scope[0] cap = self._get_capabilities(host_state, scope) if cap is None: return False if not extra_specs_ops.match(str(cap), req): LOG.debug("%(host_state)s fails extra_spec requirements. " "'%(req)s' does not match '%(cap)s'", {'host_state': host_state, 'req': req, 'cap': cap}) return False return True
def _satisfies_extra_specs(self, capabilities, instance_type): """Check that the capabilities provided by the compute service satisfy the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): # Either not scope format, or in capabilities scope scope = key.split(':') if len(scope) > 1 and scope[0] != "capabilities": continue elif scope[0] == "capabilities": del scope[0] cap = capabilities for index in range(0, len(scope)): try: cap = cap.get(scope[index], None) except AttributeError: return False if cap is None: return False if not extra_specs_ops.match(str(cap), req): return False return True
def host_passes(self, host_state, filter_properties): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = filter_properties.get('instance_type') if 'extra_specs' not in instance_type: return True context = filter_properties['context'].elevated() metadata = db.aggregate_metadata_get_by_host(context, host_state.host) for key, req in instance_type['extra_specs'].iteritems(): # NOTE(jogo) any key containing a scope (scope is terminated # by a `:') will be ignored by this filter. (bug 1039386) if key.count(':'): continue aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug(_("%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate."), {'host_state': host_state, 'key': key}) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug(_("%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'"), {'host_state': host_state, 'req': req, 'aggregate_vals': aggregate_vals}) return False return True
def _satisfies_extra_specs(self, capabilities, instance_type): """Check that the capabilities provided by the compute service satisfy the extra specs associated with the instance type""" if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): cap = capabilities.get(key, None) if not extra_specs_ops.match(cap, req): return False return True
def _satisfies_extra_specs(self, capabilities, instance_type): """Check that the capabilities provided by the compute service satisfy the extra specs associated with the instance type""" if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): if key.count(':'): continue cap = capabilities.get(key, None) if not extra_specs_ops.match(cap, req): return False return True
def _satisfies_extra_specs(self, host_state, instance_type, spec_obj): """Check that the host_state provided by the compute service satisfies the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type.extra_specs.items(): # Either not scope format, or in capabilities scope scope = key.split(':') # If key does not have a namespace, the scope's size is 1, check # whether host_state contains the key as an attribute. If not, # ignore it. If it contains, deal with it in the same way as # 'capabilities:key'. This is for backward-compatible. # If the key has a namespace, the scope's size will be bigger than # 1, check that whether the namespace is 'capabilities'. If not, # ignore it. if len(scope) == 1: stats = getattr(host_state, 'stats', {}) has_attr = hasattr(host_state, key) or key in stats if not has_attr: continue else: if scope[0] != "capabilities": continue else: del scope[0] cap = self._get_capabilities(host_state, scope) if cap is None: msg = ('capability is missing') self.filter_reject(host_state, spec_obj, msg) return False if not extra_specs_ops.match(str(cap), req): LOG.debug( "%(host_state)s fails extra_spec requirements. " "'%(req)s' does not match '%(cap)s'", { 'host_state': host_state, 'req': req, 'cap': cap }) msg = ("%(host_state)s fails extra_spec requirements. " "'%(req)s' does not match '%(cap)s'", { 'host_state': host_state, 'req': req, 'cap': cap }) self.filter_reject(host_state, spec_obj, msg) return False return True
def _satisfies_extra_specs(self, capabilities, instance_type): """Check that the capabilities provided by the compute service satisfy the extra specs associated with the instance type""" if 'extra_specs' not in instance_type: return True for key, req in instance_type['extra_specs'].iteritems(): # NOTE(jogo) any key containing a scope (scope is terminated # by a `:') will be ignored by this filter. (bug 1039386) if key.count(':'): continue cap = capabilities.get(key, None) if not extra_specs_ops.match(cap, req): return False return True
def host_passes(self, host_state, filter_properties, filter_errors={}): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = filter_properties.get('instance_type') if 'extra_specs' not in instance_type: return True metadata = utils.aggregate_metadata_get_by_host(host_state) for key, req in six.iteritems(instance_type['extra_specs']): # Either not scope format, or aggregate_instance_extra_specs scope scope = key.split(':', 1) if len(scope) > 1: if scope[0] != _SCOPE: continue else: del scope[0] key = scope[0] aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate.", { 'host_state': host_state, 'key': key }) # PF9 change self.mark_filter_error(self.__class__, filter_errors) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'", { 'host_state': host_state, 'req': req, 'aggregate_vals': aggregate_vals }) # PF9 change self.mark_filter_error(self.__class__, filter_errors) return False return True
def host_passes(self, host_state, spec_obj): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = spec_obj.flavor # If 'extra_specs' is not present or extra_specs are empty then we # need not proceed further if (not instance_type.obj_attr_is_set('extra_specs') or not instance_type.extra_specs): return True metadata = utils.aggregate_metadata_get_by_host(host_state) for key, req in instance_type.extra_specs.items(): # Either not scope format, or aggregate_instance_extra_specs scope scope = key.split(':', 1) if len(scope) > 1: if scope[0] != _SCOPE: continue else: del scope[0] key = scope[0] aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate.", { 'host_state': host_state, 'key': key }) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'", { 'host_state': host_state, 'req': req, 'aggregate_vals': aggregate_vals }) return False return True
def host_passes(self, host_state, filter_properties): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = filter_properties.get("instance_type") if "extra_specs" not in instance_type: return True context = filter_properties["context"].elevated() metadata = db.aggregate_metadata_get_by_host(context, host_state.host) for key, req in instance_type["extra_specs"].iteritems(): # Either not scope format, or aggregate_instance_extra_specs scope scope = key.split(":", 1) if len(scope) > 1: if scope[0] != _SCOPE: continue else: del scope[0] key = scope[0] aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug( _( "%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate." ), {"host_state": host_state, "key": key}, ) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug( _( "%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'" ), {"host_state": host_state, "req": req, "aggregate_vals": aggregate_vals}, ) return False return True
def host_passes(self, host_state, spec_obj): """Return whether the instance matches the host's spec. All host's metadata entries have to be present. It effectively filters out flavors and images without the required or even no specs. """ # get the host/aggregate specs metadata = utils.aggregate_metadata_get_by_host(host_state) # try to get the instance specs instance_type = spec_obj.flavor # If 'extra_specs' is not present or extra_specs are empty then we # need not proceed further if (not instance_type.obj_attr_is_set('extra_specs') or not instance_type.extra_specs): # if no instance specs are present, the host is denied if it defines # some specs return not metadata for key, req in metadata.items(): aggregate_vals = instance_type.extra_specs.get(key, None) if not aggregate_vals: # keys may be scoped with 'aggregate_instance_extra_specs' aggregate_vals = instance_type.extra_specs.get( "aggregate_instance_extra_specs:" + key, None) if not aggregate_vals: LOG.debug( "%(extra_specs)s fails require host extra_specs, key %(key)s is not in instance definition.", { 'extra_specs': instance_type.extra_specs, 'key': key }) return False for aggregate_val in aggregate_vals: if not extra_specs_ops.match(aggregate_val, req): LOG.debug( "%(extra_specs)s fails required host extra_specs, '%(aggregate_vals)s' do not " "match '%(req)s' for key %{key}s.", { 'extra_specs': instance_type.extra_specs, 'req': req, 'aggregate_vals': aggregate_vals, 'key': key }) return False return True
def host_passes(self, host_state, spec_obj): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = spec_obj.flavor # If 'extra_specs' is not present or extra_specs are empty then we # need not proceed further if (not instance_type.obj_attr_is_set('extra_specs') or not instance_type.extra_specs): return True metadata = utils.aggregate_metadata_get_by_host(host_state) for key, req in instance_type.extra_specs.items(): # Either not scope format, or aggregate_instance_extra_specs scope scope = key.split(':', 1) if len(scope) > 1: if scope[0] != _SCOPE: continue else: del scope[0] key = scope[0] aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate.", {'host_state': host_state, 'key': key}) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug("%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'", {'host_state': host_state, 'req': req, 'aggregate_vals': aggregate_vals}) return False return True
def host_passes(self, host_state, filter_properties): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = filter_properties.get('instance_type') if 'extra_specs' not in instance_type: return True context = filter_properties['context'] metadata = utils.aggregate_metadata_get_by_host(context, host_state.host) for key, req in instance_type['extra_specs'].iteritems(): # Either not scope format, or aggregate_instance_extra_specs scope scope = key.split(':', 1) if len(scope) > 1: if scope[0] != _SCOPE: continue else: del scope[0] key = scope[0] aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug("%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate.", {'host_state': host_state, 'key': key}) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug("%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'", {'host_state': host_state, 'req': req, 'aggregate_vals': aggregate_vals}) return False return True
def _satisfies_extra_specs(self, host_state, instance_type): """Check that the host_state provided by the compute service satisfies the extra specs associated with the instance type. """ if 'extra_specs' not in instance_type: return True for key, req in instance_type.extra_specs.items(): # Either not scope format, or in capabilities scope scope = key.split(':') # If key does not have a namespace, the scope's size is 1, check # whether host_state contains the key as an attribute. If not, # ignore it. If it contains, deal with it in the same way as # 'capabilities:key'. This is for backward-compatible. # If the key has a namespace, the scope's size will be bigger than # 1, check that whether the namespace is 'capabilities'. If not, # ignore it. if len(scope) == 1: stats = getattr(host_state, 'stats', {}) has_attr = hasattr(host_state, key) or key in stats if not has_attr: continue else: if scope[0] != "capabilities": continue else: del scope[0] cap = self._get_capabilities(host_state, scope) if cap is None: return False if not extra_specs_ops.match(str(cap), req): LOG.debug("%(host_state)s fails extra_spec requirements. " "'%(req)s' does not match '%(cap)s'", {'host_state': host_state, 'req': req, 'cap': cap}) return False return True
def host_passes(self, host_state, spec_obj): """Return a list of hosts that can create instance_type Check that the extra specs associated with the instance type match the metadata provided by aggregates. If not present return False. """ instance_type = spec_obj.flavor # If 'extra_specs' is not present or extra_specs are empty then we # need not proceed further if (not instance_type.obj_attr_is_set('extra_specs') or not instance_type.extra_specs): return True metadata = utils.aggregate_metadata_get_by_host(host_state) is_ironic = nova_utils.is_ironic_compute(host_state) for key, req in instance_type.extra_specs.items(): # Either not scope format, or aggregate_instance_extra_specs scope scope = key.split(':', 1) if len(scope) > 1: if scope[0] != _SCOPE: continue else: del scope[0] key = scope[0] # WRS - Hybrid baremetal support if is_ironic and key in BAREMETAL_IGNORE_KEYS: continue aggregate_vals = metadata.get(key, None) if not aggregate_vals: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. Extra_spec %(key)s is not in aggregate.", { 'host_state': host_state, 'key': key }) msg = ("extra_specs '%(key)s' not in aggregate, " "cannot match '%(req)s'." % { 'key': key, 'req': req }) self.filter_reject(host_state, spec_obj, msg) return False for aggregate_val in aggregate_vals: if extra_specs_ops.match(aggregate_val, req): break else: LOG.debug( "%(host_state)s fails instance_type extra_specs " "requirements. '%(aggregate_vals)s' do not " "match '%(req)s'", { 'host_state': host_state, 'req': req, 'aggregate_vals': aggregate_vals }) msg = ("extra_specs '%(agg)s' do not match '%(req)s'" % { 'req': req, 'agg': aggregate_vals }) self.filter_reject(host_state, spec_obj, msg) return False return True
def _do_extra_specs_ops_test(self, value, req, matches): assertion = self.assertTrue if matches else self.assertFalse assertion(extra_specs_ops.match(value, req))