class MMCClient(object): def __init__(self, url, username, password): self._url = url if url.endswith('/'): self._url = url[:-1] self._http_connection = HttpConnection(url, username, password) self._request = HttpRequest(self._http_connection, username, password) @staticmethod def create_client_from_deployed(deployed): mmc = deployed.container.mmc return MMCClient(mmc.url, mmc.username, mmc.password) def upload_to_repository(self, app_name, version, file_name, file_path): parts = {'name': HttpEntityBuilder.create_string_body(app_name), 'version': HttpEntityBuilder.create_string_body(version), 'file': HttpEntityBuilder.create_file_body(file_path) } r = self._request.post_without_headers("/api/repository", HttpEntityBuilder.create_multipart_entity(parts)) if not r.isSuccessful and r.status != 201: raise Exception("Failed to upload [%s]. Server return %s.\n%s" % (file_path, r.status, r.response)) print "Received response after upload [%s].\n" % r.response return json.loads(r.response) def delete_deployment_by_id(self, deployment_id): r = self._request.delete("/api/deployments/%s" % deployment_id, contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to delete [%s]. Server return %s.\n%s" % (deployment_id, r.status, r.response)) def get_deployment_id_by_name(self, name): r = self._request.get("/api/deployments", contentType = 'application/json') deployments = json.loads(r.response)['data'] for d in deployments: if d['name'] == name: return d['id'] return None def get_deployment_by_id(self, deployment_id): r = self._request.get("/api/deployments/%s" % deployment_id, contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to get deployment [%s]. Server return %s.\n%s" % (deployment_id, r.status, r.response)) return json.loads(r.response) def delete_deployment(self, name): deployment_id = self.get_deployment_id_by_name(name) if deployment_id: self.delete_deployment_by_id(deployment_id) def get_application_version_id(self, name, version): r = self._request.get("/api/repository", contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to get application version [%s]-[%s]. Server return %s.\n%s\n" % (name, version, r.status, r.response)) applications = json.loads(r.response)['data'] for a in applications: if a['name'] == name: for v in a['versions']: if v['name'] == version: return v['id'] return None def get_server_groups(self): r = self._request.get("/api/serverGroups", contentType = 'application/json') return json.loads(r.response)['data'] def get_server_group_id(self, server_group): for g in self.get_server_groups(): if g['name'] == server_group: return g['id'] raise Exception("No sever group found having the name %s " % server_group) def get_servers_for_group(self, server_group): r = self._request.get("/api/servers", contentType = 'application/json') server_ids = set() servers = json.loads(r.response)['data'] for s in servers: for g in s['groups']: if server_group == g['name']: server_ids.add(s['id']) return [str(i) for i in server_ids] def get_clusters(self): r = self._request.get("/api/clusters", contentType = 'application/json') return json.loads(r.response)['data'] def get_clusters_by_name(self, cluster_name): cluster_ids = set() for c in self.get_clusters(): if cluster_name == c['name']: cluster_ids.add(c['id']) return [str(i) for i in cluster_ids] def delete_application_by_id(self, application_version_id): r = self._request.get("api/repository/%s" % application_version_id, contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to delete application [%s]. Server return %s.\n%s" % (application_version_id, r.status, r.response)) def delete_application(self, application_name, version): application_version_id = self.get_application_version_id(application_name, version) if application_version_id: self.delete_application_by_id(application_version_id) def _create_deployment(self, name, cluster_ids, server_ids, version_id): # delete existing deployment before creating new one self.delete_deployment(name) req = {'name': name, 'clusters': cluster_ids, 'servers': server_ids, 'applications': [version_id]} r = self._request.post("/api/deployments", HttpEntityBuilder.create_string_entity(json.dumps(req)), contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to create deployment. Server return %s.\n%s" % (r.status, r.response)) return json.loads(r.response)['id'] def create_cluster_deployment(self, cluster_name, deployment_name, version_id): cluster_ids = self.get_clusters_by_name(cluster_name) if len(cluster_ids) == 0: raise Exception("No cluster found with name : [%s] " % cluster_name) return self._create_deployment(deployment_name, cluster_ids, [], version_id) def create_server_group_deployment(self, server_group, deployment_name, version_id): servers_ids = self.get_servers_for_group(server_group) if len(servers_ids) == 0: raise Exception("No server found into group : %s " % server_group) return self._create_deployment(deployment_name, [], servers_ids, version_id) def deploy_deployment_by_id(self, deployment_id): r = self._request.post("/api/deployments/%s/deploy" % deployment_id,HttpEntityBuilder.create_string_entity(''), contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to deploy [%s]. Server return %s.\n%s" % (deployment_id, r.status, r.response)) def redeploy_deployment_by_id(self, deployment_id): r = self._request.post("/api/deployments/%s/redeploy" % deployment_id,HttpEntityBuilder.create_string_entity(''), contentType = 'application/json') if not r.isSuccessful(): raise Exception("Failed to redeploy [%s]. Server return %s.\n%s" % (deployment_id, r.status, r.response)) def wait_for_deployment(self, deployment_id): status = "Unknown" deployment = None while status != "FAILED" and status != "DEPLOYED": deployment = self.get_deployment_by_id(deployment_id) status = deployment["status"] time.sleep(5) return status == "DEPLOYED", deployment
class RancherClient(object): def __init__(self, host, port, username, password): # print "Executing method __init__() in class RancherClient in file RancherClient.py\n" self.baseUrl = urlunparse(('http', '%s:%s' % (host,port), '', '', '', '')) self.http_connection = HttpConnection(self.baseUrl, username, password) self.request = HttpRequest(self.http_connection, username, password) # End __init__ @staticmethod def createClient(host, port, username, password): # print "Executing method createClient() in class RancherClient class in file RancherClient.py\n" return RancherClient(host, port, username, password) # End createClient def activateServices(self, stack): # print "Executing method activateServices() in class RancherClient in file RancherClient.py with parameters stackId = %s\n" % stack['id'] action = stack['actions']['activateservices'] urlString = urlunparse(('', '', urlparse(action).path, '', urlparse(action).query, ''))[1:] r = self.request.post(urlString, None, contentType='application/json') if r.getStatus() not in HTTP_SUCCESS: self.throw_error(r) servicesList = self.getStackServices(stack) for service in servicesList: serviceAfterTransitioning = self.getStateAfterTransitioning(service) if serviceAfterTransitioning['state'] == 'active': continue else: print "Failure to activate service %s (%s) in stack %s (%s)\n" % (serviceAfterTransitioning['name'], serviceAfterTransitioning['id'], stack['name'], stack['id']) sys.exit(1) stackAfterTransitioning = self.getStateAfterTransitioning(stack) if stackAfterTransitioning['state'] == 'active': print "Services for stack %s (%s) have been activated\n" % (stack['name'], stack['id']) return stackAfterTransitioning else: print "Services for stack %s (%s) have not been activated; do rollback\n" % (stack['name'], stack['id']) sys.exit(1) # End activateServices def createStack(self, project, stackName, dockerCompose, rancherCompose): # print "Executing method createStack() in class RancherClient in file RancherClient.py with parameters projectId=%s, stackName=%s" % (project['id'], stackName) urlString = 'v2-beta/projects/%s/stacks?name=%s&dockerCompose=%s&rancherCompose=%s' % (project['id'], stackName, dockerCompose, rancherCompose) r = self.request.post(urlString, None, contentType='application/json') if r.getStatus() in HTTP_SUCCESS: stack = json.loads(r.getResponse()) else: self.throw_error(r) stackAfterTransitioning = self.getStateAfterTransitioning(stack) if stackAfterTransitioning['state'] == 'active': print "Stack %s (%s) is active\n" % (stack['name'], stack['id']) else: print "Stack %s (%s) is not active; do rollback\n" % (stack['name'], stack['id']) return stackAfterTransitioning # End createStack def getStackServices(self, stack): # print "Executing method getStackServices() in class RancherClient in file RancherClient.py with parameters projectId=%s, stackName=%s" % (project['id'], stackName) link = stack['links']['services'] urlString = urlparse(link).path[1:] r = self.request.get(urlString, contentType = 'application/json') if r.getStatus() in HTTP_SUCCESS: return json.loads(r.response)['data'] else: self.throw_error(r) # End getStackServices def getStateAfterTransitioning(self, rancherObject): # print "Executing method getStateAfterTransitioning() in class RancherClient class in file RancherClient.py\n" link = rancherObject['links']['self'] urlString = urlparse(link).path[1:] r = self.request.get(urlString, contentType = 'application/json') if r.getStatus() in HTTP_SUCCESS: transitioning = json.loads(r.response)['transitioning'] else: self.throw_error(r) pollCount = 0 while transitioning != 'no': time.sleep(5) pollCount = pollCount + 1 print "Transitioning, waiting... %d\n" % pollCount r = self.request.get(urlString, contentType = 'application/json') if r.getStatus() in HTTP_SUCCESS: transitioning = json.loads(r.response)['transitioning'] else: self.throw_error(r) r = self.request.get(urlString, contentType = 'application/json') if r.getStatus() in HTTP_SUCCESS: return json.loads(r.response) else: self.throw_error(r) # End getStateAfterTransitioning def lookupProjectByName(self, projectName): # print "Executing method lookupProjectByName() in class RancherClient in file RancherClient.py with parameters projectName=%s" % (projectName) urlString = "v2-beta/projects?name=%s" % projectName r = self.request.get(urlString, contentType = 'application/json') if r.getStatus() in HTTP_SUCCESS: response = json.loads(r.response) else: self.throw_error(r) projectList = [] for project in response['data']: if project['name'] == projectName: projectList.append(project) return projectList # End lookupProjectByName def lookupStackByName(self, project, stackName): # print "Executing method lookupStackByName() in class RancherClient in file RancherClient.py with parameters project=%s, stackName=%s\n" % (project['id'], stackName) link = project['links']['stacks'] urlString = "%s?name=%s" % (urlparse(link).path[1:], stackName) r = self.request.get(urlString, contentType = 'application/json') if r.getStatus() in HTTP_SUCCESS: response = json.loads(r.response) else: self.throw_error(r) stackList = [] for stack in response['data']: if stack['name'] == stackName: stackList.append(stack) return stackList # End lookupStackByName def upgradeService(self, service): # print "Executing method upgradeService() in class RancherClient class in file RancherClient.py\n" if service['state'] != 'active': print "%s cannot be upgraded because its current state is %s" % (service['name'], service['state']) sys.exit(1) print "Upgrading %s, state was %s\n" % (service['name'], service['state']) link = service['actions']['upgrade'] if service['upgrade']: upgradeConfig = service['upgrade']['inServiceStrategy'] else: upgradeConfig = None upgradeRequestBody = {"inServiceStrategy":upgradeConfig,"toServiceStrategy": None} urlString = urlunparse(('', '', urlparse(link).path, '', urlparse(link).query, ''))[1:] r =self.request.post(urlString, HttpEntityBuilder.create_string_entity(json.dumps(upgradeRequestBody)), contentType='application/json') if r.getStatus() not in HTTP_SUCCESS: self.throw_error(r) serviceAfterTransitioning = self.getStateAfterTransitioning(service) if serviceAfterTransitioning['state'] == 'upgraded': print "Service %s has been upgraded\n" % service['id'] else: print "Service %s has not been upgraded; do rollback\n" % service['id'] return serviceAfterTransitioning # End upgradeService def validateListLength(self, vList, uniqueMatchOnly): # print "Executing method validateListLength() in class RancherClient class in file RancherClient.py\n" if not vList: print "No matches found. Aborting this operation.\n" sys.exit(1) if uniqueMatchOnly and len(vList) > 1: print "Nonunique matches found. Aborting this operation.\n" sys.exit(1) # End validateListLength def throw_error(self, response): # print "Executing method throw_error() in class RancherClient in file RancherClient.py\n" print "Error from Rancher, HTTP Return: %s\n" % (response.getStatus()) sys.exit(1)
class datapowerClient( object ): def __init__( self, url, username, password ): ''' Builds a datapowerClient :param url: The url of the REST inteface of the Datapower device :param username: The username to connect to the datapower device :param password: The passoword to connecto to the datapwoer device ''' self.url = url if url.endswith('/'): self.url = url[:-1] self.http_connection = HttpConnection(url, username, password) self.request = HttpRequest( self.http_connection, username, password) # End __init__ def uploadFile( self, domain, path, fileName, fileData ): ''' Upload a file to a Datapower device param: domain: The domain in the Datapower device where the file will be stored param: path: the Datapower path param: fileName: the file to be stored on the datapower devide param: fileData: the file content to be stored on the datapower devide ''' uri = '/mgmt/filestore/%s/%s/%s' % ( domain, path, fileName ) fileData64 = base64.encodestring( fileData ) payload = ''' { "file": { "name":"%s", "content":"%s" } } ''' body = payload % ( fileName, fileData64 ) r = self.request.put( uri, HttpEntityBuilder.create_string_entity( body ), contentType = 'application/json' ) response = json.loads( r.response ) return response['result'] # End uploadFile def downloadFile( self, domain, path, fileName ): ''' Download a file from a Datapower device param: domain: The domain in the Datapower device where the file will be stored param: path: the Datapower path param: file: the file to be stored on the datapower devide ''' uri = '/mgmt/filestore/%s/%s/%s' % ( domain, path, fileName ) r = self.request.get( uri, contentType = 'application/json' ) response = json.loads(r.response) print response['_links']['self']['href'] return base64.decodestring(response['file']) # End downloadFile def deleteFile( self, domain, path, fileName ): ''' Delete a file from a Datapower device param: domain: The domain in the Datapower device where the file will be stored param: path: the Datapower path param: file: the file to be stored on the datapower devide ''' uri = '/mgmt/filestore/%s/%s/%s' % ( domain, path, fileName ) r = self.request.delete( uri, contentType = 'application/json' ) response = json.loads(r.response) return response['result']
class datapowerClient(object): def __init__(self, url, username, password): ''' Builds a datapowerClient :param url: The url of the REST inteface of the Datapower device :param username: The username to connect to the datapower device :param password: The passoword to connecto to the datapwoer device ''' self.url = url if url.endswith('/'): self.url = url[:-1] self.http_connection = HttpConnection(url, username, password) self.request = HttpRequest(self.http_connection, username, password) # End __init__ def uploadFile(self, domain, path, fileName, fileData): ''' Upload a file to a Datapower device param: domain: The domain in the Datapower device where the file will be stored param: path: the Datapower path param: fileName: the file to be stored on the datapower devide param: fileData: the file content to be stored on the datapower devide ''' uri = '/mgmt/filestore/%s/%s/%s' % (domain, path, fileName) fileData64 = base64.encodestring(fileData) payload = ''' { "file": { "name":"%s", "content":"%s" } } ''' body = payload % (fileName, fileData64) r = self.request.put(uri, HttpEntityBuilder.create_string_entity(body), contentType='application/json') response = json.loads(r.response) return response['result'] # End uploadFile def downloadFile(self, domain, path, fileName): ''' Download a file from a Datapower device param: domain: The domain in the Datapower device where the file will be stored param: path: the Datapower path param: file: the file to be stored on the datapower devide ''' uri = '/mgmt/filestore/%s/%s/%s' % (domain, path, fileName) r = self.request.get(uri, contentType='application/json') response = json.loads(r.response) print response['_links']['self']['href'] return base64.decodestring(response['file']) # End downloadFile def deleteFile(self, domain, path, fileName): ''' Delete a file from a Datapower device param: domain: The domain in the Datapower device where the file will be stored param: path: the Datapower path param: file: the file to be stored on the datapower devide ''' uri = '/mgmt/filestore/%s/%s/%s' % (domain, path, fileName) r = self.request.delete(uri, contentType='application/json') response = json.loads(r.response) return response['result']