def __init__(self, httpConnection, apiKey, username="", password=""):
     self.headers        = {"X-NuGet-ApiKey": apiKey}
     self.query_params   = ""
     self.httpConnection = httpConnection
     self.httpConnection['username'] = username
     self.httpConnection['password'] = password
     self.httpRequest = HttpRequest(self.httpConnection, username, password)
 def revoke_token(self):
     print "Revoking token"
     httpRequest = HttpRequest(self.httpConnection, None, None)
     servicenowApiUrl = "/oauth_revoke_token.do?token=%s" % self.accessToken
     response = httpRequest.get(servicenowApiUrl)
     servicenowApiUrl = "/oauth_revoke_token.do?token=%s" % self.refreshToken
     response = httpRequest.get(servicenowApiUrl)
class VersionOneClient( object ):
   def __init__(self, v1CI ):
      self.Token = v1CI['accessToken']
      self.uriBase = v1CI['uriBase']
      self.storyStatus = v1CI['StoryStatus']
      self.httpConnection = v1CI
      self.httpRequest = HttpRequest( v1CI )
      self.optionHeader = {"Accept" : "application/json",
                           "Authorization" : "Bearer %s" % self.Token}
   # End def

   @staticmethod
   def create_v1Client( v1CI ):
      return VersionOneClient( v1CI )
   # End def
   
   def getStories(self, whereClause=None):
      uri = "%s/rest-1.v1/Data/Story" % self.uriBase
      if whereClause is not None:
         uri = "%s?where=%s" % ( uri, whereClause )
      # End if
      print( "getStories uri = %s" % uri )
      print( "Headers = %s" % self.optionHeader )
      response = self.httpRequest.get( uri, headers=self.optionHeader )
      reqStatus = response.getStatus()
      print( "Request Status %s" % reqStatus )
      if reqStatus == STATUS_OK:
         return json.loads( response.getResponse() )
      # End if
      raise ValueError('Error getting stories', reqStatus )
   # End def
   
   def updateStoryStatus(self, ticket, status):
      whereClause="Number='%s'" % ticket
      data = self.getStories( whereClause )
      uri = data['Assets'][0]['href']
      xml = "<Asset> <Relation name=\"Status\" act=\"set\"> <Asset idref=\"StoryStatus:%s\" /> </Relation> </Asset>" % self.storyStatus[status]
      print( "Update Status uri = %s" % uri )
      print( "Update Status XML ~%s~" % xml )
      print( "Update Status Headers = %s" % self.optionHeader )
      response = self.httpRequest.post( uri, xml, headers=self.optionHeader )
      reqStatus = response.getStatus()
      print( "Request Status %s" % reqStatus )
      if reqStatus == STATUS_OK:
         return
      # End if
      raise ValueError('Error getting stories', reqStatus )
   # End def
   
   def get_story_status_list(self):
      uri = "%s/rest-1.v1/Data/StoryStatus" % self.uriBase
      print( "getStoryStatus uri = %s" % uri )
      print( "Headers = %s" % self.optionHeader )
      response = self.httpRequest.get( uri, headers=self.optionHeader )
      req_status = response.getStatus()
      print( "Request Status %s" % req_status )
      if req_status == STATUS_OK:
         return json.loads( response.getResponse() )
      # End if
      raise ValueError('Error getting stories', req_status )
Example #4
0
    def __init__(self, server):
        self.logger = LoggerFactory.getLogger("com.xebialabs.snyk-plugin")
        if server in [None, ""]:
            raise Exception("server is undefined")

        self.orgId = server['orgId']
        self.http_request = HttpRequest(server)
def get_applications(ancestor, applications_count):
    request = HttpRequest(server, username, password)
    applications_batch = []
    results_remain = True
    page = 0
    while results_remain:
        endpoint = '/deployit/repository/query?page={}&resultsPerPage=100&type=udm.Application&ancestor={}'.format(
            page, ancestor)
        response = request.get(endpoint, contentType='application/json')
        if not response.isSuccessful():
            raise Exception(
                "Failed to get application information from XL Deploy. Server return [%s], with content [%s]"
                % (response.status, response.response))
        results = json.loads(response.response)
        if results == []:
            results_remain = False
        else:
            for result in results:
                applications_batch.append({
                    "id": "{}".format(applications_count),
                    "name": result["ref"]
                })
                applications_count += 1
            page += 1
    return {"batch": applications_batch, "count": applications_count}
 def revoke_token(self):
     print "Revoking token"
     httpRequest = HttpRequest(self.httpConnection, None, None)
     servicenowApiUrl = "/oauth_revoke_token.do?token=%s" % self.accessToken
     response = httpRequest.get(servicenowApiUrl)
     servicenowApiUrl = "/oauth_revoke_token.do?token=%s" % self.refreshToken
     response = httpRequest.get(servicenowApiUrl)
Example #7
0
 def testServer(self, variables):
     httpConnection = variables['params']
     httpRequest = HttpRequest(httpConnection)
     response = httpRequest.get("/")
     self.logger.error("Response Status = %s" % response.getStatus())
     if response.getStatus() == 200:
         return
     sys.exit(-1)
Example #8
0
class CircleCiClient(object):
    def __init__(self, http_connection, token=None):
        self.http_request = HttpRequest(
            http_connection, token, ""
        )  # Should not have to pass the empty P/W string, will work on fix.

    @staticmethod
    def create_client(http_connection, token=None):
        return CircleCiClient(http_connection, token)

    def get_user(self):
        get_user_endpoint = "/me"
        get_user_response = self.http_request.get(
            get_user_endpoint, contentType='application/json')
        if not get_user_response.isSuccessful():
            raise Exception(
                "Failed to get user information. Server return [%s], with content [%s]"
                % (get_user_response.status, get_user_response.response))
        return json.loads(get_user_response.getResponse())

    def trigger_build(self, vcs, username, project, branch, wait,
                      waitInterval):
        trigger_build_endpoint = "/project/%s/%s/%s/tree/%s" % (
            vcs, username, project, branch)
        trigger_build_response = self.http_request.post(
            trigger_build_endpoint, '{}', contentType='application/json')
        if not trigger_build_response.isSuccessful():
            raise Exception(
                "Failed to trigger build for project [%s] on branch [%s]. Server return [%s], with content [%s]"
                % (project, branch, trigger_build_response.status,
                   trigger_build_response.response))
        json_data = json.loads(trigger_build_response.getResponse())

        if wait:
            build_num = json_data["build_num"]
            while (True):
                build_information_endpoint = "/project/%s/%s/%s/%s" % (
                    vcs, username, project, build_num)
                build_information_response = self.http_request.get(
                    build_information_endpoint, contentType='application/json')
                if not build_information_response.isSuccessful():
                    raise Exception(
                        "Failed to retrieve build information for project [%s] on branch [%s] build number[%s]. Server return [%s], with content [%s]"
                        % (project, branch, build_num,
                           build_information_response.status,
                           build_information_response.response))
                build_information = json.loads(
                    build_information_response.getResponse())
                status = build_information["status"]
                # TODO: Need to obtain a better understanding of these states and what constitutes fail vs. pass from XLR perspective.
                if status == "success" or status == "fixed":
                    return build_information
                elif status == "failed" or status == "canceled" or status == "infrastructure_fail" or status == "timedout" or status == "no_tests":
                    sys.exit(1)
                else:
                    time.sleep(float(waitInterval))
        return json_data
 def __init__(self, httpConnection, username=None, password=None):
     self.headers = {}
     self.query_params = ""
     self.httpConnection = httpConnection
     if username is not None:
         self.httpConnection['username'] = username
     if password is not None:
         self.httpConnection['password'] = password
     self.httpRequest = HttpRequest(self.httpConnection, username, password)
Example #10
0
 def __init__(self, httpConnection, username=None, password=None):
     self.headers = {"Accept": "application/json"}
     self.accessToken = None
     self.refreshToken = None
     self.httpConnection = httpConnection
     if username:
         self.httpConnection['username'] = username
     if password:
         self.httpConnection['password'] = password
     self.httpRequest = HttpRequest(self.httpConnection, username, password)
 def __init__(self, v1CI):
     self.Token = v1CI['accessToken']
     self.uriBase = v1CI['uriBase']
     self.storyStatus = v1CI['StoryStatus']
     self.httpConnection = v1CI
     self.httpRequest = HttpRequest(v1CI)
     self.optionHeader = {
         "Accept": "application/json",
         "Authorization": "Bearer %s" % self.Token
     }
Example #12
0
 def __init__(self,
              httpConnection,
              webhookToken,
              maxChecksPerDeploymentId=30,
              timeout=5):
     self.httpConnection = httpConnection
     self.httpRequest = HttpRequest(httpConnection)
     self.webhookToken = webhookToken
     self.headers = self._get_headers()
     self.maxChecksPerDeploymentId = maxChecksPerDeploymentId
     self.timeout = timeout
Example #13
0
 def __init__(self, httpConnection, username=None, password=None): 
     self.headers        = {}
     self.accessToken    = None
     self.refreshToken   = None
     self.httpConnection = httpConnection
     self.useOAuth = httpConnection['useOAuth']
     if username:
        self.httpConnection['username'] = username
     if password:
        self.httpConnection['password'] = password
     self.httpRequest = HttpRequest(self.httpConnection, username, password)
     self.sysparms = 'sysparm_display_value=%s&sysparm_input_display_value=%s' % (self.httpConnection['sysparmDisplayValue'], self.httpConnection['sysparmInputDisplayValue'])
 def complete_task(self, taskId, username=None, password=None):
     request = HttpRequest(self.httpConnection, username, password)
     context = '/api/v1/tasks/%s/complete' % taskId
     body = '{"comment":"Completed by XL Deploy"}'
     response = request.post(context, body, contentType='application/json')
     if response.isSuccessful() and self.isTaskCompleted(taskId):
         print "Current Task with id [%s] is %s." % (taskId, COMPLETED)
         return True
     else:
         print "Failed to complete task with id: %s" % taskId
         response.errorDump()
         sys.exit(1)
 def assign_task(self, task_id, owner, username=None, password=None):
     request = HttpRequest(self.httpConnection, username, password)
     context = '/api/v1/tasks/%s/assign/%s' % (task_id, owner)
     body = ''
     response = request.post(context, body, contentType='application/json')
     if response.isSuccessful():
         print "Assigned task with id [%s] to [%s]" % (task_id, owner)
         return True
     else:
         print "Failed to assign task with id [%s] to [%s]" % (task_id,
                                                               owner)
         response.errorDump()
         sys.exit(1)
 def isTaskCompleted(self, taskId, username=None, password=None):
     request = HttpRequest(self.httpConnection, username, password)
     context = '/api/v1/tasks/%s' % taskId
     response = request.get(context, contentType='application/json')
     if response.isSuccessful():
         data = json.loads(response.response)
         status = data["status"]
         print "Current Task with id [%s] is %s." % (taskId, status)
         return status == COMPLETED
     else:
         print "Failed to get status for task with id: %s" % taskId
         response.errorDump()
         sys.exit(1)
 def refresh_token(self, httpConnection, refreshToken):
     servicenowUrl = "/oauth_token.do"
     content                  = {}
     content['grant_type']    = 'refresh_token'
     content['client_id']     = httpConnection['clientId']
     content['client_secret'] = httpConnection['clientSecret']
     content['refresh_token'] = refreshToken
     httpRequest = HttpRequest(httpConnection, None, None)
     response = httpRequest.post(servicenowUrl, body=urllib.urlencode(content), contentType='application/x-www-form-urlencoded')
     if response.getStatus() == SN_RESULT_STATUS:
         data = json.loads(response.getResponse())
         return data
     print "Unable to refresh token using %s" % refreshToken
     self.throw_error(response)        
Example #18
0
 def meetup_getpostcomments(self, variables):
     httpConnection = variables['server']
     httpRequest = HttpRequest(httpConnection, variables['username'], variables['password'])
     url = "/comments?postId=%s" % variables['postId']
     self.logger.error("Get Post Comments %s" % (url))
     response = httpRequest.get(url, contentType='application/json')
     jsonData = response.getResponse()
     data = json.loads( jsonData )
     listData = []
     for recordData in data:
         self.logger.error( recordData['body'] )
         listData.append( recordData['body'] )
     returnData = {"responseJson": jsonData, "comments": listData }
     return returnData
Example #19
0
 def refresh_token(self, httpConnection, refreshToken):
     servicenowUrl = "/oauth_token.do"
     content                  = {}
     content['grant_type']    = 'refresh_token'
     content['client_id']     = httpConnection['clientId']
     content['client_secret'] = httpConnection['clientSecret']
     content['refresh_token'] = refreshToken
     httpRequest = HttpRequest(httpConnection, None, None)
     response = httpRequest.post(servicenowUrl, body=urllib.urlencode(content), contentType='application/x-www-form-urlencoded')
     if response.getStatus() == SN_RESULT_STATUS:
         data = json.loads(response.getResponse())
         return data
     print "Unable to refresh token using %s" % refreshToken
     self.throw_error(response)        
Example #20
0
    def __init__(self, httpConnection, username=None, password=None):
        self.headers = {}
        self.accessToken = None
        self.httpConnection = httpConnection

        self.username = username if username else httpConnection['username']
        self.password = password if password else httpConnection['password']

        # clear username/password so underlying library doesn't try to do basic authentication
        del httpConnection['username']
        del httpConnection['password']

        self.httpRequest = HttpRequest(self.httpConnection)

        self.issue_token()
 def create_token(self, httpConnection):
     servicenow_oauth_url     = "/oauth_token.do"
     content                  = {}
     content['grant_type']    = 'password'
     content['client_id']     = httpConnection['clientId']
     content['client_secret'] = httpConnection['clientSecret']
     content['username']      = httpConnection['oauthUsername']
     content['password']      = httpConnection['oauthPassword']
     httpRequest              = HttpRequest(httpConnection, None, None)
     response                 = httpRequest.post(servicenow_oauth_url, body=urllib.urlencode(content), contentType='application/x-www-form-urlencoded')
     if response.getStatus() == SN_RESULT_STATUS:
         data = json.loads(response.getResponse())
         return data
     print 'Could not get access token'
     self.throw_error(response)
Example #22
0
 def create_token(self, httpConnection):
     servicenow_oauth_url     = "/oauth_token.do"
     content                  = {}
     content['grant_type']    = 'password'
     content['client_id']     = httpConnection['clientId']
     content['client_secret'] = httpConnection['clientSecret']
     content['username']      = httpConnection['oauthUsername']
     content['password']      = httpConnection['oauthPassword']
     httpRequest              = HttpRequest(httpConnection, None, None)
     response                 = httpRequest.post(servicenow_oauth_url, body=urllib.urlencode(content), contentType='application/x-www-form-urlencoded')
     if response.getStatus() == SN_RESULT_STATUS:
         data = json.loads(response.getResponse())
         return data
     print 'Could not get access token'
     self.throw_error(response)
 def __init__(self, httpConnection, username=None, password=None):
     self.headers = {'Content-type': 'application/json; charset=UTF-8'}
     self.accessToken = None
     self.refreshToken = None
     self.httpConnection = httpConnection
     self.useServicenowApp = httpConnection['useServicenowApp']
     self.useOAuth = httpConnection['useOAuth']
     self.service_now_url = httpConnection['url'].rstrip("/")
     if username:
         self.httpConnection['username'] = username
     if password:
         self.httpConnection['password'] = password
     self.httpRequest = HttpRequest(self.httpConnection, username, password)
     self.sysparms = 'sysparm_display_value=%s&sysparm_input_display_value=%s' % (
         self.httpConnection['sysparmDisplayValue'],
         self.httpConnection['sysparmInputDisplayValue'])
Example #24
0
 def _putRequest(self, url, data):
     encoded_data = json.dumps(data).encode(self.encoding)
     response = HttpRequest(self.params).put(url,
                                             encoded_data,
                                             contentType=self.content_type,
                                             headers=self.headers)
     return response
def get_applications_metadata(applications):
    request = HttpRequest(server, username, password)
    application_metadata = {}
    for application in applications:
        applicationShortName = application["name"].split('/')[-1]
        application_metadata[applicationShortName] = {}

        application_metadata[applicationShortName]["plotId"] = application[
            "id"]

        endpoint = '/deployit/repository/ci/{}'.format(application["name"])
        response = request.get(endpoint, contentType='application/json')
        if not response.isSuccessful():
            raise Exception(
                "Failed to get application information from XL Deploy. Server return [%s], with content [%s]"
                % (response.status, response.response))
        lastVersion = json.loads(response.response)["lastVersion"]
        application_metadata[applicationShortName]["lastVersion"] = lastVersion

        if lastVersion == "":
            applicationDependencies = []
        else:
            endpoint = '/deployit/repository/ci/{}/{}'.format(
                application["name"], lastVersion)
            response = request.get(endpoint, contentType='application/json')
            if not response.isSuccessful():
                raise Exception(
                    "Failed to get deployment package information from XL Deploy. Server return [%s], with content [%s]"
                    % (response.status, response.response))
            if json.loads(response.response)["type"] == "udm.CompositePackage":
                applicationDependencies = []
            else:
                applicationDependencies = json.loads(
                    response.response)["applicationDependencies"].keys()
        application_metadata[applicationShortName][
            "applicationDependencies"] = applicationDependencies

        application_metadata[applicationShortName]["dependedUponCount"] = 0

    for application in application_metadata.keys():
        for dependency in application_metadata[application][
                "applicationDependencies"]:
            if dependency in application_metadata.keys(
            ):  # only add if dependency exists in XLD
                application_metadata[dependency]["dependedUponCount"] += 1

    return application_metadata
Example #26
0
    def __init__(self, tokenServer, url, username, password):

        try:
            from urlparse import urlparse  # Python 2.X
        except ImportError:
            from urllib.parse import urlparse  # Python 3+

        # Fixes some issues with TLS
        os.environ['REQUESTS_CA_BUNDLE'] = 'ca.pem'

        # logger.info("Executing SamlTokenProvider.__init__()")
        # print("Executing SamlTokenProvider.__init__() \r\n")

        # print("url: " + url + " \r\n")
        hostname = urlparse(url).hostname
        # print("hostname: " + hostname + " \r\n")

        # logger.info("url = %s" % url)
        self.tokenServer = tokenServer
        self.tokenParams = {
            'url': 'https://login.microsoftonline.com',
            'username': username,
            'password': password
        }
        self.cookieParams = {
            'url': 'https://' + urlparse(url).hostname,
            'username': username,
            'password': password
        }
        self.url = url
        self.tokenRequest = HttpRequest(self.tokenParams, username, password)
        self.cookieRequest = HttpRequest(self.cookieParams, username, password)
        self.username = username
        self.password = password

        # External Security Token Service for SPO
        self.sts = {'host': 'login.microsoftonline.com', 'path': '/extSTS.srf'}

        # Sign in page url
        self.login = '******'

        # Last occurred error
        self.error = ''

        self.token = None
        self.FedAuth = None
        self.rtFa = None
 def __init__(self, v1CI ):
    self.Token = v1CI['accessToken']
    self.uriBase = v1CI['uriBase']
    self.storyStatus = v1CI['StoryStatus']
    self.httpConnection = v1CI
    self.httpRequest = HttpRequest( v1CI )
    self.optionHeader = {"Accept" : "application/json",
                         "Authorization" : "Bearer %s" % self.Token}
 def __init__(self, httpConnection, username=None, password=None):
     self.httpConnection = httpConnection
     if username is not None:
         self.httpConnection['username'] = username
     if password is not None:
         self.httpConnection['password'] = password
     params = {
         'url': httpConnection['url'],
         'proxyHost': httpConnection['proxyHost'],
         'proxyPort': httpConnection['proxyPort']
     }
     self.httpRequest = HttpRequest(params)
     self.accessToken = self._getAuthToken()
     self.headers = {
         'Accept': 'application/json',
         'Cookie': 'token=%s' % self.accessToken
     }
def hasPermission(task, is610andAbove, configs=None):
    de = getProperty(t, is610andAbove, "environment", "deploymentEnvironment")
    if de != None:
        u = getProperty(t, is610andAbove, "username")
        p = getProperty(t, is610andAbove, "password", isPassword=True)
        dp = getProperty(t, is610andAbove, "deploymentPackage")
        if is610andAbove:
            s = getProperty(t, is610andAbove, "server")
            if u == None or u == "":
                u = s.username
            if p == None or p == "":
                p = s.password
            url = s.url
        else:
            s = findServerData(getProperty(t, is610andAbove, "server"),
                               configs)[0]
            if u == None or u == "":
                u = s["username"]
            if p == None or p == "":
                p = s["password"]
                p = "admin"
            url = s["url"]
        http_request = HttpRequest(
            {
                "url": url,
                "username": str(u),
                "password": str(p)
            }, "", "")
        response = http_request.get(
            "/deployit/security/check/deploy%23initial/Environments/" + de,
            contentType="application/xml")
        if response.status == 200:
            res_text = response.getResponse()
            if res_text.find("false") > -1:
                return False
            else:
                return True
        else:
            return False
    else:
        return False
 def __init__(self, httpConnection, username=None, password=None): 
     self.headers        = {}
     self.accessToken    = None
     self.refreshToken   = None
     self.httpConnection = httpConnection
     self.useOAuth = httpConnection['useOAuth']
     if username:
        self.httpConnection['username'] = username
     if password:
        self.httpConnection['password'] = password
     self.httpRequest = HttpRequest(self.httpConnection, username, password)
     self.sysparms = 'sysparm_display_value=%s&sysparm_input_display_value=%s' % (self.httpConnection['sysparmDisplayValue'], self.httpConnection['sysparmInputDisplayValue'])
Example #31
0
    def __init__(self, tokenServer, url, username, password):

        logger.info("Executing SamlTokenProvider.__init__()")
        logger.info("url = %s" % url)
        self.tokenServer = tokenServer
        self.tokenParams = {
            'url': 'https://login.microsoftonline.com',
            'username': username,
            'password': password
        }
        self.cookieParams = {
            'url': 'https://login.microsoftonline.com',
            'username': username,
            'password': password
        }
        self.url = url
        self.tokenRequest = HttpRequest(self.tokenParams, username, password)
        self.cookieRequest = HttpRequest(self.cookieParams, username, password)
        self.username = username
        self.password = password

        # External Security Token Service for SPO
        self.sts = {'host': 'login.microsoftonline.com', 'path': '/extSTS.srf'}

        # Sign in page url
        self.login = '******'

        #dwang_DEBUG
        self.msftlogin = '******'
        self.msfthost = 'login.microsoftonline.com'

        # Last occurred error
        self.error = ''

        self.token = None
        self.FedAuth = None
        self.rtFa = None

        logger.info("Exiting SamlTokenProvider.__init__()")
Example #32
0
 def __init__(self, buildId, testName, testNameWildCard, hourRange, limit,
              http_connection, acctUsername, accessKey):
     self.configUsername = acctUsername
     self.configAccessKey = accessKey
     self.http_connection = http_connection
     # If not username and accessKey not configured in the getJobs task, use the info from the
     #    SauceLabs server configuration
     if not self.configUsername:
         self.configUsername = http_connection.get("username")
     if not self.configAccessKey:
         self.configAccessKey = http_connection.get("password")
     self.http_request = HttpRequest(http_connection, self.configUsername,
                                     self.configAccessKey)
     self.acctUsername = acctUsername
     self.buildId = buildId
     self.testName = testName
     self.testNameWildCard = testNameWildCard
     self.beginRange = None
     self.endRange = None
     self.limit = limit
     if hourRange and hourRange > 0:
         self.endRange = str(int(time.time()))
         self.beginRange = str(int(time.time()) - (int(hourRange) * 3600))
class RedhatSatelliteClient(object):
    def __init__(self, httpConnection, username=None, password=None):
        self.headers = {}
        self.query_params = ""
        self.httpConnection = httpConnection
        if username is not None:
            self.httpConnection['username'] = username
        if password is not None:
            self.httpConnection['password'] = password
        self.httpRequest = HttpRequest(self.httpConnection, username, password)

    @staticmethod
    def create_client(httpConnection, username=None, password=None):
        return RedhatSatelliteClient(httpConnection, username, password)

    def ping(self):
        api_url = '/katello/api/v2/ping'
        print "RedHat Satellite URL = %s " % (api_url)
        response = self.httpRequest.get(api_url,
                                        contentType='application/json',
                                        headers=self.headers)

        if response.getStatus() == SUCCES_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data
        else:
            print "find_record error %s" % (response)
            self.throw_error(response)
            # End if

    # End find_record

    def throw_error(self, response):
        print "Error from RedhatSatelliteClient, HTTP Return: %s\n" % (
            response.getStatus())
        print "Detailed error: %s\n" % response.response
        sys.exit(1)

    def EmptyToNone(self, value):
        if value is None:
            return None
        elif value.strip() == '':
            return None
        else:
            return value
 def __init__(self, buildId, testName, testNameWildCard, hourRange, limit, http_connection, 
     acctUsername, accessKey):
     self.configUsername = acctUsername
     self.configAccessKey = accessKey
     self.http_connection = http_connection
     # If not username and accessKey not configured in the getJobs task, use the info from the
     #    SauceLabs server configuration
     if not self.configUsername:
         self.configUsername = http_connection.get("username")
     if not self.configAccessKey:
         self.configAccessKey = http_connection.get("password")
     self.http_request = HttpRequest(http_connection, self.configUsername, self.configAccessKey)
     self.acctUsername = acctUsername
     self.buildId = buildId
     self.testName = testName
     self.testNameWildCard = testNameWildCard
     self.beginRange = None
     self.endRange = None
     self.limit = limit
     if hourRange and hourRange > 0:
         self.endRange = str(int(time.time()))
         self.beginRange = str(int(time.time()) - (int(hourRange)*3600))
class NuGetClient(object):
    def __init__(self, httpConnection, apiKey, username="", password=""):
        self.headers        = {"X-NuGet-ApiKey": apiKey}
        self.query_params   = ""
        self.httpConnection = httpConnection
        self.httpConnection['username'] = username
        self.httpConnection['password'] = password
        self.httpRequest = HttpRequest(self.httpConnection, username, password)

    @staticmethod
    def create_client(httpConnection, apiKey, username="", password=""):
        return NuGetClient(httpConnection, apiKey, username, password)

    def get_latest_version(self, package_id):
        api_url = '/api/v2/package-versions/%s?semVerLevel=2.0.0&includePrerelease=false' % (package_id)
        response = self.httpRequest.get(api_url, contentType='application/json', headers = self.headers)

        if response.getStatus() == SUCCES_RESULT_STATUS:
            versions_list = json.loads(response.getResponse())
            #print("Versions founds: %s" % str(versions_list))

            # there may be a 'latest' but that's not helpful to us to see if there's a new version 
            if "latest" in versions_list:
                versions_list.remove("latest")
            # End if

            try:
                versions_list.sort(key=LooseVersion)
                #print("Tags sorted %s" % str(versions_list))
            except Exception, e:
                print("Failed to sort, ignoring: %s " % str(e))
            # End try

            if len(versions_list) > 0:
                return versions_list[-1]
            else:
                return None
        else:
class ServiceNowClient(object):
    def __init__(self, httpConnection, username=None, password=None): 
        self.headers        = {}
        self.accessToken    = None
        self.refreshToken   = None
        self.httpConnection = httpConnection
        self.useOAuth = httpConnection['useOAuth']
        if username:
           self.httpConnection['username'] = username
        if password:
           self.httpConnection['password'] = password
        self.httpRequest = HttpRequest(self.httpConnection, username, password)
        self.sysparms = 'sysparm_display_value=%s&sysparm_input_display_value=%s' % (self.httpConnection['sysparmDisplayValue'], self.httpConnection['sysparmInputDisplayValue'])

    @staticmethod
    def create_client(httpConnection, username=None, password=None):
        return ServiceNowClient(httpConnection, username, password)

    def get_change_request_states(self):
        if self.useOAuth : self.issue_token()
        servicenow_api_url = '/api/now/v1/table/%s?element=state&name=task&sysparm_fields=%s&%s' % ('sys_choice', 'value,label', self.sysparms)
        response = self.httpRequest.get(servicenow_api_url, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()
        
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        self.throw_error(response)
       
    def get_scorecards(self):
        if self.useOAuth :self.issue_token()
        servicenow_api_url = '/api/now/v1/pa/scorecards'
        response = self.httpRequest.get(servicenow_api_url, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        self.throw_error(response)

    def get_change_request_with_fields(self, table_name, number, fields):
        if self.useOAuth :self.issue_token()
        servicenow_api_url = '/api/now/v1/table/%s?number=%s&sysparm_fields=%s&%s' % (table_name, number, ",".join(fields), self.sysparms)
        response = self.httpRequest.get(servicenow_api_url, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()

        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            if len(data['result']) == 1:
                return data['result'][0]
        self.throw_error(response)

    def get_change_request(self, table_name, sys_id):
        if self.useOAuth :self.issue_token()
        servicenow_api_url = '/api/now/v1/table/%s/%s?%s' % (table_name, sys_id, self.sysparms)
        response = self.httpRequest.get(servicenow_api_url, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()

        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        self.throw_error(response)

    def create_record(self, table_name, content):
        if self.useOAuth :self.issue_token()
        servicenow_api_url = '/api/now/v1/table/%s?%s' % (table_name, self.sysparms)
        response = self.httpRequest.post(servicenow_api_url, body=content, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()

        if response.getStatus() == RECORD_CREATED_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        else:
            self.throw_error(response)
        # End if

    # End create_record

    def update_record(self, table_name, sysId, content):
        if self.useOAuth :self.issue_token()
        servicenow_api_url = '/api/now/v1/table/%s/%s?%s' % (table_name, sysId, self.sysparms)
        response = self.httpRequest.put(servicenow_api_url, body=content, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()

        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        else:
            self.throw_error(response)
        # End if

    # End create_record

    def find_record(self, table_name, query):
        if self.useOAuth :self.issue_token()
        servicenow_api_url = '/api/now/v1/table/%s?%s&%s' % (table_name, query, self.sysparms)
        print "Service Now URL = %s " % (servicenow_api_url)
        response = self.httpRequest.get(servicenow_api_url, contentType='application/json', headers = self.headers)
        if self.useOAuth :self.revoke_token()

        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        else:
            print "find_record error %s" % (response)
            self.throw_error(response)
            # End if

    # End find_record

    def print_error(self, response):
        if type(response) is dict:
           outStr =   "| Status  | %s |\n" % ( response["status"] )
           outStr = "%s| Message | %s |\n" % ( outStr, response["error"]["message"] )
           outStr = "%s| Detail  | %s |\n" % ( outStr, response["error"]["detail"] )
           return outStr
        # End if
        return response
    #End  print_error

    def print_table(self, headers, rows):
        print "\n|", "|".join(headers), "|"
        print "|", " ------ |" * len(headers)
        for r in rows:
            print "| ", "  |".join(r), " |"
        print "\n"

    def print_record(self, myObj, outStr="", prefix="", header=True):
        if header:
            outStr = "%s| Key | Value |\n" % (outStr)
            outStr = "%s| --- | --- |\n" % (outStr)
        if type(myObj) is dict:
            for key in myObj.iterkeys():
                value = myObj[key]
                if type(value) is dict or type(value) is list:
                    p = "%s%s." % (prefix, key)
                    outStr = "%s| %s%s |\n%s" % (outStr, prefix, key, self.print_record(value, "", p, False))
                else:
                    p = "%s%s" % (prefix, key)
                    outStr = "%s| %s%s |%s |\n" % (outStr, prefix, key, value)

        elif type(myObj) is list:
            for value in myObj:
                outStr = "%s| | %s\n" % (outStr, value)
        else:
            outStr = "%s%s" % (outStr, myObj)
        # End if
        return outStr

    def throw_error(self, response):
        print "Error from ServiceNow, HTTP Return: %s\n" % (response.getStatus())
        print "Detailed error: %s\n" % response.response
        if self.useOAuth :self.revoke_token()
        sys.exit(1)

    def EmptyToNone(self,value):
        if value is None:
           return None
        elif value.strip() == '':
             return None
        else:
            return value

    def issue_token(self):
        print "Issuing a new token"
        tokenData = self.create_token(self.httpConnection)
        self.set_token_header(tokenData)

    def create_token(self, httpConnection):
        servicenow_oauth_url     = "/oauth_token.do"
        content                  = {}
        content['grant_type']    = 'password'
        content['client_id']     = httpConnection['clientId']
        content['client_secret'] = httpConnection['clientSecret']
        content['username']      = httpConnection['oauthUsername']
        content['password']      = httpConnection['oauthPassword']
        httpRequest              = HttpRequest(httpConnection, None, None)
        response                 = httpRequest.post(servicenow_oauth_url, body=urllib.urlencode(content), contentType='application/x-www-form-urlencoded')
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data
        print 'Could not get access token'
        self.throw_error(response)

    def refresh_token(self, httpConnection, refreshToken):
        servicenowUrl = "/oauth_token.do"
        content                  = {}
        content['grant_type']    = 'refresh_token'
        content['client_id']     = httpConnection['clientId']
        content['client_secret'] = httpConnection['clientSecret']
        content['refresh_token'] = refreshToken
        httpRequest = HttpRequest(httpConnection, None, None)
        response = httpRequest.post(servicenowUrl, body=urllib.urlencode(content), contentType='application/x-www-form-urlencoded')
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data
        print "Unable to refresh token using %s" % refreshToken
        self.throw_error(response)        

    def set_token_header(self, tokenData):
        self.accessToken  = tokenData['access_token']
        self.refreshToken = tokenData['refresh_token']
        self.headers['Authorization'] = "Bearer %s" % (self.accessToken)

    def revoke_token(self):
        print "Revoking token"
        httpRequest = HttpRequest(self.httpConnection, None, None)
        servicenowApiUrl = "/oauth_revoke_token.do?token=%s" % self.accessToken
        response = httpRequest.get(servicenowApiUrl)
        servicenowApiUrl = "/oauth_revoke_token.do?token=%s" % self.refreshToken
        response = httpRequest.get(servicenowApiUrl)
Example #37
0
 def __init__(self, http_connection, username=None, password=None):
     self.http_request = HttpRequest(http_connection, username, password)
Example #38
0
class XLDeployClient(object):
    def __init__(self, http_connection, username=None, password=None):
        self.http_request = HttpRequest(http_connection, username, password)

    @staticmethod
    def create_client(http_connection, username=None, password=None):
        return XLDeployClient(http_connection, username, password)

    def get_parameter_names(self, parameter_type_id):
        metadata_url = "/deployit/metadata/type/%s" % (parameter_type_id)
        metadata_response = self.http_request.get(metadata_url, contentType='application/xml')
        root = ET.fromstring(metadata_response.getResponse())
        params = root.find("property-descriptors")
        parameter_names = []
        if params:
            for child in params:
                parameter_names.append(child.get("name"))
        return parameter_names

    def prepare_control_task(self, control_task_name, target_ci_id, parameters=None):
        prepare_control_task_url = "/deployit/control/prepare/%s/%s" % (control_task_name, target_ci_id)
        prepare_response = self.http_request.get(prepare_control_task_url, contentType='application/xml')
        check_response(prepare_response,
                       "Failed to prepare control task [%s]. Server return [%s], with content [%s]" % (
                           target_ci_id, prepare_response.status, prepare_response.response))
        control_obj = prepare_response.getResponse()
        root = ET.fromstring(control_obj)
        if parameters:
            parameter_type_id = get_parameter_type_name(root)
            if parameter_type_id:
                parameter_names = self.get_parameter_names(parameter_type_id)
                for parameterName in parameter_names:
                    add_parameter(root, parameter_type_id, parameterName, parameters)
        invoke_response = self.http_request.post('/deployit/control', ET.tostring(root), contentType='application/xml')
        check_response(invoke_response, "Failed to create control task [%s]. Server return [%s], with content [%s]" % (
            target_ci_id, invoke_response.status, invoke_response.response))
        task_id = invoke_response.getResponse()
        return task_id

    def invoke_task_and_wait_for_result(self, task_id, polling_interval=10, number_of_trials=None,
                                        continue_if_step_fails=False, number_of_continue_retrials=0,
                                        fail_on_pause=True, display_step_logs = False):
        start_task_url = "/deployit/task/%s/start" % task_id
        self.http_request.post(start_task_url, '', contentType='application/xml')
        trial = 0
        while not number_of_trials or trial < number_of_trials:
            trial += 1
            get_task_status_url = "/deployit/task/%s" % task_id
            task_state_response = self.http_request.get(get_task_status_url, contentType='application/xml')
            check_response(task_state_response, "Failure to get task status")
            task_state_xml = task_state_response.getResponse()
            status = extract_state(task_state_xml)

            print 'Task [%s] now in state [%s] \n' % (task_id, status)
            if fail_on_pause:
                if status in (
                    'FAILED', 'ABORTED', 'STOPPED') and continue_if_step_fails and number_of_continue_retrials > 0:
                    status = self.invoke_task_and_wait_for_result(task_id, polling_interval, number_of_trials,
                                                                  continue_if_step_fails,
                                                                  number_of_continue_retrials - 1)
                if status in ('FAILED', 'ABORTED', 'STOPPED', 'CANCELLED', 'DONE', 'EXECUTED'):
                    break
            else:
                if status in ('FAILED', 'ABORTED') and continue_if_step_fails and number_of_continue_retrials > 0:
                    status = self.invoke_task_and_wait_for_result(task_id, polling_interval, number_of_trials,
                                                                  continue_if_step_fails,
                                                                  number_of_continue_retrials - 1)
                if status in ('FAILED', 'ABORTED', 'CANCELLED', 'DONE', 'EXECUTED'):
                    break
            time.sleep(polling_interval)
        if display_step_logs:
            print "Display the step logs"
            self.display_step_logs(task_id)
        return status

    def get_deployment_package(self, deployed_application_id):
        ci = self.get_ci(deployed_application_id, 'json')
        data = json.loads(ci)
        return data['version']

    def deployment_exists(self, deployment_package, environment):
        deployment_exists_url = "/deployit/deployment/exists?application=%s&environment=%s" % (
            deployment_package.rsplit('/', 1)[0], environment)
        deployment_exists_response = self.http_request.get(deployment_exists_url, contentType='application/xml')
        response = deployment_exists_response.getResponse()
        return 'true' in response

    def deployment_exists2(self, deployed_application):
        deployment_exists_url = "/deployit/repository/exists/{0}".format(deployed_application)
        deployment_exists_response = self.http_request.get(deployment_exists_url, contentType='application/xml')
        response = deployment_exists_response.getResponse()
        return 'true' in response

    def deployment_prepare_undeploy(self, deployed_application_id, orchestrators=None,
                                    deployed_application_properties=None):
        deployment_prepare_undeploy_url = "/deployit/deployment/prepare/undeploy?deployedApplication=%s" % deployed_application_id
        deployment_prepare_undeploy_url_response = self.http_request.get(deployment_prepare_undeploy_url,
                                                                         contentType='application/xml')
        check_response(deployment_prepare_undeploy_url_response,
                       "Failed to prepare undeploy. Server return [%s], with content [%s]" % (
                           deployment_prepare_undeploy_url_response.status,
                           deployment_prepare_undeploy_url_response.response))
        undeployment_xml = deployment_prepare_undeploy_url_response.getResponse()
        undeployment_xml = add_orchestrators(undeployment_xml, orchestrators)
        undeployment_xml = set_deployed_application_properties(undeployment_xml, deployed_application_properties)
        return undeployment_xml

    def deployment_prepare_update(self, deployment_package, environment):
        deployment_prepare_update_url = "/deployit/deployment/prepare/update?version=%s&deployedApplication=%s" % (
            deployment_package, "%s/%s" % (environment, deployment_package.rsplit('/', 2)[1]))
        deployment_prepare_update_response = self.http_request.get(deployment_prepare_update_url,
                                                                   contentType='application/xml')
        check_response(deployment_prepare_update_response,
                       "Failed to prepare update deploy. Server return [%s], with content [%s]" % (
                           deployment_prepare_update_response.status, deployment_prepare_update_response.response))
        return deployment_prepare_update_response.getResponse()

    def deployment_prepare_initial(self, deployment_package, environment):
        deployment_prepare_initial_url = "/deployit/deployment/prepare/initial?version=%s&environment=%s" % (
            deployment_package, environment)
        deployment_prepare_initial_response = self.http_request.get(deployment_prepare_initial_url,
                                                                    contentType='application/xml')
        check_response(deployment_prepare_initial_response,
                       "Failed to prepare initial deploy. Server return [%s], with content [%s]" % (
                           deployment_prepare_initial_response.status, deployment_prepare_initial_response.response))
        return deployment_prepare_initial_response.getResponse()

    def deployment_prepare_deployeds(self, deployment, orchestrators=None, deployed_application_properties=None,
                                     overrideDeployedProps=None, deployed_properties=None):
        deployment_prepare_deployeds = "/deployit/deployment/prepare/deployeds"
        deployment_prepare_deployeds_response = self.http_request.post(deployment_prepare_deployeds, deployment,
                                                                       contentType='application/xml')
        check_response(deployment_prepare_deployeds_response,
                       "Failed to prepare deployeds. Server return [%s], with content [%s]" % (
                           deployment_prepare_deployeds_response.status,
                           deployment_prepare_deployeds_response.response))
        deployment_xml = deployment_prepare_deployeds_response.getResponse()
        deployment_xml = add_orchestrators(deployment_xml, orchestrators)
        deployment_xml = set_deployed_application_properties(deployment_xml, deployed_application_properties)
        deployment_xml = override_deployed_properties(deployment_xml, overrideDeployedProps)
        deployment_xml = set_deployed_properties(deployment_xml,
                                                 deployed_properties)  # Deprecated. Should be remove starting 3.0.0
        return deployment_xml

    def validate(self, deployment):
        get_deployment_task_id = "/deployit/deployment/validate"
        deployment_with_validation_response = self.http_request.post(get_deployment_task_id, deployment,
                                                                     contentType='application/xml')
        deployment = deployment_with_validation_response.getResponse()
        root = ET.fromstring(deployment)
        return map(lambda vm: "CI: %s Message: %s" % (vm.attrib['ci'], vm.text), root.iter('validation-message'))

    def get_deployment_task_id(self, deployment):
        get_deployment_task_id = "/deployit/deployment"
        deployment_task_id_response = self.http_request.post(get_deployment_task_id, deployment,
                                                             contentType='application/xml')
        return deployment_task_id_response.getResponse()

    def deployment_rollback(self, taskId):
        deployment_rollback = "/deployit/deployment/rollback/%s" % taskId
        deployment_rollback_response = self.http_request.post(deployment_rollback, '', contentType='application/xml')
        return deployment_rollback_response.getResponse()

    def archive_task(self, task_id):
        archive_task = "/deployit/task/%s/archive" % task_id
        self.http_request.post(archive_task, '', contentType='application/xml')

    def cancel_task(self, task_id):
        cancel_task = "/deployit/task/%s" % task_id
        self.http_request.delete(cancel_task, contentType='application/xml')

    def stop_task(self, task_id):
        stop_task = "/deployit/task/%s/stop" % task_id
        self.http_request.post(stop_task, '', contentType='application/xml')

    def get_download_uuid(self, deployment_package):
        export_task = "/deployit/export/deploymentpackage/%s" % deployment_package
        export_task_response = self.http_request.get(export_task, contentType='application/xml')
        return export_task_response.getResponse()

    def fetch_package2(self, url, user_name, password):
        fetch_task = "/deployit/package/fetch2"
        params = {
            "url": url,
            "user": user_name,
            "password": password
        }
        response = self.http_request.post(fetch_task, json.dumps(params), contentType='application/json')
        check_response(response, "Failed to import package. Server return [%s], with content [%s]" % (
            response.status, response.response))

    def get_latest_package_version(self, application_id):
        query_task = "/deployit/repository/query?parent=%s&resultsPerPage=-1" % application_id
        query_task_response = self.http_request.get(query_task, contentType='application/xml')
        root = ET.fromstring(query_task_response.getResponse())
        items = root.findall('ci')
        latest_package = ''
        if len(items) > 0:
            latest_package = items[-1].attrib['ref']
        return latest_package

    def get_all_package_version(self, application_id):
        query_task = "/deployit/repository/query?parent=%s&resultsPerPage=-1" % application_id
        query_task_response = self.http_request.get(query_task, contentType='application/xml')
        root = ET.fromstring(query_task_response.getResponse())
        items = root.findall('ci')
        all_package = list()
        for item in items:
            all_package.append(item.attrib['ref'])
        return all_package

    def get_latest_deployed_version(self, environment_id, application_name):
        query_task_response = self.get_ci("%s/%s" % (environment_id, application_name), 'xml')
        root = ET.fromstring(query_task_response)
        items = root.findall('version')
        latest_package = ''
        for item in items:
            latest_package = item.attrib['ref']
        return latest_package

    def check_ci_exist(self, ci_id, throw_on_fail=False):
        query_task = "/deployit/repository/exists/%s" % ci_id
        headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
        query_task_response = self.http_request.get(query_task, headers=headers)
        check_response(query_task_response, "Failed to check ci [%s]. Server return [%s], with content [%s]" % (
            ci_id, query_task_response.status, query_task_response.response))
        if query_task_response.getResponse().find('true') > 0:
            return True
        if throw_on_fail:
            raise Exception("CI with id [%s] does not exist or you do not have the correct permissions to read it." % ci_id)
        return False

    def create_folder_tree(self, folder_id, folder_type):
        folders = folder_id.split("/")
        folder_create = '%s' % folder_type
        for folder in folders:
            folder_create += "/" + folder
            if self.check_ci_exist(folder_create):
                print "Folder [%s] already exists" % folder_create
                print "\n"
            else:
                self.create_directory(folder_create)
                print "\n"

    def create_directory(self, ci_id):
        self.create_ci(ci_id, 'core.Directory')

    def create_application(self, app_id):
        self.create_ci(app_id, 'udm.Application')

    def create_ci(self, id, ci_type, xml_descriptor=''):
        xml = '<' + ci_type + ' id="' + id + '">' + xml_descriptor.strip() + '</' + ci_type + '>'
        create_task = '/deployit/repository/ci/%s' % id
        response = self.http_request.post(create_task, xml, contentType='application/xml')
        check_response(response, "Failed to create ci [%s]. Server return [%s], with content [%s]" % (
            id, response.status, response.response))
        print "Created ci [%s] and received response [%s]" % (id, response.response)

    def update_ci_property(self, ci_id, ci_property, property_value):
        self.check_ci_exist(ci_id, throw_on_fail=True)
        ci = self.get_ci(ci_id, 'json')
        data = json.loads(ci)
        if ci_property in data and isinstance(data[ci_property], list):
            data[ci_property] = eval(property_value)
        else:
            data[ci_property] = property_value
        self.update_ci(ci_id, json.dumps(data), 'json')

    def add_ci_to_environment(self, env_id, ci_id, ci_type):
        self.check_ci_exist(env_id, throw_on_fail=True)
        ci = self.get_ci(env_id, 'json')
        data = json.loads(ci)
        if str(ci_type) == 'udm.Dictionary':
            data["dictionaries"].append(ci_id)
        else:
            data["members"].append(ci_id)
        self.update_ci(env_id, json.dumps(data), 'json')

    def remove_ci_from_environment(self, env_id, ci_id):
        get_env_response = self.get_ci(env_id, 'xml')
        print get_env_response
        env_root = ET.fromstring(get_env_response)
        member_to_remove = None
        for child in env_root:
            if child.tag in ('members','dictionaries'):
                for member in child:
                    if member.attrib['ref'] == ci_id:
                        print 'Found ' + ci_id + ' in ' + env_id
                        env_members = child
                        member_to_remove = member
        if member_to_remove is not None:
            print 'Removing ' + ci_id + ' from ' + env_id
            env_members.remove(member_to_remove)
            self.update_ci(env_id, ET.tostring(env_root), 'xml')

    def get_ci(self, ci_id, accept):
        get_ci = "/deployit/repository/ci/%s" % ci_id
        headers = {'Accept': 'application/%s' % accept, 'Content-Type': 'application/%s' % accept}
        response = self.http_request.get(get_ci, headers=headers)
        check_response(response, "Failed to get ci [%s]. Server return [%s], with content [%s]" % (
            ci_id, response.status, response.response))
        return response.getResponse()

    def update_ci(self, ci_id, data, content_type):
        update_ci = "/deployit/repository/ci/%s" % ci_id
        content_type_header = "application/%s" % content_type
        response = self.http_request.put(update_ci, data, contentType=content_type_header)
        check_response(response, "Failed to update ci [%s]. Server return [%s], with content [%s]" % (
            ci_id, response.status, response.response))

    def delete_ci(self, ci_id):
        delete_task = '/deployit/repository/ci/' + ci_id
        headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
        response = self.http_request.delete(delete_task, headers=headers)
        check_response(response, "Failed to delete ci with id [%s]. Server return [%s], with content [%s]" % (
            ci_id, response.status, response.response))

    def get_ci_tree(self, ci_id):
        infrastructure_list = [ci_id]
        query = '/deployit/repository/query?parent=%s' % ci_id
        response = self.http_request.get(query, contentType='application/xml')
        check_response(response, "Unable to retrieve CI Tree from parent: %s" % ci_id)
        root = ET.fromstring(response.getResponse())
        for ci in root.findall('ci'):
            infrastructure_list.extend(self.get_ci_tree(ci.get('ref')))
        return infrastructure_list

    def display_step_logs(self, task_id):
        get_task_steps = '/deployit/task/' + task_id + '/step'
        get_task_steps_response = self.http_request.get(get_task_steps, contentType='application/xml')
        task_steps_root = ET.fromstring(get_task_steps_response.getResponse())
        for child in task_steps_root:
            if child.tag == 'steps':
                step_counter = 0
                for grandchild in child:
                    if grandchild.tag == 'step':
                        step_counter = step_counter + 1
                        print 'DEPLOYMENT STEP %d:  Failures=%s  State=%s\n' % (
                            step_counter, str(grandchild.attrib['failures']), str(grandchild.attrib['state']))
                        for item in grandchild:
                            if item.tag in ('description', 'startDate', 'completionDate'):
                                print '%s %s\n' % (item.tag, item.text)
                            else:
                                print "%s\n" % item.tag
                                print "%s\n" % item.text

    def query_archived_tasks(self, end_date=None):
        get_tasks = '/deployit/tasks/v2/query'
        if end_date:
            get_tasks += '?begindate=2008-01-01&enddate=%s' % end_date
        headers = {'Accept': 'application/json', 'Content-Type': 'application/json'}
        response = self.http_request.get(get_tasks, headers=headers)
        check_response(response, "Failed to get archived tasks. Server return [%s], with content [%s]" % (
            response.status, response.response))
        return response.getResponse()

    def get_deployed_applications_for_environment(self, environment, date=None):
        archived_tasks = self.query_archived_tasks(date)
        deployed_apps = {}
        if archived_tasks:
            tasks = json.loads(archived_tasks)
            for task in tasks:
                if task['state'] == 'DONE' and task['metadata']['taskType'] not in (
                    'CONTROL', 'INSPECTION', 'DEFAULT') and task['metadata']['environment_id'] == environment:
                    if task['metadata']['taskType'] in ('INITIAL', 'UPGRADE', 'ROLLBACK'):
                        deployed_apps[task['metadata']['application']] = get_row_data(task)
                    if task['metadata']['taskType'] in ('UNDEPLOY') and task['metadata'][
                        'application'] in deployed_apps:
                        del deployed_apps[task['metadata']['application']]
        return deployed_apps
class ServiceNowClient(object):

    def __init__(self, httpConnection, username=None, password=None):
        self.httpConnection = httpConnection
        self.httpRequest = HttpRequest(httpConnection, username, password)

    @staticmethod
    def create_client(httpConnection, username=None, password=None):
        return ServiceNowClient(httpConnection, username, password)


    def get_change_request_states(self):
        servicenow_api_url = '/api/now/v1/table/%s?element=state&name=task&sysparm_fields=%s' % ('sys_choice','value,label')
        response = self.httpRequest.get(servicenow_api_url, contentType = 'application/json')
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        self.throw_error(response)

    def get_change_request(self, table_name,number,fields):
        servicenow_api_url = '/api/now/v1/table/%s?number=%s&sysparm_fields=%s' % (table_name,number,",".join(fields))
        response = self.httpRequest.get(servicenow_api_url, contentType = 'application/json')
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            if len(data['result']) == 1:
                return data['result'][0]
        self.throw_error(response)

    def get_change_request(self, table_name,sysId):
        servicenow_api_url = '/api/now/v1/table/%s/%s' % (table_name, sysId)
        response = self.httpRequest.get(servicenow_api_url, contentType = 'application/json')
        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        self.throw_error(response)
        
    def create_record(self, table_name, content):
        servicenow_api_url = '/api/now/v1/table/%s' % (table_name)
        response = self.httpRequest.post(servicenow_api_url, body = content, contentType = 'application/json')

        if response.getStatus() == RECORD_CREATED_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        else:
            self.throw_error(response)
        # End if
    #End create_record

    def update_record(self, table_name, sysId, content):
        servicenow_api_url = '/api/now/v1/table/%s/%s' % (table_name, sysId)
        response = self.httpRequest.put(servicenow_api_url, body = content, contentType = 'application/json')

        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads(response.getResponse())
            return data['result']
        else:
            self.throw_error(response)
        # End if
    #End create_record

    def find_record( self, table_name, query ):
        servicenow_api_url = '/api/now/v1/table/%s?%s' % (table_name, query)
        print "Servic Now URL = %s " % ( servicenow_api_url )
        response = self.httpRequest.get( servicenow_api_url, contentType = 'application/json' )

        if response.getStatus() == SN_RESULT_STATUS:
            data = json.loads( response.getResponse() )
            return data['result']
        else:
            print "find_record error %s" % ( response )
            self.throw_error(response)
        # End if
    #End find_record

    def print_error(self, response):
        if type(response) is dict:
           outStr =   "| Status  | %s |\n" % ( response["status"] )
           outStr = "%s| Message | %s |\n" % ( outStr, response["error"]["message"] )
           outStr = "%s| Detail  | %s |\n" % ( outStr, response["error"]["detail"] )
           return outStr
        # End if
        return response
    #End  print_error

    def print_table(self, headers, rows):
        print "\n|", "|".join(headers), "|"
        print "|", " ------ |" * len(headers)
        for r in rows:
            print "| ", "  |".join(r), " |"
        print "\n"

    def print_record( self, myObj, outStr = "", prefix="", header=True ):
       if header:
          outStr = "%s| Key | Value |\n" % (outStr)
          outStr = "%s| --- | --- |\n" % (outStr)
       if type(myObj) is dict:
          for key in myObj.iterkeys():
              value = myObj[key]
              if type(value) is dict or type(value) is list:
                 p = "%s%s." % (prefix, key)
                 outStr =  "%s| %s%s |\n%s" % (outStr, prefix, key, self.print_record( value, "", p, False ) )
              else:
                 p = "%s%s" % (prefix, key)
                 outStr =  "%s| %s%s |%s |\n" % (outStr, prefix, key, value )
                 
       elif type(myObj) is list:
          for value in myObj:
              outStr = "%s| | %s\n" % (outStr, value)
       else:
          outStr = "%s%s" % (outStr, myObj)
       # End if
       return outStr


    def throw_error(self, response):
        print "Error from ServiceNow, HTTP Return: %s\n" % (response.getStatus())
        sys.exit(1)
class XLDeployClient(object):
    def __init__(self, http_connection, username=None, password=None):
        self.http_request = HttpRequest(http_connection, username, password)

    @staticmethod
    def create_client(http_connection, username=None, password=None):
        return XLDeployClient(http_connection, username, password)

    def extract_state(self, task_state_xml):
        state_pos = task_state_xml.find('state2="')
        state_offset = len('state2="')
        state_end_pos = task_state_xml.find('"', state_pos + state_offset + 1)
        state = task_state_xml[state_pos + state_offset:state_end_pos]
        return state

    def getParameterTypeName(self, root):
        params = root.find("parameters")
        if params:
            for child in params:
                return child.tag

    def getParameterNames(self, parameterTypeId):
        metadata_url = "/deployit/metadata/type/%s" % (parameterTypeId)
        metadata_response = self.http_request.get(metadata_url, contentType='application/xml')
        root = ET.fromstring(metadata_response.getResponse())
        params = root.find("property-descriptors")
        if params:
            parameterNames = []
            for child in params:
                parameterNames.append(child.get("name"))
        return parameterNames

    def addParameter(self, root, parameterTypeId, parameterName, parameters):
        params = root.find("parameters")
        propertyDict = dict(ast.literal_eval(parameters))
        if params:
            for child in params:
                if child.tag == parameterTypeId:
                    param = ET.SubElement(child, parameterName)
                    param.text = propertyDict[parameterName]

    def prepare_control_task(self, control_task_name, target_ci_id, parameters=None):
        # print 'DEBUG: prepare the control task'
        prepare_control_task_url = "/deployit/control/prepare/%s/%s" % (control_task_name, target_ci_id)
        prepare_response = self.http_request.get(prepare_control_task_url, contentType='application/xml')
        control_obj = prepare_response.getResponse()
        root = ET.fromstring(control_obj)
        # print 'DEBUG: Control obj from /prepare', control_obj, '\n'
        parameterTypeId = self.getParameterTypeName(root)
        # print 'DEBUG: got parameterTypeId: %s' % parameterTypeId
        if parameterTypeId:
            parameterNames = self.getParameterNames(parameterTypeId)
            # print 'Found parameter names: %s' % parameterNames
            for parameterName in parameterNames:
                self.addParameter(root, parameterTypeId, parameterName, parameters)
        # print 'DEBUG: Control obj after udating parameters ', ET.tostring(root), '\n'
        invoke_response = self.http_request.post('/deployit/control', ET.tostring(root), contentType='application/xml')
        task_id = invoke_response.getResponse()
        # print 'DEBUG: Control task ID', task_id, '\n'
        return task_id

    def invoke_task_and_wait_for_result(self, task_id, polling_interval=10, number_of_trials=None, continue_if_step_fails=False, number_of_continue_retrials=0, fail_on_pause=True):
        start_task_url = "/deployit/task/%s/start" % (task_id)
        # print 'DEBUG: About to invoke task by post %s - continue enabled: %s - trial: %s \n' % (task_id, continue_if_step_fails, number_of_continue_retrials)
        self.http_request.post(start_task_url, '', contentType='application/xml')
        trial = 0
        while not number_of_trials or trial < number_of_trials:
            # print 'DEBUG: About to get task status', task_id, '\n'
            trial += 1
            get_task_status_url = "/deployit/task/%s" % (task_id)
            task_state_response = self.http_request.get(get_task_status_url, contentType='application/xml')
            task_state_xml = task_state_response.getResponse()
            # print 'DEBUG task_state_xml is ' + task_state_xml
            status = self.extract_state(task_state_xml)
            print 'Task', task_id, 'now in state', status, '\n'
            if fail_on_pause:
                if status in ('FAILED', 'ABORTED', 'STOPPED') and continue_if_step_fails and number_of_continue_retrials > 0:
                    status = self.invoke_task_and_wait_for_result(task_id, polling_interval, number_of_trials, continue_if_step_fails, number_of_continue_retrials - 1)
                if status in ('FAILED', 'ABORTED', 'STOPPED', 'CANCELLED', 'DONE', 'EXECUTED'):
                    break
            else:
                if status in ('FAILED', 'ABORTED') and continue_if_step_fails and number_of_continue_retrials > 0:
                    status = self.invoke_task_and_wait_for_result(task_id, polling_interval, number_of_trials, continue_if_step_fails, number_of_continue_retrials - 1)
                if status in ('FAILED', 'ABORTED', 'CANCELLED', 'DONE', 'EXECUTED'):
                    break
            time.sleep(polling_interval)
        return status

    def get_deployment_package(self, deployed_application_id):
        ci = self.get_ci(deployed_application_id, 'json')
        data = json.loads(ci)
        return data['version']

    def deployment_exists(self, deployment_package, environment):
        deployment_exists_url = "/deployit/deployment/exists?application=%s&environment=%s" % (deployment_package.rsplit('/', 1)[0], environment)
        # print 'DEBUG: checking deployment exists with url %s \n' % deployment_exists_url
        deployment_exists_response = self.http_request.get(deployment_exists_url, contentType='application/xml')
        response = deployment_exists_response.getResponse()
        return 'true' in response

    def deployment_prepare_undeploy(self, deployed_application_id):
        deployment_prepare_undeploy_url = "/deployit/deployment/prepare/undeploy?deployedApplication=%s" % (deployed_application_id)
        deployment_prepare_undeploy_url_response = self.http_request.get(deployment_prepare_undeploy_url, contentType='application/xml')
        return deployment_prepare_undeploy_url_response.getResponse()

    def deploymentPrepareUpdate(self, deploymentPackage, environment):
        deploymentPrepareUpdateUrl = "/deployit/deployment/prepare/update?version=%s&deployedApplication=%s" % (deploymentPackage, "%s/%s" % (environment, deploymentPackage.rsplit('/', 2)[1]))
        deploymentPrepareUpdate_response = self.http_request.get(deploymentPrepareUpdateUrl, contentType='application/xml')
        return deploymentPrepareUpdate_response.getResponse()

    def deploymentPrepareInitial(self, deploymentPackage, environment):
        deploymentPrepareInitialUrl = "/deployit/deployment/prepare/initial?version=%s&environment=%s" % (deploymentPackage, environment)
        deploymentPrepareInitial_response = self.http_request.get(deploymentPrepareInitialUrl, contentType='application/xml')
        return deploymentPrepareInitial_response.getResponse()

    def add_orchestrators(self, deployment_xml, orchestrators):
        root = ET.fromstring(deployment_xml)
        if orchestrators:
            params = root.find(".//orchestrator")
            params.clear()
            orchs = orchestrators.split(",")
            for orch in orchs:
                orchestrator = ET.SubElement(params, 'value')
                orchestrator.text = orch.strip()
        return ET.tostring(root)

    def set_deployed_application_properties(self, deployment_xml, deployed_application_properties):
        root = ET.fromstring(deployment_xml)
        if deployed_application_properties:
            deployeds_application_properties_dict = dict(ast.literal_eval(deployed_application_properties))
            # print 'DEBUG: deployed application properties dict is %s \n' % deployeds_application_properties_dict
            # print 'DEBUG: Deployment object is now: %s \n' % ET.tostring(root)
            for key in deployeds_application_properties_dict:
                # print "DEBUG: Key is %s" % key
                pkey_xml = root.find(key)
                if not pkey_xml:
                    application = root.find("application")
                    for child in application:
                        # print "DEBUG: Going to add key: %s" % key
                        # print "DEBUG: Searching for deployed application: %s" % child
                        pkey_xml = ET.SubElement(child, key)
                pkey_xml.text = deployeds_application_properties_dict[key]
        return ET.tostring(root)

    def set_deployed_properties(self, deployment_xml, deployed_properties):
        root = ET.fromstring(deployment_xml)
        if deployed_properties:
            deployeds_properties_dict = dict(ast.literal_eval(deployed_properties))
            for key in deployeds_properties_dict:
                for xlr_tag_deployed in root.findall(".//deployeds/*"):
                    # print 'DEBUG: deployed is %s \n' % ET.tostring(xlr_tag_deployed)
                    # print 'DEBUG: xlrTag exists? %s' % xlr_tag_deployed.findtext('xlrTag')
                    # print 'DEBUG: xlrTag key? %s' % key
                    if key == xlr_tag_deployed.findtext('xlrTag'):
                        deployed_properties_dict = dict(ast.literal_eval(deployeds_properties_dict[key]))
                        # print 'DEBUG: deployed properties dict is %s \n' % deployed_properties_dict
                        for pkey in deployed_properties_dict:
                            pkey_xml = xlr_tag_deployed.find(pkey)
                            if not pkey_xml:
                                pkey_xml = ET.SubElement(xlr_tag_deployed, pkey)
                            pkey_xml.text = deployed_properties_dict[pkey]
        return ET.tostring(root)

    def deployment_prepare_deployeds(self, deployment, orchestrators=None, deployed_application_properties=None, deployed_properties=None):
        deployment_prepare_deployeds = "/deployit/deployment/prepare/deployeds"
        # print 'DEBUG: Prepare deployeds for deployment object %s \n' % deployment
        deployment_prepare_deployeds_response = self.http_request.post(deployment_prepare_deployeds, deployment, contentType='application/xml')
        if not deployment_prepare_deployeds_response.isSuccessful():
            raise Exception("Failed to prepare deployeds. Server return [%s], with content [%s]" % (deployment_prepare_deployeds_response.status, deployment_prepare_deployeds_response.response))
        deployment_xml = deployment_prepare_deployeds_response.getResponse()
        # print 'DEBUG: deployment_xml is ' + deployment_xml
        deployment_xml = self.add_orchestrators(deployment_xml, orchestrators)
        deployment_xml = self.set_deployed_application_properties(deployment_xml, deployed_application_properties)
        # print 'DEBUG: Deployment object after updating orchestrators: %s \n' % ET.tostring(root)
        deployment_xml = self.set_deployed_properties(deployment_xml, deployed_properties)
        return deployment_xml

    def validate(self, deployment):
        getDeploymentTaskId = "/deployit/deployment/validate"
        # print 'DEBUG: validate for deployment object %s \n' % deployment
        deploymentWithValidation_response = self.http_request.post(getDeploymentTaskId, deployment, contentType='application/xml')
        # print 'DEBUG: deploymentWithValidation response is %s \n' % (deploymentWithValidation_response.getResponse())
        deployment = deploymentWithValidation_response.getResponse()
        root = ET.fromstring(deployment)
        return map(lambda vm: "CI: %s Message: %s" % (vm.attrib['ci'], vm.text), root.iter('validation-message'))

    def get_deployment_task_id(self, deployment):
        getDeploymentTaskId = "/deployit/deployment"
        # print 'DEBUG: creating task id for deployment object %s \n' % deployment
        deploymentTaskId_response = self.http_request.post(getDeploymentTaskId, deployment, contentType='application/xml')
        # print 'DEBUG: getDeploymentTaskId response is %s \n' % (deploymentTaskId_response.getResponse())
        return deploymentTaskId_response.getResponse()

    def deployment_rollback(self, taskId):
        deploymentRollback = "/deployit/deployment/rollback/%s" % taskId
        # print 'DEBUG: calling rollback for taskId %s \n' % taskId
        deploymentRollback_response = self.http_request.post(deploymentRollback, '', contentType='application/xml')
        # print 'DEBUG: received rollback taskId %s \n' % deploymentRollback_response.getResponse()
        return deploymentRollback_response.getResponse()

    def archive_task(self, task_id):
        archive_task = "/deployit/task/%s/archive" % task_id
        self.http_request.post(archive_task, '', contentType='application/xml')

    def cancel_task(self, taskId):
        cancelTask = "/deployit/task/%s" % taskId
        self.http_request.delete(cancelTask, contentType='application/xml')

    def stop_task(self, taskId):
        stopTask = "/deployit/task/%s/stop" % taskId
        self.http_request.post(stopTask, '', contentType='application/xml')

    def get_download_uuid(self, deploymentPackage):
        exportTask = "/deployit/export/deploymentpackage/%s" % deploymentPackage
        exportTask_response = self.http_request.get(exportTask, contentType='application/xml')
        return exportTask_response.getResponse()

    def fetch_package(self, fetchURL):
        fetchTask = "/deployit/package/fetch"
        self.http_request.post(fetchTask, fetchURL, contentType='application/xml')

    def get_latest_package_version(self, application_id):
        query_task = "/deployit/repository/query?parent=%s&resultsPerPage=-1" % application_id
        query_task_response = self.http_request.get(query_task, contentType='application/xml')
        root = ET.fromstring(query_task_response.getResponse())
        items = root.findall('ci')
        latest_package = ''
        if len(items) > 0:
            latest_package = items[-1].attrib['ref']
        return latest_package

    def get_latest_deployed_version(self, environment_id, application_name):
        query_task_response = self.get_ci("%s/%s" % (environment_id, application_name), 'xml')
        root = ET.fromstring(query_task_response)
        items = root.findall('version')
        latest_package = ''
        for item in items:
            latest_package = item.attrib['ref']
        # End for
        return latest_package

    def check_CI_exist(self, ci_id):
        query_task = "/deployit/repository/exists/%s" % ci_id
        query_task_response = self.http_request.get(query_task, contentType='application/xml')
        if not query_task_response.isSuccessful():
            raise Exception("Failed to check ci [%s]. Server return [%s], with content [%s]" % (ci_id, query_task_response.status, query_task_response.response))
        return query_task_response.getResponse().find('true') > 0

    def create_directory(self, ciId):
        createTask = "/deployit/repository/ci/%s" % ciId
        xml = '<core.Directory id="' + ciId + '" />'
        self.http_request.post(createTask, xml, contentType='application/xml')

    def create_application(self, appId):
        createTask = "/deployit/repository/ci/%s" % appId
        xml = '<udm.Application id="' + appId + '" />'
        self.http_request.post(createTask, xml, contentType='application/xml')

    def createCI(self, id, ciType, xmlDescriptor):
        xml = '<' + ciType + ' id="' + id + '">' + xmlDescriptor + '</' + ciType + '>'
        createTask = '/deployit/repository/ci/' + id
        self.http_request.post(createTask, xml, contentType='application/xml')

    def update_ci_property(self, ci_id, ci_property, property_value):
        if self.check_CI_exist(ci_id):
            ci = self.get_ci(ci_id, 'json')
            data = json.loads(ci)
            data[ci_property] = property_value
            self.update_ci(ci_id, json.dumps(data), 'json')
        else:
            raise Exception("Did not find ci with id [%s]" % ci_id)

    def add_ci_to_environment(self, env_id, ci_id):
        get_env_response = self.get_ci(env_id, 'xml')
        items = get_env_response.partition('</members>')
        xml = items[0] + '<ci ref="' + ci_id + '"/>' + items[1] + items[2]
        print(xml)
        self.update_ci(env_id, xml, 'xml')

    def remove_ci_from_environment(self, env_id, ci_id):
        get_env_response = self.get_ci(env_id, 'xml')
        print get_env_response
        env_root = ET.fromstring(get_env_response)
        member_to_remove = None
        for child in env_root:
            if child.tag == 'members':
                for member in child:
                    if member.attrib['ref'] == ci_id:
                        print 'Found ' + ci_id + ' in ' + env_id
                        env_members = child
                        member_to_remove = member
        if member_to_remove is not None:
            print 'Removing ' + ci_id + ' from ' + env_id
            env_members.remove(member_to_remove)
            self.update_ci(env_id, ET.tostring(env_root), 'xml')

    def get_ci(self, ci_id, accept):
        get_ci = "/deployit/repository/ci/%s" % ci_id
        headers = {'Accept': 'application/%s' % accept}
        response = self.http_request.get(get_ci, headers=headers)
        if not response.isSuccessful():
            raise Exception("Failed to get ci [%s]. Server return [%s], with content [%s]" % (ci_id, response.status, response.response))
        return response.getResponse()

    def update_ci(self, ci_id, data, content_type):
        update_ci = "/deployit/repository/ci/%s" % ci_id
        content_type_header = "application/%s" % content_type
        response = self.http_request.put(update_ci, data, contentType=content_type_header)
        if not response.isSuccessful():
            raise Exception("Failed to update ci [%s]. Server return [%s], with content [%s]" % (ci_id, response.status, response.response))

    def delete_ci(self, ci_id):
        delete_task = '/deployit/repository/ci/' + ci_id
        self.http_request.delete(delete_task)

    def display_step_logs(self, task_id):
        get_task_steps = '/deployit/task/' + task_id + '/step'
        get_task_steps_response = self.http_request.get(get_task_steps, contentType='application/xml')
        task_steps_root = ET.fromstring(get_task_steps_response.getResponse())
        for child in task_steps_root:
            if child.tag == 'steps':
                step_counter = 0
                for grandchild in child:
                    if grandchild.tag == 'step':
                        step_counter = step_counter + 1
                        print 'DEPLOYMENT STEP %d:  Failures=%s  State=%s\n' % (step_counter, str(grandchild.attrib['failures']), str(grandchild.attrib['state']))
                        for item in grandchild:
                            if item.tag in ('description', 'startDate', 'completionDate'):
                                print '%s %s\n' % (item.tag, item.text)
                            else:
                                print "%s\n" % item.tag
                                print "%s\n" % item.text
#
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#


import json
from xlrelease.HttpRequest import HttpRequest

if not sonarServer:
    raise Exception("Sonar server ID must be provided")

sonar_url = sonarServer['url']
sonar_server_api_url = '/api/measures/component?componentKey=%s&metricKeys=%s' % (resource, ','.join(metrics.keys()))
http_request = HttpRequest(sonarServer, username, password)
sonar_response = http_request.get(sonar_server_api_url)
if sonar_response.isSuccessful():
    json_data = json.loads(sonar_response.getResponse())
    data1 = {}
    data1['id'] = json_data['component']['id']
    data1['key'] = json_data['component']['key']
    data1['name'] = json_data['component']['name']
    data1['sonarUrl'] = sonar_url
    for item in json_data['component']['measures']:
        data1[item['metric']] = item['value']
    data = data1
else:
    error = json.loads(sonar_response.getResponse())
    if 'Invalid table' in error['error']['message']:
        print "Invalid Table Name"
class SauceLabsClient(object):
    def __init__(self, buildId, testName, testNameWildCard, hourRange, limit, http_connection, 
        acctUsername, accessKey):
        self.configUsername = acctUsername
        self.configAccessKey = accessKey
        self.http_connection = http_connection
        # If not username and accessKey not configured in the getJobs task, use the info from the
        #    SauceLabs server configuration
        if not self.configUsername:
            self.configUsername = http_connection.get("username")
        if not self.configAccessKey:
            self.configAccessKey = http_connection.get("password")
        self.http_request = HttpRequest(http_connection, self.configUsername, self.configAccessKey)
        self.acctUsername = acctUsername
        self.buildId = buildId
        self.testName = testName
        self.testNameWildCard = testNameWildCard
        self.beginRange = None
        self.endRange = None
        self.limit = limit
        if hourRange and hourRange > 0:
            self.endRange = str(int(time.time()))
            self.beginRange = str(int(time.time()) - (int(hourRange)*3600))
            

    @staticmethod
    def create_client(buildId, testName, testNameWildCard, hourRange, limit, http_connection, 
        acctUsername, accessKey):
        return SauceLabsClient(buildId, testName, testNameWildCard, hourRange, limit, http_connection, 
             acctUsername, accessKey)

    def filterList(self, data):
        filteredJobs = []
        for testJob in data:
            passedName = True
            passedBuild = True
            testJobName = testJob["name"] if testJob["name"] else ""
            testJobBuild = testJob["build"] if testJob['build'] else ""
            # Note: hour and limit are filtered in the intial http request
            if self.testName:
                if self.testNameWildCard:
                    if self.testName not in testJobName:
                        passedName = False
                else: 
                    if self.testName != testJobName:
                        passedName = False
            if self.buildId:
                if self.buildId != testJobBuild:
                    passedBuild = False 
            if passedName and passedBuild:
                filteredJobs.append(testJob)
        return filteredJobs

    def getAdditionalParams(self):
        theLimit = ""
        theHourRange = ""
        if self.limit:
            theLimit = "&limit="+str(self.limit)
        if self.beginRange and self.endRange:
            theHourRange = "&from="+self.beginRange+"&to="+self.endRange
        paramsString = theLimit+theHourRange
        return paramsString

    def get_jobs(self,):
        addParams = self.getAdditionalParams()
        saucelabs_api_url = "/rest/v1/%s/jobs?full=true%s" % (self.configUsername, addParams)

        jobs_response = self.http_request.get(saucelabs_api_url, contentType='application/json')
        if not jobs_response.isSuccessful():
            raise Exception("Failed to get jobs. Server return [%s], with content [%s] when calling [%s]" % (jobs_response.status, jobs_response.response, saucelabs_api_url))
        data = json.loads(jobs_response.getResponse())
        filteredJobs = self.filterList(data)
        jobs = {}
        nothingFound = "No jobs matching the search criteria were found. Search URL - "+saucelabs_api_url
        if len(filteredJobs) > 0:
            print 'Description | Start Time | Build Id | Name | Passed | Link'
            print ':---: | :---: | :---: | :---: | :---: | :---:'
        else:
            print nothingFound
            jobs["0"] = nothingFound
        counter = 0
        for job in filteredJobs: 
            counter += 1
            jobName = job["name"] if job["name"] else " "
            jobBuildId = job["build"] if job["build"] else " " 
            description = job["os"]+"/"+job["browser"]+"-"+job["browser_short_version"]
            jobPassed = job["passed"] if job["passed"] else " "
            
            jobPassedConverted =" "
            if jobPassed != " ":
                if job["passed"]:
                    jobPassedConverted = "Passed"
                else:
                    jobPassedConverted = "Failed"
                
            ts = int(job["start_time"])
            dateAndTime = datetime.utcfromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S')
            link = "[View]("+self.http_connection.get("url")+"/jobs/"+job["id"]+")"
            print '%s|%s|%s|%s|%s|%s' % (description, dateAndTime, jobBuildId, jobName, jobPassed,link)
            jobs[str(job["id"])] = jobPassedConverted

        filteredJobsStr = json.dumps(filteredJobs)
        return filteredJobsStr, jobs