Friday, May 15, 2015

Adding Groups, adding classes to Group, and adding nodes to Group with Puppet Enterprise 3.7's REST API and python

#!/usr/bin/env python

import requests
import json
import sys
import getopt

#
# if you get this error message:
#
#requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL #routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
#
# try executing: # pip install requests[security]
#
# to install pip execute:
#
# yum install python-pip
#

def usage(msg):
        print """
usage: add-group.py -p <FQDN of puppet master> -g <Group to add> -c <Class to assign to group> <node> [node]

        add-group.py will add the specified group to the specified Puppet Master's
        dashboard and assign the specified class to that group.  Also add-group.py
        will assigned the listed nodes to the specified group.

        example:

                $ ./add-group.py -p ppt-001.example.com \\
                > -g OSC4-Controller \\
                > -c wrapcontroller \\
                > mgmt-001 mgmt-002 mgmt-003

%s
""" % msg

'''
        p is puppetmaster
        g is group
        c is class
'''
def add_group(p,g,c):

        url="https://%s:4433/classifier-api/v1/groups" % p
        headers = {"Content-Type": "application/json"}
        data="{ \"name\": \"%s\", \"parent\": \"00000000-0000-4000-8000-000000000000\", \"environment\": \"production\", \"classes\": { \"%s\": {}} }" % (g,c)
        cacert='/etc/puppetlabs/puppet/ssl/certs/ca.pem'
        key="/etc/puppetlabs/puppet/ssl/private_keys/%s.pem" % p
        cert="/etc/puppetlabs/puppet/ssl/certs/%s.pem" % p
        result = requests.post(url,
                data=data, #no data needed for this request
                headers=headers, #dict {"Content-Type":"application/json"}
                cert=(cert,key), #key/cert pair
                verify=cacert
                )
        
        try:
                grp_id = result.json()['id']
        except:
                print "\nError:\n %s\n" % result.json()['msg']
                sys.exit(2)
        return grp_id

def assign_nodes(p,gid,nodes):
        url="https://%s:4433/classifier-api/v1/groups/%s" % (p,gid)
        headers = {"Content-Type": "application/json"}
        #
        # build the form data
        #
        data="{ \"rule\": [\"or\", "
        print "nodes=%s" % nodes
        # for i in nodes.split():
        for i in nodes:
                data += "[\"=\", \"name\", \"%s\"]," % i
        # knock off unneeded last comma
        data = data[:-1]
        data += "]}"
        print "\n:%s:\n" % data
        cacert='/etc/puppetlabs/puppet/ssl/certs/ca.pem'
        key="/etc/puppetlabs/puppet/ssl/private_keys/%s.pem" % p
        cert="/etc/puppetlabs/puppet/ssl/certs/%s.pem" % p
        result = requests.post(url,
                data=data, #no data needed for this request
                headers=headers, #dict {"Content-Type":"application/json"}
                cert=(cert,key), #key/cert pair
                verify=cacert
                )
        print result.json()

def main(argv):
        puppet_master = ''
        group_to_add  = ''
        class_to_add  = ''
        try:
                opts, args = getopt.getopt(argv,"hp:g:c:",["puppetmaster=","group=","class="])
        except getopt.GetoptError:
                usage ('usage error')
                sys.exit(2)

        for opt, arg in opts:
                if opt == '-h':
                        usage ('help called')
                        sys.exit()
                elif opt in ("-p", "--puppetmaster"):
                        puppet_master = arg
                elif opt in ("-g", "--group"):
                        group_to_add = arg
                elif opt in ("-c", "--class"):
                        class_to_add = arg

        if not puppet_master:
                usage ('Please specifiy puppet master with -p')
                sys.exit(2)
        if not group_to_add:
                usage ('Please specifiy group to add with -g')
                sys.exit(2)
        if not class_to_add:
                usage ('Please specifiy class to add with -c')
                sys.exit(2)

        print 'Puppet Master is [%s]' % puppet_master
        print 'Group to add is [%s]' % group_to_add
        print 'Class to add is [%s]' % class_to_add
        print args
        grp_id = add_group( puppet_master, group_to_add, class_to_add )
        print "Group id [%s]" % grp_id
        assign_nodes(puppet_master,grp_id,args)

if __name__ == "__main__":
        main(sys.argv[1:])

#
# Notes:
#
# curl https://${PEFQDN}:4433/classifier-api/v1/groups \
# -H "Content-Type: application/json" \
# --cert /etc/puppetlabs/puppet/ssl/certs/${PEFQDN}.pem \
# --key /etc/puppetlabs/puppet/ssl/private_keys/${PEFQDN}.pem \


# --cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem | python -m json.tool
#
# curl -X POST -H 'Content-Type: application/json' \
# --cert /etc/puppetlabs/puppet/ssl/certs/${PEFQDN}.pem \
# --key /etc/puppetlabs/puppet/ssl/private_keys/${PEFQDN}.pem \
# --cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem \
# --data "{ \"name\": \"$GROUP\", \"parent\": \"00000000-0000-4000-8000-000000000000\",
# \"environment\": \"production\", \"classes\": { \"$CLASS\": {}} }" \
# https://${PEFQDN}:4433/classifier-api/v1/groups | python -m json.tool
'''
curl -X POST -H 'Content-Type: application/json' \
  --cert /etc/puppetlabs/puppet/ssl/certs/${PEFQDN}.pem \
  --key /etc/puppetlabs/puppet/ssl/private_keys/${PEFQDN}.pem \
  --cacert /etc/puppetlabs/puppet/ssl/certs/ca.pem \
  -d '{ "rule": ["or", ["=", "name", "mgmt-001"], ["=", "name", "mgmt-002"], ["=", "name", "mgmt-003"]] }' \
https://${PEFQDN}:4433/classifier-api/v1/groups/$GROUP | python -m json.tool
     '{ "rule": ["or", ["=", "name", "node1"]            , ["=", "name", "node2"]            , ["=", "name", "node3"]}'
echo $NODES
DATA="'{ \"rule\": [\"or\", "
for i in $NODES
do
        DATA="${DATA} [\"=\", \"name\", \"$i\"],"

done

DATA=`echo $DATA | sed -e's/.$//g'`
DATA="${DATA}] }'"
echo "data is [$DATA]"
'''

No comments:

Post a Comment