#!/usr/bin/env python

'''Deploy docker-ci report container on Digital Ocean.
Usage:
    export CONFIG_JSON='
        { "DROPLET_NAME":        "Digital_Ocean_dropplet_name",
          "DO_CLIENT_ID":        "Digital_Ocean_client_id",
          "DO_API_KEY":          "Digital_Ocean_api_key",
          "DOCKER_KEY_ID":       "Digital_Ocean_ssh_key_id",
          "DOCKER_CI_KEY_PATH":  "docker-ci_private_key_path",
          "DOCKER_CI_PUB":       "$(cat docker-ci_ssh_public_key.pub)",
          "DOCKER_CI_ADDRESS"    "user@docker-ci_fqdn_server",
          "SMTP_USER":           "SMTP_server_user",
          "SMTP_PWD":            "SMTP_server_password",
          "EMAIL_SENDER":        "Buildbot_mailing_sender",
          "EMAIL_RCP":           "Buildbot_mailing_receipient" }'
    python deployment.py
'''

import re, json, requests, base64
from fabric import api
from fabric.api import cd, run, put, sudo
from os import environ as env
from time import sleep
from datetime import datetime

# Populate environment variables
CONFIG = json.loads(env['CONFIG_JSON'])
for key in CONFIG:
    env[key] = CONFIG[key]

# Load DOCKER_CI_KEY
env['DOCKER_CI_KEY'] = open(env['DOCKER_CI_KEY_PATH']).read()

DROPLET_NAME = env.get('DROPLET_NAME','report')
TIMEOUT = 120            # Seconds before timeout droplet creation
IMAGE_ID = 1004145       # Docker on Ubuntu 13.04
REGION_ID = 4            # New York 2
SIZE_ID = 66             # memory 512MB
DO_IMAGE_USER = 'root'   # Image user on Digital Ocean
API_URL = 'https://api.digitalocean.com/'


class digital_ocean():

    def __init__(self, key, client):
        '''Set default API parameters'''
        self.key = key
        self.client = client
        self.api_url = API_URL

    def api(self, cmd_path, api_arg={}):
        '''Make api call'''
        api_arg.update({'api_key':self.key, 'client_id':self.client})
        resp = requests.get(self.api_url + cmd_path, params=api_arg).text
        resp = json.loads(resp)
        if resp['status'] != 'OK':
            raise Exception(resp['error_message'])
        return resp

    def droplet_data(self, name):
        '''Get droplet data'''
        data = self.api('droplets')
        data = [droplet for droplet in data['droplets']
            if droplet['name'] == name]
        return data[0] if data else {}

def json_fmt(data):
    '''Format json output'''
    return json.dumps(data, sort_keys = True, indent = 2)


do = digital_ocean(env['DO_API_KEY'], env['DO_CLIENT_ID'])

# Get DROPLET_NAME data
data = do.droplet_data(DROPLET_NAME)

# Stop processing if DROPLET_NAME exists on Digital Ocean
if data:
    print ('Droplet: {} already deployed. Not further processing.'
        .format(DROPLET_NAME))
    exit(1)

# Create droplet
do.api('droplets/new', {'name':DROPLET_NAME, 'region_id':REGION_ID,
    'image_id':IMAGE_ID, 'size_id':SIZE_ID,
    'ssh_key_ids':[env['DOCKER_KEY_ID']]})

# Wait for droplet to be created.
start_time = datetime.now()
while (data.get('status','') != 'active' and (
 datetime.now()-start_time).seconds < TIMEOUT):
    data = do.droplet_data(DROPLET_NAME)
    print data['status']
    sleep(3)

# Wait for the machine to boot
sleep(15)

# Get droplet IP
ip = str(data['ip_address'])
print 'droplet: {}    ip: {}'.format(DROPLET_NAME, ip)

api.env.host_string = ip
api.env.user = DO_IMAGE_USER
api.env.key_filename = env['DOCKER_CI_KEY_PATH']

# Correct timezone
sudo('echo "America/Los_Angeles" >/etc/timezone')
sudo('dpkg-reconfigure --frontend noninteractive tzdata')

# Load JSON_CONFIG environment for Dockerfile
CONFIG_JSON= base64.b64encode(
    '{{"DOCKER_CI_PUB":     "{DOCKER_CI_PUB}",'
    '  "DOCKER_CI_KEY":     "{DOCKER_CI_KEY}",'
    '  "DOCKER_CI_ADDRESS": "{DOCKER_CI_ADDRESS}",'
    '  "SMTP_USER":         "{SMTP_USER}",'
    '  "SMTP_PWD":          "{SMTP_PWD}",'
    '  "EMAIL_SENDER":      "{EMAIL_SENDER}",'
    '  "EMAIL_RCP":         "{EMAIL_RCP}"}}'.format(**env))

run('mkdir -p /data/report')
put('./', '/data/report')
with cd('/data/report'):
    run('chmod 700 report.py')
    run('echo "{}" > credentials.json'.format(CONFIG_JSON))
    run('docker build -t report .')
    run('rm credentials.json')
    run("echo -e '30 09 * * * /usr/bin/docker run report\n' |"
        " /usr/bin/crontab -")
