Exemple #1
0
    def new(self, **kwargs):
        """Opens new bug

        It automatically generates bug_url from product as bugzilla wants product name in GET response

        Args:
            product: Product name in the site
            component: Component name in bugzilla page
            security: Whether it is security vulnerability
            url: External url
            status: Initial but status. (NEW, RESOLVED)
            assigned_to: Email address to assign
            alias: Bug alias (NOT IMPLEMENTED)
            blocks: Bugs that this bug blocks
            dependson: Bug that depends on.
            cc: E-mail addresses to CC

        Returns:
            Integer indicating the bugzilla id for new bug

        Raises:
            BugzillaError: Required arguments are not provided

        """
        log = logging.getLogger("bugzilla.NEW")

        args = BugStruct(**kwargs)

        # control required vars
        if not (args.has("component") and args.has("product")
                and args.has("title") and args.has("description")):
            raise BugzillaError(
                "Missing argument. Component, Product, Title and Description are needed"
            )

        bug_url = self.constants.get_new_bug_url(args.product)

        log.debug("Opening new bug page")
        self.browser.open(bug_url)
        log.debug("Selecting form name: Create")
        self.browser.select_form(name="Create")

        log.debug("Adding component, title and comment")
        self.browser["component"] = [args.component]
        self.browser["short_desc"] = args.title
        self.browser["comment"] = args.description

        if args.has("url"):
            log.debug("URL: %s" % args.url)
            self.browser["bug_file_loc"] = args.url

        if args.has("security"):
            log.debug("Security: 1")
            self.browser["bit-10"] = ["1"]

        if args.has("status"):
            log.debug("Bug_status: %s" % args.status)
            self.browser["bug_status"] = [args.status]

        if args.has("assigned_to"):
            log.debug("Assign: %s" % args.assigned_to)
            self.browser["assigned_to"] = args.assigned_to

        if args.has("dependson"):
            log.debug("Depends on: %s" % args.dependson)
            self.browser["dependson"] = args.dependson

        if args.has("blocks"):
            log.debug("Blocks: %s" % args.blocks)
            self.browser["blocked"] = args.blocks

        if args.has("version"):
            log.debug("Version: %s" % args.version)
            self.browser["version"] = [args.version]

        if args.has("cc"):
            log.debug("CC: %s" % args.cc)
            self.browser["cc"] = args.cc

        # FIXME: Our bugzilla page doesn't show alias field.
        # FIXME: Uncomment it when it is done
        # if args.has("alias"):
        #     self.browser["alias"] = args.alias

        response = self.browser.submit()
        response = response.read()

        log.info("Bug submitted")

        # get bug id.
        re_compile = re.compile("Bug (.*?) Submitted")
        bug_id = re.findall(re_compile, response)

        if len(bug_id) != 0:
            return bug_id[0]
        else:
            log.error("Wohoops. Unexpected data returned after submitting.")
            return False
Exemple #2
0
    def modify(self, **kwargs):
        # TODO: Implement Product/Component/CC list
        """Modifies the bug.

        All arguments can be supplied. This function modifies the form on the page and submits just like an ordinary browser does.

        Args:
            bug_id: Bug id to edit
            title: New bug title
            comment: Comment to write
            status: Status (NEW, ASSIGNED, RESOLVED)
            resolution: (FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE)
            security: Whether it is security or not
            assigned_to: E-mail address to assign a bug
            blocks: Bugs that this bug blocks
            dependson: Bug that depends on.
            cc: Add e-mail address to cc list

        Raises:
            BugzillaError: You should first login to modify the bug
            ModifyError: Changes are not applied
        """
        log = logging.getLogger("bugzilla.MODIFY")

        args = BugStruct(**kwargs)

        if not args.has("bug_id"):
            raise BugzillaError("Bug id is needed to modify")

        if not self.is_logged_in:
            log.error("Login is needed")
            raise LoginError("You should first login to comment")

        log.info("Opening bug #%s to modify" % args.bug_id)

        bug_data = self._bug_open(args.bug_id, xml=False)
        # do we have permission to see this bug?
        if bug_data.find(self.constants.NO_PERMISSON_STRING) > -1:
            log.error("Don't have permission to modify the bug")
            raise BugzillaError("You don't have permission to see this bug")

        log.info("Opened bug #%s page" % args.bug_id)

        log.debug("Selecting changeform")
        self.browser.select_form(name="changeform")

        # for x in self.browser.forms():
        #     print x

        if args.has("title"):
            log.debug("New title: %s" % args.title)
            self.browser["short_desc"] = args.title

        if args.has("status"):
            log.debug("Bug_status: %s" % args.status)
            self.browser["bug_status"] = [args.status]

        if args.has("resolution"):
            log.debug("Resolution: %s" % args.resolution)
            self.browser["resolution"] = [args.resolution]

        if args.has("comment"):
            log.debug("Setting comment")
            self.browser["comment"] = args.comment

        if args.has("security"):
            # Pardus has specific setting for security vulnerabilities that will not be public. The checkbox name is "bit-10"
            log.debug("Marking as security")
            if args.security == "1":
                # if the bug has bit-10 field set
                if len(self.browser["bit-10"]) != 0:
                    log.warning(
                        "Bug is already in security group, not setting security tag"
                    )
                else:
                    self.browser["bit-10"] = ["1"]
            # marking as non-security
            else:
                if len(self.browser["bit-10"]) == 0:
                    log.warning(
                        "Bug is already public, not setting security tag..")
                else:
                    self.browser["bit-10"] = []

        if args.has("assigned_to"):
            log.debug("Assigned: %s" % args.assigned_to)
            self.browser["assigned_to"] = args.assigned_to

        if args.has("keywords"):
            log.debug("Keywords: %s" % args.keywords)
            self.browser["keywords"] += ", %s" % args.keywords

        if args.has("dependson"):
            log.debug("Dependson: %s" % args.dependson)
            self.browser["dependson"] = args.dependson

        if args.has("blocks"):
            log.debug("Blocks: %s" % args.blocks)
            self.browser["blocked"] = args.blocks

        if args.has("cc"):
            log.debug("CC: %s" % args.cc)
            self.browser["newcc"] = args.cc

        if args.has("version"):
            log.debug("Version: %s" % args.version)
            self.browser["version"] = [args.version]

        log.info("Submitting the changes")
        response = self.browser.submit()
        response = response.read()

        # is everything alright?
        if response.find(self.constants.BUG_PROCESS_OK_STRING) > -1:
            log.info("Changes have been submitted")
            return True
        else:
            # something is wrong.
            log.error("Errr, something is wrong in returned value.")
            #print response
            raise ModifyError("Unexpected return value", response)
Exemple #3
0
    def new(self, **kwargs):
        """Opens new bug

        It automatically generates bug_url from product as bugzilla wants product name in GET response

        Args:
            product: Product name in the site
            component: Component name in bugzilla page
            security: Whether it is security vulnerability
            url: External url
            status: Initial but status. (NEW, RESOLVED)
            assigned_to: Email address to assign
            alias: Bug alias (NOT IMPLEMENTED)
            blocks: Bugs that this bug blocks
            dependson: Bug that depends on.
            cc: E-mail addresses to CC

        Returns:
            Integer indicating the bugzilla id for new bug

        Raises:
            BugzillaError: Required arguments are not provided

        """
        log = logging.getLogger("bugzilla.NEW")

        args = BugStruct(**kwargs)

        # control required vars
        if not (args.has("component") and args.has("product") and args.has("title") and args.has("description")):
            raise BugzillaError("Missing argument. Component, Product, Title and Description are needed")

        bug_url = self.constants.get_new_bug_url(args.product)

        log.debug("Opening new bug page")
        self.browser.open(bug_url)
        log.debug("Selecting form name: Create")
        self.browser.select_form(name="Create")

        log.debug("Adding component, title and comment")
        self.browser["component"] = [args.component]
        self.browser["short_desc"] = args.title
        self.browser["comment"] = args.description

        if args.has("url"):
            log.debug("URL: %s" % args.url)
            self.browser["bug_file_loc"] = args.url

        if args.has("security"):
            log.debug("Security: 1")
            self.browser["bit-10"] = ["1"]

        if args.has("status"):
            log.debug("Bug_status: %s" % args.status)
            self.browser["bug_status"] = [args.status]

        if args.has("assigned_to"):
            log.debug("Assign: %s" % args.assigned_to)
            self.browser["assigned_to"] = args.assigned_to

        if args.has("dependson"):
            log.debug("Depends on: %s" % args.dependson)
            self.browser["dependson"] = args.dependson

        if args.has("blocks"):
            log.debug("Blocks: %s" % args.blocks)
            self.browser["blocked"] = args.blocks

        if args.has("version"):
            log.debug("Version: %s" % args.version)
            self.browser["version"] = [args.version]

        if args.has("cc"):
            log.debug("CC: %s" % args.cc)
            self.browser["cc"] = args.cc

        # FIXME: Our bugzilla page doesn't show alias field. 
        # FIXME: Uncomment it when it is done
        # if args.has("alias"):
        #     self.browser["alias"] = args.alias

        response = self.browser.submit()
        response = response.read()

        log.info("Bug submitted")

        # get bug id.
        re_compile = re.compile("Bug (.*?) Submitted")
        bug_id = re.findall(re_compile, response)

        if len(bug_id) != 0:
            return bug_id[0]
        else:
            log.error("Wohoops. Unexpected data returned after submitting.")
            return False
Exemple #4
0
def main():
    log = logging.getLogger("bugzilla.BIN")

    parser = setup_parser()
    (global_opts, args) = parser.parse_args()

    global_opts = BugStruct(**global_opts.__dict__)

    # Get our action from these args
    if len(args) and args[0] in cmdlist:
        action = args.pop(0)
    else:
        parser.error("command must be one of: %s" % ','.join(cmdlist))

    action_parser = setup_action_parser(action)
    (opt, args) = action_parser.parse_args(args)
    opt = BugStruct(**opt.__dict__)

    # Helper functions
    def check_valid_resolutions():
        """Checks if valid resolution is given for --resolution and --close"""

        # make it upper-case for easy-of-use
        if opt.resolution:
            opt.resolution = opt.resolution.upper()
            if not opt.resolution in VALID_RESOLUTIONS:
                parser.error("resolution must be one of: %s" %
                             ','.join(VALID_RESOLUTIONS))
                sys.exit(1)
        elif opt.close:
            opt.close = opt.close.upper()
            # --close is an alias for -s RESOLVED -r FIXED.
            # When --close is used, only resolution is appended. So control it.
            #
            # bugspy.py modify -b 12346 --close invalid
            #
            if not opt.close in VALID_RESOLUTIONS:
                parser.error("resolution must be one of: %s" %
                             ','.join(VALID_RESOLUTIONS))
                sys.exit(1)

    def check_valid_statuses():
        # make it upper-case for easy-of-use
        opt.status = opt.status.upper()

        if not opt.status in VALID_STATUSES:
            parser.error("status must be one of: %s" %
                         ','.join(VALID_STATUSES))

    def check_valid_keywords():
        # make it upper-case for easy-of-use
        opt.keywords = opt.keywords.upper()

        if not opt.keywords in VALID_KEYWORDS:
            parser.error("keyword must be one of: %s" %
                         ','.join(VALID_KEYWORDS))

    if not os.path.exists(CONFIG_FILE) and action != "generate-config":
        log.error("Configuation file is not found, please generate it first")
        sys.exit(1)

    c = BugspyConfig()
    bugzilla = Bugzilla(c.bugzillaurl, c.username, c.password)

    if action == "generate-config":
        if os.path.exists(CONFIG_FILE):
            log.warning(
                "Configuration file exists. Please edit ~/.bugspy.conf with your text editor. Exiting..."
            )
            sys.exit(1)

        # check arguments
        if not (opt.user and opt.password and opt.bugzilla_url):
            parser.error("Missing argument! See --help")
            sys.exit(1)

        config_data = CONFIG_TEMPLATE % {
            "bugzilla": opt.bugzilla_url,
            "user": opt.user,
            "password": opt.password
        }

        log.info("Writing configuration file")
        open(CONFIG_FILE, "w+").write(config_data)
        log.info(
            "Configuration file is written. You can edit ~/.bugspy.conf for later use"
        )

    if action == "modify":
        modify = {}
        if not opt.bug_id:
            log.error("Bud id must be provided!")
            sys.exit(1)

        modify["bug_id"] = opt.bug_id

        if opt.comment:
            modify["comment"] = opt.comment

        if opt.status:
            check_valid_statuses()
            if opt.status == "RESOLVED" and not opt.resolution:
                parser.error("RESOLVED should be used along with RESOLUTION.")
                sys.exit(1)

            modify["status"] = opt.status

        if opt.resolution:
            check_valid_resolutions()

            # we cannot set resolution on NEW bugs
            bugzilla.login()
            bug_info = bugzilla.get(opt.bug_id)
            if bug_info.has("status") and bug_info.status == "NEW":
                log.error(
                    "You cannot change resolution on NEW bugs. Maybe you want to this?: --status RESOLVED --resolution %s"
                    % opt.resolution)
                sys.exit(1)

            modify["resolution"] = opt.resolution

        if opt.close and not opt.resolution:
            check_valid_resolutions()
            modify["status"] = "RESOLVED"
            modify["resolution"] = opt.close

        if opt.title:
            modify["title"] = opt.title

        if opt.assigned_to:
            modify["assigned_to"] = opt.assigned_to

        if opt.security:
            modify["security"] = opt.security

        if opt.keywords:
            modify["keywords"] = opt.keywords

        if opt.blocks:
            modify["blocks"] = opt.blocks

        if opt.depends:
            modify["dependson"] = opt.depends

        if opt.cc:
            modify["cc"] = opt.cc

        if opt.version:
            if not opt.version in VALID_VERSIONS:
                parser.error("version must be one of: %s" %
                             ', '.join(VALID_VERSIONS))

            modify["version"] = opt.version

        try:
            bugzilla.login()
            bugzilla.modify(**modify)
        except BugzillaError, e:
            log.error(e.msg)
Exemple #5
0
    def modify(self, **kwargs):
        # TODO: Implement Product/Component/CC list
        """Modifies the bug.

        All arguments can be supplied. This function modifies the form on the page and submits just like an ordinary browser does.

        Args:
            bug_id: Bug id to edit
            title: New bug title
            comment: Comment to write
            status: Status (NEW, ASSIGNED, RESOLVED)
            resolution: (FIXED, INVALID, WONTFIX, LATER, REMIND, DUPLICATE)
            security: Whether it is security or not
            assigned_to: E-mail address to assign a bug
            blocks: Bugs that this bug blocks
            dependson: Bug that depends on.
            cc: Add e-mail address to cc list

        Raises:
            BugzillaError: You should first login to modify the bug
            ModifyError: Changes are not applied
        """
        log = logging.getLogger("bugzilla.MODIFY")

        args = BugStruct(**kwargs)

        if not args.has("bug_id"):
            raise BugzillaError("Bug id is needed to modify")

        if not self.is_logged_in:
            log.error("Login is needed")
            raise LoginError("You should first login to comment")

        log.info("Opening bug #%s to modify" % args.bug_id)

        bug_data = self._bug_open(args.bug_id, xml=False)
        # do we have permission to see this bug?
        if bug_data.find(self.constants.NO_PERMISSON_STRING) > -1:
            log.error("Don't have permission to modify the bug")
            raise BugzillaError("You don't have permission to see this bug")

        log.info("Opened bug #%s page" % args.bug_id)

        log.debug("Selecting changeform")
        self.browser.select_form(name="changeform")

        # for x in self.browser.forms():
        #     print x

        if args.has("title"):
            log.debug("New title: %s" % args.title)
            self.browser["short_desc"] = args.title

        if args.has("status"):
            log.debug("Bug_status: %s" % args.status)
            self.browser["bug_status"] = [args.status]

        if args.has("resolution"):
            log.debug("Resolution: %s" % args.resolution)
            self.browser["resolution"] = [args.resolution]

        if args.has("comment"):
            log.debug("Setting comment")
            self.browser["comment"] = args.comment

        if args.has("security"):
            # Pardus has specific setting for security vulnerabilities that will not be public. The checkbox name is "bit-10"
            log.debug("Marking as security")
            if args.security == "1":
                # if the bug has bit-10 field set
                if len(self.browser["bit-10"]) != 0:
                    log.warning("Bug is already in security group, not setting security tag")
                else:
                    self.browser["bit-10"] = ["1"]
            # marking as non-security
            else:
                if len(self.browser["bit-10"]) == 0:
                    log.warning("Bug is already public, not setting security tag..")
                else:
                    self.browser["bit-10"] = []

        if args.has("assigned_to"):
            log.debug("Assigned: %s" % args.assigned_to)
            self.browser["assigned_to"] = args.assigned_to

        if args.has("keywords"):
            log.debug("Keywords: %s" % args.keywords)
            self.browser["keywords"] += ", %s" % args.keywords

        if args.has("dependson"):
            log.debug("Dependson: %s" % args.dependson)
            self.browser["dependson"] = args.dependson

        if args.has("blocks"):
            log.debug("Blocks: %s" % args.blocks)
            self.browser["blocked"] = args.blocks

        if args.has("cc"):
            log.debug("CC: %s" % args.cc)
            self.browser["newcc"] = args.cc

        if args.has("version"):
            log.debug("Version: %s" % args.version)
            self.browser["version"] = [args.version]

        log.info("Submitting the changes")
        response = self.browser.submit()
        response = response.read()

        # is everything alright?
        if response.find(self.constants.BUG_PROCESS_OK_STRING) > -1:
            log.info("Changes have been submitted")
            return True
        else:
            # something is wrong.
            log.error("Errr, something is wrong in returned value.")
            #print response
            raise ModifyError("Unexpected return value", response)