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
Пример #2
0
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']