예제 #1
0
    def DELETE(self):
        """
    Delete models for multiple instances

    ::

        DELETE /_instances

    DELETE data:

    ::

        [
            "{region}/{namespace}/{instanceId}",
            ...
        ]

    Returns:

    ::

        {
            "result": "success"
        }
    """
        try:
            instances = json.loads(web.data())
        except:
            raise InvalidRequestResponse({"result": "Invalid request"})

        if not instances:
            raise InvalidRequestResponse(
                {"result": ("Missing instances in DELETE"
                            " request")})

        deleted = []
        if instances:
            for server in instances:
                if server.count("/") == 4:
                    (lhs, _, identifier) = server.rpartition("/")
                    (regionAndNamespace, _, _) = lhs.rpartition("/")
                    serverSansDimension = regionAndNamespace + "/" + identifier
                else:
                    serverSansDimension = server
                with web.ctx.connFactory() as conn:
                    modelIds = repository.listMetricIDsForInstance(
                        conn, serverSansDimension)
                if modelIds:
                    for modelId in modelIds:
                        ModelHandler.deleteModel(modelId)
                    deleted.append(server)

        if instances == deleted:
            self.addStandardHeaders()
            return encodeJson({'result': 'success'})

        raise web.notfound("Not able to delete %s" %
                           encodeJson(list(set(instances) - set(deleted))))
예제 #2
0
  def DELETE(self):
    """
    Delete models for multiple instances

    ::

        DELETE /_instances

    DELETE data:

    ::

        [
            "{region}/{namespace}/{instanceId}",
            ...
        ]

    Returns:

    ::

        {
            "result": "success"
        }
    """
    try:
      instances = json.loads(web.data())
    except:
      raise InvalidRequestResponse({"result": "Invalid request"})

    if not instances:
      raise InvalidRequestResponse({"result": ("Missing instances in DELETE"
                                               " request")})

    deleted = []
    if instances:
      for server in instances:
        if server.count("/") == 4:
          (lhs, _, identifier) = server.rpartition("/")
          (regionAndNamespace, _, _) = lhs.rpartition("/")
          serverSansDimension = regionAndNamespace + "/" + identifier
        else:
          serverSansDimension = server
        with web.ctx.connFactory() as conn:
          modelIds = repository.listMetricIDsForInstance(conn,
                                                         serverSansDimension)
        if modelIds:
          for modelId in modelIds:
            ModelHandler.deleteModel(modelId)
          deleted.append(server)

    if instances == deleted:
      self.addStandardHeaders()
      return encodeJson({'result': 'success'})

    raise web.notfound("Not able to delete %s" %
                       encodeJson(list(set(instances)-set(deleted))))
예제 #3
0
  def POST(self, region, namespace, instanceId=None):
    """
    Monitor a set of default metrics for a specific instance

    ::

        POST /_instances/{region}/{namespace}/{instanceId}

    Returns:

    ::

        {
            "result": "success"
        }

    OR

    Monitor a set of default metrics for multiple specific instances

    ::

        POST /_instances/{region}/{namespace}

    POST data:

    ::

        [
            {instanceId},
            ...
        ]

    Returns:

    ::

        {
            "result": "success"
        }

    Note:
    We expect a 200 OK even when attempting to POST to an instanece in the wrong
    namespace or the wrong region, this saves the overhead of asking AWS if
    we're dealing with a valid instance in the given namespace or region
    with every POST request.
    We expect the CLI user to know the correct instance ID.
    """
    if instanceId is None:
      try:
        dimension = None
        instances = json.loads(web.data())
      except:
        raise InvalidRequestResponse({"result": "Invalid request"})

    else:
      (dimension, _, identifier) = instanceId.rpartition("/")
      instances = [identifier]

    # Check for invalid region or namespace
    cwAdapter = datasource.createDatasourceAdapter("cloudwatch")

    supportedRegions = set(region for region, _desc in
                           cwAdapter.describeRegions())
    if region not in supportedRegions:
      raise InvalidRequestResponse({"result": ("Not supported. Region '%s' was"
                                               " not found.") % region})

    supportedNamespaces = set()
    for resourceInfo in cwAdapter.describeSupportedMetrics().values():
      for metricInfo in resourceInfo.values():
        supportedNamespaces.add(metricInfo["namespace"])
    if namespace not in supportedNamespaces:
      raise InvalidRequestResponse({"result": ("Not supported. Namespace '%s' "
                                               "was not found.") % namespace})

    try:
      # Attempt to validate instances list using validictory
      validate(instances, _INSTANCES_MODEL_CREATION_SCHEMA)
    except ValidationError as e:
      response = "InvalidArgumentsError: " + str(e)
      raise InvalidRequestResponse({"result": response})

    if instances:
      for instanceId in instances:
        server = "/".join([region, namespace, instanceId])
        with web.ctx.connFactory() as conn:
          numMetrics = repository.getMetricCountForServer(conn, server)
        if numMetrics > 0:
          # Metrics exist for instance id.
          pass

        else:
          try:
            resourceType = cloudwatch.NAMESPACE_TO_RESOURCE_TYPE[namespace]
          except KeyError:
            raise InvalidRequestResponse({"result": "Not supported."})

          modelSpecs = cwAdapter.getDefaultModelSpecs(
              resourceType, region, instanceId, dimension)

          for modelSpec in modelSpecs:
            ModelHandler.createModel(modelSpec)

    self.addStandardHeaders()
    return encodeJson({"result": "success"})
예제 #4
0
    def POST(self, region, namespace, instanceId=None):
        """
    Monitor a set of default metrics for a specific instance

    ::

        POST /_instances/{region}/{namespace}/{instanceId}

    Returns:

    ::

        {
            "result": "success"
        }

    OR

    Monitor a set of default metrics for multiple specific instances

    ::

        POST /_instances/{region}/{namespace}

    POST data:

    ::

        [
            {instanceId},
            ...
        ]

    Returns:

    ::

        {
            "result": "success"
        }

    Note:
    We expect a 200 OK even when attempting to POST to an instanece in the wrong
    namespace or the wrong region, this saves the overhead of asking AWS if
    we're dealing with a valid instance in the given namespace or region
    with every POST request.
    We expect the CLI user to know the correct instance ID.
    """
        if instanceId is None:
            try:
                dimension = None
                instances = json.loads(web.data())
            except:
                raise InvalidRequestResponse({"result": "Invalid request"})

        else:
            (dimension, _, identifier) = instanceId.rpartition("/")
            instances = [identifier]

        # Check for invalid region or namespace
        cwAdapter = datasource.createDatasourceAdapter("cloudwatch")

        supportedRegions = set(
            region for region, _desc in cwAdapter.describeRegions())
        if region not in supportedRegions:
            raise InvalidRequestResponse({
                "result": ("Not supported. Region '%s' was"
                           " not found.") % region
            })

        supportedNamespaces = set()
        for resourceInfo in cwAdapter.describeSupportedMetrics().values():
            for metricInfo in resourceInfo.values():
                supportedNamespaces.add(metricInfo["namespace"])
        if namespace not in supportedNamespaces:
            raise InvalidRequestResponse({
                "result": ("Not supported. Namespace '%s' "
                           "was not found.") % namespace
            })

        try:
            # Attempt to validate instances list using validictory
            validate(instances, _INSTANCES_MODEL_CREATION_SCHEMA)
        except ValidationError as e:
            response = "InvalidArgumentsError: " + str(e)
            raise InvalidRequestResponse({"result": response})

        if instances:
            for instanceId in instances:
                server = "/".join([region, namespace, instanceId])
                with web.ctx.connFactory() as conn:
                    numMetrics = repository.getMetricCountForServer(
                        conn, server)
                if numMetrics > 0:
                    # Metrics exist for instance id.
                    pass

                else:
                    try:
                        resourceType = cloudwatch.NAMESPACE_TO_RESOURCE_TYPE[
                            namespace]
                    except KeyError:
                        raise InvalidRequestResponse(
                            {"result": "Not supported."})

                    modelSpecs = cwAdapter.getDefaultModelSpecs(
                        resourceType, region, instanceId, dimension)

                    for modelSpec in modelSpecs:
                        ModelHandler.createModel(modelSpec)

        self.addStandardHeaders()
        return encodeJson({"result": "success"})