Пример #1
0
def delete_target(target_id):
    """Removes a target."""

    logger.info("DELETE: path={}, client={}, ID={}".format(request.path, request.remote_addr, target_id))

    try:
        target = Target.get(Target.id == target_id)
    except Target.DoesNotExist:
        abort(404, "Target with this ID doesn't exists.")

    target.delete_instance(recursive=True)

    # Generate YAML files
    generate_targets_yaml()

    logger.info("Target ID {} deleted.".format(target.id))
    return '', 204
Пример #2
0
def get_single_targets(target_id):
    """Returns a single target."""

    logger.info("GET: path={}, client={}, target_id={}".format(request.path, request.remote_addr, target_id))

    try:
        tg_entry = Target.get(Target.id == target_id)
    except Target.DoesNotExist:
        abort(404, "Target with this ID doesn't exists.")

    target = {"id": tg_entry.id,
              "target": tg_entry.host,
              "job": tg_entry.job.name,
              "labels": create_labels_hash(tg_entry.labels)
              }

    logger.debug("Showing target ID {}.".format(tg_entry.id))
    return jsonify(target)
Пример #3
0
def get_targets():
    """Returns all targets."""

    logger.info("GET: path={}, client={}".format(request.path, request.remote_addr))

    targets = []
    for target in Target.select():

        # Add target to array, so we can return an array of all targets.
        targets.append({
            "id": target.id,
            "target": target.host,
            "job": target.job.name,
            "labels": create_labels_hash(target.labels)
        })

    logger.debug("Showing all targets.")
    return jsonify(targets), 200
Пример #4
0
def update_target(target_id):
    """Creates or updates an existing target."""

    document = request.json

    logger.info("PUT: path={}, client={}, ID={}".format(request.path, request.remote_addr, target_id))
    logger.debug("PUT: document={}".format(document))

    # Check if we received a valid document and fail with error message.
    validate_document(document)

    # Update target if it exists, else create it
    if Target.get_or_none(Target.id == target_id):
        logger.debug("Updating record with ID {}".format(target_id))

        # Get target
        target = Target.get(Target.id == target_id)

        # Remove existing labels, will readd them later
        Label.delete().where(Label.target == target_id).execute()

        # Update target
        target.host = document['target']
        target.job = Job.get(Job.name == document['job'])
        target.save()

        # Create labels if they are passed in document
        if 'labels' in document:
            for label, value in document['labels'].items():
                Label.create(target=target, label=label, value=value)

        return_code = 200
        logger.info("Target '{}' updated.".format(target.host))

    else:
        logger.debug("Creating record with ID {}".format(target_id))

        # Create new target
        target = Target.create( id=target_id,
                                host=document['target'],
                                job=Job.get(Job.name == document['job']))

        # Create labels if they are passed in document
        if 'labels' in document:
            for label, value in document['labels'].items():
                Label.create(target=target, label=label, value=value)

        return_code = 201
        logger.info("Target '{}' created.".format(target.host))

    # Generate YAML files
    generate_targets_yaml()

    # Add ID field in returned document.
    document['id'] = target.id

    # Return document with correct return code based on event (update or create)
    return jsonify(document), return_code
Пример #5
0
def create_target():
    """
    Creates a new target.
    ---
    tags:
      - targets
    definitions:
      - schema:
          id: Target
          properties:
            target:
             type: string
            job:
             type: string
            labels:
              type: hash
              items:
                $ref: "#/definitions/Label"
          id: Label
          properties:
            target_id:
              type: integer
            label:
              type: string
            value:
              type: string

    # parameters:
    #   - in: body
    #     name: body
    #     schema:
    #       id: Target
    #       required:
    #         - target
    #         - job
    #       properties:
    #         target:
    #           type: string
    #           description: target's fqdn
    #         job:
    #           type: string
    #           description: exporter's name
    #         labels:
    #           type: object
    #           properties:
    #             label_name:
    #               type: string
    #           description: list of labels
    responses:
      201:
        description: Target created
      400:
        description: Mailformed JSON, labels not array or missing field.
    """

    document = request.json

    logger.info("POST: path={}, client={}".format(request.path, request.remote_addr))
    logger.debug("POST: document={}".format(document))

    # Check if we received a valid document and fail with error message.
    validate_document(document)

    # Check if this target/job pair already exists
    target_exists = Target.select().where(
        Target.host == document['target'],
        Target.job == Job.select().where(Job.name == document['job'])
    ).exists()
    if target_exists:
        logger.debug("Target {} exists.".format(document['target']))
        abort(409, 'This target already exists. If you want to modify it, use PUT request.')

    # Get job object
    job = Job.get(Job.name == document['job'])

    # Create target
    target = Target.create(host=document['target'], job=job)

    # Create labels if they are passed in document
    if 'labels' in document:
        for label, value in document['labels'].items():
            Label.create(target=target, label=label, value=value)

    # Generate YAML files
    generate_targets_yaml()

    # Add ID field in returned document.
    document['id'] = target.id

    logger.info("Target '{}' added.".format(target.host))
    return jsonify(document), 201
Пример #6
0
def generate_targets_yaml():
    """ Generate and write YAML files for ingestion by Prometheus file SD. """
    targets = {}

    yaml_dir = os.path.join(config.PROMETHEUS_YAML_DIR)

    if not os.path.isdir(yaml_dir):
        try:
            os.makedirs(yaml_dir, 0o755)
        except os.error:
            logger.critical("Prometheus YAML directory can't be created.")


    for target in Target.select():
        # Create required label
        labels = {"job": target.job.name}

        # Add other labels if present
        for label in target.labels:
            labels[label.label] = label.value
            # labels.append({label.label: label.value})

        # Generate configuration for single target
        single_target = {
            "targets": [target.host + ":" + str(target.job.port)],
            "labels": labels}

        # Append target to job's array, so we can dump same jobs to same file: {"job": [target1, target2,...]...}
        targets.setdefault(target.job.name, []).append(single_target)


    # Get a list of all YAML files, so we can remove unchanged ones.
    f_to_delete = [f for f in os.listdir(yaml_dir) if os.path.isfile(os.path.join(yaml_dir, f))]

    # Create YAML files for prometheus file SD
    for k, v in targets.items():
        file_path = os.path.join(yaml_dir, k + ".yaml")
        try:
            file = open(file_path, "w")
        except FileNotFoundError:
            logger.error("Could not save YAML files. Folder '{}' doesn't exists.".format(config.PROMETHEUS_YAML_DIR))
            abort(500)
        except PermissionError:
            logger.error("Could not write to file '{}'.".format(file_path))
            abort(500)
        except:
            logger.info("Unexpected error:", exc_info=True)
            abort(500)
        file.write(dump(v, default_flow_style=False))
        file.close()

        # If file was modified, remove it from array. Pass if file is not in array (new file).
        try:
            f_to_delete.remove(k + ".yaml")
        except ValueError:
            pass

    # If we still have files in array, remove them because they are empty
    if len(f_to_delete) > 0:
        for f_delete in f_to_delete:
            os.remove(os.path.join(yaml_dir, f_delete))

    logger.info("YAML files generated in '{}'".format(os.path.abspath(config.PROMETHEUS_YAML_DIR)))