Exemple #1
0
    def request(self, method="get"):
        """
        Request REST API Call
        :return: HTTP status code
        """
        assert (self.rest_url and self.rest_url != "")

        if self._is_network_initialized is False:
            raise ConnectionError("Not initialized yet.")

        self.log("HTTP Request URL : " + self.base_url + self.rest_url)
        self.log("HTTP Request headers :", self.http_headers)

        self.res_body = None
        self.res = requests.request(method=method,
                                    url=self.base_url + self.rest_url,
                                    headers=self.http_headers,
                                    auth=(self.username, self.password),
                                    params=self.http_args,
                                    data=self.post_body,
                                    proxies=self.proxies)

        try:
            self.res_body = util.VersatileDict(self.res.json())
        except ValueError:  # Not json format
            self.res_body = None

        self.log("HTTP Request URL: %s" % self.res.url)
        self.log("HTTP Response status : %d" % self.res.status_code)

        if self.res.status_code == requests.codes.unauthorized:
            self.log("Status Code: %d, Message: Unauthorized, URL: %s" %
                     (self.res.status_code, self.res.url))

        return self.res.status_code
Exemple #2
0
    def __init__(self, obj=None, mapping=DEFAULT_JIRA_FIELDS_MAP, server_url=None, username=None, password=None,
                 permission=PERMISSION_READ, debug_level=0):
        """

        :param obj: JIRA Issue data. VersatilaDict type or Dictionary
        :param mapping: JIRA Field and JSON Path mapping dictionary or JIRAFieldsMap
        :param server_url:
        :param username:
        :param password:
        :param debug_level:
        :return:
        """

        if obj:
            if isinstance(obj, util.VersatileDict):
                self._data = obj
            else:
                self._data = util.VersatileDict(obj)

            if isinstance(mapping, JIRAFieldsMap):
                self.map = mapping
            else:
                self.map = JIRAFieldsMap(mapping)

            for field in mapping.keys():                   # set key names to attributes
                try:
                    v = self.map.value(field)
                    d = self._data.value(v)
                    setattr(self, field, d)
                except KeyError:                           # Some key is absent in some project. Skip it.
                    pass

        if server_url is not None:                         # if don't want to initialize network
            super().__init__(server_url=server_url, username=username, password=password, permission=permission,
                             debug_level=debug_level)      # Constructor of RESTNetwork
Exemple #3
0
    def create_issue(self,
                     project_id,
                     summary,
                     issuetype,
                     assignee=None,
                     priority=None,
                     description="",
                     args={}):
        """
        Create JIRA Issue.

        :param project_id:
        :param summary:
        :param issuetype:
        :param assignee:
        :param priority:
        :param description:
        :return:
        """

        if self.is_writable() is False:
            raise PermissionError("Not writable")

        req_body = util.VersatileDict()
        req_body.add("fields/project/key", project_id)
        req_body.add("fields/summary", summary)
        req_body.add("fields/description", description)
        req_body.add("fields/issuetype/name", issuetype)

        if len(args) > 0:
            arg_list = list(args.keys())

            for arg in arg_list:
                if args[arg] is None:
                    continue

                self.log("Create issue arg => %s : %s" % (arg, args[arg]))
                req_body.add(arg, args[arg])

        self.log("Issue creation json data:\n", req_body)
        self.set_post_body(req_body.json())

        self.http_headers["Content-Type"] = "application/json"

        self.set_resturl("/issue")
        status = self.request_post()

        if status != requests.codes.created:
            self.log("Fail to create issue. Status Code: %d, URL: %s" %
                     (status, self.res.url))
            self.log(self.res.text)
            return status

        return status
Exemple #4
0
    def _update_field(self, key, value):
        """
        Update field data
        :param value: field API path. ex) /fields/custom_1104
        :return: HTTP code
        """

        if self.is_writable() is False:
            raise PermissionError("Not writable")

        self.set_resturl("/issue/%s" % self.key)
        self.http_headers["Content-Type"] = "application/json"
        req_body = util.VersatileDict()
        req_body.add(key, value)

        self.set_post_body(req_body.json())
        return self.request("put")
Exemple #5
0
    def assign(self, user):
        """
        Assign issue to specific user.
        :param user:
        :return:
        """

        if self.is_writable() is False:
            raise PermissionError("Not writable")

        self.set_resturl("/issue/%s/assignee" % self.key)
        self.http_headers["Content-Type"] = "application/json"

        req_body = util.VersatileDict()
        req_body.add("name", user)

        self.set_post_body(req_body.json())
        return self.request("put")
Exemple #6
0
    def update_status(self, value):
        """
        Update issue status
        :param value: new issue status
        :return: HTTP code
        """

        if self.is_writable() is False:
            raise PermissionError("Not writable")

        self.set_resturl("/issue/%s/transitions" % self.key)
        self.http_headers["Content-Type"] = "application/json"
        req_body = util.VersatileDict()
        req_body.add("update", {})
        req_body.add("transition/id", value)

        self.set_post_body(req_body.json())
        return self.request_post()
Exemple #7
0
def issue_sync(source_factory, target_factory):
    """
    :param source_factory:
    :param target_factory:
    :return:
    """
    loop = True
    start_at = 0
    changed_count = 0

    print (" ####################")
    print (" #### POST WORKS ####")
    print (" ####################")
    print()
    print (" #### Processing issues not assigned to S-Core ####\n")
    # No.    Inter-key     SPIN-key    Summary
    print("%7s %-10s %-10s %s" % ("No.", "Inter-key", "SPIN-key", "Action"))

    while loop:
        print("=" * 80)

        # Phase 1. Get issues from Target
        target_factory.retrieve_search(jql="project = SPIN and status = Closed", max_results=JQL_MAX_RESULTS,
                                       start_at=start_at)

        if target_factory.http_status != 200:
            print("Fail to get issues from Target")
            sys.exit(-1)

        data = util.VersatileDict(target_factory.value())

        total_count = int(data.value("total"))
        data._data = data.value("issues")

        # Phase 2. Find existing issue
        for i in range(JQL_MAX_RESULTS):

            # Exit loop condition
            if i + start_at >= total_count:
                loop = False
                break

            # Make issue instance for convenience
            target_issue = target_factory._new_issue_object(data.value(str(i)), DataMap.TARGET_JIRA_ISSUE_MAP)
            print("%4d:%2d %-10s  %-10s " % (i + start_at, i, target_issue.key, target_issue.spin_id), end="")

            if target_issue.spin_id is None:
                print("Invalid Issue. SPIN ID is none. Skip")
                continue

            try:
                found_issue = find_issue_in_source(source_factory, target_issue)
            except ConnectionError as err:
                print(err, end="")
                found_issue = None

            # Phase 3. Change assignee
            if found_issue is None:
                continue

            # Phase 4. Change issue status. In fact, this phase  is not necessary work, but convenient work for viewing
            result = target_issue.update_spin_resolved(found_issue.resolutiondate)

            if result == 204:
                print("RSV: updated with %s " % found_issue.resolutiondate, end="")
            else:
                errmsg = target_issue.value()
                print("RSV: [%s] " % (errmsg['errors']), end="")

            print("")

        start_at += JQL_MAX_RESULTS

    print("")
    print("Total changed: %d" % (changed_count))
Exemple #8
0
def update_existing_issues(source_connection, target_connection):
    """
    Update issues of target connection

    :param source_connection:
    :param target_connection:
    :return:
    """
    loop = True
    start_at = 0
    changed_count = 0


    # No.    Inter-key     SPIN-key    Summary
    print("%7s %-10s %-10s %s" % ("No.", "Target-key", "Source-key", "Action"))

    while loop:
        print("=" * 80)

        # STEP 1. Get issues from Target
        target_connection.retrieve_search(jql=DataMap.get_target_assigned_issue_jql(),
                                       max_results=JQL_MAX_RESULTS,
                                       start_at=start_at)

        if target_connection.http_status != 200:
            print("Fail to get issues from Target")
            sys.exit(-1)

        data = util.VersatileDict(target_connection.value())

        total_count = int(data.value("total"))
        data._data = data.value("issues")

        # STEP 2. Find existing issue
        for i in range(JQL_MAX_RESULTS):
            assign_flag = False
            status_flag = False

            new_assignee = ""
            new_status = ""

            # Exit loop condition
            if i + start_at >= total_count:
                loop = False
                break

            # Make issue instance for convenience
            target_issue = target_connection._new_issue_object(data.value(str(i)), DataMap.TARGET_JIRA_ISSUE_MAP)
            print("%4d:%2d %-10s %-10s " % (i + start_at, i, target_issue.key, target_issue.spin_id), end="")

            if target_issue.spin_id is None:  # if the issue is not imported from source.
                print("Invalid Issue. SPIN ID is none. Skip.")
                continue

            # STEP 3. Find source issue
            try:
                found_issue = find_issue_in_source(source_connection, target_issue)
            except ConnectionError as err:
                print(str(err), end="")
                found_issue = None
            except LookupError as err:
                print(str(err), end="")

            # STEP 4. Compare issues
            if found_issue and DataMap.get_user(found_issue.assignee) != DataMap.get_user(target_issue.assignee):
                assign_flag = True
                new_assignee = DataMap.get_user(found_issue.assignee)
            else:
                assign_flag = False

            if found_issue and DataMap.get_issue_status(found_issue.issuestatus) != target_issue.issuestatus:
                status_flag = True
                new_status = DataMap.get_issue_status(found_issue.issuestatus)
            else:
                status_flag = False

            if found_issue and found_issue.key != target_issue.spin_id:
                # TODO
                pass

            if not assign_flag and not status_flag:  # if not changed, go next.
                print("Skip")
                continue

            # STEP 4. Change assignee
            if assign_flag:
                reporter = target_issue.reporter

                if new_status in ("Resolved", "Closed") and reporter == new_assignee:
                    print("USR: automatic assign by issue resolve. Reporter: %s, Current assignee: %s"
                          % (reporter, target_issue.assignee))
                else:
                    r = issue_assign(target_issue, new_assignee, True, UNASSIGNED_USER)
                    print("USR: %s -> %s : %s " % (target_issue.assignee, new_assignee, r["MESSAGE"]), end="")

            # STEP 5. Change status
            if status_flag:
                # if closed issue, set resolved date before status changing, because closed issue can't be modified.
                if new_status == "Closed":
                    target_issue.update_spin_resolved(found_issue.resolutiondate)

                transition_id = DataMap.get_transition_id(new_status)
                r = issue_change_status(target_issue, transition_id)
                print("STAT: %s -> %s : %s " % (target_issue.issuestatus, new_status, r["MESSAGE"]), end="")

                if new_status == "Closed":
                    print("with Resolved date '%s'" % found_issue.resolutiondate, end="")

            print("")

            changed_count += 1

        start_at += JQL_MAX_RESULTS

    print("")
    print("Total changed: %d" % changed_count)
Exemple #9
0
def issue_importing(source_connection, target_connection):
    """
    Issue migration part. In this function, all issue of source jira are copied to target jira,
    and issue status and assignee are changed.

    :param source_connection:
    :param target_connection:
    :return:
    """
    loop = True
    start_at = 0
    source_issue = jira.Issue()
    created_count = 0

    # No.  SPIN-Key Exist  Action   New Key, Summary
    print("%7s %-10s %-5s   %-8s %-10s %s" % ("No.", "SPIN-key", "Exist", "Action", "New-key", "Summary"))

    while loop:
        print("=" * 80)

        # Phase 1. Get created issues from SPIN
        source_connection.retrieve_search(jql=DataMap.get_new_issues_jql(), max_results=JQL_MAX_RESULTS, start_at=start_at)

        if source_connection.http_status != 200:
            print("Fail to get issues from SPIN")
            sys.exit(-1)

        data = util.VersatileDict(source_connection.value())

        total_count = int(data.value("total"))
        data._data = data.value("issues")

        # Phase 2. Insert issues to target JIRA
        for i in range(JQL_MAX_RESULTS):

            # Exit loop condition
            if i + start_at >= total_count:
                loop = False
                break

            # Make issue instance for convenience. source_issue is not a connected object.
            source_issue.set_data(data.value(str(i)))
            print("%4d:%2d %-10s " % (i + start_at, i, source_issue.key), end="")

            try:
                existing_issue = find_issue_in_target(target_connection, source_issue)
            except LookupError as e:
                print(str(e))

            if not existing_issue:
                # Phase 1. Create issue
                print("%5s   " % "N", end="")

                created_count += 1

                r = issue_create(target_connection, source_issue)

                if r["CODE"] == 0:
                    print("Created %-10s %s" % (target_connection.value("key"), source_issue.summary), end="")
                else:
                    print("CR: %-10s" % r["MESSAGE"], end="")
            else:
                print("%5s   " % "Y", end="")

            print("")

        start_at += JQL_MAX_RESULTS

    print("")
    print("Total imported: %d" % created_count)

    return created_count