Friday, September 25, 2015

What version of a Perl CPAN module do I have installed?

[red@dev1 ~]$ perl -MDateTime -e"print DateTime->VERSION"; echo

0.4501

Wednesday, August 26, 2015

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]"
'''

Thursday, May 14, 2015

Listing Puppet Enterprise Groups in PE 3.7 with Python

some useful stackoverflow links:
http://stackoverflow.com/questions/30243480/how-to-parse-complex-json-in-python-2-7-5
#!/usr/bin/env python
import requests
import json
# 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
#
# 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
#
url='https://ppt-001.example.com:4433/classifier-api/v1/groups'
headers = {"Content-Type": "application/json"}data={}
cacert='/etc/puppetlabs/puppet/ssl/certs/ca.pem'
key='/etc/puppetlabs/puppet/ssl/private_keys/ppt-001.example.com.pem'
cert='/etc/puppetlabs/puppet/ssl/certs/ppt-001.example.com.pem'
result = requests.get(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 json.dumps( result.json(), sort_keys=True, indent=4, separators=(',', ': '))
for i in result.json():
        print i['name']
        print i['id']

Monday, May 04, 2015

good explanation of perl map

http://perlmeme.org/howtos/perlfunc/map_function.html

summary

Using the Perl map() function

Introduction

The map function is used for transforming lists element-wise: given a list and a code block, map builds a new list (or hash) with elements derived from the corresponding elements of the original.
The basic syntax is
    @out = map { CODE } @in;
where CODE is some perl code that is given an element of the list as $_ and returns the replacement value for the new list.

Example 1

Say you have a list of names, and you want to capitalise them all. We can use map along with the built-in function ucfirst to do them all at once:
    #!/usr/bin/perl
    use strict;
    use warnings;

    my @names = qw(bob anne frank jill);
    my @capitalised_names = map { ucfirst $_ } @names;

    foreach my $name (@capitalised_names) {
        print "$name\n";
    }
This produces the output:
    Bob
    Anne
    Frank
    Jill

Example 2: Multiple outputs per input

If your code block returns a list for each element, all the lists are concatenated into the result:
    #!/usr/bin/perl
    use strict;
    use warnings;

 my @names = qw(bob anne frank jill);

    my @everyone = map {
        $_, $_ . "'s dog", $_ . "'s cat"
    } @names;

    foreach my $name (@everyone) {
        print "$name\n";
    }
This produces the output:
    bob
    bob's dog
    bob's cat
    anne
    anne's dog
    anne's cat
    frank
    frank's dog
    frank's cat
    jill
    jill's dog
    jill's cat

Example 3: Producing a hash as output

Generating a hash is almost identical to earlier examples:
    #!/usr/bin/perl
    use strict;
    use warnings;

    my @names = qw(bob anne frank jill);

    my %lengths = map { $_ => length $_ } @names;

    while (my ($name, $length) = each %lengths) {
        print "'$name' has $length characters\n";
    }
This produces the output:
    'bob' has 3 characters
    'anne' has 4 characters
    'frank' has 5 characters
    'jill' has 4 characters

Example 4: Restructuring data

Say you have some data stored as a list of hashrefs and you want to convert it to a hash based on some key field id.
    #!/usr/bin/perl
    use strict;
    use warnings;

    my @array = ({
        id      => 1,
        name    => 'Bob',
    },{
        id      => 2,
        name    => 'Anne',
    },{
        id      => 3,
        name    => 'Frank'
    });

    my %hash = map { 
        $_->{id} => { name => $_->{name} } 
    } @array;

    for my $id (1..3) {
        my $name = $hash{$id}->{name};
        print "User $id: $name\n";
    }
This produces the output:
    User 1: Bob
    User 2: Anne
    User 3: Frank

See also

    perldoc -f map

Friday, April 24, 2015

Generating files based on puppet array

First off a big thank you to alexharv074 and ask.puppetlabs.com for giving me this solution.

I need to generate the files:

# more /tmp/rabbit-* /tmp/mongo-el7-001.cfg 
::::::::::::::
/tmp/rabbit-1.cfg
::::::::::::::
define host {
         use                     linux-server
         host_name               rabbit-1
         alias                   rabbit-1
         hostgroups              rabbit_hosts 
         address                 10.29.103.33
}
::::::::::::::
/tmp/rabbit-2.cfg
::::::::::::::
define host {
         use                     linux-server
         host_name               rabbit-2
         alias                   rabbit-2
         hostgroups              rabbit_hosts 
         address                 10.29.103.34
}
::::::::::::::
/tmp/mongo-el7-001.cfg
::::::::::::::
define host {
         use                     linux-server
         host_name               mongo-el7-001
         alias                   mongo-el7-001
         hostgroups              mongo_hosts 
         address                 10.29.103.31

}

... so I wrote this puppet class:

class make_files (
     $rabbit_servers = ['rabbit-1:10.29.103.33','rabbit-2:10.29.103.34'],
     $mongo_servers = ['mongo-el7-001:10.29.103.31'],
) {
    define my_file ($content, $hostgroup) {
          $tuple = split($name, ':')
          $host_name = $tuple[0]
          $file_name = "/tmp/$host_name.cfg"
          $ipaddress = $tuple[1]
          $config = "define host {
              use                     linux-server
              host_name               $host_name
              alias                   $host_name
              hostgroups              $hostgroup 
              address                 $ipaddress
}"

        file { $file_name:
          ensure  => file,
          content => $config,
        }
    }
    $rabbit_content = join($rabbit_servers, ',')
    my_file { $rabbit_servers: content => $rabbit_content, hostgroup => 'rabbit_hosts' }
    $mongo_content = join($mongo_servers, ',')
    my_file { $mongo_servers: content => $mongo_content, hostgroup => 'mongo_hosts' }
}

Tuesday, March 03, 2015

strace command


# strace -f -e trace=connect,read -s2048 glance --debug image-list > /tmp/st 2>&1

Wednesday, February 25, 2015

how to unblock hung unresponsive screen session

^a q

http://stackoverflow.com/questions/4367669/the-gnu-screen-is-unresponsive-seems-blocked

Thursday, January 22, 2015

disable selinux centos7

from http://blog.zwiegnet.com/linux-server/disable-selinux-centos-7/

summary:
[root@localhost ~]# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      28
now execute:

[root@localhost ~]# sed -i 's/enforcing/disabled/g' /etc/selinux/config 

then reboot

Friday, January 09, 2015

how to deference Data::Dumper output

see my post here:
http://stackoverflow.com/questions/27870579/how-do-i-dereference-datadumper-output