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
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)
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
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
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
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)))