#!/usr/bin/python

from __future__ import print_function
import sys
import json
import ipaddress
import requests
from optparse import OptionParser
from maasclient.auth import MaasAuth
from maasclient import MaasClient

# For some reason the maasclient doesn't provide a put method. So
# we will add it here
def put(client, url, params=None):
    return requests.put(url=client.auth.api_url + url,
                            auth=client._oauth(),
                            data=params)

def add_or_update_node_group_interface(client, ng, gw, foundIfc, ifcName, subnet):
    ip = ipaddress.IPv4Network(unicode(subnet, 'utf-8'))
    hosts = list(ip.hosts())

    # if the caller specified the default gateway then honor that, else used the default
    gw = gw or str(hosts[0])

    ifc = {
        'ip_range_high': str(hosts[-1]),
        'ip_range_low': str(hosts[2]),
	'static_ip_range_high' : None,
	'static_ip_range_low' : None,
        'management': 2,
        'name': ifcName,
        #'router_ip' : gw,
        #'gateway_ip' : gw,
        'ip': str(hosts[0]),
        'subnet_mask': str(ip.netmask),
        'broadcast_ip': str(ip.broadcast_address),
        'interface': ifcName,
    }

    if foundIfc is not None:
        print("INFO: network for specified interface, '%s', already exists" % (ifcName))

	resp = client.get('/nodegroups/' + ng['uuid'] + '/interfaces/' + ifcName + '/', dict())
	if int(resp.status_code / 100) != 2:
	    print("ERROR: unable to read specified interface, '%s', '%d : %s'"
	          % (ifcName, resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)

	# A bit of a hack here. Turns out MAAS won't return the router_ip / gateway_ip value
	# so we can't really tell if that value is set correctly. So we will compare the
	# values we can and use that as the "CHANGED" value, but always set all values.

	# Save the compare value
	same = ifc == json.loads(resp.text)

	# Add router_ip and gateway_ip to the desired state so that those will be set
	ifc['router_ip'] = gw
	ifc['gateway_ip'] = gw

        # If the network already exists, update it with the information we want
        resp = put(client, '/nodegroups/' + ng['uuid'] + '/interfaces/' + ifcName + '/', ifc)
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to update specified network, '%s', on specified interface '%s', '%d : %s'"
                   % (subnet, ifcName, resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)

        if not same:
            print("CHANGED: updated network, '%s', for interface '%s'" % (subnet, ifcName))
	else:
            print("INFO: Network settings for interface '%s' unchanged" % ifcName)

    else:
        # Add the operation
        ifc['op'] = 'new'
	ifc['router_ip'] = gw
        ifc['gateway_ip'] = gw

        resp = client.post('/nodegroups/' + ng['uuid'] + '/interfaces/', ifc)
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to create specified network, '%s', on specified interface '%s', '%d : %s'"
                % (subnet, ifcName, resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)
        else:
            print("CHANGED: created network, '%s', for interface '%s'" % (subnet, ifcName))

    # Add the first host to the subnet as the dns_server
    subnets = None
    resp = client.get('/subnets/', dict())
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to query subnets: '%d : %s'" % (resp.status_code, resp.text))
	sys.exit(1)
    else:
        subnets = json.loads(resp.text)

    id = None
    for sn in subnets:
        if sn['name'] == subnet:
            id = str(sn['id'])
            break

    if id == None:
        print("ERROR: unable to find subnet entry for network '%s'" % (subnet))
	sys.exit(1)

    resp = client.get('/subnets/' + id + '/')
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to query subnet '%s': '%d : %s'" % (subnet, resp.status_code, resp.text))
	sys.exit(1)

    data = json.loads(resp.text)

    found = False
    for ns in data['dns_servers']:
        if unicode(ns) == unicode(hosts[0]):
	    found = True

    if not found:
        resp = put(client, '/subnets/' + id + '/', dict(dns_servers=[hosts[0]]))
	if int(resp.status_code / 100) != 2:
            print("ERROR: unable to query subnet '%s': '%d : %s'" % (subnet, resp.status_code, resp.text))
	    sys.exit(1)
	else:
	    print("CHANGED: updated DNS server information")
    else:
        print("INFO: DNS already set correctly")
    

def main():
    parser = OptionParser()
    parser.add_option('-c', '--config', dest='config_file',
        help="specifies file from which configuration should be read", metavar='FILE')
    parser.add_option('-a', '--apikey', dest='apikey',
        help="specifies the API key to use when accessing MAAS")
    parser.add_option('-u', '--url', dest='url', default='http://localhost/MAAS/api/1.0',
        help="specifies the URL on which to contact MAAS")
    parser.add_option('-z', '--zone', dest='zone', default='administrative',
        help="specifies the zone to create for manually managed hosts")
    parser.add_option('-i', '--interface', dest='interface', default='eth0:1',
        help="the interface on which to set up DHCP for POD local hosts")
    parser.add_option('-n', '--network', dest='network', default='10.0.0.0/16',
        help="subnet to use for POD local DHCP")
    parser.add_option('-b', '--bridge', dest='bridge', default='mgmtbr',
        help="bridge to use for host local VM allocation")
    parser.add_option('-t', '--bridge-subnet', dest='bridge_subnet', default='172.18.0.0/16',
        help="subnet to assign from for bridged hosts")
    parser.add_option('-r', '--cluster', dest='cluster', default='Cluster master',
        help="name of cluster to user for POD / DHCP")
    parser.add_option('-s', '--sshkey', dest='sshkey', default=None,
        help="specifies public ssh key")
    parser.add_option('-d', '--domain', dest='domain', default='cord.lab',
        help="specifies the domain to configure in maas")
    parser.add_option('-g', '--gateway', dest='gw', default=None,
        help="specifies the gateway to configure for servers")
    (options, args) = parser.parse_args()

    if len(args) > 0:
        print("unknown command line arguments specified", file=sys.stderr)
        parser.print_help()
        sys.exit(1)

    # If a config file was specified then read the config from that
    config = {}
    if options.config_file != None:
        with open(options.config_file) as config_file:
            config = json.load(config_file)

    # Override the config with any command line options
    if options.apikey == None:
        print("must specify a  MAAS API key", file=sys.stderr)
        sys.exit(1)
    else:
        config['key'] = options.apikey
    if options.url != None:
        config['url'] = options.url
    if options.zone != None:
        config['zone'] = options.zone
    if options.interface != None:
        config['interface'] = options.interface
    if options.network != None:
        config['network'] = options.network
    if options.bridge != None:
        config['bridge'] = options.bridge
    if options.bridge_subnet != None:
        config['bridge-subnet'] = options.bridge_subnet
    if options.cluster != None:
        config['cluster'] = options.cluster
    if options.domain != None:
        config['domain'] = options.domain
    if options.gw != None:
        config['gw'] = options.gw
    if not 'gw' in config.keys():
        config['gw'] = None
    if options.sshkey == None:
        print("must specify a SSH key to use for cord user", file=sys.stderr)
        sys.exit(1)
    else:
        config['sshkey'] = options.sshkey
    
    auth = MaasAuth(config['url'], config['key'])
    client = MaasClient(auth)

    resp = client.get('/account/prefs/sshkeys/', dict(op='list'))
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to query SSH keys from server '%d : %s'"
	        % (resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    found_key = False
    keys = json.loads(resp.text)
    for key in keys:
	if key['key'] == config['sshkey']:
	    print("INFO: specified SSH key already exists")
            found_key = True

    # Add the SSH key to the user
    # POST /api/2.0/account/prefs/sshkeys/ op=new
    if not found_key:
        resp = client.post('/account/prefs/sshkeys/', dict(op='new', key=config['sshkey']))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to add sshkey for user: '%d : %s'"
                    % (resp.status_code, resp.text), file=sys.stderr)
            sys.exit(1)
	else:
	    print("CHANGED: updated ssh key")
    
    # Check to see if an "administrative" zone exists and if not
    # create one
    found = None
    zones = client.zones
    for zone in zones:
        if zone['name'] == config['zone']:
            found=zone
    
    if found is not None:
        print("INFO: administrative zone, '%s', already exists" % config['zone'], file=sys.stderr)
    else:
        if not client.zone_new(config['zone'], "Zone for manually administrated nodes"):
            print("ERROR: unable to create administrative zone '%s'" % config['zone'], file=sys.stderr)
            sys.exit(1)
        else:
            print("CHANGED: Zone '%s' created" % config['zone'])
    
    # If the interface doesn't already exist in the cluster then
    # create it. Look for the "Cluster Master" node group, but
    # if it is not found used the first one in the list, if the
    # list is empty, error out
    found = None
    ngs = client.nodegroups
    for ng in ngs:
        if ng['cluster_name'] == config['cluster']:
            found = ng
            break
    
    if found is None:
        print("ERROR: unable to find cluster with specified name, '%s'" % config['cluster'], file=sys.stderr)
        sys.exit(1)

    resp = client.get('/nodegroups/' + ng['uuid'] + '/', dict())
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to get node group information for cluster '%s': '%d : %s'"
	    % (config['cluster'], resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    data = json.loads(resp.text)
    
    # Set the DNS domain name (zone) for the cluster
    if data['name'] != config['domain']:
        resp = put(client, '/nodegroups/' + ng['uuid'] + '/', dict(name=config['domain']))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to set the DNS domain name for the cluster with specified name, '%s': '%d : %s'"
                % (config['cluster'], resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)
        else:
            print("CHANGE: updated name of cluster to '%s' : %s" % (config['domain'], resp))
    else:
        print("INFO: domain name already set")
    
    found = None
    resp = client.get('/nodegroups/' + ng['uuid'] + '/interfaces/', dict(op='list'))
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to fetch interfaces for cluster with specified name, '%s': '%d : %s'"
            % (config['cluster'], resp.status_code, resp.text), file=sys.stderr)
        sys.exit(1)
    ifcs = json.loads(resp.text)

    localIfc = hostIfc = None 
    for ifc in ifcs:
        localIfc = ifc if ifc['name'] == config['interface'] else localIfc
        hostIfc = ifc if ifc['name'] == config['bridge'] else hostIfc

    add_or_update_node_group_interface(client, ng, config['gw'], localIfc, config['interface'], config['network'])
    #add_or_update_node_group_interface(client, ng, config['gw'], hostIfc, config['bridge'], config['bridge-subnet'])

    # Update the server settings to upstream DNS request to Google
    # POST /api/2.0/maas/ op=set_config
    resp = client.get('/maas/', dict(op='get_config', name='upstream_dns'))
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to get the upstream DNS servers: '%d : %s'"
              % (resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    if unicode(json.loads(resp.text)) != u'8.8.8.8 8.8.8.4':
        resp = client.post('/maas/', dict(op='set_config', name='upstream_dns', value='8.8.8.8 8.8.8.4'))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to set the upstream DNS servers: '%d : %s'"
                % (resp.status_code, resp.text), file=sys.stderr)
        else:
            print("CHANGED: updated up stream DNS servers")
    else:
        print("INFO: Upstream DNS servers correct")

    # Start the download of boot images
    resp = client.get('/boot-resources/', None)
    if int(resp.status_code / 100) != 2:
        print("ERROR: unable to read existing images download: '%d : %s'" % (resp.status_code, resp.text), file=sys.stderr)
	sys.exit(1)

    imgs = json.loads(resp.text)
    found = False
    for img in imgs:
	if img['name'] == u'ubuntu/trusty' and img['architecture'] == u'amd64/hwe-t':
	    found = True

    if not found:
        resp = client.post('/boot-resources/', dict(op='import'))
        if int(resp.status_code / 100) != 2:
            print("ERROR: unable to start image download: '%d : %s'" % (resp.status_code, resp.text), file=sys.stderr)
	    sys.exit(1)
        else:
            print("CHANGED: Image download started")
    else:
	print("INFO: required images already available")
    
if __name__ == '__main__':
    #try:
        main()
    #except:
#	e = sys.exc_info()[0]
#	print("ERROR: Unexpected exception: '%s'" % e, file=sys.stderr)
