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: raise InvalidPropertyValueError(what=(occurrences))
def test_built_in_datatype(self): value_snippet = ''' private_network: network_name: private network_id: 3e54214f-5c09-1bc9-9999-44100326da1b addresses: [ 10.111.128.10 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.NetworkInfo', value.get('private_network')) self.assertIsNotNone(data.validate()) value_snippet = ''' portspec_valid: protocol: tcp ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.PortSpec', value.get('portspec_valid')) self.assertIsNotNone(data.validate()) value_snippet = ''' portspec_invalid: protocol: xyz ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.PortSpec', value.get('portspec_invalid')) err = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual(_('The value "xyz" of property "protocol" is not ' 'valid. Expected a value from "[udp, tcp, igmp]".' ), err.__str__())
def test_range_unbounded(self): value_snippet = ''' temperature: [-100, 999999] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
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 _translate_inputs(self): hot_inputs = [] hot_default = None for input in self.inputs: hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type] if input.name in self.parsed_params: input_type = hot_input_type if input.type == "scalar-unit.size": input_type = input.type DataEntity.validate_datatype(input_type, self.parsed_params[input.name]) hot_default = self.parsed_params[input.name] elif input.default is not None: hot_default = input.default else: log.warning(_("Need to specify a value " "for input {0}").format(input.name)) raise Exception(_("Need to specify a value " "for input {0}").format(input.name)) if input.type == "scalar-unit.size": # Assumption here is to use this scalar-unit.size for size of # cinder volume in heat templates and will be in GB. # should add logic to support other types if needed. input_value = hot_default hot_default = (ScalarUnit_Size(hot_default). get_num_from_scalar_unit('GiB')) if hot_default == 0: log.warning(_('Unit value should be > 0.')) raise Exception(_( 'Unit value should be > 0.')) elif int(hot_default) < hot_default: hot_default = int(hot_default) + 1 log.warning(_("Cinder unit value should be in multiples" " of GBs. So corrected %(input_value)s " "to %(hot_default)s GB.") % {'input_value': input_value, 'hot_default': hot_default}) if input.type == 'version': hot_default = TOSCAVersionProperty(hot_default).get_version() hot_constraints = [] if input.constraints: for constraint in input.constraints: constraint.validate( int(hot_default) if hot_input_type == "number" else hot_default) hc, hvalue = self._translate_constraints( constraint.constraint_key, constraint.constraint_value) hot_constraints.append({hc: hvalue}) hot_inputs.append(HotParameter(name=input.name, type=hot_input_type, description=input.description, default=hot_default, constraints=hot_constraints)) return hot_inputs
def test_default_field_in_dataentity(self): value_snippet = ''' name: Mike ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) data = data.validate() self.assertEqual('unknown', data.get('gender'))
def test_custom_datatype(self): value_snippet = ''' name: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
def test_built_in_datatype_without_properties(self): value_snippet = ''' 2 ''' value = yamlparser.simple_parse(value_snippet) datatype = DataType('PortDef') self.assertEqual('integer', datatype.value_type) data = DataEntity('PortDef', value) self.assertIsNotNone(data.validate())
def _validate_value(self, value): tosca = EntityType.TOSCA_DEF datatype = None if self.type in tosca: datatype = tosca[self.type] elif EntityType.DATATYPE_NETWORK_PREFIX + self.type in tosca: datatype = tosca[EntityType.DATATYPE_NETWORK_PREFIX + self.type] DataEntity.validate_datatype(self.type, value, None, datatype)
def test_valid_range_type(self): value_snippet = ''' user_port: protocol: tcp target_range: [20000, 60000] source_range: [1000, 3000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) self.assertIsNotNone(data.validate())
def test_built_in_nested_datatype(self): value_snippet = ''' user_port: protocol: tcp target: [50000] source: [9000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) self.assertIsNotNone(data.validate())
def test_functions_datatype(self): value_snippet = ''' admin_credential: user: username token: { get_input: password } ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.Credential', value.get('admin_credential')) self.assertIsNotNone(data.validate())
def test_built_in_datatype(self): value_snippet = ''' private_network: network_name: private network_id: 3e54214f-5c09-1bc9-9999-44100326da1b addresses: [ 10.111.128.10 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.NetworkInfo', value.get('private_network')) self.assertIsNotNone(data.validate())
def test_built_in_datatype_with_short_name(self): value_snippet = ''' ethernet_port: port_name: port1 port_id: 2c0c7a37-691a-23a6-7709-2d10ad041467 network_id: 3e54214f-5c09-1bc9-9999-44100326da1b mac_address: f1:18:3b:41:92:1e addresses: [ 172.24.9.102 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortInfo', value.get('ethernet_port')) self.assertIsNotNone(data.validate())
def test_range_unbounded(self): value_snippet = ''' humidity: [-100, 100] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.InvalidSchemaError, lambda: data.validate()) self.assertEqual(_('The property "in_range" expects comparable values.' ), err.__str__())
def test_port_spec_addl_reqs(self): value_snippet = ''' test_port: protocol: tcp target: 65535 target_range: [ 1, 65535 ] source: 1 source_range: [ 1, 65535 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.PortSpec', value.get('test_port')) self.assertIsNotNone(data.validate())
def test_custom_datatype_with_parent(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_phone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
def result(self): if self.tosca_tpl.parsed_params and self.input_name in self.tosca_tpl.parsed_params: return DataEntity.validate_datatype( self.tosca_tpl.tpl["inputs"][self.input_name]["type"], self.tosca_tpl.parsed_params[self.input_name] ) input = [input_def for input_def in self.tosca_tpl.inputs if self.input_name == input_def.name][0] return input.default
def validate(self): '''Validate if not a reference property.''' if not is_function(self.value): if self.type == Schema.STRING: self.value = str(self.value) self.value = DataEntity.validate_datatype(self.type, self.value, self.entry_schema, self.custom_def) self._validate_constraints()
def test_valid_ranges_against_constraints(self): # The TestLab range type has max=UNBOUNDED value_snippet = ''' temperature1: [-255, 999999] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate()) # The TestLab range type has min=UNBOUNDED value_snippet = ''' temperature2: [-999999, 255] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
def _groups(self): groups = [] member_nodes = None for group_name, group_tpl in self._tpl_groups().items(): member_names = group_tpl.get('members') if member_names is not None: DataEntity.validate_datatype('list', member_names) if len(member_names) < 1 or \ len(member_names) != len(set(member_names)): exception.ExceptionCollector.appendException( exception.InvalidGroupTargetException( message=_('Member nodes "%s" should be >= 1 ' 'and not repeated') % member_names)) else: member_nodes = self._get_group_members(member_names) group = Group(group_name, group_tpl, member_nodes, self.custom_defs) groups.append(group) return groups
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 test_invalid_range_datatype(self): value_snippet = ''' user_port: protocol: tcp target: 1 target_range: [20000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) err = self.assertRaises(ValueError, data.validate) self.assertEqual(_('"[20000]" is not a valid range.' ), err.__str__()) value_snippet = ''' user_port: protocol: tcp target: 1 target_range: [20000, 3000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) err = self.assertRaises(ValueError, data.validate) self.assertEqual(_('"[20000, 3000]" is not a valid range.' ), err.__str__()) value_snippet = ''' humidity: [-100, 100] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.InvalidSchemaError, lambda: data.validate()) self.assertEqual(_('The property "in_range" expects comparable values.' ), err.__str__())
def test_field_error_in_dataentity(self): value_snippet = ''' nema: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual( _('Data value of type ' '"tosca.my.datatypes.PeopleBase" contains unknown ' 'field "nema". Refer to the definition to verify ' 'valid values.'), error.__str__())
def test_invalid_ranges_against_constraints(self): # The TestLab range type has min=-256, max=UNBOUNDED value_snippet = ''' temperature1: [-257, 999999] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual( _('The value "-257" of property "temperature1" is ' 'out of range "(min:-256, max:UNBOUNDED)".'), err.__str__()) value_snippet = ''' temperature2: [-999999, 257] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual( _('The value "257" of property "temperature2" is ' 'out of range "(min:UNBOUNDED, max:256)".'), err.__str__())
def test_validation_in_nested_datatype(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_pone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual( _('Data value of type ' '"tosca.my.datatypes.ContactInfo" contains unknown ' 'field "contact_pone". Refer to the definition to ' 'verify valid values.'), error.__str__())
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 _translate_inputs(self): mano_inputs = [] if 'key_name' in self.parsed_params and 'key_name' not in self.inputs: name = 'key_name' type = 'string' default = self.parsed_params[name] schema_dict = {'type': type, 'default': default} input = Input(name, schema_dict) self.inputs.append(input) self.log.info(_('Translating TOSCA input type to MANO input type.')) for input in self.inputs: mano_default = None mano_input_type = TOSCA_TO_MANO_INPUT_TYPES[input.type] if input.name in self.parsed_params: mano_default = DataEntity.validate_datatype( input.type, self.parsed_params[input.name]) elif input.default is not None: mano_default = DataEntity.validate_datatype( input.type, input.default) else: if self.deploy: msg = _("Need to specify a value " "for input {0}.").format(input.name) self.log.error(msg) raise Exception(msg) if input.type == "scalar-unit.size": # Assumption here is to use this scalar-unit.size for size of # cinder volume in heat templates and will be in GB. # should add logic to support other types if needed. input_value = mano_default mano_default = (ScalarUnit_Size( mano_default).get_num_from_scalar_unit('GiB')) if mano_default == 0: msg = _('Unit value should be > 0.') self.log.error(msg) raise Exception(msg) elif int(mano_default) < mano_default: mano_default = int(mano_default) + 1 self.log.warning( _("Cinder unit value should be in" " multiples of GBs. So corrected" " %(input_value)s to %(mano_default)s" " GB.") % { 'input_value': input_value, 'mano_default': mano_default }) if input.type == 'version': mano_default = TOSCAVersionProperty(mano_default).get_version() mano_constraints = [] if input.constraints: for constraint in input.constraints: if mano_default: constraint.validate(mano_default) hc, hvalue = self._translate_constraints( constraint.constraint_key, constraint.constraint_value) mano_constraints.append({hc: hvalue}) mano_inputs.append( ManoParameter(self.log, name=input.name, type=mano_input_type, description=input.description, default=mano_default, constraints=mano_constraints)) return mano_inputs
def _translate_inputs(self): hot_inputs = [] if 'key_name' in self.parsed_params and 'key_name' not in self.inputs: name = 'key_name' type = 'string' default = self.parsed_params[name] schema_dict = {'type': type, 'default': default} input = Input(name, schema_dict) self.inputs.append(input) log.info(_('Translating TOSCA input type to HOT input type.')) for input in self.inputs: hot_default = None hot_input_type = TOSCA_TO_HOT_INPUT_TYPES[input.type] if input.name in self.parsed_params: hot_default = DataEntity.validate_datatype( input.type, self.parsed_params[input.name]) elif input.default is not None: hot_default = DataEntity.validate_datatype(input.type, input.default) else: if self.deploy: msg = _("Need to specify a value " "for input {0}.").format(input.name) log.error(msg) raise Exception(msg) if input.type == "scalar-unit.size": # Assumption here is to use this scalar-unit.size for size of # cinder volume in heat templates and will be in GB. # should add logic to support other types if needed. input_value = hot_default hot_default = (ScalarUnit_Size(hot_default). get_num_from_scalar_unit('GiB')) if hot_default == 0: msg = _('Unit value should be > 0.') log.error(msg) raise Exception(msg) elif int(hot_default) < hot_default: hot_default = int(hot_default) + 1 log.warning(_("Cinder unit value should be in multiples" " of GBs. So corrected %(input_value)s " "to %(hot_default)s GB.") % {'input_value': input_value, 'hot_default': hot_default}) if input.type == 'version': hot_default = TOSCAVersionProperty(hot_default).get_version() hot_constraints = [] if input.constraints: for constraint in input.constraints: if hot_default: constraint.validate(hot_default) hc, hvalue = self._translate_constraints( constraint.constraint_key, constraint.constraint_value) hot_constraints.append({hc: hvalue}) hot_inputs.append(HotParameter(name=input.name, type=hot_input_type, description=input.description, default=hot_default, constraints=hot_constraints)) return hot_inputs
def entry_schema_entity(self): if self._entry_schema_entity is None and self.entry_schema: self._entry_schema_entity = DataEntity(self.entry_schema['type'], None, self.custom_def, self.name) return self._entry_schema_entity