#!/usr/bin/python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
# 
#   http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import base64
import hmac
import os
import sys
import urllib2
import urllib
import httplib
from datetime import datetime
from optparse import OptionParser
from urlparse import urlparse

try:
    from hashlib import sha1 as sha
except ImportError:
    import sha

def get_signature(key, url, query):    
    netloc, path = urlparse(url)[1:3]
    return urllib.quote_plus(base64.b64encode(
            hmac.new(key, '\n'.join(['GET', netloc, path, query]), sha).digest()))

def get_url(url, api_key, secret_key, action, query):
    amzn_string = 'AWSAccessKeyId=' + api_key + '&Action=' + action + '&SignatureMethod=HmacSHA1'
    amzn_string += '&SignatureVersion=2&Timestamp='+ datetime.now().isoformat()[:19] +'Z&Version=2010-11-15'
    query = amzn_string + '&' + query
    url = url + '?' + query + '&Signature=' + get_signature(secret_key, url, query)
    try:
        urllib2.urlopen(url)
	if action == 'SetCertificate':
		print 'User registration is successful!'
	return True
    except urllib2.HTTPError, e:
		print  'User registration failed with http error code:' , e.code
		return False
    except urllib2.URLError, e:    
		print 'User registration failed with error: ' , e.reason
		return False
   

def register(url, api_key, secret_key, cert):
    # Register API keys
    query = 'accesskey=' + api_key + '&secretkey=' + secret_key
    result = get_url(url, api_key, secret_key, 'SetUserKeys', query)

    if result == True:
	    # Tie Certifcate to API keys
	    query = 'cert=' + urllib.quote_plus(cert)
	    get_url(url, api_key, secret_key, 'SetCertificate', query)


def get_opts():
    parser = OptionParser()
    parser.add_option('-a', '--apikey') 
    parser.add_option('-s', '--secretkey') 
    parser.add_option('-c', '--cert', help='Name of a file containing an X.509 certificate') 
    parser.add_option('-u', '--url', help='CloudStack AWSAPI URL, eg. http://cloudstack.host:8080/awsapi') 
    (options, args) = parser.parse_args()
    if None in [options.apikey, options.secretkey, options.cert, options.url]:
        print 'Error: Missing argument\n'
        parser.print_help()
        sys.exit(1)
    return options

def validate_opts(options):
    if not os.path.isfile(options.cert):
        print 'Error reading file: ' + options.cert  
        sys.exit(1)
    f = open(options.cert) 
    options.cert = f.read()
    return options

if __name__ == '__main__':
    opts = validate_opts(get_opts())
    register(opts.url, opts.apikey, opts.secretkey, opts.cert)
