import httplib
import base64
from xml.dom import minidom
import time
import logging
from xml.etree.ElementTree import ElementTree, QName, tostring, dump
#logging.basicConfig(level=logging.Info)
# Azure Configuration
SERVICE_MANAGEMENT_HOST = 'management.core.windows.net'
# User Configuration
USER_CERTIFICATE = 'azure-certificate.pem'
SUBSCRIPTION_ID='c86aebd3-affe-4feb-aaa1-e69e7ee65d10'
class HostedService():
def __init__(self, subscription_id=SUBSCRIPTION_ID, user_certificate=USER_CERTIFICATE):
logging.debug("init hosted service")
self.subscription_id = subscription_id
self.user_certificate = user_certificate
self.h = httplib.HTTPSConnection(SERVICE_MANAGEMENT_HOST, 443, cert_file=user_certificate, timeout=120)
#if(logging.getLogger('').isEnabledFor(logging.DEBUG)):
# self.h.set_debuglevel(7)
def list(self):
""" list all hosted services """
self.h.request('GET', '/' + self.subscription_id +'/services/hostedservices', headers={"x-ms-version":"2009-10-01"})
response = self.h.getresponse()
logging.debug("HTTP Response: " + str(response.status) + " " + str(response.reason) + "\n"+response.read())
def createDeployment(self, serviceName, deploymentName, slotName, serviceLocation, serviceConfiguration, numberNodes):
configuration = self.prepareConfiguration(serviceConfiguration, numberNodes)
#create payload string
data = """
%s
%s
%s
""" % (deploymentName, serviceLocation, base64.encodestring(deploymentName), base64.encodestring(configuration))
logging.debug(data)
url = "/" + self.subscription_id +"/services/hostedservices/" + serviceName + "/deploymentslots/"+ slotName
logging.debug("URL: " + url)
self.h.request('POST', url, body=data,
headers={"x-ms-version":"2009-10-01", "Content-Type": "application/xml"})
response = self.h.getresponse()
requestId = response.getheader("x-ms-request-id")
responseData = response.read()
logging.debug("HTTP Response: " + str(response.status) + " " + str(response.reason)
+ "\nRequest-Id: " + requestId)
return requestId
def prepareConfiguration(self, serviceConfiguration, numberNodes):
""" read configuration and adjust number of nodes """
tree = ElementTree(file=serviceConfiguration)
instanceElement = tree.find("*/{http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration}Instances")
instanceElement.set("count", str(numberNodes))
configuration = tostring(tree.getroot())
logging.debug("Configuration: " + configuration)
return configuration
def deleteDeployment(self, serviceName, slotName):
""" delete Azure deployment """
url = "/" + self.subscription_id +"/services/hostedservices/" + serviceName + "/deploymentslots/"+ slotName
self.h.request('DELETE', url, headers={"x-ms-version":"2009-10-01"})
response = self.h.getresponse()
requestId = response.getheader("x-ms-request-id")
responseData = response.read()
logging.debug("HTTP Response: " + str(response.status) + " " + str(response.reason)
+ "\nRequest-Id: " + requestId)
return requestId
def getOperationStatus(self, requestId):
url = "/" + self.subscription_id +"/operations/" + requestId
self.h.request('GET', url, headers={"x-ms-version":"2009-10-01"})
response = self.h.getresponse()
responseData = response.read()
logging.debug("HTTP Response: " + str(response.status) + " " + str(response.reason)
+ "\n" + responseData)
dom = minidom.parseString(responseData)
statusElement = dom.getElementsByTagName("Status")[0]
status = statusElement.firstChild.toxml()
return status
def waitForRequest(self, requestId):
while True:
status = self.getOperationStatus(requestId)
logging.debug("Status: " + str(status))
if(status == "Succeeded" or status == "Failed"):
return status
time.sleep(10)
def updateDeploymentStatus(self, serviceName, slotName, status):
"""updates delployment status: new status should be either Running or Suspended"""
if (status != "Running" and status != "Suspended"):
logging.error("Invalid status: " + status + " (should be either Running or Suspended)")
return
#build URL and payload
url = "/" + self.subscription_id +"/services/hostedservices/" + serviceName + "/deploymentslots/"+ slotName + "/?comp=status"
data ="""
%s
""" % (status)
self.h.request('POST', url, body=data,
headers={"x-ms-version":"2009-10-01", "Content-Type": "application/xml"})
response = self.h.getresponse()
responseData = response.read()
requestId = response.getheader("x-ms-request-id")
logging.debug("HTTP Response: " + str(response.status) + " " + str(response.reason)
+ "\nRequest-Id: " + str(requestId))
return requestId
def __del__(self):
self.h.close()
def main():
h = HostedService(subscription_id="2ffebf74-01b0-4ee8-a4e7-3a9178002908")
h.list()
requestId = h.createDeployment( "drelu", "bigjob", "staging",
"http://drelu.blob.core.windows.net/namd-service/BigJobService.cspkg",
"BigJobService/deploy/ServiceConfiguration.cscfg", 1)
# wait for deployment to be done
status = h.waitForRequest(requestId);
if status != "Succeeded":
logging.debug("Deployment Failed")
return
# change status to running
logging.debug("Setting deployment status to Running")
requestId = h.updateDeploymentStatus("drelu", "staging", "Running")
status = h.waitForRequest(requestId);
# do what ever you need to do with your Azure instances
time.sleep(300)
# delete deployment
logging.debug("Deleting deployment")
requestId = h.updateDeploymentStatus("drelu", "staging", "Suspended")
status = h.waitForRequest(requestId)
requestId = h.deleteDeployment("drelu", "staging")
status = h.waitForRequest(requestId)
if __name__ == '__main__':
main()