From 92c56e9e9955c117a5aba06a13bfd35c31a1dcec Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Fri, 30 Oct 2015 15:24:17 +0900 Subject: [PATCH] Fetch puppet logs and facts after puppet run After we run puppet, we should copy the puppet logs back to the host so that we can inject them into puppetdb. Change-Id: I51332b02950d6fb4d4ff0c1edeca774d84df4270 --- library/puppet_post_puppetdb | 125 +++++++++++++++++++++++++++++++++++ tasks/main.yml | 22 ++++++ 2 files changed, 147 insertions(+) create mode 100644 library/puppet_post_puppetdb diff --git a/library/puppet_post_puppetdb b/library/puppet_post_puppetdb new file mode 100644 index 0000000..9b79cb1 --- /dev/null +++ b/library/puppet_post_puppetdb @@ -0,0 +1,125 @@ +#!/usr/bin/python + +# Copyright (c) 2015 IBM +# +# This module is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software. If not, see . + +import json +import os +import requests + +DOCUMENTATION = ''' +--- +module: puppet_post_puppetdb +short_description: Posts facts and logfile to a puppetdb server +description: + - Posts facts and logfile to a puppetdb server +version_added: "2.0" +options: + puppetdb: + description: + - The hostname of the puppetdb server to post to + required: true + hostvars: + desciption: + - Ansible hostvars to pull facts from + required: true + logfile: + desciption: + - Absolute path of the Puppet logfile to post + required: true + whoami: + description: + - FQDN of the host that is contacting the puppetdb + required: true + environment: + desciption: + - Puppet environment to be used. + required: false + default: production +requirements: [ puppet ] +author: "Monty Taylor (@emonty)" +''' + +EXAMPLES = ''' +# Post the facter facts to puppetdb.openstack.org +- puppet_post_facts: + hostvars: hostvars[inventory_hostname] + puppetdb: puppetdb.openstack.org + logfile: /var/lib/puppet/reports/review.openstack.org/20151030.json + whoami: puppetmaster.openstack.org +''' + + +def main(): + module = AnsibleModule( + argument_spec=dict( + puppetdb=dict(required=True), + hostvars=dict(required=True), + logfile=dict(required=True), + whoami=dict(required=True), + environment=dict(required=False, default='production'), + ), + supports_check_mode=True, + ) + p = module.params + endpoint = '{puppetdb}/v3/commands'.format(puppetdb=p['puppetdb']) + fqdn = p['hostvars']['inventory_hostname'] + whoami = p['whoami'] + cert = '/var/lib/puppet/ssl/certs/{whoami}.pem'.format(whoami=whoami) + key = '/var/lib/puppet/ssl/private_keys/{whoami}.pem'.format(whoami=whoami) + cacert = '/var/lib/puppet/ssl/ca/ca_crt.pem' + requests_kwargs = dict(cert=(cert, key), verify=cacert) + try: + dt = os.path.basename(p['logfile']).split('_')[0] + timestamp = "{0}-{1}-{2}".format(dt[0:4], dt[4:6], dt[6:8]) + except: + # we don't REALLY care about this - but might as well give it a stab + timestamp = '2015-01-01' + + facts = {} + for k, v in p['hostvars'].items(): + if k.startswith('facter_'): + facts[k[7:]] = v + payload = { + "command": "replace facts", + "version": 3, + "payload": { + "name": fqdn, + "environment": p['environment'], + "producer-timestamp": timestamp, + "values": facts }} + + r = requests.post(endpoint, json=payload, **requests_kwargs) + if r.status_code != 200: + module.fail_json( + rc=r.status_code, + msg="Failed to post facts to {puppetdb}".format( + puppetdb=p['puppetdb'])) + + log_data = json.load(open(p['logfile'], 'r')) + r = requests.post(endpoint, json=log_data, **requests_kwargs) + if r.status_code != 200: + module.fail_json( + rc=r.status_code, + msg="Failed to post log data to {puppetdb}".format( + puppetdb=p['puppetdb'])) + + # success with changes + module.exit_json(rc=0, changed=True) + +# import module snippets +from ansible.module_utils.basic import * + +main() diff --git a/tasks/main.yml b/tasks/main.yml index 0a6325f..4f78bc5 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -53,3 +53,25 @@ show_diff: "{{ show_diff|default(false) }}" facts: "{{ facts|default(omit) }}" facter_basename: "{{ facter_basename|default(omit) }}" +- name: find logs + shell: "ls -tr /var/lib/puppet/reports/{{ inventory_hostname }}/*_puppetdb.json" + register: files + when: puppetdb is defined +- name: set log filename + set_fact: puppet_logfile="{{ files.stdout_lines|sort|last }}" + when: puppetdb is defined +- name: fetch file + synchronize: + mode: pull + src: "{{ puppet_logfile }}" + dest: /var/lib/puppet/reports/{{ inventory_hostname }} + when: puppetdb is defined +- name: post facts + puppet_post_puppetdb: + puppetdb: "{{ puppetdb }}" + hostvars: "{{ hostvars[inventory_hostname] }}" + logfile: "{{ puppet_logfile }}" + whoami: "{{ whoami }}" + delegate_to: localhost + connection: local + when: puppetdb is defined