def validate(self): res = super(SaharaCluster, self).validate() if res: return res # check if running on neutron and MANAGEMENT_NETWORK missing if (self.is_using_neutron() and not self.properties[self.MANAGEMENT_NETWORK]): msg = _("%s must be provided") % self.MANAGEMENT_NETWORK raise exception.StackValidationFailed(message=msg) self.client_plugin().validate_hadoop_version( self.properties[self.PLUGIN_NAME], self.properties[self.HADOOP_VERSION])
def validate(self): '''Validate the template. Validates the top-level sections of the template as well as syntax inside select sections. Some sections are not checked here but in code parts that are responsible for working with the respective sections (e.g. parameters are check by parameters schema class). ''' # check top-level sections for k in self.t.keys(): if k not in self.SECTIONS: raise exception.InvalidTemplateSection(section=k) # check resources tmpl_resources = self[self.RESOURCES] if not tmpl_resources: LOG.warn( _('Template does not contain any resources, so ' 'the template would not really do anything when ' 'being instantiated.')) for res in tmpl_resources.values(): try: if not res.get('Type'): message = _('Every Resource object must ' 'contain a Type member.') raise exception.StackValidationFailed(message=message) except AttributeError: type_res = type(res) if isinstance(res, unicode): type_res = "string" message = _('Resources must contain Resource. ' 'Found a [%s] instead') % type_res raise exception.StackValidationFailed(message=message)
def validate(self): if self.validation_exception is not None: msg = six.text_type(self.validation_exception) raise exception.StackValidationFailed(message=msg) try: self.template_data() except ValueError as ex: msg = _("Failed to retrieve template data: %s") % ex raise exception.StackValidationFailed(message=msg) # If we're using an existing resource type as a facade for this # template, check for compatibility between the interfaces. try: fri = self.stack.env.get_resource_info(self.type(), resource_name=self.name, ignore=self.resource_info) except exception.EntityNotFound: pass else: facade_cls = fri.get_class(files=self.stack.t.files) self._validate_against_facade(facade_cls) return super(TemplateResource, self).validate()
def get_class(resource_type, resource_name=None, environment=None): '''Return the Resource class for a given resource type.''' if environment: resource_type = environment.get_resource_type(resource_type, resource_name) if resource_type.endswith(('.yaml', '.template')): cls = _template_class else: cls = _resource_classes.get(resource_type) if cls is None: msg = "Unknown resource Type : %s" % resource_type raise exception.StackValidationFailed(message=msg) else: return cls
def _validate_belonging_subnet_to_net(self, network): if network.get(self.NETWORK_PORT) is None and self.is_using_neutron(): net = self._get_network_id(network) # check if there are subnet and network both specified that # subnet belongs to specified network subnet = network.get(self.NETWORK_SUBNET) if (subnet is not None and net is not None): subnet_net = self.client_plugin( 'neutron').network_id_from_subnet_id(subnet) if subnet_net != net: msg = _('Specified subnet %(subnet)s does not belongs to ' 'network %(network)s.') % { 'subnet': subnet, 'network': net} raise exception.StackValidationFailed(message=msg)
def validate(self): res = super(SaharaNodeGroupTemplate, self).validate() if res: return res pool = self.properties[self.FLOATING_IP_POOL] if pool: if self.is_using_neutron(): try: self.client_plugin('neutron').find_neutron_resource( self.properties, self.FLOATING_IP_POOL, 'network') except Exception as ex: if (self.client_plugin('neutron').is_not_found(ex) or self.client_plugin('neutron').is_no_unique(ex)): raise exception.StackValidationFailed( message=ex.message) raise else: try: self.client('nova').floating_ip_pools.find(name=pool) except Exception as ex: if self.client_plugin('nova').is_not_found(ex): raise exception.StackValidationFailed( message=ex.message) raise
def validate_nested_stack(self): try: name = "%s-%s" % (self.stack.name, self.name) nested_stack = self._parse_nested_stack( name, self.child_template(), self.child_params()) nested_stack.strict_validate = False nested_stack.validate() except AssertionError: raise except Exception as ex: path = "%s<%s>" % (self.name, self.template_url) raise exception.StackValidationFailed( ex, path=[self.stack.t.RESOURCES, path])
def validate(self): ''' Validate any of the provided params ''' super(RouterInterface, self).validate() prop_subnet_exists = self._validate_depr_subnet_keys( self.properties, self.SUBNET, self.SUBNET_ID) port_id = self.properties.get(self.PORT_ID) if prop_subnet_exists and port_id: raise exception.ResourcePropertyConflict(self.SUBNET, self.PORT_ID) if not prop_subnet_exists and not port_id: msg = 'Either subnet or port_id must be specified.' raise exception.StackValidationFailed(message=msg)
def validate_nested_stack(self): try: name = "%s-%s" % (self.stack.name, self.name) nested_stack = self._parse_nested_stack(name, self.child_template(), self.child_params()) nested_stack.strict_validate = False nested_stack.validate() except AssertionError: raise except Exception as ex: raise exception.StackValidationFailed( error=_("Failed to validate"), path=[self.stack.t.get_section_name('resources'), self.name], message=six.text_type(ex))
def rsrc_defn_item(name, snippet): try: data = self.parse(stack, snippet) self._validate_resource_definition(name, data) except (TypeError, ValueError, KeyError) as ex: msg = six.text_type(ex) raise exception.StackValidationFailed(message=msg) depends = data.get(self.RES_DEPENDS_ON) if isinstance(depends, six.string_types): depends = [depends] deletion_policy = function.resolve( data.get(self.RES_DELETION_POLICY)) if deletion_policy is not None: if deletion_policy not in self.deletion_policies: msg = _('Invalid deletion policy "%s"') % deletion_policy raise exception.StackValidationFailed(message=msg) else: deletion_policy = self.deletion_policies[deletion_policy] kwargs = { 'resource_type': data.get(self.RES_TYPE), 'properties': data.get(self.RES_PROPERTIES), 'metadata': data.get(self.RES_METADATA), 'depends': depends, 'deletion_policy': deletion_policy, 'update_policy': data.get(self.RES_UPDATE_POLICY), 'description': data.get(self.RES_DESCRIPTION) or '' } if hasattr(self, 'RES_CONDITION'): kwargs['condition'] = data.get(self.RES_CONDITION) defn = rsrc_defn.ResourceDefinition(name, **kwargs) return name, defn
def validate(self): res = super(L7Rule, self).validate() if res: return res if (self.properties[self.TYPE] in (self.HEADER, self.COOKIE) and self.properties[self.KEY] is None): msg = (_('Property %(key)s is missing. ' 'This property should be specified for ' 'rules of %(header)s and %(cookie)s types.') % { 'key': self.KEY, 'header': self.HEADER, 'cookie': self.COOKIE }) raise exception.StackValidationFailed(message=msg)
def _validate_signal_data(self, data): if data is not None: input_value = data.get(self.SIGNAL_DATA_INPUT) params_value = data.get(self.SIGNAL_DATA_PARAMS) if input_value is not None: if not isinstance(input_value, dict): message = (_('Input in signal data must be a map, ' 'find a %s') % type(input_value)) raise exception.StackValidationFailed( error=_('Signal data error'), message=message) for key in six.iterkeys(input_value): if (self.properties.get(self.INPUT) is None or key not in self.properties.get(self.INPUT)): message = _('Unknown input %s') % key raise exception.StackValidationFailed( error=_('Signal data error'), message=message) if params_value is not None and not isinstance(params_value, dict): message = (_('Params must be a map, find a ' '%s') % type(params_value)) raise exception.StackValidationFailed( error=_('Signal data error'), message=message)
def validate_datastore(self, datastore_type, datastore_version, ds_type_key, ds_version_key): if datastore_type: # get current active versions allowed_versions = self.client().datastore_versions.list( datastore_type) allowed_version_names = [v.name for v in allowed_versions] if datastore_version: if datastore_version not in allowed_version_names: msg = _("Datastore version %(dsversion)s " "for datastore type %(dstype)s is not valid. " "Allowed versions are %(allowed)s.") % { 'dstype': datastore_type, 'dsversion': datastore_version, 'allowed': ', '.join(allowed_version_names) } raise exception.StackValidationFailed(message=msg) else: if datastore_version: msg = _("Not allowed - %(dsver)s without %(dstype)s.") % { 'dsver': ds_version_key, 'dstype': ds_type_key } raise exception.StackValidationFailed(message=msg)
def validate(self): res = super(SaharaCluster, self).validate() if res: return res self._validate_depr_keys(self.properties, self.IMAGE_ID, self.IMAGE) # check if running on neutron and MANAGEMENT_NETWORK missing # NOTE(pshchelo): on nova-network with MANAGEMENT_NETWORK present # overall stack validation will fail due to neutron.network constraint, # although the message will be not really relevant. if (self.is_using_neutron() and not self.properties.get(self.MANAGEMENT_NETWORK)): msg = _("%s must be provided" ) % self.MANAGEMENT_NETWORK raise exception.StackValidationFailed(message=msg)
def validate(self): '''Validate SoftwareComponent properties consistency.''' super(SoftwareComponent, self).validate() # One lifecycle action (e.g. CREATE) can only be associated with one # config; otherwise a way to define ordering would be required. configs = self.properties.get(self.CONFIGS, []) config_actions = set() for config in configs: actions = config.get(self.CONFIG_ACTIONS) if any(action in config_actions for action in actions): msg = _('Defining more than one configuration for the same ' 'action in SoftwareComponent "%s" is not allowed.' ) % self.name raise exception.StackValidationFailed(message=msg) config_actions.update(actions)
def validate(self): try: td = self.template_data except ValueError as ex: msg = _("Failed to retrieve template data: %s") % str(ex) raise exception.StackValidationFailed(message=msg) cri = self.stack.env.get_resource_info( self.type(), registry_type=environment.ClassResourceInfo) # If we're using an existing resource type as a facade for this # template, check for compatibility between the interfaces. if cri is not None and not isinstance(self, cri.get_class()): facade_cls = cri.get_class() self._validate_against_facade(facade_cls) return super(TemplateResource, self).validate()
def validate(self): ''' Validate any of the provided params :raises StackValidationFailed: if any property failed validation. ''' super(SoftwareDeployment, self).validate() server = self.properties.get(self.SERVER) if server: res = self.stack.resource_by_refid(server) if res: if not res.user_data_software_config(): raise exception.StackValidationFailed(message=_( "Resource %s's property user_data_format should be " "set to SOFTWARE_CONFIG since there are software " "deployments on it.") % server)
def validate(self): super(KeystoneRoleAssignment, self).validate() if self.properties.get(self.ROLES) is not None: for role_assignment in self.properties.get(self.ROLES): project = role_assignment.get(self.PROJECT) domain = role_assignment.get(self.DOMAIN) if project is not None and domain is not None: raise exception.ResourcePropertyConflict( self.PROJECT, self.DOMAIN) if project is None and domain is None: msg = _('Either project or domain must be specified for' ' role %s') % role_assignment.get(self.ROLE) raise exception.StackValidationFailed(message=msg)
def validate_with_client(self, client, value): params = {} neutron_client = client.client(CLIENT_NAME) if self.service_type: params['service_type'] = self.service_type providers = neutron_client.list_service_providers( retrieve_all=True, **params)['service_providers'] names = [provider['name'] for provider in providers] if value not in names: not_found_message = ( _("Unable to find neutron provider '%(provider)s', " "available providers are %(providers)s.") % { 'provider': value, 'providers': names }) raise exception.StackValidationFailed(message=not_found_message)
def validate(self): result = super(Delay, self).validate() if not self.stack.strict_validate: return result min_wait_secs, max_jitter_secs = self._delay_parameters() max_wait = min_wait_secs + max_jitter_secs if max_wait > self.stack.timeout_secs(): raise exception.StackValidationFailed( _('%(res_type)s maximum ' 'delay %(max_wait)ss ' 'exceeds stack timeout.') % { 'res_type': self.type, 'max_wait': max_wait }) return result
def validate(self): ''' Validates the template. ''' # TODO(sdake) Should return line number of invalid reference # validate overall template (top-level structure) self.t.validate() # Validate parameters self.parameters.validate(context=self.context, validate_value=self.strict_validate) # Validate Parameter Groups parameter_groups = param_groups.ParameterGroups(self.t) parameter_groups.validate() # Check duplicate names between parameters and resources dup_names = set(self.parameters.keys()) & set(self.keys()) if dup_names: LOG.debug("Duplicate names %s" % dup_names) raise exception.StackValidationFailed( message=_("Duplicate names %s") % dup_names) for res in self.dependencies: try: result = res.validate() except exception.HeatException as ex: LOG.info(ex) raise ex except Exception as ex: LOG.exception(ex) raise exception.StackValidationFailed( message=encodeutils.safe_decode(six.text_type(ex))) if result: raise exception.StackValidationFailed(message=result) for val in self.outputs.values(): try: if not val or not val.get('Value'): message = _('Each Output must contain ' 'a Value key.') raise exception.StackValidationFailed(message=message) function.validate(val.get('Value')) except AttributeError: message = _('Output validation error: ' 'Outputs must contain Output. ' 'Found a [%s] instead') % type(val) raise exception.StackValidationFailed(message=message) except Exception as ex: reason = _('Output validation error: ' '%s') % six.text_type(ex) raise exception.StackValidationFailed(message=reason)
def validate(self): super(RandomString, self).validate() char_sequences = self.properties[self.CHARACTER_SEQUENCES] char_classes = self.properties[self.CHARACTER_CLASSES] def char_min(char_dicts, min_prop): if char_dicts: return sum(char_dict[min_prop] for char_dict in char_dicts) return 0 length = self.properties[self.LENGTH] min_length = (char_min(char_sequences, self.CHARACTER_SEQUENCES_MIN) + char_min(char_classes, self.CHARACTER_CLASSES_MIN)) if min_length > length: msg = _("Length property cannot be smaller than combined " "character class and character sequence minimums") raise exception.StackValidationFailed(message=msg)
def validate(self): """Validate any of the provided params. :raises StackValidationFailed: if any property failed validation. """ super(SoftwareDeployment, self).validate() server = self.properties[self.SERVER] if server: res = self.stack.resource_by_refid(server) if res: user_data_format = res.properties.get('user_data_format') if user_data_format and \ not (user_data_format == 'SOFTWARE_CONFIG'): raise exception.StackValidationFailed(message=_( "Resource %s's property user_data_format should be " "set to SOFTWARE_CONFIG since there are software " "deployments on it.") % server)
def validate(self): super(Container, self).validate() policy = self.properties[self.RESTART_POLICY] if policy and not self._parse_restart_policy(policy): msg = _('restart_policy "%s" is invalid. Valid values are ' '"no", "on-failure[:max-retry]", "always", and ' '"unless-stopped".') % policy raise exception.StackValidationFailed(message=msg) mounts = self.properties[self.MOUNTS] or [] for mount in mounts: self._validate_mount(mount) networks = self.properties[self.NETWORKS] or [] for network in networks: self._validate_network(network)
def validate(self): """Validate any of the provided params.""" res = super(LoadBalancer, self).validate() if res: return res if (cfg.CONF.loadbalancer_template and not os.access(cfg.CONF.loadbalancer_template, os.R_OK)): msg = _('Custom LoadBalancer template can not be found') raise exception.StackValidationFailed(message=msg) health_chk = self.properties[self.HEALTH_CHECK] if health_chk: interval = float(health_chk[self.HEALTH_CHECK_INTERVAL]) timeout = float(health_chk[self.HEALTH_CHECK_TIMEOUT]) if interval < timeout: return {'Error': 'Interval must be larger than Timeout'}
def validate(self): res = super(Pool, self).validate() if res: return res session_p = self.properties[self.VIP].get(self.VIP_SESSION_PERSISTENCE) if session_p is None: # session persistence is not configured, skip validation return persistence_type = session_p[self.VIP_SESSION_PERSISTENCE_TYPE] if persistence_type == 'APP_COOKIE': if session_p.get(self.VIP_SESSION_PERSISTENCE_COOKIE_NAME): return msg = _('Property cookie_name is required, when ' 'session_persistence type is set to APP_COOKIE.') raise exception.StackValidationFailed(message=msg)
def validate(self): ''' Validate any of the provided params ''' res = super(LoadBalancer, self).validate() if res: return res if cfg.CONF.loadbalancer_template and \ not os.access(cfg.CONF.loadbalancer_template, os.R_OK): msg = _('Custom LoadBalancer template can not be found') raise exception.StackValidationFailed(message=msg) health_chk = self.properties['HealthCheck'] if health_chk: if float(health_chk['Interval']) < float(health_chk['Timeout']): return {'Error': 'Interval must be larger than Timeout'}
def test_stack_update_verify_err(self): stack_name = 'service_update_verify_err_test_stack' params = {'foo': 'bar'} template = '{ "Template": "data" }' old_stack = tools.get_stack(stack_name, self.ctx) old_stack.store() sid = old_stack.store() old_stack.set_stack_user_project_id('1234') s = stack_object.Stack.get_by_id(self.ctx, sid) stk = tools.get_stack(stack_name, self.ctx) # prepare mocks mock_stack = self.patchobject(stack, 'Stack', return_value=stk) mock_load = self.patchobject(stack.Stack, 'load', return_value=old_stack) mock_tmpl = self.patchobject(templatem, 'Template', return_value=stk.t) mock_env = self.patchobject(environment, 'Environment', return_value=stk.env) ex_expected = exception.StackValidationFailed(message='fubar') mock_validate = self.patchobject(stk, 'validate', side_effect=ex_expected) # do update api_args = {'timeout_mins': 60} ex = self.assertRaises(dispatcher.ExpectedException, self.man.update_stack, self.ctx, old_stack.identifier(), template, params, None, api_args) # assertions self.assertEqual(exception.StackValidationFailed, ex.exc_info[0]) mock_tmpl.assert_called_once_with(template, files=None) mock_env.assert_called_once_with(params) mock_stack.assert_called_once_with( self.ctx, stk.name, stk.t, convergence=False, current_traversal=old_stack.current_traversal, prev_raw_template_id=None, current_deps=None, disable_rollback=True, nested_depth=0, owner_id=None, parent_resource=None, stack_user_project_id='1234', strict_validate=True, tenant_id='test_tenant_id', timeout_mins=60, user_creds_id=u'1', username='******') mock_load.assert_called_once_with(self.ctx, stack=s) mock_validate.assert_called_once_with(validate_resources=True)
def handle_create(self): plugin_name = self.properties[self.PLUGIN_NAME] hadoop_version = self.properties[self.HADOOP_VERSION] cluster_template_id = self.properties[self.CLUSTER_TEMPLATE_ID] image_id = (self.properties[self.IMAGE_ID] or self.properties[self.IMAGE]) if image_id: image_id = self.client_plugin('glance').find_image_by_name_or_id( image_id) # check that image is provided in case when # cluster template is missing one cluster_template = self.client().cluster_templates.get( cluster_template_id) if cluster_template.default_image_id is None and not image_id: msg = _("%(img)s must be provided: Referenced cluster template " "%(tmpl)s has no default_image_id defined.") % { 'img': self.IMAGE, 'tmpl': cluster_template_id } raise exception.StackValidationFailed(message=msg) key_name = self.properties[self.KEY_NAME] net_id = self.properties[self.MANAGEMENT_NETWORK] if net_id: if self.is_using_neutron(): net_id = self.client_plugin('neutron').find_neutron_resource( self.properties, self.MANAGEMENT_NETWORK, 'network') else: net_id = self.client_plugin('nova').get_nova_network_id(net_id) use_autoconfig = self.properties[self.USE_AUTOCONFIG] shares = self.properties[self.SHARES] cluster = self.client().clusters.create( self._cluster_name(), plugin_name, hadoop_version, cluster_template_id=cluster_template_id, user_keypair_id=key_name, default_image_id=image_id, net_id=net_id, use_autoconfig=use_autoconfig, shares=shares) LOG.info(_LI('Cluster "%s" is being started.'), cluster.name) self.resource_id_set(cluster.id) return self.resource_id
def validate(self): """Validate the provided params.""" super(ClusterTemplate, self).validate() coe = self.properties[self.COE] volume_driver = self.properties[self.VOLUME_DRIVER] # Confirm that volume driver is supported by Magnum COE per # SUPPORTED_VOLUME_DRIVER. value = self.SUPPORTED_VOLUME_DRIVER[coe] if volume_driver is not None and volume_driver not in value: msg = (_('Volume driver type %(driver)s is not supported by ' 'COE:%(coe)s, expecting a %(supported_volume_driver)s ' 'volume driver.') % { 'driver': volume_driver, 'coe': coe, 'supported_volume_driver': value}) raise exception.StackValidationFailed(message=msg)