#!/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, low, high):
    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_low': low if low != "" else str(hosts[2]),
        'ip_range_high': high if high != "" else str(hosts[-1]),
        '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('-l', '--network-low', dest='network_low', default='',
        help="low address in network to lease via DHCP")
    parser.add_option('-H', '--network-high', dest='network_high', default='',
        help="high address in network to lease via 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.network_low != None:
        config['network_low'] = options.network_low
    if options.network_high != None:
        config['network_high'] = options.network_high
    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'],
         config['network_low'], config['network_high'])
    #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)
