Exemple #1
0
    def _validate_flavor(self, obj, name_or_id, reason=None):
        flavor = None
        msg = ''
        try:
            flavor = self.compute(obj).flavor_find(name_or_id, False)
        except exc.InternalError as ex:
            msg = six.text_type(ex)
            if reason is None:  # reaons is 'validate'
                if ex.code == 404:
                    msg = _(
                        "The specified %(k)s '%(v)s' could not be found.") % {
                            'k': self.FLAVOR,
                            'v': name_or_id
                        }
                    raise exc.InvalidSpec(message=msg)
                else:
                    raise

        if flavor is not None:
            if not flavor.is_disabled:
                return flavor
            msg = _("The specified %(k)s '%(v)s' is disabled") % {
                'k': self.FLAVOR,
                'v': name_or_id
            }

        if reason == 'create':
            raise exc.EResourceCreation(type='server', message=msg)
        elif reason == 'update':
            raise exc.EResourceUpdate(type='server',
                                      id=obj.physical_id,
                                      message=msg)
        else:
            raise exc.InvalidSpec(message=msg)
Exemple #2
0
    def validate(self, context, validate_props=False):
        super(LoadBalancingPolicy, self).validate(context, validate_props)

        if not validate_props:
            return True

        nc = self.network(context.user, context.project)

        # validate pool subnet
        name_or_id = self.pool_spec.get(self.POOL_SUBNET)
        try:
            nc.subnet_get(name_or_id)
        except exc.InternalError:
            msg = _(
                "The specified %(key)s '%(value)s' could not be found.") % {
                    'key': self.POOL_SUBNET,
                    'value': name_or_id
                }
            raise exc.InvalidSpec(message=msg)

        # validate VIP subnet
        name_or_id = self.vip_spec.get(self.VIP_SUBNET)
        try:
            nc.subnet_get(name_or_id)
        except exc.InternalError:
            msg = _(
                "The specified %(key)s '%(value)s' could not be found.") % {
                    'key': self.VIP_SUBNET,
                    'value': name_or_id
                }
            raise exc.InvalidSpec(message=msg)
Exemple #3
0
    def validate(self):
        # validate cron expression if specified
        if TIME_CONSTRAINTS in self.spec:
            tcs = self.alarm_properties[TIME_CONSTRAINTS]
            for tc in tcs:
                exp = tc.get(TC_START, '')
                try:
                    croniter.croniter(exp)
                except Exception as ex:
                    msg = _("Invalid cron expression specified for property "
                            "'%(property)s' (%(exp)s): %(ex)s") % {
                                'property': TC_START,
                                'exp': exp,
                                'ex': six.text_type(ex)
                            }
                    raise exc.InvalidSpec(message=msg)

                tz = tc.get(TC_TIMEZONE, '')
                try:
                    pytz.timezone(tz)
                except Exception as ex:
                    msg = _("Invalid timezone value specified for property "
                            "'%(property)s' (%(tz)s): %(ex)s") % {
                                'property': TC_TIMEZONE,
                                'tz': tz,
                                'ex': six.text_type(ex)
                            }
                    raise exc.InvalidSpec(message=msg)
Exemple #4
0
    def do_validate(self, obj):
        """Validate if the spec has provided valid configuration.

        :param obj: The node object.
        """
        cluster = self.properties[self.HOST_CLUSTER]
        node = self.properties[self.HOST_NODE]
        if all([cluster, node]):
            msg = _("Either '%(c)s' or '%(n)s' must be specified, but not "
                    "both.") % {'c': self.HOST_CLUSTER, 'n': self.HOST_NODE}
            raise exc.InvalidSpec(message=msg)

        if not any([cluster, node]):
            msg = _("Either '%(c)s' or '%(n)s' must be specified."
                    ) % {'c': self.HOST_CLUSTER, 'n': self.HOST_NODE}
            raise exc.InvalidSpec(message=msg)

        if cluster:
            try:
                co.Cluster.find(self.context, cluster)
            except (exc.ResourceNotFound, exc.MultipleChoices):
                msg = _("The specified %(key)s '%(val)s' could not be found "
                        "or is not unique."
                        ) % {'key': self.HOST_CLUSTER, 'val': cluster}
                raise exc.InvalidSpec(message=msg)

        if node:
            try:
                no.Node.find(self.context, node)
            except (exc.ResourceNotFound, exc.MultipleChoices):
                msg = _("The specified %(key)s '%(val)s' could not be found "
                        "or is not unique."
                        ) % {'key': self.HOST_NODE, 'val': node}
                raise exc.InvalidSpec(message=msg)
Exemple #5
0
    def validate(self, context, validate_props=False):
        super(LoadBalancingPolicy, self).validate(context, validate_props)

        if not validate_props:
            return True

        nc = self.network(context.user_id, context.project_id)
        oc = self.octavia(context.user_id, context.project_id)

        # validate pool subnet
        name_or_id = self.pool_spec.get(self.POOL_SUBNET)
        try:
            nc.subnet_get(name_or_id)
        except exc.InternalError:
            msg = _("The specified %(key)s '%(value)s' could not be found."
                    ) % {'key': self.POOL_SUBNET, 'value': name_or_id}
            raise exc.InvalidSpec(message=msg)

        # validate VIP subnet or network
        subnet_name_or_id = self.vip_spec.get(self.VIP_SUBNET)
        network_name_or_id = self.vip_spec.get(self.VIP_NETWORK)
        if not subnet_name_or_id and not network_name_or_id:
            msg = _("At least one of VIP Subnet or Network must be defined.")
            raise exc.InvalidSpec(message=msg)
        try:
            # Check subnet if it is set
            obj_type = self.VIP_SUBNET
            name_or_id = subnet_name_or_id
            if name_or_id:
                nc.subnet_get(name_or_id)

            # Check network if it is set
            obj_type = self.VIP_NETWORK
            name_or_id = network_name_or_id
            if name_or_id:
                nc.network_get(name_or_id)

            # TODO(rm_work): We *could* do more validation here to catch issues
            # at validation time, like verifying the subnet's network_id is the
            # same as the id of the network, if both are set -- but for now we
            # will just leave that up to the LB API, which means if there is a
            # failure, it won't be caught until attach time.
        except exc.InternalError:
            msg = _("The specified %(key)s '%(value)s' could not be found."
                    ) % {'key': obj_type, 'value': name_or_id}
            raise exc.InvalidSpec(message=msg)

        # validate loadbalancer
        if self.lb:
            try:
                oc.loadbalancer_get(self.lb)
            except exc.InternalError:
                msg = _("The specified %(key)s '%(value)s' could not be found."
                        ) % {'key': self.LOADBALANCER, 'value': self.lb}
                raise exc.InvalidSpec(message=msg)
Exemple #6
0
    def validate(self, context, validate_props=False):
        super(ScalingPolicy, self).validate(context, validate_props)

        if self.adjustment_number <= 0:
            msg = _("the 'number' for 'adjustment' must be > 0")
            raise exc.InvalidSpec(message=msg)

        if self.adjustment_min_step < 0:
            msg = _("the 'min_step' for 'adjustment' must be >= 0")
            raise exc.InvalidSpec(message=msg)

        if self.cooldown < 0:
            msg = _("the 'cooldown' for 'adjustment' must be >= 0")
            raise exc.InvalidSpec(message=msg)
Exemple #7
0
    def create(cls, ctx, name, spec, metadata=None):
        """Create a profile object and validate it.

        :param ctx: The requesting context.
        :param name: The name for the profile object.
        :param spec: A dict containing the detailed spec.
        :param metadata: An optional dictionary specifying key-value pairs to
                         be associated with the profile.
        :returns: An instance of Profile.
        """
        if metadata is None:
            metadata = {}

        try:
            profile = cls(name, spec, metadata=metadata, user=ctx.user_id,
                          project=ctx.project_id)
            profile.validate(True)
        except (exc.ResourceNotFound, exc.ESchema) as ex:
            error = _("Failed in creating profile %(name)s: %(error)s"
                      ) % {"name": name, "error": six.text_type(ex)}
            raise exc.InvalidSpec(message=error)

        profile.store(ctx)

        return profile
Exemple #8
0
    def test_profile_create_with_spec_validation_failed(self, mock_call,
                                                        mock_parse,
                                                        mock_enforce):
        self._mock_enforce_setup(mock_enforce, 'create', True)
        body = {
            'profile': {
                'name': 'test_profile',
                'spec': {
                    'type': 'test_profile_type',
                    'version': '1.0',
                    'properties': {'param': 'value'},
                },
                'metadata': {},
            }
        }
        req = self._post('/profiles', jsonutils.dumps(body))
        obj = mock.Mock()
        mock_parse.return_value = obj

        msg = 'Spec validation error (param): value'
        error = senlin_exc.InvalidSpec(message=msg)
        mock_call.side_effect = shared.to_remote_error(error)

        resp = shared.request_with_middleware(fault.FaultWrapper,
                                              self.controller.create,
                                              req, body=body)

        self.assertEqual(400, resp.json['code'])
        self.assertEqual('InvalidSpec', resp.json['error']['type'])
        mock_parse.assert_called_once_with(
            'ProfileCreateRequest', mock.ANY, body, 'profile')
        mock_call.assert_called_once_with(
            req.context, 'profile_create', obj)
Exemple #9
0
    def test_profile_validate_invalide_spec(self, mock_call,
                                            mock_parse, mock_enforce):
        self._mock_enforce_setup(mock_enforce, 'validate', True)
        body = {
            'profile': {
                'spec': {
                    'type': 'os.nova.server',
                    'version': '1.0'
                }
            }
        }

        req = self._post('/profiles/validate', jsonutils.dumps(body),
                         version='1.2')

        msg = 'Spec validation error'
        error = senlin_exc.InvalidSpec(message=msg)
        mock_call.side_effect = shared.to_remote_error(error)
        obj = mock.Mock()
        mock_parse.return_value = obj

        resp = shared.request_with_middleware(fault.FaultWrapper,
                                              self.controller.validate,
                                              req, body=body)

        self.assertEqual(400, resp.json['code'])
        self.assertEqual('InvalidSpec', resp.json['error']['type'])
Exemple #10
0
 def test_policy_create_failed_validation(self):
     self.spec['properties'] = {'KEY2': 1}
     self.patchobject(fakes.TestPolicy, 'validate',
                      side_effect=exception.InvalidSpec(message='BOOM'))
     ex = self.assertRaises(rpc.ExpectedException,
                            self.eng.policy_create,
                            self.ctx, 'p-2', self.spec)
     self.assertEqual(exception.SenlinBadRequest, ex.exc_info[0])
Exemple #11
0
    def validate(self):
        super(ServerProfile, self).validate()

        if self.properties[self.TIMEOUT] > cfg.CONF.default_action_timeout:
            suggest = cfg.CONF.default_action_timeout
            err = _("Value of the 'timeout' property must be lower than the "
                    "upper limit (%s).") % suggest
            raise exception.InvalidSpec(message=err)
Exemple #12
0
 def test_trigger_create_failed_validation(self):
     spec = parser.simple_parse(trigger_spec)
     self.patchobject(fakes.TestTrigger,
                      'validate',
                      side_effect=exception.InvalidSpec(message='BOOM'))
     ex = self.assertRaises(rpc.ExpectedException, self.eng.trigger_create,
                            self.ctx, 't1', spec)
     self.assertEqual(exception.InvalidSpec, ex.exc_info[0])
Exemple #13
0
    def test_profile_create_invalid_spec(self, mock_create):
        self._setup_fakes()
        mock_create.side_effect = exc.InvalidSpec(message="badbad")
        body = vorp.ProfileCreateRequestBody(name='foo', spec=self.spec)
        req = vorp.ProfileCreateRequest(profile=body)
        ex = self.assertRaises(rpc.ExpectedException, self.svc.profile_create,
                               self.ctx, req.obj_to_primitive())

        self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
        self.assertEqual("badbad", six.text_type(ex.exc_info[1]))
Exemple #14
0
    def test_policy_create_failed_validation(self):
        self._setup_fakes()

        mock_validate = self.patchobject(fakes.TestPolicy, 'validate')
        mock_validate.side_effect = exc.InvalidSpec(message='BOOM')

        req = orpo.PolicyCreateRequestBody(name='Fake', spec=self.spec)
        ex = self.assertRaises(rpc.ExpectedException, self.eng.policy_create,
                               self.ctx, req.obj_to_primitive())
        self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
        self.assertEqual('BOOM', six.text_type(ex.exc_info[1]))
Exemple #15
0
    def test_profile_create_failed_validation(self):
        self._setup_fakes()

        mock_validate = self.patchobject(fakes.TestProfile, 'validate')
        mock_validate.side_effect = exc.InvalidSpec(message='BOOM')

        ex = self.assertRaises(rpc.ExpectedException, self.eng.profile_create,
                               self.ctx, 'p-2', self.spec)
        self.assertEqual(exc.BadRequest, ex.exc_info[0])
        self.assertEqual('The request is malformed: BOOM',
                         six.text_type(ex.exc_info[1]))
Exemple #16
0
    def test_policy_validate_failed(self):
        self._setup_fakes()
        mock_validate = self.patchobject(fakes.TestPolicy, 'validate')
        mock_validate.side_effect = exc.InvalidSpec(message='BOOM')

        body = orpo.PolicyValidateRequestBody(spec=self.spec)

        ex = self.assertRaises(rpc.ExpectedException, self.svc.policy_validate,
                               self.ctx, body.obj_to_primitive())
        self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
        self.assertEqual('BOOM', str(ex.exc_info[1]))
Exemple #17
0
    def validate(self, context, validate_props=False):
        super(HealthPolicy, self).validate(context,
                                           validate_props=validate_props)

        if len(self.recover_actions) > 1:
            message = _(
                "Only one '%s' is supported for now.") % self.RECOVERY_ACTIONS
            raise exc.ESchema(message=message)

        if self.interval < cfg.CONF.health_check_interval_min:
            message = _("Specified interval of %(interval)d seconds has to be "
                        "larger than health_check_interval_min of "
                        "%(min_interval)d seconds set in configuration.") % {
                            "interval": self.interval,
                            "min_interval": cfg.CONF.health_check_interval_min
                        }
            raise exc.InvalidSpec(message=message)

        # check valid detection types
        polling_types = [
            consts.NODE_STATUS_POLLING, consts.NODE_STATUS_POLL_URL
        ]

        has_valid_polling_types = all(d.type in polling_types
                                      for d in self.detection_modes)
        has_valid_lifecycle_type = (len(self.detection_modes) == 1
                                    and self.detection_modes[0].type
                                    == consts.LIFECYCLE_EVENTS)

        if not has_valid_polling_types and not has_valid_lifecycle_type:
            message = ("Invalid detection modes in health policy: %s" %
                       ', '.join([d.type for d in self.detection_modes]))
            raise exc.InvalidSpec(message=message)

        if len(self.detection_modes) != len(set(self.detection_modes)):
            message = ("Duplicate detection modes are not allowed in "
                       "health policy: %s" %
                       ', '.join([d.type for d in self.detection_modes]))
            raise exc.InvalidSpec(message=message)
Exemple #18
0
    def validate(self, validate_props=False):
        '''Validate the schema and the data provided.'''
        # general validation
        self.spec_data.validate()
        self.properties.validate()
        # validate template
        template = self.properties[self.TEMPLATE]
        template_url = self.properties[self.TEMPLATE_URL]
        if not template and not template_url:
            msg = _("Both template and template_url are not specified "
                    "for profile '%s'.") % self.name
            raise exc.InvalidSpec(message=msg)

        if validate_props:
            self.do_validate(obj=self)
Exemple #19
0
    def test_policy_create_invalid_value(self):
        self._setup_fakes()
        spec = copy.deepcopy(self.spec)
        spec['properties']['KEY2'] = 'value3'

        mock_validate = self.patchobject(fakes.TestPolicy, 'validate')
        mock_validate.side_effect = exc.InvalidSpec(
            message="The specified KEY2 'value3' could not be found.")

        req = orpo.PolicyCreateRequestBody(name='Fake', spec=spec)
        ex = self.assertRaises(rpc.ExpectedException, self.svc.policy_create,
                               self.ctx, req.obj_to_primitive())
        self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
        self.assertEqual("The specified KEY2 'value3' could not be "
                         "found.", str(ex.exc_info[1]))
    def validate(self, context, validate_props=False):
        super(RegionPlacementPolicy, self).validate(context, validate_props)

        if not validate_props:
            return True

        kc = self.keystone(context.user_id, context.project_id)
        input_regions = sorted(self.regions.keys())
        valid_regions = kc.validate_regions(input_regions)
        invalid_regions = sorted(set(input_regions) - set(valid_regions))
        if invalid_regions:
            msg = _("The specified regions '%(value)s' could not be "
                    "found.") % {'value': invalid_regions}
            raise exc.InvalidSpec(message=msg)

        return True
    def test_create(self):
        exobj = None
        try:
            {}['key']
        except Exception:
            ex = exception.InvalidSpec(message='boom')
            exobj = base.ExceptionPayload.from_exception(ex)

        sot = base.NodeActionPayload(node=self.node,
                                     action=self.action,
                                     exception=exobj)

        self.assertTrue(sot.obj_attr_is_set('node'))
        self.assertTrue(sot.obj_attr_is_set('action'))
        self.assertTrue(sot.obj_attr_is_set('exception'))
        self.assertIsNotNone(sot.exception)
Exemple #22
0
    def validate(self, context, validate_props=False):
        super(AffinityPolicy, self).validate(context, validate_props)

        if not validate_props:
            return True

        az_name = self.properties.get(self.AVAILABILITY_ZONE)
        if az_name:
            nc = self.nova(context.user, context.project)
            valid_azs = nc.validate_azs([az_name])
            if not valid_azs:
                msg = _("The specified %(key)s '%(value)s' could not be "
                        "found.") % {'key': self.AVAILABILITY_ZONE,
                                     'value': az_name}
                raise exc.InvalidSpec(message=msg)

        return True
Exemple #23
0
    def validate(self, context, validate_props=False):
        super(HealthPolicy, self).validate(context,
                                           validate_props=validate_props)

        if len(self.recover_actions) > 1:
            message = _(
                "Only one '%s' is supported for now.") % self.RECOVERY_ACTIONS
            raise exc.ESchema(message=message)

        if self.interval < cfg.CONF.health_check_interval_min:
            message = _("Specified interval of %(interval)d seconds has to be "
                        "larger than health_check_interval_min of "
                        "%(min_interval)d seconds set in configuration.") % {
                            "interval": self.interval,
                            "min_interval": cfg.CONF.health_check_interval_min
                        }
            raise exc.InvalidSpec(message=message)
Exemple #24
0
    def validate(self, context, validate_props=False):
        super(ZonePlacementPolicy, self).validate(context, validate_props)

        if not validate_props:
            return True

        nc = self.nova(context.user_id, context.project_id)
        input_azs = sorted(self.zones.keys())
        valid_azs = nc.validate_azs(input_azs)
        invalid_azs = sorted(set(input_azs) - set(valid_azs))
        if invalid_azs:
            msg = _("The specified %(key)s '%(value)s' could not be "
                    "found.") % {'key': self.ZONE_NAME,
                                 'value': list(invalid_azs)}
            raise exc.InvalidSpec(message=msg)

        return True
Exemple #25
0
 def _validate_keypair(self, obj, name_or_id, reason=None):
     try:
         return self.compute(obj).keypair_find(name_or_id, False)
     except exc.InternalError as ex:
         if reason == 'create':
             raise exc.EResourceCreation(type='server',
                                         message=six.text_type(ex))
         elif reason == 'update':
             raise exc.EResourceUpdate(type='server',
                                       id=obj.physical_id,
                                       message=six.text_type(ex))
         elif ex.code == 404:
             msg = _("The specified %(k)s '%(v)s' could not be found.") % {
                 'k': self.KEY_NAME,
                 'v': name_or_id
             }
             raise exc.InvalidSpec(message=msg)
         else:
             raise
Exemple #26
0
    def do_validate(self, obj):
        '''Validate if the spec has provided info for stack creation.'''

        kwargs = {
            'stack_name': obj.name,
            'template': self.properties[self.TEMPLATE],
            'timeout_mins': self.properties[self.TIMEOUT],
            'disable_rollback': self.properties[self.DISABLE_ROLLBACK],
            'parameters': self.properties[self.PARAMETERS],
            'files': self.properties[self.FILES],
            'environment': self.properties[self.ENVIRONMENT],
        }
        try:
            self.heat(obj).stacks.validate(**kwargs)
        except Exception as ex:
            msg = _('Failed validate stack template due to '
                    '"%s"') % six.text_type(ex)
            raise exception.InvalidSpec(message=msg)

        return True
Exemple #27
0
    def _validate_az(self, obj, az_name, reason=None):
        try:
            res = self.compute(obj).validate_azs([az_name])
        except exc.InternalError as ex:
            if reason == 'create':
                raise exc.EResourceCreation(type='server',
                                            message=six.text_type(ex))
            else:
                raise

        if not res:
            msg = _("The specified %(key)s '%(value)s' could not be found") % {
                'key': self.AVAILABILITY_ZONE,
                'value': az_name
            }
            if reason == 'create':
                raise exc.EResourceCreation(type='server', message=msg)
            else:
                raise exc.InvalidSpec(message=msg)

        return az_name
Exemple #28
0
    def do_validate(self, obj):
        """Validate the stack template used by a node.

        :param obj: Node object to operate.
        :returns: True if validation succeeds.
        :raises: `InvalidSpec` exception is raised if template is invalid.
        """
        kwargs = {
            'stack_name': utils.random_name(),
            'template': self.properties[self.TEMPLATE],
            'template_url': self.properties[self.TEMPLATE_URL],
            'parameters': self.properties[self.PARAMETERS],
            'files': self.properties[self.FILES],
            'environment': self.properties[self.ENVIRONMENT],
            'preview': True,
        }
        try:
            self.orchestration(obj).stack_create(**kwargs)
        except exc.InternalError as ex:
            msg = _('Failed in validating template: %s') % six.text_type(ex)
            raise exc.InvalidSpec(message=msg)

        return True
Exemple #29
0
    def _validate_network(self, obj, network, reason=None):
        result = {}
        error = None
        # check network
        net_ident = network.get(self.NETWORK)
        if net_ident:
            try:
                net = self.network(obj).network_get(net_ident)
                if reason == 'update':
                    result['net_id'] = net.id
                else:
                    result['uuid'] = net.id
            except exc.InternalError as ex:
                error = six.text_type(ex)

        # check port
        port_ident = network.get(self.PORT)
        if not error and port_ident:
            try:
                port = self.network(obj).port_find(port_ident)
                if port.status != 'DOWN':
                    error = _(
                        "The status of the port %(port)s must be DOWN") % {
                            'port': port_ident
                        }

                if reason == 'update':
                    result['port_id'] = port.id
                else:
                    result['port'] = port.id
            except exc.InternalError as ex:
                error = six.text_type(ex)
        elif port_ident is None and net_ident is None:
            error = _("'%(port)s' is required if '%(net)s' is omitted") % {
                'port': self.PORT,
                'net': self.NETWORK
            }

        fixed_ip = network.get(self.FIXED_IP)
        if not error and fixed_ip:
            if port_ident is not None:
                error = _("The '%(port)s' property and the '%(fixed_ip)s' "
                          "property cannot be specified at the same time") % {
                              'port': self.PORT,
                              'fixed_ip': self.FIXED_IP
                          }
            else:
                if reason == 'update':
                    result['fixed_ips'] = [{'ip_address': fixed_ip}]
                else:
                    result['fixed_ip'] = fixed_ip

        if error:
            if reason == 'create':
                raise exc.EResourceCreation(type='server', message=error)
            elif reason == 'update':
                raise exc.EResourceUpdate(type='server',
                                          id=obj.physical_id,
                                          message=error)
            else:
                raise exc.InvalidSpec(message=error)

        return result