def validate(self): validator = pupa.utils.DatetimeValidator(required_by_default=False) try: validator.validate(self.as_dict(), self.schema) except ValidationError as ve: raise ValidationError('validation of {} {} failed: {}'.format( self.__class__.__name__, self._form_jurisdiction, ve) )
def validate(self, schema=None): """ Validate that we have a valid object. On error, this will either raise a `ValueError` or a `validictory.ValidationError` (a subclass of `ValueError`). This also expects that the schemas assume that omitting required in the schema asserts the field is optional, not required. This is due to upstream schemas being in JSON Schema v3, and not validictory's modified syntax. """ if schema is None: schema = self._schema validator = utils.DatetimeValidator(required_by_default=False, fail_fast=False) try: validator.validate(self.as_dict(), schema) except ValidationError as ve: raise ValidationError('validation of {} {} failed: {}'.format( self.__class__.__name__, self._id, ve))
def PUT(self, modelId=None): """ Create Model :: POST /_models Data: Use the metric as returned by the datasource metric list. For example, create a Cloudwatch model as follows: :: curl http://localhost:8081/_models -X POST -d ' { "region": "us-east-1", "namespace": "AWS/EC2", "datasource": "cloudwatch", "metric": "CPUUtilization", "dimensions": { "InstanceId": "i-12345678" } }' Or to create a Grok custom model, include the following data in the POST request (uid is the same for the metric and model): :: { "uid": "2a123bb1dd4d46e7a806d62efc29cbb9", "datasource": "custom", "min": 0.0, "max": 5000.0 } The "min" and "max" options are optional for both Cloudwatch and Grok custom metrics. """ if modelId: # ModelHandler is overloaded to handle both single-model requests, and # multiple-model requests. As a result, if a user makes a POST, or PUT # request, it's possible that the request can be routed to this handler # if the url pattern matches. This specific POST handler is not meant # to operate on a known model, therefore, raise an exception, and return # a `405 Method Not Allowed` response. raise NotAllowedResponse({"result": "Not supported"}) data = web.data() if data: try: if isinstance(data, basestring): request = utils.jsonDecode(data) else: request = data except ValueError as e: response = "InvalidArgumentsError(): " + repr(e) raise InvalidRequestResponse({"result": response}) if not isinstance(request, list): request = [request] response = [] for nativeMetric in request: try: # Attempt to validate the request data against a schema # TODO: Move this logic into datasource-specific adapters if ("type" in nativeMetric.keys() and nativeMetric["type"] == "autostack"): validate(nativeMetric, _AUTOSTACK_CREATION_SCHEMA) elif nativeMetric["datasource"] == "custom": validate(nativeMetric, _CUSTOM_MODEL_CREATION_SCHEMA) elif nativeMetric["datasource"] == "autostack": validate(nativeMetric, _AUTOSTACK_MODEL_IMPORT_SCHEMA) else: validate(nativeMetric, _CLOUDWATCH_MODEL_CREATION_SCHEMA) # Perform additional cloudwatch-specific validation that can't be # captured properly in schema. if "metricSpec" in nativeMetric: # New-style arg metricSpec = nativeMetric["metricSpec"] else: # Legacy arg metricSpec = nativeMetric if (not isinstance(metricSpec["dimensions"], dict) or not metricSpec["dimensions"] or not all(key and value for (key, value) in metricSpec["dimensions"].iteritems())): raise ValidationError( "At least one dimension is required") except ValidationError as e: # Catch ValidationError if validation fails # InvalidRequestResponse produces an HTTP 400 error code response = "InvalidArgumentsError(): " + repr(e) raise InvalidRequestResponse({"result": response}) else: # Metric data is missing log.error( "Data is missing in request, raising BadRequest exception") raise web.badrequest("Metric data is missing") try: self.addStandardHeaders() metricRowList = self.createModels(data) metricDictList = [ formatMetricRowProxy(metricRow) for metricRow in metricRowList ] response = utils.jsonEncode(metricDictList) raise web.created(response) except web.HTTPError as ex: if bool(re.match("([45][0-9][0-9])\s?", web.ctx.status)): # Log 400-599 status codes as errors, ignoring 200-399 log.error(str(ex) or repr(ex)) raise except Exception as ex: log.exception("PUT Failed") raise web.internalerror(str(ex) or repr(ex))