#!/usr/bin/python
#
#####################################################################################
# Scriptname	: sat6-register.py
# Scriptauthor	: Frank Reimer
# Creation date	: 2016-01-05
# License	: GPL v. 3
#
# This script was inspired by https://github.com/sideangleside/sat6-bootstrap
#
#####################################################################################
#
# Description:
#
# This script will help you to register your RHEL clients to your Satellite 6 server.
# This script also creates "Host" entries and configures the Puppet agent if needed.
# Unfortunately the given values are not selectable at the moment so you need to
# copy/paste the values if for example you are asked to select the organization your
# client should be assigned to. If you want to run this script unattended then you
# need to add ALL options mentioned in the sc
ript usage before using the "-u" flag.
# If you do not pass all values the script will ask you for the remaining. If you
# also want to update your system you can pass by the option "-U". Please ignore the
# following message during the first Puppet run:
#
# Warning: Local environment: "production" doesn't match server specified
 node
# environment [...]
#
#####################################################################################

import json
import getpass
import urllib2
import base64
import sys
import commands
import subprocess
import platform
import os.path
from datetime import datetime
from optparse import OptionParser
from uuid import getnode

devnull = open(os.devnull, 'w')

CURRENT_DATE = datetime.now().strftime('%Y-%m-%d_%H:%M:%S')

HOSTNAME  = platform.node().split(".")[0]
PUPPETFQDN= platform.node()
HEXMAC    = hex(getnode())
NOHEXMAC  = HEXMAC[2:]
MAC       = NOHEXMAC.zfill(13)[0:12]

class log:
	HEADER	= '\033[0;36m'
	ERROR	= '\033[1;31m'
	INFO	= '\033[0;32m'
	WARN	= '\033[1;33m'
	SUMM	= '\033[1;35m'
	END	= '\033[0m'

def get_json(url):
        # Generic function to HTTP GET JSON from Satellite's API
    try:
        request = urllib2.Request(urllib2.quote(url,':/'))
        base64string = base64.encodestring('%s:%s' % (LOGIN, PASSWORD)).strip()
        request.add_header("Authorization", "Basic %s" % base64string)
        result = urllib2.urlopen(request)
        return json.load(result)
    except urllib2.URLError, e:
        print "Error: cannot connect to the API: %s" % (e)
        print "Check your URL & try to login using the same user/pass via the WebUI and check the error!"
        sys.exit(1)
    except:
        print "FATAL Error - %s" % (e)
        sys.exit(2)

def post_json(url, jdata):
    try:
        opener = urllib2.build_opener(urllib2.HTTPHandler)
        request = urllib2.Request(url)
        base64string = base64.encodestring('%s:%s' % (LOGIN, PASSWORD)).strip()
        request.add_data(json.dumps(jdata))
        request.add_header("Authorization", "Basic %s" % base64string)
        request.add_header("Content-Type", "application/json")
        request.add_header("Accept", "application/json")
        #request.get_method = lambda: 'PUT'
        request.get_method = lambda: 'POST'
        url = opener.open(request)

    except urllib2.URLError, e:
        print "Error: cannot connect to the API: %s" % (e)
        print "Check your URL & try to login using the same user/pass via the WebUI and check the error!"
        sys.exit(1)
    except:
        print "FATAL Error - %s" % (e)
        sys.exit(2)

def return_organization_name():
	myurl = "https://" + SAT6_FQDN+ "/api/v2/organizations/"
	organizations = get_json(myurl)
	org_name= []
	for org in organizations['results']:
		name = str(org['name'])
		org_name.append(name)
	return org_name

def return_organization_id(orgname):
        myurl = "https://" + SAT6_FQDN+ "/api/v2/organizations/"
        organizations = get_json(myurl)
	org_id=''
        for orgid in organizations['results']:
		if str(orgid['name']) == orgname:
                	org_id = orgid['id']
			return org_id

def return_location_name():
        myurl = "https://" + SAT6_FQDN+ "/api/v2/locations/"
        locations = get_json(myurl)
        loc_name = []
        for loc in locations['results']:
                name = str(loc['name'])
                loc_name.append(name)
        return loc_name

def return_location_id(location):
	myurl = "https://" + SAT6_FQDN+ "/api/v2/locations/"
        locations = get_json(myurl)
        loc_id = ''
	for locid in locations['results']:
		if str(locid['name']) == location:
			loc_id = locid['id']
			return loc_id

def return_organization_label(orgname):
        myurl = 'https://' + SAT6_FQDN + '/katello/api/v2/organizations/' + str(orgname) + '/'
        orglabel = get_json(myurl)
        orglabel_name = str(orglabel['label'])
        return orglabel_name

def return_hostgroups():
	myurl = "https://" + SAT6_FQDN+ "/api/v2/hostgroups/"
	hostgroups = get_json(myurl)
	hg_name = []
	for hg in hostgroups['results']:
		name = str(hg['name']) + " \t\t(parent: " + str(hg['title'] + ")")
		hg_name.append(name)
	return hg_name

def return_hostgroup_id(hostgroup):
	myurl = "https://" + SAT6_FQDN+ "/api/v2/hostgroups/"
        hostgroups = get_json(myurl)
        hg_id = ''
	for hgid in hostgroups['results']:
                if str(hgid['name']) == hostgroup:
                        hg_id = hgid['id']
                        return hg_id

def return_capsule_name():
	myurl = "https://" + SAT6_FQDN+ "/katello/api/capsules/"
        capsules = get_json(myurl)
	capsule_name = [] 
        for capsule in capsules['results']:
                name = str(capsule['name'])
		capsule_name.append(name)	
		#capsules.append(str(capsule_name))
	return capsule_name

def return_activation_key_name(orgid):
	myurl = 'https://' + SAT6_FQDN + '/katello/api/v2/organizations/' + str(orgid) + '/activation_keys/'
	activationkeys = get_json(myurl)
	activationkey_name = []
	for activationkey in activationkeys['results']:
		act_name = str(activationkey['name'])
		activationkey_name.append(act_name)
	return activationkey_name

def register_system(destination,activationkey,organization):
	cmd_yum = "/usr/bin/yum -y localinstall http://" + destination + "/pub/katello-ca-consumer-latest.noarch.rpm --nogpgcheck"
	cmd_sub = "/usr/sbin/subscription-manager register --org " + organization + " --activationkey " + activationkey
	print log.INFO + "INFO: Calling subscription-manager to register your system" + log.END
	try:
		subprocess.call(cmd_yum, shell=True, stdout=subprocess.PIPE)
		subprocess.call(cmd_sub, shell=True, stdout=subprocess.PIPE)
		print log.INFO + "INFO: your system was successfully registered." + log.END
		
	except:
		print log.ERROR + "ERROR: failed to run Subscription Manager. EXIT." + log.END
		sys.exit(1)

def update_system():
	cmd_update = "/usr/bin/yum update -y"
	try:
		subprocess.call(cmd_update, shell=True, stdout=subprocess.PIPE)
		print log.INFO + "INFO: your system was successfully updated." + log.END
	except:
		print log.ERROR + "ERROR: failed to update your system Please check /var/log/messages for more informations." + log.END

def check_subscription_manager_status():
	cmd_check = '/usr/sbin/subscription-manager status'
	if subprocess.call(cmd_check, shell=True, stdout=subprocess.PIPE) == 0:
		return 0
	else:
		return 1

def install_needed_packages():
	cmd_yum = "/usr/bin/yum install -y katello-agent --nogpgcheck"
	print log.INFO + "INFO: Installing katello-agent." + log.END
        try:
                subprocess.call(cmd_yum, shell=True, stdout=subprocess.PIPE)
                print log.INFO + "INFO: katello-agent sucessfully installed." + log.END
	except:
                print log.ERROR + "ERROR: failed to install katello-agent. EXIT." + log.END
                sys.exit(1)

def create_new_host(hostgroup,location,organization):
        orgid = return_organization_id(organization)
	locid = return_location_id(location)
	hgid = return_hostgroup_id(hostgroup)
	jsondata = json.loads('{"host": {"name": "%s","hostgroup_id": %s,"organization_id": %s,"location_id": %s,"mac":"%s"}}' % (HOSTNAME,hgid,orgid,locid,MAC))
	myurl = "https://" + SAT6_FQDN + "/api/v2/hosts/"
	print log.INFO + "INFO: Calling Satellite 