Exemple #1
0
    def on_put(self, req, res, alarm_id):

        helpers.validate_authorization(req, self._default_authorized_roles)

        tenant_id = helpers.get_tenant_id(req)

        alarm = helpers.read_http_resource(req)
        schema_alarm.validate(alarm)

        # Validator makes state optional, so check it here
        if 'state' not in alarm or not alarm['state']:
            raise HTTPUnprocessableEntityError('Unprocessable Entity',
                                               "Field 'state' is required")
        if 'lifecycle_state' not in alarm or not alarm['lifecycle_state']:
            raise HTTPUnprocessableEntityError(
                'Unprocessable Entity', "Field 'lifecycle_state' is required")
        if 'link' not in alarm or not alarm['link']:
            raise HTTPUnprocessableEntityError('Unprocessable Entity',
                                               "Field 'link' is required")

        self._alarm_update(tenant_id, alarm_id, alarm['state'],
                           alarm['lifecycle_state'], alarm['link'])

        result = self._alarm_show(req.uri, tenant_id, alarm_id)

        res.body = helpers.dumpit_utf8(result)
        res.status = falcon.HTTP_200
Exemple #2
0
    def on_put(self, req, res, alarm_id):

        helpers.validate_authorization(req, ['api:alarms:put'])

        alarm = helpers.from_json(req)
        schema_alarm.validate(alarm)

        # Validator makes state optional, so check it here
        if 'state' not in alarm or not alarm['state']:
            raise HTTPUnprocessableEntityError('Unprocessable Entity',
                                               "Field 'state' is required")
        if 'lifecycle_state' not in alarm or not alarm['lifecycle_state']:
            raise HTTPUnprocessableEntityError(
                'Unprocessable Entity', "Field 'lifecycle_state' is required")
        if 'link' not in alarm or not alarm['link']:
            raise HTTPUnprocessableEntityError('Unprocessable Entity',
                                               "Field 'link' is required")

        self._alarm_update(req.project_id, alarm_id, alarm['state'],
                           alarm['lifecycle_state'], alarm['link'])

        result = self._alarm_show(req.uri, req.project_id, alarm_id)

        res.body = helpers.to_json(result)
        res.status = falcon.HTTP_200
Exemple #3
0
    def on_get(self, req, res):
        helpers.validate_authorization(req, self._default_authorized_roles)
        tenant_id = helpers.get_tenant_id(req)
        query_parms = falcon.uri.parse_query_string(req.query_string)

        if 'state' in query_parms:
            validation.validate_alarm_state(query_parms['state'])

        if 'severity' in query_parms:
            validation.validate_alarm_definition_severity(query_parms['severity'])

        if 'group_by' in query_parms:
            if not isinstance(query_parms['group_by'], list):
                query_parms['group_by'] = [query_parms['group_by']]
            self._validate_group_by(query_parms['group_by'])

        # ensure metric_dimensions is a list
        if 'metric_dimensions' in query_parms and isinstance(query_parms['metric_dimensions'], str):
            query_parms['metric_dimensions'] = query_parms['metric_dimensions'].split(',')

        offset = helpers.get_query_param(req, 'offset')

        if offset is not None:
            try:
                offset = int(offset)
            except Exception:
                raise HTTPUnprocessableEntityError("Unprocessable Entity",
                                                   "Offset must be a valid integer, was {}".format(offset))

        limit = helpers.get_limit(req)

        result = self._alarms_count(req.uri, tenant_id, query_parms, offset, limit)

        res.body = helpers.dumpit_utf8(result)
        res.status = falcon.HTTP_200
Exemple #4
0
    def on_get(self, req, res):
        helpers.validate_authorization(req, self._get_alarms_authorized_roles)
        query_parms = falcon.uri.parse_query_string(req.query_string)

        if 'state' in query_parms:
            validation.validate_alarm_state(query_parms['state'])
            query_parms['state'] = query_parms['state'].upper()

        if 'severity' in query_parms:
            validation.validate_severity_query(query_parms['severity'])
            query_parms['severity'] = query_parms['severity'].upper()

        if 'group_by' in query_parms:
            if not isinstance(query_parms['group_by'], list):
                query_parms['group_by'] = query_parms['group_by'].split(',')
            self._validate_group_by(query_parms['group_by'])

        query_parms['metric_dimensions'] = helpers.get_query_dimensions(req, 'metric_dimensions')
        helpers.validate_query_dimensions(query_parms['metric_dimensions'])

        offset = helpers.get_query_param(req, 'offset')

        if offset is not None:
            try:
                offset = int(offset)
            except Exception:
                raise HTTPUnprocessableEntityError("Unprocessable Entity",
                                                   "Offset must be a valid integer, was {}".format(offset))

        result = self._alarms_count(req.uri, req.project_id, query_parms, offset, req.limit)

        res.body = helpers.dumpit_utf8(result)
        res.status = falcon.HTTP_200
Exemple #5
0
def get_query_dimensions(req):
    """Gets and parses the query param dimensions.

    :param req: HTTP request object.
    :return: Returns the dimensions as a JSON object
    :raises falcon.HTTPBadRequest: If dimensions are malformed.
    """
    try:
        params = falcon.uri.parse_query_string(req.query_string)
        dimensions = {}
        if 'dimensions' in params:
            dimensions_param = params['dimensions']

            if isinstance(dimensions_param, basestring):
                dimensions_str_array = dimensions_param.split(',')
            elif isinstance(dimensions_param, list):
                dimensions_str_array = []
                for sublist in dimensions_param:
                    dimensions_str_array.extend(sublist.split(","))
            else:
                raise Exception("Error parsing dimensions, unknown format")

            for dimension in dimensions_str_array:
                dimension_name_value = dimension.split(':')
                if len(dimension_name_value) == 2:
                    dimensions[
                        dimension_name_value[0]] = dimension_name_value[1]
                elif len(dimension_name_value) == 1:
                    dimensions[dimension_name_value[0]] = ""
                else:
                    raise Exception('Dimensions are malformed')
        return dimensions
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
Exemple #6
0
    def try_it(*args, **kwargs):
        try:
            return fun(*args, **kwargs)

        except falcon.HTTPError:
            raise

        except exceptions.DoesNotExistException:
            raise falcon.HTTPNotFound

        except exceptions.MultipleMetricsException as ex:
            raise falcon.HTTPConflict("MultipleMetrics", ex.message)

        except exceptions.AlreadyExistsException as ex:
            raise falcon.HTTPConflict(ex.__class__.__name__, ex.message)

        except exceptions.InvalidUpdateException as ex:
            raise HTTPUnprocessableEntityError(ex.__class__.__name__, ex.message)

        except exceptions.RepositoryException as ex:
            LOG.exception(ex)
            msg = " ".join(map(str, ex.message.args))
            raise falcon.HTTPInternalServerError('The repository was unable '
                                                 'to process your request',
                                                 msg)

        except Exception as ex:
            LOG.exception(ex)
            raise falcon.HTTPInternalServerError('Service unavailable',
                                                 ex.message)
Exemple #7
0
    def on_get(self, req, res, notification_method_id=None):
        if notification_method_id is None:
            helpers.validate_authorization(
                req, self._get_notifications_authorized_roles)
            sort_by = helpers.get_query_param(req, 'sort_by', default_val=None)
            if sort_by is not None:
                if isinstance(sort_by, basestring):
                    sort_by = sort_by.split(',')

                allowed_sort_by = {
                    'id', 'name', 'type', 'address', 'updated_at', 'created_at'
                }

                validation.validate_sort_by(sort_by, allowed_sort_by)

            offset = helpers.get_query_param(req, 'offset')
            if offset is not None and not isinstance(offset, int):
                try:
                    offset = int(offset)
                except Exception:
                    raise HTTPUnprocessableEntityError(
                        'Unprocessable Entity',
                        'Offset value {} must be an integer'.format(offset))

            result = self._list_notifications(req.project_id, req.uri, sort_by,
                                              offset, req.limit)
            res.body = helpers.dumpit_utf8(result)
            res.status = falcon.HTTP_200
        else:
            helpers.validate_authorization(
                req, self._get_notifications_authorized_roles)
            result = self._list_notification(req.project_id,
                                             notification_method_id, req.uri)
            res.body = helpers.dumpit_utf8(result)
            res.status = falcon.HTTP_200
Exemple #8
0
 def on_get(self, req, res, version_id=None):
     result = {
         'links': [{
             'rel': 'self',
             'href': req.uri.decode('utf8')
         }],
         'elements': []
     }
     if version_id is None:
         for version in VERSIONS:
             VERSIONS[version]['links'][0]['href'] = (
                 req.uri.decode('utf8') + version)
             result['elements'].append(VERSIONS[version])
         res.body = helpers.to_json(result)
         res.status = falcon.HTTP_200
     else:
         if version_id in VERSIONS:
             VERSIONS[version_id]['links'][0]['href'] = (
                 req.uri.decode('utf8'))
             res.body = helpers.to_json(VERSIONS[version_id])
             res.status = falcon.HTTP_200
         else:
             raise HTTPUnprocessableEntityError(
                 'Invalid version',
                 'No versions found matching ' + version_id)
Exemple #9
0
 def _validate_group_by(self, group_by):
     allowed_values = {'alarm_definition_id', 'name', 'state', 'severity',
                       'link', 'lifecycle_state', 'metric_name',
                       'dimension_name', 'dimension_value'}
     if not set(group_by).issubset(allowed_values):
         raise HTTPUnprocessableEntityError(
             "Unprocessable Entity",
             "One or more group-by values from {} are not in {}".format(group_by, allowed_values))
Exemple #10
0
    def on_get(self, req, res, alarm_id=None):
        helpers.validate_authorization(req, self._default_authorized_roles)
        tenant_id = helpers.get_tenant_id(req)

        if alarm_id is None:
            query_parms = falcon.uri.parse_query_string(req.query_string)
            if 'state' in query_parms:
                validation.validate_alarm_state(query_parms['state'])

            if 'severity' in query_parms:
                validation.validate_alarm_definition_severity(
                    query_parms['severity'])

            if 'sort_by' in query_parms:
                if isinstance(query_parms['sort_by'], basestring):
                    query_parms['sort_by'] = [query_parms['sort_by']]

                allowed_sort_by = {
                    'alarm_id', 'alarm_definition_id', 'alarm_definition_name',
                    'state', 'severity', 'lifecycle_state', 'link',
                    'state_updated_timestamp', 'updated_timestamp',
                    'created_timestamp'
                }
                validation.validate_sort_by(query_parms['sort_by'],
                                            allowed_sort_by)

            # ensure metric_dimensions is a list
            if 'metric_dimensions' in query_parms and isinstance(
                    query_parms['metric_dimensions'], str):
                query_parms['metric_dimensions'] = query_parms[
                    'metric_dimensions'].split(',')
                self._validate_dimensions(query_parms['metric_dimensions'])

            offset = helpers.get_query_param(req, 'offset')
            if offset is not None and not isinstance(offset, int):
                try:
                    offset = int(offset)
                except Exception as ex:
                    LOG.exception(ex)
                    raise HTTPUnprocessableEntityError(
                        "Unprocessable Entity",
                        "Offset value {} must be an integer".format(offset))

            limit = helpers.get_limit(req)

            result = self._alarm_list(req.uri, tenant_id, query_parms, offset,
                                      limit)

            res.body = helpers.dumpit_utf8(result)
            res.status = falcon.HTTP_200

        else:
            result = self._alarm_show(req.uri, tenant_id, alarm_id)

            res.body = helpers.dumpit_utf8(result)
            res.status = falcon.HTTP_200
Exemple #11
0
def validate_sort_by(sort_by_list, allowed_sort_by):
    for sort_by_field in sort_by_list:
        sort_by_values = sort_by_field.split()
        if len(sort_by_values) > 2:
            raise HTTPUnprocessableEntityError(
                "Unprocessable Entity",
                "Invalid sort_by {}".format(sort_by_field))
        if sort_by_values[0] not in allowed_sort_by:
            raise HTTPUnprocessableEntityError(
                "Unprocessable Entity",
                "sort_by field {} must be one of [{}]".format(
                    sort_by_values[0], ','.join(list(allowed_sort_by))))
        if len(sort_by_values) > 1 and sort_by_values[1] not in [
                'asc', 'desc'
        ]:
            raise HTTPUnprocessableEntityError(
                "Unprocessable Entity",
                "sort_by value {} must be 'asc' or 'desc'".format(
                    sort_by_values[1]))
Exemple #12
0
def validate_query_dimensions(dimensions):
    """Validates the query param dimensions.

    :param dimensions: Query param dimensions.
    :raises falcon.HTTPBadRequest: If dimensions are not valid.
    """
    try:
        dimensions_schema.validate(dimensions)
    except schemas_exceptions.ValidationException as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
def get_query_alarm_definition_severity(alarm_definition, return_none=False):
    if 'severity' in alarm_definition:
        severity = encodeutils.safe_decode(alarm_definition['severity'], 'utf-8').upper()
        if severity not in ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL']:
            raise HTTPUnprocessableEntityError('Unprocessable Entity', 'Invalid severity')
        return severity
    else:
        if return_none:
            return None
        else:
            return 'LOW'
Exemple #14
0
    def _validate_alarm_definition(self, alarm_definition, require_all=False):

        try:
            schema_alarms.validate(alarm_definition, require_all=require_all)
            if 'match_by' in alarm_definition:
                for name in alarm_definition['match_by']:
                    metric_validation.validate_dimension_key(name)

        except Exception as ex:
            LOG.debug(ex)
            raise HTTPUnprocessableEntityError('Unprocessable Entity', str(ex))
Exemple #15
0
    def _validate_metrics(self, metrics):

        try:
            if isinstance(metrics, list):
                for metric in metrics:
                    self._validate_single_metric(metric)
            else:
                self._validate_single_metric(metrics)
        except Exception as ex:
            LOG.exception(ex)
            raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
Exemple #16
0
def validate_query_name(name):
    """Validates the query param name.

    :param name: Query param name.
    :raises falcon.HTTPBadRequest: If name is not valid.
    """
    try:
        metric_name_schema.validate(name)
    except schemas_exceptions.ValidationException as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
Exemple #17
0
def read_http_resource(req):
    """Read from http request and return json.

    :param req: the http request.
    """
    try:
        msg = req.stream.read()
        json_msg = simplejson.loads(msg)
        return json_msg
    except ValueError as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', 'Request body is not valid JSON')
Exemple #18
0
    def on_get(self, req, res, alarm_definition_id=None):
        if alarm_definition_id is None:
            helpers.validate_authorization(
                req, self._get_alarmdefs_authorized_roles)
            tenant_id = helpers.get_tenant_id(req)
            name = helpers.get_query_name(req)
            dimensions = helpers.get_query_dimensions(req)
            severity = helpers.get_query_param(req,
                                               "severity",
                                               default_val=None)
            if severity is not None:
                validation.validate_severity_query(severity)
            sort_by = helpers.get_query_param(req, 'sort_by', default_val=None)
            if sort_by is not None:
                if isinstance(sort_by, basestring):
                    sort_by = sort_by.split(',')

                allowed_sort_by = {
                    'id', 'name', 'severity', 'updated_at', 'created_at'
                }

                validation.validate_sort_by(sort_by, allowed_sort_by)

            offset = helpers.get_query_param(req, 'offset')
            if offset is not None and not isinstance(offset, int):
                try:
                    offset = int(offset)
                except Exception:
                    raise HTTPUnprocessableEntityError(
                        'Unprocessable Entity',
                        'Offset value {} must be an integer'.format(offset))
            limit = helpers.get_limit(req)

            result = self._alarm_definition_list(tenant_id, name, dimensions,
                                                 severity, req.uri, sort_by,
                                                 offset, limit)

            res.body = helpers.dumpit_utf8(result)
            res.status = falcon.HTTP_200

        else:
            helpers.validate_authorization(
                req, self._get_alarmdefs_authorized_roles)
            tenant_id = helpers.get_tenant_id(req)

            result = self._alarm_definition_show(tenant_id,
                                                 alarm_definition_id)

            helpers.add_links_to_resource(
                result, re.sub('/' + alarm_definition_id, '', req.uri))
            res.body = helpers.dumpit_utf8(result)
            res.status = falcon.HTTP_200
Exemple #19
0
def validate_query_name(name):
    """Validates the query param name.

    :param name: Query param name.
    :raises falcon.HTTPBadRequest: If name is not valid.
    """
    if not name:
        return
    try:
        metric_validation.validate_name(name)
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', str(ex))
def get_query_alarm_definition_name(alarm_definition, return_none=False):
    try:
        if 'name' in alarm_definition:
            name = alarm_definition['name']
            return name
        else:
            if return_none:
                return None
            else:
                raise Exception("Missing name")
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
Exemple #21
0
def get_query_group_by(req):
    try:
        params = falcon.uri.parse_query_string(req.query_string)
        if 'group_by' in params:
            group_by = params['group_by']
            if not isinstance(group_by, list):
                group_by = [group_by]
            return group_by
        else:
            return None
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
Exemple #22
0
def get_query_endtime_timestamp(req, required=True):
    try:
        params = falcon.uri.parse_query_string(req.query_string)
        if 'end_time' in params:
            return _convert_time_string(params['end_time'])
        else:
            if required:
                raise Exception("Missing end time")
            else:
                return None
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
def get_query_alarm_definition_expression(alarm_definition, return_none=False):
    try:
        if 'expression' in alarm_definition:
            expression = alarm_definition['expression']
            return expression
        else:
            if return_none:
                return None
            else:
                raise Exception("Missing expression")
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
Exemple #24
0
    def on_get(self, req, res, alarm_id=None):
        helpers.validate_authorization(req, ['api:alarms:get'])

        if alarm_id is None:
            query_parms = falcon.uri.parse_query_string(req.query_string)
            if 'state' in query_parms:
                validation.validate_alarm_state(query_parms['state'])
                query_parms['state'] = query_parms['state'].upper()

            if 'severity' in query_parms:
                validation.validate_severity_query(query_parms['severity'])
                query_parms['severity'] = query_parms['severity'].upper()

            if 'sort_by' in query_parms:
                if isinstance(query_parms['sort_by'], six.string_types):
                    query_parms['sort_by'] = query_parms['sort_by'].split(',')

                allowed_sort_by = {
                    'alarm_id', 'alarm_definition_id', 'alarm_definition_name',
                    'state', 'severity', 'lifecycle_state', 'link',
                    'state_updated_timestamp', 'updated_timestamp',
                    'created_timestamp'
                }
                validation.validate_sort_by(query_parms['sort_by'],
                                            allowed_sort_by)

            query_parms['metric_dimensions'] = helpers.get_query_dimensions(
                req, 'metric_dimensions')
            helpers.validate_query_dimensions(query_parms['metric_dimensions'])

            offset = helpers.get_query_param(req, 'offset')
            if offset is not None and not isinstance(offset, int):
                try:
                    offset = int(offset)
                except Exception as ex:
                    LOG.exception(ex)
                    raise HTTPUnprocessableEntityError(
                        "Unprocessable Entity",
                        "Offset value {} must be an integer".format(offset))

            result = self._alarm_list(req.uri, req.project_id, query_parms,
                                      offset, req.limit)

            res.body = helpers.to_json(result)
            res.status = falcon.HTTP_200

        else:
            result = self._alarm_show(req.uri, req.project_id, alarm_id)

            res.body = helpers.to_json(result)
            res.status = falcon.HTTP_200
    def _alarm_definition_create(self, tenant_id, name, expression,
                                 description, severity, match_by,
                                 alarm_actions, undetermined_actions,
                                 ok_actions):
        try:

            sub_expr_list = (
                monasca_api.expression_parser.alarm_expr_parser.
                AlarmExprParser(expression).sub_expr_list)

        except (pyparsing.ParseException,
                pyparsing.ParseFatalException) as ex:
            LOG.exception(ex)
            title = u"Invalid alarm expression"
            msg = u"parser failed on expression '{}' at column {}: {}".format(
                encodeutils.safe_decode(expression, 'utf-8'),
                encodeutils.safe_decode(str(ex.column), 'utf-8'),
                encodeutils.safe_decode(ex.msg, 'utf-8'))
            raise HTTPUnprocessableEntityError(title, msg)

        self._validate_name_not_conflicting(tenant_id, name)

        alarm_definition_id = (
            self._alarm_definitions_repo.
            create_alarm_definition(tenant_id,
                                    name,
                                    expression,
                                    sub_expr_list,
                                    description,
                                    severity,
                                    match_by,
                                    alarm_actions,
                                    undetermined_actions,
                                    ok_actions))

        self._send_alarm_definition_created_event(tenant_id,
                                                  alarm_definition_id,
                                                  name, expression,
                                                  sub_expr_list,
                                                  description, match_by)
        result = (
            {u'alarm_actions': alarm_actions, u'ok_actions': ok_actions,
             u'description': description, u'match_by': match_by,
             u'severity': severity, u'actions_enabled': True,
             u'undetermined_actions': undetermined_actions,
             u'expression': expression, u'id': alarm_definition_id,
             u'deterministic': is_definition_deterministic(expression),
             u'name': name})

        return result
Exemple #26
0
 def _validate_dimensions(dimensions):
     try:
         assert isinstance(dimensions, list)
         for dimension in dimensions:
             name_value = dimension.split(':')
             validation.dimension_key(name_value[0])
             if len(name_value) > 1:
                 if '|' in name_value[1]:
                     values = name_value[1].split('|')
                     for value in values:
                         validation.dimension_value(value)
                 else:
                     validation.dimension_value(name_value[1])
     except Exception as e:
         raise HTTPUnprocessableEntityError("Unprocessable Entity", e.message)
Exemple #27
0
    def on_post(self, req, res):
        helpers.validate_json_content_type(req)
        helpers.validate_authorization(req, ['api:metrics:post'])
        metrics = helpers.from_json(req)
        try:
            metric_validation.validate(metrics)
        except Exception as ex:
            LOG.exception(ex)
            raise HTTPUnprocessableEntityError("Unprocessable Entity", str(ex))

        tenant_id = helpers.get_x_tenant_or_tenant_id(req, ['api:delegate'])
        transformed_metrics = metrics_message.transform(
            metrics, tenant_id, self._region)
        self._send_metrics(transformed_metrics)
        res.status = falcon.HTTP_204
Exemple #28
0
def get_limit(req):
    limit = get_query_param(req, 'limit')

    if limit:
        if limit.isdigit():
            limit = int(limit)
            if limit > constants.PAGE_LIMIT:
                return constants.PAGE_LIMIT
            else:
                return limit
        else:
            raise HTTPUnprocessableEntityError(
                "Invalid limit", "Limit parameter must "
                "be a positive integer")
    else:
        return constants.PAGE_LIMIT
Exemple #29
0
def get_query_period(req):
    try:
        params = falcon.uri.parse_query_string(req.query_string)
        if 'period' in params:
            period = params['period']
            try:
                period = int(period)
            except Exception:
                raise Exception("Period must be a valid integer")
            if period < 0:
                raise Exception("Period must be a positive integer")
            return str(period)
        else:
            return None
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)
def get_query_alarm_definition_actions_enabled(alarm_definition,
                                               required=False,
                                               return_none=False):
    try:
        if 'actions_enabled' in alarm_definition:
            enabled_actions = alarm_definition['actions_enabled']
            return enabled_actions
        else:
            if return_none:
                return None
            elif required:
                raise Exception("Missing actions-enabled")
            else:
                return ''
    except Exception as ex:
        LOG.debug(ex)
        raise HTTPUnprocessableEntityError('Unprocessable Entity', ex.message)