ansible-role-puppet/library/puppet_post_puppetdb

151 lines
4.6 KiB
Python

#!/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 <http://www.gnu.org/licenses/>.
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
# remove some problematic facts from facts (if they exist)
# files can be a long list of files in a directory
if facts.get('files') is not None:
del facts['files']
# groups can be the entire ansible inventory
if facts.get('groups') is not None:
del facts['groups']
if facts:
# Don't post facts update if we don't have facts
payload = {
"command": "replace facts",
"version": 3,
"payload": {
"name": fqdn,
"environment": p['environment'],
"producer-timestamp": timestamp,
"values": facts }}
payload_dump = p['logfile'][:-4] + "facts_payload.json"
with open(payload_dump, 'w') as f:
f.write(json.dumps(payload))
try:
r = requests.post(endpoint, json=payload, **requests_kwargs)
except Exception as e:
module.fail_json(
msg="Exception: {e}".format(e=e),
puppetdb=p['puppetdb'],
endpoint=endpoint,
logfile=payload_dump)
log_data = json.load(open(p['logfile'], 'r'))
try:
r = requests.post(endpoint, json=log_data, **requests_kwargs)
except Exception as e:
module.fail_json(
msg="Exception: {e}".format(e=e),
puppetdb=p['puppetdb'],
endpoint=endpoint,
logfile=p['logfile'])
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 *
if __name__ == '__main__':
main()