#!/usr/bin/python
from urllib import urlencode
import httplib2
import re
import sys
import os
import os.path
import json
import socket
import time
try:
    # For c speedups
    from simplejson import loads, dumps
except ImportError:
    from json import loads, dumps

client_id = sys.argv[1];
http = httplib2.Http(disable_ssl_certificate_validation=True)
http.follow_redirects = False
url = "https://localhost/request?client_id=" + client_id \
      + "&response_type=code&redirect_uri=/cmd"
headerz, content = http.request(url, "GET")
code = re.search('code=(\d+)',content)
code = code.group(1)
url = "https://localhost//token?grant_type=authorization_code&client_id=" \
      + client_id + "&redirect_uri=/cmd&code=" + code
headerz, content = http.request(url, "GET")
accesstoken = re.search('access_token":(\d+)',content)
accesstoken = accesstoken.group(1);
refreshtoken = re.search('refresh_token":(\d+)',content)
refreshtoken = refreshtoken.group(1);
PATH='credentials.csv'
if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print PATH+" exists and is readable"
else:
    print PATH+" is missing or is not readable"
with open(PATH) as f:
    for line in f:
        items=line.split(',');
data = {'cmd': [['aws_configure',items[1],items[2]],
                ['cmd','hostname'],
                ['cwd','/bin'],
                ['cmd_raw','export HELLO=hello'],
                ['cmd','echo $HELLO'],
                ['cmd','pwd'],
                ['cmd','aws ec2 describe-instances']]}
bearer  = "Bearer "+accesstoken
headers = {'Content-Type': 'application/json','Authorization': bearer }
url     = 'https://localhost/cmd'
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
result = json.loads(result[5][0])
myip=([l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] \
     if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)), \
     s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, \
     socket.SOCK_DGRAM)]][0][1]]) if l][0][0])
for inst in result['Reservations']:
   print inst
   for elem in inst['Instances']:
      print elem
      if elem['State']['Name'] == 'terminated':
            print "GOT CONTINUE"
            continue
      if myip == elem['PrivateIpAddress']:
            print elem['SecurityGroups'][0]['GroupId']
            print elem['PrivateIpAddress']
            print elem['State']['Name']
            print elem['SubnetId']
            break
   else:
      continue
   break
gid      = elem['SecurityGroups'][0]['GroupId']
sid      = elem['SubnetId']
headers  = {'Content-Type': 'application/json','Authorization': bearer }
dsg      = 'aws ec2 describe-security-groups'
data     = {'cmd':[['cmd',dsg]]};
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
result = json.loads(result[0][0])
print result
cidr=''
dockergid=''
for inst in result['SecurityGroups']:
   print inst
   dockergid = inst['GroupId']
   cidr      = inst['IpPermissions'][0]['IpRanges'][0]['CidrIp']
   if gid == inst['GroupId']:
      break
new_sg   = 'aws ec2 create-security-group --group-name ' + \
           'DockerSecurityGroup --description ' + \
           '"Docker.com Security Group" 2>&1';
ingress  = 'aws ec2 authorize-security-group-ingress ' + \
           '--group-name DockerSecurityGroup --protocol tcp ' + \
           '--port 22 --cidr ' + cidr + ' 2>&1'
PATH='fullauto.pem'
print ingress
if os.path.isfile(PATH) and os.access(PATH, os.R_OK):
    print PATH+" exists and is readable"
else:
    print PATH+" is missing or is not readable"
with open(PATH,'rb') as f:
    pemfile = f.read()
print pemfile

# http://mancoosi.org/~abate/upload-file-using-httplib
def upload(url,filename,bearer):
    def encode (file_path, fields=[]):
        BOUNDARY = '----------bundary------'
        CRLF = '\r\n'
        body = []
        # Add the metadata about the upload first
        for key, value in fields:
            body.extend(
              ['--' + BOUNDARY,
               'Content-Disposition: form-data; name="%s"' % key,
               '',
               value,
               ])
        # Now add the file itself
        file_name = os.path.basename(file_path)
        f = open(file_path, 'rb')
        file_content = f.read()
        f.close()
        body.extend(
          ['--' + BOUNDARY,
           'Content-Disposition: form-data; name="file"; filename="%s"'
           % file_name,
           # The upload server determines the mime-type, no need to set it.
           'Content-Type: application/octet-stream',
           '',
           file_content,
           ])
        # Finalize the form body
        body.extend(['--' + BOUNDARY + '--', ''])
        return 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body)

    if os.path.exists(filename):
        content_type, body = encode(filename)
        headers = { 'Content-Type': content_type,'Authorization': bearer }
        httpx = httplib2.Http(disable_ssl_certificate_validation=True)
        httpx.request(url,'POST', body, headers)

upload(url,'/home/Administrator/FullAutoAPI/fullauto.pem',bearer)

time.sleep( 1 )

data = {'cmd': [['cmd','mv /tmp/fullauto.pem /home/Administrator/FullAutoAPI'],
                ['cwd','/home/Administrator/FullAutoAPI'],
                ['cmd','chmod 400 fullauto.pem'],
                ['cmd',new_sg],
                ['cmd',ingress]]}
                #['cmd',new_inst]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
sec_group_id=''
if re.search('already exists for VPC',result[3][0]):
   get_sec='aws ec2 describe-security-groups --group-names DockerSecurityGroup'
   data = {'cmd': [['cmd',get_sec]]}
   time.sleep( 1 )
   headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
   result = json.loads(content)
   result = json.loads(result['result'])
   result = json.loads(result[0][0])
   sec_group_id = result['SecurityGroups'][0]['GroupId']
else:
   result=json.loads(result[3][0])
   sec_group_id=result['GroupId']
time.sleep( 1 )
new_inst = 'aws ec2 run-instances --image-id ami-c229c0a2 --count=1 ' + \
           '--key-name fullauto ' + \
           '--instance-type=t2.micro --security-group-ids ' + \
           sec_group_id + ' --subnet-id ' + sid
data = {'cmd': [['cmd',new_inst]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
result = json.loads(result[0][0])
print result
docker_ip=result['Instances'][0]['PrivateIpAddress']
instance_id=result['Instances'][0]['InstanceId']
loop = 1
while loop == 1: # This creates an infinite loop
   time.sleep( 1 )
   data = {'cmd': [['cmd','aws ec2 describe-instances --instance-ids '+instance_id+' 2>&1']]};
   headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
   result = json.loads(content)
   result = json.loads(result['result'])
   result = json.loads(result[0][0])
   print '------------------'
   print result['Reservations'][0]['Instances'][0]['State']['Name']
   if result['Reservations'][0]['Instances'][0]['State']['Name'] == 'running':
      break
print '==================='
print docker_ip
data = {'cmd': [['connect_secure',{'ip':docker_ip,'login':'ec2-user','identityfile':'fullauto.pem','noretry':'1'}]]}
time.sleep( 1 )
docker_server1='';
while loop == 1: # This creates an infinite loop
   print "GOING FOR CONNECT"
   headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
   result = json.loads(content)
   result = json.loads(result['result'])
   if re.search('Connection timed out|Connection refused',result[0][1]):
      print result[0][1]
      time.sleep( 1 )
      continue
   else:
      print "GOT DOCKER!!!!"
      docker_server1=result[0][0]
   break
time.sleep( 1 )
print "DOCKER_SERVER1="+docker_server1
data = {'cmd': [['label',[docker_server1,'cmd','sudo yum -y install docker docker-registry']],
                ['label',[docker_server1,'cmd','sudo service docker start']],
                ['label',[docker_server1,'cmd','sudo usermod -a -G docker ec2-user']]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
print "LABEL_RESULT="+str(result[0][0])
time.sleep( 1 )
data = {'cmd': [['label',[docker_server1,'close']]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
print "LABEL_RESULT="+str(result)
data = {'cmd': [['connect_secure',{'ip':docker_ip,'login':'ec2-user','identityfile':'fullauto.pem','noretry':'1'}]]}
time.sleep( 1 )
docker_server1='';
while loop == 1: # This creates an infinite loop
   print "GOING FOR CONNECT"
   headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
   result = json.loads(content)
   result = json.loads(result['result'])
   if re.search('Connection timed out|Connection refused',result[0][1]):
      print result[0][1]
      time.sleep( 1 )
      continue
   else:
      print "GOT DOCKER AGAIN!!!!"
      docker_server1=result[0][0]
   break
time.sleep( 1 )
print "DOCKER_SERVER1="+docker_server1
data = {'cmd': [['label',[docker_server1,'cmd','hostname']]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
print "HOSTNAME="+str(result[0][0])
time.sleep( 1 )
data = {'cmd': [['label',[docker_server1,'cmd','docker info']]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
print "DOCKER INFO="+str(result[0][0])
time.sleep( 1 )
data = {'cmd': [['label',[docker_server1,'docker_run','ubuntu /bin/bash']]]}
headerz, content = http.request(url, "POST", body=dumps(data), headers=headers)
result = json.loads(content)
result = json.loads(result['result'])
print "DOCKER CONTAINER HOSTNAME="+str(result[0][0])

