def _validate_fields(self): if self.defs: for name in self.defs.keys(): if name not in self.SECTIONS: ExceptionCollector.appendException( UnknownFieldError(what='Group Type %s' % self.grouptype, field=name))
def _validate_type_version(self, version): if version not in self.VALID_TEMPLATE_VERSIONS: ExceptionCollector.appendException( InvalidTemplateVersion( what=version + " in " + self.import_def, valid_versions=", ".join(self.VALID_TEMPLATE_VERSIONS) ) )
def _validate_interfaces(self): ifaces = self.type_definition.get_value(self.INTERFACES, self.entity_tpl) if ifaces: for name, value in ifaces.items(): if name in (LIFECYCLE, LIFECYCLE_SHORTNAME): self._common_validate_field( value, InterfacesDef. interfaces_node_lifecycle_operations, 'interfaces') elif name in (CONFIGURE, CONFIGURE_SHORTNAME): self._common_validate_field( value, InterfacesDef. interfaces_relationship_configure_operations, 'interfaces') elif name in self.type_definition.interfaces.keys(): self._common_validate_field( value, self._collect_custom_iface_operations(name), 'interfaces') else: ExceptionCollector.appendException( UnknownFieldError( what='"interfaces" of template "%s"' % self.name, field=name))
def __init__(self, property_name, property_type, constraint): super(Pattern, self).__init__(property_name, property_type, constraint) if not isinstance(self.constraint_value, self.valid_types): ExceptionCollector.appendException( InvalidSchemaError(message=_('The property "pattern" ' 'expects a string.'))) self.match = re.compile(self.constraint_value).match
def __init__(self, property_name, property_type, constraint): super(MaxLength, self).__init__(property_name, property_type, constraint) if not isinstance(self.constraint_value, self.valid_types): ExceptionCollector.appendException( InvalidSchemaError(message=_('The property "max_length" ' 'expects an integer.')))
def __init__(self, name, value=None, schema=None): self.name = name self.value = value self.schema = schema try: self.schema['type'] except KeyError: msg = (_('Schema definition of "%(pname)s" must have a "type" ' 'attribute.') % dict(pname=self.name)) ExceptionCollector.appendException( InvalidSchemaError(message=msg)) if 'required' in self.schema: required = self.schema['required'] if not isinstance(required, bool): if required.lower() not in self.VALID_REQUIRED_VALUES: valid_values = ', '.join(self.VALID_REQUIRED_VALUES) msg = (_('Schema definition of "%(propname)s" has ' '"required" attribute with invalid value ' '"%(value1)s". The value must be one of ' '"%(value2)s".') % {"propname": self.name, "value1": required, "value2": valid_values}) ExceptionCollector.appendException( InvalidSchemaError(message=msg))
def _validate_requirements(self): type_requires = self.type_definition.get_all_requirements() allowed_reqs = ["template"] if type_requires: for treq in type_requires: for key, value in treq.items(): allowed_reqs.append(key) if isinstance(value, dict): for key in value: allowed_reqs.append(key) requires = self.type_definition.get_value(self.REQUIREMENTS, self.entity_tpl) if requires: if not isinstance(requires, list): ExceptionCollector.appendException( TypeMismatchError( what='"requirements" of template "%s"' % self.name, type='list')) for req in requires: for r1, value in req.items(): if isinstance(value, dict): self._validate_requirements_keys(value) self._validate_requirements_properties(value) allowed_reqs.append(r1) self._common_validate_field(req, allowed_reqs, 'requirements')
def validate(self): if len(self.args) < 1: ExceptionCollector.appendException( ValueError( _('Invalid arguments for function "{0}". Expected ' "at least one arguments.").format(CONCAT) ) )
def _common_validate_properties(self, entitytype, properties): allowed_props = [] required_props = [] for p in entitytype.get_properties_def_objects(): allowed_props.append(p.name) # If property is 'required' and has no 'default' value then record if p.required and p.default is None: required_props.append(p.name) # validate all required properties have values if properties: req_props_no_value_or_default = [] self._common_validate_field(properties, allowed_props, 'properties') # make sure it's not missing any property required by a tosca type for r in required_props: if r not in properties.keys(): req_props_no_value_or_default.append(r) # Required properties found without value or a default value if req_props_no_value_or_default: ExceptionCollector.appendException( MissingRequiredFieldError( what='"properties" of template "%s"' % self.name, required=req_props_no_value_or_default)) else: # Required properties in schema, but not in template if required_props: ExceptionCollector.appendException( MissingRequiredFieldError( what='"properties" of template "%s"' % self.name, required=required_props))
def validate(self): if len(self.args) < 2: ExceptionCollector.appendException( ValueError(_('Expected arguments: "node-template-name", "req-or-cap" ' '(optional), "property name".')) ) return if len(self.args) == 2: found_prop = self._find_property(self.args[1]) if not found_prop: return prop = found_prop.value if not isinstance(prop, Function): get_function(self.tosca_tpl, self.context, prop) elif len(self.args) >= 3: # do not use _find_property to avoid raise KeyError # if the prop is not found # First check if there is property with this name node_tpl = self._find_node_template(self.args[0]) props = node_tpl.get_properties() if node_tpl else [] index = 2 found = [props[self.args[1]]] if self.args[1] in props else [] if found: property_value = found[0].value else: index = 3 # then check the req or caps property_value = self._find_req_or_cap_property(self.args[1], self.args[2]) if len(self.args) > index: for elem in self.args[index:]: if isinstance(property_value, list): int_elem = int(elem) property_value = self._get_index_value(property_value, int_elem) else: property_value = self._get_attribute_value(property_value, elem)
def __init__(self, node_type, interfacetype, node_template=None, name=None, value=None): self.ntype = node_type self.node_template = node_template self.type = interfacetype self.name = name self.value = value self.implementation = None self.inputs = None self.defs = {} if interfacetype == LIFECYCLE_SHORTNAME: interfacetype = LIFECYCLE if interfacetype == CONFIGURE_SHORTNAME: interfacetype = CONFIGURE if node_type: self.defs = self.TOSCA_DEF[interfacetype] if value: if isinstance(self.value, dict): for i, j in self.value.items(): if i == IMPLEMENTATION: self.implementation = j elif i == INPUTS: self.inputs = j else: what = ('"interfaces" of template "%s"' % self.node_template.name) ExceptionCollector.appendException( UnknownFieldError(what=what, field=i)) else: self.implementation = value
def _get_capability_property(self, node_template, capability_name, property_name): """Gets a node template capability property.""" caps = node_template.get_capabilities() if caps and capability_name in caps.keys(): cap = caps[capability_name] property = None props = cap.get_properties() if props and property_name in props.keys(): property = props[property_name].value if not property: ExceptionCollector.appendException( KeyError(_('Property "%(prop)s" was not found in ' 'capability "%(cap)s" of node template ' '"%(ntpl1)s" referenced from node template ' '"%(ntpl2)s".') % {'prop': property_name, 'cap': capability_name, 'ntpl1': node_template.name, 'ntpl2': self.context.name})) return property msg = _('Requirement/Capability "{0}" referenced from node template ' '"{1}" was not found in node template "{2}".').format( capability_name, self.context.name, node_template.name) ExceptionCollector.appendException(KeyError(msg))
def validate_range(range): # list class check validate_list(range) # validate range list has a min and max if len(range) != 2: ExceptionCollector.appendException( ValueError(_('"%s" is not a valid range.') % range)) # validate min and max are numerics or the keyword UNBOUNDED min_test = max_test = False if not range[0] == RANGE_UNBOUNDED: min = validate_numeric(range[0]) else: min_test = True if not range[1] == RANGE_UNBOUNDED: max = validate_numeric(range[1]) else: max_test = True # validate the max > min (account for UNBOUNDED) if not min_test and not max_test: # Note: min == max is allowed if min > max: ExceptionCollector.appendException( ValueError(_('"%s" is not a valid range.') % range)) return range
def _common_validate_properties(self, entitytype, properties): allowed_props = [] required_props = [] for p in entitytype.get_properties_def_objects(): allowed_props.append(p.name) if p.required: required_props.append(p.name) if properties: self._common_validate_field(properties, allowed_props, 'properties') # make sure it's not missing any property required by a tosca type missingprop = [] for r in required_props: if r not in properties.keys(): missingprop.append(r) if missingprop: ExceptionCollector.appendException( MissingRequiredFieldError( what='"properties" of template "%s"' % self.name, required=missingprop)) else: if required_props: ExceptionCollector.appendException( MissingRequiredFieldError( what='"properties" of template "%s"' % self.name, required=missingprop))
def _validate_and_load_imports(self): imports_names = set() if not self.importslist: msg = _('"imports" keyname is defined without including ' 'templates.') log.error(msg) ExceptionCollector.appendException(ValidationError(message=msg)) return for import_def in self.importslist: if isinstance(import_def, dict): for import_name, import_uri in import_def.items(): if import_name in imports_names: msg = (_('Duplicate import name "%s" was found.') % import_name) log.error(msg) ExceptionCollector.appendException( ValidationError(message=msg)) imports_names.add(import_name) custom_type = self._load_import_template(import_name, import_uri) namespace_prefix = None if isinstance(import_uri, dict): namespace_prefix = import_uri.get( self.NAMESPACE_PREFIX) self._update_custom_def(custom_type, namespace_prefix) else: # old style of imports custom_type = self._load_import_template(None, import_def) if custom_type: self._update_custom_def(custom_type, None)
def __init__(self, property_name, property_type, constraint): super(GreaterThan, self).__init__(property_name, property_type, constraint) if not isinstance(constraint[self.GREATER_THAN], self.valid_types): ExceptionCollector.appendException( InvalidSchemaError(message=_('The property "greater_than" ' 'expects comparable values.')))
def _validate_keys(self): """validate the keys of substitution mappings.""" for key in self.sub_mapping_def.keys(): if key not in self.SECTIONS: ExceptionCollector.appendException( UnknownFieldError(what='SubstitutionMappings', field=key))
def __init__(self, property_name, property_type, constraint): super(LessOrEqual, self).__init__(property_name, property_type, constraint) if not isinstance(self.constraint_value, self.valid_types): ExceptionCollector.appendException( InvalidSchemaError(message=_('The property "less_or_equal" ' 'expects comparable values.')))
def validate_additional_req(properties, prop_name, custom_def=None, ): try: source = properties.get(PortSpec.SOURCE) source_range = properties.get(PortSpec.SOURCE_RANGE) target = properties.get(PortSpec.TARGET) target_range = properties.get(PortSpec.TARGET_RANGE) # verify one of the specified values is set if source is None and source_range is None and \ target is None and target_range is None: ExceptionCollector.appendException( InvalidTypeAdditionalRequirementsError( type=PortSpec.TYPE_URI)) # Validate source value is in specified range if source and source_range: validateutils.validate_value_in_range(source, source_range, PortSpec.SOURCE) else: from toscaparser.dataentity import DataEntity portdef = DataEntity('PortDef', source, None, PortSpec.SOURCE) portdef.validate() # Validate target value is in specified range if target and target_range: validateutils.validate_value_in_range(target, target_range, PortSpec.TARGET) else: from toscaparser.dataentity import DataEntity portdef = DataEntity('PortDef', source, None, PortSpec.TARGET) portdef.validate() except Exception: msg = _('"%(value)s" do not meet requirements ' 'for type "%(type)s".') \ % {'value': properties, 'type': PortSpec.SHORTNAME} ExceptionCollector.appendException( ValueError(msg))
def _validate_requirements_keys(self, requirement): for key in requirement.keys(): if key not in self.REQUIREMENTS_SECTION: ExceptionCollector.appendException( UnknownFieldError( what='"requirements" of template "%s"' % self.name, field=key))
def _get_capability_attribute(self, node_template, capability_name, attr_name): """Gets a node template capability attribute.""" caps = node_template.get_capabilities() if caps and capability_name in caps.keys(): cap = caps[capability_name] attribute = None attrs = cap.definition.get_attributes_def() if attrs and attr_name in attrs.keys(): attribute = attrs[attr_name] if not attribute: ExceptionCollector.appendException( KeyError(_('Attribute "%(attr)s" was not found in ' 'capability "%(cap)s" of node template ' '"%(ntpl1)s" referenced from node template ' '"%(ntpl2)s".') % {'attr': attr_name, 'cap': capability_name, 'ntpl1': node_template.name, 'ntpl2': self.context.name})) return attribute msg = _('Requirement/Capability "{0}" referenced from node template ' '"{1}" was not found in node template "{2}".').format( capability_name, self.context.name, node_template.name) ExceptionCollector.appendException(KeyError(msg))
def __init__(self, property_name, property_type, constraint): super(ValidValues, self).__init__(property_name, property_type, constraint) if not isinstance(self.constraint_value, collections.Sequence): ExceptionCollector.appendException( InvalidSchemaError(message=_('The property "valid_values" ' 'expects a list.')))
def _validate_keys(self): if self.defs: for key in self.defs.keys(): if key not in self.SECTIONS: ExceptionCollector.appendException( UnknownFieldError(what='Nodetype"%s"' % self.ntype, field=key))
def _validate_capabilities_properties(self, capabilities): for cap, props in capabilities.items(): capability = self.get_capability(cap) if not capability: continue capabilitydef = capability.definition self._common_validate_properties(capabilitydef, props[self.PROPERTIES]) # validating capability properties values for prop in self.get_capability(cap).get_properties_objects(): prop.validate() # TODO(srinivas_tadepalli): temporary work around to validate # default_instances until standardized in specification if cap == "scalable" and prop.name == "default_instances": prop_dict = props[self.PROPERTIES] min_instances = prop_dict.get("min_instances") max_instances = prop_dict.get("max_instances") default_instances = prop_dict.get("default_instances") if not (min_instances <= default_instances <= max_instances): err_msg = ('"properties" of template "%s": ' '"default_instances" value is not between ' '"min_instances" and "max_instances".' % self.name) ExceptionCollector.appendException( ValidationError(message=err_msg))
def validate(self): if len(self.args) != 2: ExceptionCollector.appendException( ValueError(_('Illegal arguments for function "{0}". Expected ' 'arguments: "node-template-name", ' '"attribute-name"').format(GET_ATTRIBUTE))) self._find_node_template_containing_attribute()
def _validate_occurrences(self, occurrences): DataEntity.validate_datatype('list', occurrences) for value in occurrences: DataEntity.validate_datatype('integer', value) if len(occurrences) != 2 or not (0 <= occurrences[0] <= occurrences[1]) \ or occurrences[1] == 0: ExceptionCollector.appendException( InvalidPropertyValueError(what=(occurrences)))
def _find_interface_name(self, interface_name): if interface_name in toscaparser.elements.interfaces.SECTIONS: return interface_name else: ExceptionCollector.appendException( ValueError(_('Enter a valid interface name' ).format(GET_OPERATION_OUTPUT))) return
def validate(self, value): self.value_msg = value if self.property_type in scalarunit.ScalarUnit.SCALAR_UNIT_TYPES: value = scalarunit.get_scalarunit_value(self.property_type, value) if not self._is_valid(value): err_msg = self._err_msg(value) ExceptionCollector.appendException( ValidationError(message=err_msg))
def _common_validate_field(self, schema, allowedlist, section): for name in schema: if name not in allowedlist: ExceptionCollector.appendException( UnknownFieldError( what=('"%(section)s" of template "%(nodename)s"' % {'section': section, 'nodename': self.name}), field=name))
def validate(self): if len(self.args) != 1: ExceptionCollector.appendException( ValueError(_('Expected one argument for function "get_input" but ' 'received "%s".') % self.args) ) inputs = [input.name for input in self.tosca_tpl.inputs] if self.args[0] not in inputs: ExceptionCollector.appendException(UnknownInputError(input_name=self.args[0]))
def _validate_field(self, template): if not isinstance(template, dict): ExceptionCollector.appendException( MissingRequiredFieldError(what='Template "%s"' % self.name, required=self.TYPE)) try: relationship = template.get('relationship') if relationship and not isinstance(relationship, str): relationship[self.TYPE] elif isinstance(relationship, str): template['relationship'] else: template[self.TYPE] except KeyError: ExceptionCollector.appendException( MissingRequiredFieldError(what='Template "%s"' % self.name, required=self.TYPE))
def _validate_import_keys(self, import_name, import_uri_def): if self.FILE not in import_uri_def.keys(): log.warning('Missing keyname "file" in import "%(name)s".' % {'name': import_name}) ExceptionCollector.appendException( MissingRequiredFieldError( what='Import of template "%s"' % import_name, required=self.FILE)) for key in import_uri_def.keys(): if key not in self.IMPORTS_SECTION: log.warning('Unknown keyname "%(key)s" error in ' 'imported definition "%(def)s".' % {'key': key, 'def': import_name}) ExceptionCollector.appendException( UnknownFieldError( what='Import of template "%s"' % import_name, field=key))
def validate_timestamp(value): try: # Note: we must return our own exception message # as dateutil's parser returns different types / values on # different systems. OSX, for example, returns a tuple # containing a different error message than Linux dateutil.parser.parse(value) except Exception as e: original_err_msg = str(e) log.error(original_err_msg) ExceptionCollector.appendException( ValueError( _('"%(val)s" is not a valid timestamp. "%(msg)s"') % { 'val': value, 'msg': original_err_msg })) return
def validate_implementation(self): if isinstance(self.implementation, dict): for key, value in self.implementation.items(): if key == PRIMARY: self.validate_inline_artifact(value) elif key == DEPENDENCIES: if not isinstance(value, list): ExceptionCollector.appendException( ValidationError(message=self._msg)) else: for artifact in value: self.validate_inline_artifact(artifact) elif key not in IMPLEMENTATION_DEF_RESERVED_WORDS: ExceptionCollector.appendException( UnknownFieldError(what="implementation in " + self._msg, field=key))
def _read_template_yaml(self, template): data = self.zfile.read(template) invalid_tosca_yaml_err_msg = ( _('The file "%(template)s" in the CSAR "%(csar)s" does not ' 'contain valid YAML content.') % {'template': template, 'csar': self.path}) try: tosca_yaml = yaml.safe_load(data) if type(tosca_yaml) is not dict: ExceptionCollector.appendException( ValidationError(message=invalid_tosca_yaml_err_msg)) return None return tosca_yaml except Exception: ExceptionCollector.appendException( ValidationError(message=invalid_tosca_yaml_err_msg)) return None
def __init__(self, version): self.version = str(version) match = self.VERSION_RE.match(self.version) if not match: ExceptionCollector.appendException( InvalidTOSCAVersionPropertyException(what=(self.version))) return ver = match.groupdict() if self.version in ['0', '0.0', '0.0.0']: log.warning('Version assumed as not provided') self.version = None self.minor_version = ver['minor_version'] self.major_version = ver['major_version'] self.fix_version = ver['fix_version'] self.qualifier = self._validate_qualifier(ver['qualifier']) self.build_version = self._validate_build(ver['build_version']) self._validate_major_version(self.major_version)
def __init__(self, name, schema_dict): self.name = name if not isinstance(schema_dict, collections.Mapping): msg = (_('Schema definition of "%(pname)s" must be a dict.') % dict(pname=name)) ExceptionCollector.appendException(InvalidSchemaError(message=msg)) try: schema_dict['type'] except KeyError: msg = (_('Schema definition of "%(pname)s" must have a "type" ' 'attribute.') % dict(pname=name)) ExceptionCollector.appendException(InvalidSchemaError(message=msg)) self.schema = schema_dict self._len = None self.constraints_list = []
def generate_artifacts(new_artifacts, directory): """ From the info of new artifacts generate files which execute :param new_artifacts: list of dicts containing (value, source, parameters, executor, name, configuration_tool) :return: None """ r_artifacts = [] for art in new_artifacts: filename = os.path.join(directory, art[NAME]) configuration_class = get_configuration_tool_class(art[EXECUTOR])() if not configuration_class: ExceptionCollector.appendException( UnsupportedExecutorType(what=art[EXECUTOR])) configuration_class.create_artifact(filename, art) r_artifacts.append(filename) return r_artifacts
def __new__(cls, property_name=None, property_type=None, constraint=None): if cls is not Constraint: return super(Constraint, cls).__new__(cls) if (not isinstance(constraint, collections.Mapping) or len(constraint) != 1): ExceptionCollector.appendException( InvalidSchemaError(message=_('Invalid constraint schema.'))) for type in constraint.keys(): ConstraintClass = get_constraint_class(type) if not ConstraintClass: msg = _('Invalid property "%s".') % type ExceptionCollector.appendException( InvalidSchemaError(message=msg)) return ConstraintClass(property_name, property_type, constraint)
def __init__(self, name, template, entity_name, custom_def=None): self.name = name self.entity_tpl = template self.custom_def = custom_def self._validate_field(self.entity_tpl) type = self.entity_tpl.get('type') UnsupportedType.validate_type(type) if '__typename' not in template: self._validate_fields(template) if entity_name == 'node_type': self.type_definition = NodeType(type, custom_def) \ if type is not None else None self._validate_directives(self.entity_tpl) if entity_name == 'relationship_type': self.type_definition = RelationshipType(type, custom_def) if entity_name == 'policy_type': if not type: msg = (_('Policy definition of "%(pname)s" must have' ' a "type" ' 'attribute.') % dict(pname=name)) ExceptionCollector.appendException( ValidationError(message=msg)) self.type_definition = PolicyType(type, custom_def) if entity_name == 'group_type': self.type_definition = GroupType(type, custom_def) \ if type is not None else None if entity_name == 'artifact_type': self.type_definition = ArtifactTypeDef(type, custom_def) \ if type is not None else None self._properties = None self._interfaces = None self._requirements = None self._capabilities = None if not self.type_definition: msg = "no type found %s for %s" % (entity_name, template) ExceptionCollector.appendException(ValidationError(message=msg)) return metadata = self.type_definition.get_definition('metadata') if metadata and 'additionalProperties' in metadata: self.additionalProperties = metadata['additionalProperties'] self._properties_tpl = self._validate_properties() for prop in self.get_properties_objects(): prop.validate() self._validate_interfaces()
def _common_validate_field(self, schema, allowedlist, section): if schema is None: ExceptionCollector.appendException( ValidationError(message=( 'Missing value for "%s". Must contain one of: "%s"' % (section, ", ".join(allowedlist))))) else: for name in schema: if name not in allowedlist: ExceptionCollector.appendException( UnknownFieldError( what=('"%(section)s" of template "%(nodename)s"' % { 'section': section, 'nodename': self.name }), field=name))
def _find_node_template(self, node_template_name): if node_template_name == HOST: # Currently this is the only way to tell whether the function # is used within the outputs section of the TOSCA template. if isinstance(self.context, list): ExceptionCollector.appendException( ValueError(_( '"get_attribute: [ HOST, ... ]" is not allowed in ' '"outputs" section of the TOSCA template.'))) return node_tpl = self._find_host_containing_attribute() if not node_tpl: ExceptionCollector.appendException( ValueError(_( '"get_attribute: [ HOST, ... ]" was used in node ' 'template "{0}" but "{1}" was not found in ' 'the relationship chain.').format(self.context.name, HOSTED_ON))) return return node_tpl if node_template_name == TARGET: if not isinstance(self.context.type_definition, RelationshipType): ExceptionCollector.appendException( KeyError(_('"TARGET" keyword can only be used in context' ' to "Relationships" target node'))) return return self.context.target if node_template_name == SOURCE: if not isinstance(self.context.type_definition, RelationshipType): ExceptionCollector.appendException( KeyError(_('"SOURCE" keyword can only be used in context' ' to "Relationships" source node'))) return return self.context.source name = self.context.name \ if node_template_name == SELF and \ not isinstance(self.context, list) \ else node_template_name for node_template in self.tosca_tpl.nodetemplates: if node_template.name == name: return node_template ExceptionCollector.appendException( KeyError(_( 'Node template "{0}" was not found.' ).format(node_template_name)))
def __init__(self, tosca_parser_template, provider, cluster_name): self.provider = provider self.provider_config = ProviderConfiguration(self.provider) self.cluster_name = cluster_name ExceptionCollector.start() for sec in self.REQUIRED_CONFIG_PARAMS: if not self.provider_config.config[ self.provider_config.MAIN_SECTION].get(sec): ExceptionCollector.appendException( ProviderConfigurationParameterError(what=sec)) ExceptionCollector.stop() if ExceptionCollector.exceptionsCaught(): raise ValidationError( message='\nTranslating to provider failed: '.join( ExceptionCollector.getExceptionsReport())) # toscaparser.tosca_template:ToscaTemplate self.tosca_parser_template = tosca_parser_template # toscaparser.topology_template:TopologyTemplate self.tosca_topology_template = tosca_parser_template.topology_template import_definition_file = ImportsLoader( [self.definition_file()], None, list(SERVICE_TEMPLATE_KEYS), self.tosca_topology_template.tpl) self.full_provider_defs = copy.copy( self.tosca_topology_template.custom_defs) self.provider_defs = import_definition_file.get_custom_defs() self.full_provider_defs.update(self.provider_defs) self.artifacts = [] self.used_conditions_set = set() self.extra_configuration_tool_params = dict() self.topology_template = self.translate_to_provider() self.node_templates = self.topology_template.nodetemplates self.relationship_templates = self.topology_template.relationship_templates self.template_dependencies = dict() # list of lists # After this step self.node_templates has requirements with node_filter parameter self.resolve_in_template_dependencies() self.resolve_in_template_get_functions() self.configuration_content = None self.configuration_ready = None # Create the list of ProviderResource instances self.provider_nodes = self._provider_nodes() self.provider_nodes_by_name = self._provider_nodes_by_name() self.relationship_templates_by_name = self._relationship_templates_by_name( ) self.provider_node_names_by_priority = self._sort_nodes_by_priority() self.provider_nodes_queue = self.sort_nodes_by_dependency()
def __init__(self, importslist, path, type_definition_list=None, tpl=None): self.importslist = importslist self.custom_defs = {} if not path and not tpl: msg = _('Input tosca template is not provided.') log.warning(msg) ExceptionCollector.appendException(ValidationError(message=msg)) self.path = path self.repositories = {} if tpl and tpl.get('repositories'): self.repositories = tpl.get('repositories') self.type_definition_list = [] if type_definition_list: if isinstance(type_definition_list, list): self.type_definition_list = type_definition_list else: self.type_definition_list.append(type_definition_list) self._validate_and_load_imports()
def __init__(self, name, value=None, schema=None): self.name = name self.value = value self.schema = schema self._status = self.PROPERTY_STATUS_DEFAULT self._required = self.PROPERTY_REQUIRED_DEFAULT # Validate required 'type' property exists try: self.schema['type'] except KeyError: msg = (_('Schema definition of "%(pname)s" must have a "type" ' 'attribute.') % dict(pname=self.name)) ExceptionCollector.appendException(InvalidSchemaError(message=msg)) if self.schema: self._load_required_attr_from_schema() self._load_status_attr_from_schema()
def _validate_type_keys(self, custom_type): version = custom_type[self.DEFINITION_VERSION] \ if self.DEFINITION_VERSION in custom_type \ else None if version: self._validate_type_version(version) self.version = version for name in custom_type: if name in self.ALLOWED_TYPE_SECTIONS: pass elif version and version in self.exttools.get_sections() and \ name in self.exttools.get_sections()[version]: pass else: ExceptionCollector.appendException( UnknownFieldError(what='Template ' + str(self.import_def), field=name))
def load_and_validate(self, val, reposit_def): self.keyname = val if isinstance(reposit_def, dict): for key in reposit_def.keys(): if key not in SECTIONS: ExceptionCollector.appendException( UnknownFieldError(what=_('repositories "%s"') % self.keyname, field=key)) if URL in reposit_def.keys(): reposit_url = reposit_def.get(URL) url_val = toscaparser.utils.urlutils.UrlUtils.\ validate_url(reposit_url) if url_val is not True: ExceptionCollector.appendException( URLException(what=_('repsositories "%s" Invalid Url') % self.keyname))
def process_req(req): log.debug("Node requirements: {}".format(req)) if tpls_requirements: keys = [] if isinstance(tpls_requirements, list): for tp in tpls_requirements: keys.extend(list(tp.keys())) else: keys = list(tpls_requirements.keys()) log.debug("Tpl keys: {}".format(keys)) for req_key in req.keys(): if req_key in keys: pass else: log.info("Unknown field Subs: {}".format(req)) ExceptionCollector.appendException( UnknownFieldError(what='SubstitutionMappings', field=req))
def _validate_and_load_imports(self): imports_names = set() if not self.importslist: msg = _('"imports" keyname is defined without including ' "templates.") log.error(msg) ExceptionCollector.appendException(ValidationError(message=msg)) return for import_def in self.importslist: if isinstance(import_def, dict): if len(import_def) == 1 and "file" not in import_def: # old style {name: uri} import_name, import_uri = list(import_def.items())[0] if import_name in imports_names: msg = _('Duplicate import name "%s" was found.') % import_name log.error(msg) ExceptionCollector.appendException(ValidationError(message=msg)) imports_names.add(import_name) else: # new style {"file": uri} import_name = None import_uri = import_def else: # import_def is just the uri string import_name = None import_uri = import_def full_file_name, imported_tpl = self._load_import_template( import_name, import_uri ) if full_file_name is None: return namespace_prefix = None if isinstance(import_uri, dict): namespace_prefix = import_uri.get(self.NAMESPACE_PREFIX) if imported_tpl: TypeValidation(imported_tpl, import_def) self._update_custom_def(imported_tpl, namespace_prefix, full_file_name) nested_imports = imported_tpl.get("imports") if nested_imports: self.nested_imports.update({full_file_name: nested_imports}) # XXX should save prefix too self._update_nested_tosca_tpls(full_file_name, imported_tpl)
def _get_index_value(self, value, index): if isinstance(value, list): if index < len(value): return value[index] else: ExceptionCollector.appendException( KeyError( _("Property '{0}' found in capability '{1}'" " referenced from node template {2}" " must have an element with index {3}.").format( self.args[2], self.args[1], self.context.name, index))) else: ExceptionCollector.appendException( KeyError( _("Property '{0}' found in capability '{1}'" " referenced from node template {2}" " must be a list.").format(self.args[2], self.args[1], self.context.name)))
def get_all_requirements(self): requires = self.requirements parent_node = self.parent_type if requires is None: requires = self.get_value(self.REQUIREMENTS, None, True) if parent_node is None: ExceptionCollector.appendException( ValidationError(message="parent_node is " + str(parent_node))) else: parent_node = parent_node.parent_type if parent_node: while parent_node.type != 'tosca.nodes.Root': req = parent_node.get_value(self.REQUIREMENTS, None, True) for r in req: if r not in requires: requires.append(r) parent_node = parent_node.parent_type return requires
def _get_attribute_value(self, value, attibute): if isinstance(value, dict): if attibute in value: return value[attibute] else: ExceptionCollector.appendException( KeyError( _("Property '{0}' found in capability '{1}'" " referenced from node template {2}" " must have an attribute named {3}.").format( self.args[2], self.args[1], self.context.name, attibute))) else: ExceptionCollector.appendException( KeyError( _("Property '{0}' found in capability '{1}'" " referenced from node template {2}" " must be a dict.").format(self.args[2], self.args[1], self.context.name)))
def get_main_template_yaml(self): main_template = self.get_main_template() if main_template: data = self.zfile.read(main_template) invalid_tosca_yaml_err_msg = ( _('The file "%(template)s" in the CSAR "%(csar)s" does not ' 'contain valid TOSCA YAML content.') % { 'template': main_template, 'csar': self.path }) try: tosca_yaml = yaml.load(data) if type(tosca_yaml) is not dict: ExceptionCollector.appendException( ValidationError(message=invalid_tosca_yaml_err_msg)) return tosca_yaml except Exception: ExceptionCollector.appendException( ValidationError(message=invalid_tosca_yaml_err_msg))
def _find_matches(): ExceptionCollector.start() # clears previous errors for expression, _tpl in overlays.items(): try: match = Ref(expression).resolve_one( RefContext(self.topology, trace=0)) if not match: continue if isinstance(match, (list, ResultsList)): for item in match: yield (item, _tpl) else: yield (match, _tpl) except: ExceptionCollector.appendException( UnfurlValidationError( f'error evaluating decorator match expression "{expression}"', log=True, ))
def add_relationship(self, reqSpec): # find the relationship for this requirement: for relSpec in self._get_relationship_specs(): # the RelationshipTemplate should have had the source node assigned by the tosca parser # XXX this won't distinguish between more than one relationship between the same two nodes # to fix this have the RelationshipTemplate remember the name of the requirement if (relSpec.toscaEntityTemplate.source.name == reqSpec.parentNode.toscaEntityTemplate.name): assert not reqSpec.relationship or reqSpec.relationship is relSpec, ( reqSpec.relationship, relSpec) reqSpec.relationship = relSpec assert not relSpec.requirement or relSpec.requirement is reqSpec, ( relSpec.requirement, reqSpec) if not relSpec.requirement: relSpec.requirement = reqSpec break else: msg = f'relationship not found for requirement "{reqSpec.name}" on "{reqSpec.parentNode}" targeting "{self.name}"' ExceptionCollector.appendException(UnfurlValidationError(msg))
def _validate_and_load_imports(self): imports_names = set() if not self.importslist: msg = _('"imports" keyname is defined without including ' 'templates.') log.error(msg) ExceptionCollector.appendException(ValidationError(message=msg)) return for import_def in self.importslist: if isinstance(import_def, dict): for import_name, import_uri in import_def.items(): if import_name in imports_names: msg = (_('Duplicate import name "%s" was found.') % import_name) log.error(msg) ExceptionCollector.appendException( ValidationError(message=msg)) imports_names.add(import_name) full_file_name, custom_type = self._load_import_template( import_name, import_uri) namespace_prefix = None if isinstance(import_uri, dict): namespace_prefix = import_uri.get( self.NAMESPACE_PREFIX) if custom_type: TypeValidation(custom_type, import_def) self._update_custom_def(custom_type, namespace_prefix) else: # old style of imports full_file_name, custom_type = self._load_import_template( None, import_def) if custom_type: TypeValidation( custom_type, import_def) self._update_custom_def(custom_type, None) if custom_type and 'imports' in custom_type.keys(): self.nested_imports.update( {full_file_name: custom_type['imports']}) self._update_nested_tosca_tpls(full_file_name, custom_type)
def translate(template_file, validate_only, provider, configuration_tool, cluster_name='', is_delete=False, a_file=True, extra=None): if a_file: template_file = os.path.join(os.getcwd(), template_file) with open(template_file, 'r') as f: template_content = f.read() else: template_content = template_file template = yaml_parse(template_content) default_import_file = os.path.join(utils.get_project_root_path(), TOSCA_DEFINITION_FILE) if not template.get(IMPORTS): template[IMPORTS] = [default_import_file] else: for i in range(len(template[IMPORTS])): template[IMPORTS][i] = os.path.abspath(template[IMPORTS][i]) template[IMPORTS].append(default_import_file) tosca_parser_template_object = ToscaTemplate(yaml_dict_tpl=template, a_file=a_file) if validate_only: msg = 'The input "%(template_file)s" successfully passed validation.' \ % {'template_file': template_file if a_file else 'template'} return msg if not provider: ExceptionCollector.appendException( UnspecifiedParameter(what=('validate-only', 'provider'))) tosca = ProviderToscaTemplate(tosca_parser_template_object, provider, cluster_name) return tosca.to_configuration_dsl(configuration_tool, is_delete, extra=extra)
def __init__(self, node_type, interfacetype, node_template=None, name=None, value=None): self.ntype = node_type self.node_template = node_template self.type = interfacetype self.name = name self.value = value self.implementation = None self.inputs = None self.defs = {} if interfacetype == LIFECYCLE_SHORTNAME: interfacetype = LIFECYCLE if interfacetype == CONFIGURE_SHORTNAME: interfacetype = CONFIGURE if hasattr(self.ntype, 'interfaces') \ and self.ntype.interfaces \ and interfacetype in self.ntype.interfaces: interfacetype = self.ntype.interfaces[interfacetype]['type'] if node_type: if self.node_template and self.node_template.custom_def \ and interfacetype in self.node_template.custom_def: self.defs = self.node_template.custom_def[interfacetype] else: self.defs = self.TOSCA_DEF[interfacetype] if value: if isinstance(self.value, dict): for i, j in self.value.items(): if i == IMPLEMENTATION: self.implementation = j elif i == INPUTS: self.inputs = j else: what = ('"interfaces" of template "%s"' % self.node_template.name) ExceptionCollector.appendException( UnknownFieldError(what=what, field=i)) else: self.implementation = value
def validate(self): if len(self.args) < 2: ExceptionCollector.appendException( ValueError(_('Illegal arguments for function "{0}". Expected ' 'arguments: "node-template-name", "req-or-cap"' '(optional), "property name"' ).format(GET_ATTRIBUTE))) return elif len(self.args) >= 2: node_tpl = self._find_node_template(self.args[0]) if node_tpl is None: return # TODO: Check additonal args in get_artifact self.artifact = self._artifact_in_node(node_tpl) if self.artifact is None: ExceptionCollector.appendException( KeyError(_('Artifact "%(att)s" was not found in node ' 'template "%(ntpl)s".') % {'att': self.args[1], 'ntpl': node_tpl.name}))
def __init__(self, entitytype, prefix, custom_def=None): entire_entitytype = entitytype if UnsupportedType.validate_type(entire_entitytype): self.defs = None else: if entitytype.startswith(self.TOSCA + ":"): entitytype = entitytype[(len(self.TOSCA) + 1):] entire_entitytype = prefix + entitytype if not entitytype.startswith(self.TOSCA): entire_entitytype = prefix + entitytype if custom_def and entitytype in list(custom_def.keys()): self.defs = custom_def[entitytype] elif entire_entitytype in list(self.TOSCA_DEF.keys()): self.defs = self.TOSCA_DEF[entire_entitytype] entitytype = entire_entitytype else: self.defs = None ExceptionCollector.appendException( InvalidTypeError(what=entitytype)) self.type = entitytype