Ejemplo n.º 1
0
    def display(self) -> None:
        while True:
            clear()
            print(thick_separator)
            print('Argus - {}'.format(self.menu_header))
            print(thick_separator)

            for menu_option in self.active_menu:
                # Menu header
                if menu_option.hotkey is None:
                    print('')
                else:
                    print('{:2}: {foo}'.format(menu_option.hotkey,
                                               foo=menu_option.entry_name))
            print(thin_separator)

            c_input = get_input('>')

            # brute force ftw.
            for menu_option in self.active_menu:
                if c_input == menu_option.hotkey:
                    if menu_option.entry_method is not None:
                        menu_option.entry_method()
                    if menu_option.needs_pause:
                        pause()
Ejemplo n.º 2
0
    def add_connection(self) -> Optional[JenkinsConnection]:
        print('Enter a name for this connection, or enter nothing to exit.')
        connection_name = get_input('>', lowered=False)
        if connection_name:
            print('Enter a Jenkins base url.')
            print('Example: http://cassci.datastax.com/')
            url = get_input('>')

            auth = {}
            is_auth = is_yes('Does this connection require authentication?')
            if is_auth:
                auth['username'] = get_input(
                    'Please enter connection username\n', lowered=False)
                print('Please enter connection password')
                auth['password'] = getpass()

            try:
                jenkins_connection = JenkinsConnection(connection_name, url,
                                                       auth)
                self.jenkins_connections[
                    jenkins_connection.name] = jenkins_connection
                self.save_jenkins_config()
                print('Successfully added connection: {}'.format(
                    connection_name))
                pause()
                return jenkins_connection
            except (HTTPError, MissingSchema, ConnectionError) as e:
                print('Error occurred adding new connection: {}'.format(e))
                print('Invalid Jenkins URL. Please try again.')
                pause()
        return None
Ejemplo n.º 3
0
    def remove_custom_report_job(self):
        if self.active_report.job_names:
            job_options = self.active_report.job_names

            while True:
                job_name = pick_value(
                    'Which Jenkins job would you like to remove?', job_options)
                if job_name:
                    for connection_name, job_name_list in self.active_report.connection_dict.iteritems(
                    ):
                        if job_name in job_name_list:
                            self.active_report.remove_job_from_report(
                                job_name, connection_name)
                    for connection_name in self.active_report.connection_names:
                        if not self.active_report.connection_dict[
                                connection_name]:
                            self.active_report.connection_dict.pop(
                                connection_name)
                    self.active_report.save_report_config()
                    print('Successfully removed job: {}'.format(job_name))
                    job_options.remove(job_name)
                else:
                    break
        else:
            print('No Jenkins jobs to remove from report.')
            pause()
Ejemplo n.º 4
0
    def add_view(self):
        view_name = pick_value('Which Jenkins view would you like to save?',
                               self.active_connection.get_list_of_views())
        if view_name:
            if view_name == 'Dev':
                dev_view_name = pick_value(
                    'Which Jenkins dev view would you like to save?',
                    self.active_connection.get_list_of_views(view_name))
                if dev_view_name:
                    dev_view_name = 'Dev-{}'.format(dev_view_name)
                    self.active_connection.jenkins_views[
                        dev_view_name] = self.active_connection.get_view(
                            dev_view_name)
                    self.active_connection.save_connection_config()
                    view_name = dev_view_name
            else:
                self.active_connection.jenkins_views[
                    view_name] = self.active_connection.get_view(view_name)
                self.active_connection.save_connection_config()
            print('Successfully added view: {}'.format(view_name))
            pause()

            if is_yes('Would you like to download jobs for this view now?'):
                self.active_connection.download_jobs(view_name)
                self.active_connection.save_job_data()
                print('Successfully downloaded jobs for view: {}'.format(
                    view_name))
                pause()
Ejemplo n.º 5
0
    def display_escalations(self):
        jira_connection_name = pick_value(
            'Select a JIRA Connection to view Escalation type tickets:',
            list(self._jira_connections.keys()))
        jira_connection = self._jira_connections[jira_connection_name]
        jira_issues = JiraUtils.get_issues_by_query(
            jira_connection,
            'type = \'Escalation\' AND resolution = unresolved')
        issue_keys = []
        for issue in jira_issues:
            issue_keys.append(issue.issue_key)

        df = DisplayFilter.default()
        while True:
            print_separator(30)
            print(os.linesep + 'Escalations' + os.linesep)
            print_separator(30)
            clear()
            df.display_and_return_sorted_issues(self, jira_issues)
            i = get_input('[#] Integer to open issue in browser. [q] to quit.')
            if i == 'q':
                break
            try:
                c_input = int(i) - 1
                JiraUtils.open_issue_in_browser(jira_connection.url,
                                                issue_keys[c_input])
            except ValueError:
                print('Bad input. Try again')
                pause()
Ejemplo n.º 6
0
 def add_organization(self) -> None:
     while True:
         if len(self._organizations.keys()) != 0:
             print('Known organizations:')
         for known_org in self._organizations.keys():
             print('   {}'.format(known_org))
         org_name = get_input('Enter a new org name, [q] to quit:', False)
         if org_name == 'q':
             break
         new_org = set()  # type: Set[str]
         while True:
             clear()
             print('Org: {}'.format(org_name))
             for team_name in new_org:
                 print('   {}'.format(team_name))
             choice = get_input('[a]dd a new team to this org, [q]uit')
             if choice == 'q':
                 break
             elif choice == 'a':
                 new_team = self.pick_team(list(new_org))
                 if new_team is not None:
                     new_org.add(new_team.name)
             else:
                 print('Bad choice. Try again.')
                 pause()
         if new_org is not None:
             self._organizations[org_name] = new_org
             self._save_config()
             print('New org {} added.'.format(org_name))
             break
Ejemplo n.º 7
0
 def view_num_jobs(self):
     """
     Displays the number of jobs cached locally and the total number of jobs on the server.
     """
     print('Jobs cached: {}'.format(len(self.active_connection.job_names)))
     print('Jobs on server: {}'.format(
         len(self.active_connection.jenkins_obj.get_jobs_list())))
     pause()
Ejemplo n.º 8
0
 def remove_custom_report(self):
     report_name = pick_value(
         'Which custom report would you like to remove?',
         list(self.jenkins_reports.keys()))
     if report_name:
         self.jenkins_reports.pop(report_name)
         self.save_jenkins_config()
         print('Successfully removed custom report: {}'.format(report_name))
         pause()
Ejemplo n.º 9
0
    def download_jobs(self):
        download_method = pick_value(
            'Would you like to download jobs by view or individually?',
            ['By View', 'Individually'],
            sort=False)
        if download_method:
            if download_method == 'By View':
                if self.active_connection.jenkins_views:
                    view_options = self.active_connection.view_names
                    all_views = '* All Views'
                    view_options.append(all_views)
                    view_name = pick_value(
                        'Which saved view would you like to download jobs for?',
                        view_options)
                    if view_name:
                        if view_name == all_views:
                            self.active_connection.download_jobs()
                            self.active_connection.save_job_data()
                            print(
                                'Successfully downloaded jobs for all views.')
                            pause()
                        else:
                            self.active_connection.download_jobs(view_name)
                            self.active_connection.save_job_data()
                            print('Successfully downloaded jobs for view: {}'.
                                  format(view_name))
                            pause()
                else:
                    if is_yes(
                            'No Jenkins views. Would you like to add one now?'
                    ):
                        self.add_view()
                        view_name = self.active_connection.view_names[0]
                        if is_yes('Download jobs for this view?'):
                            self.active_connection.download_jobs(view_name)
                            self.active_connection.save_job_data()
                            print('Successfully downloaded jobs for view: {}'.
                                  format(view_name))
                            pause()

            elif download_method == 'Individually':
                job_name = get_input(
                    'Enter the exact, case-sensitive name of the job, or enter nothing to exit.\n>',
                    lowered=False)
                if job_name:
                    if self.active_connection.download_single_job(job_name):
                        self.active_connection.save_job_data()
                        print('Successfully downloaded Jenkins job: {}'.format(
                            job_name))
                        pause()
                    else:
                        print('Failed to download Jenkins job: {}'.format(
                            job_name))
                        pause()
Ejemplo n.º 10
0
 def add_custom_report(self):
     report_name = get_input(
         'Enter a name for this custom report, or enter nothing to exit.\n>',
         lowered=False)
     if report_name:
         report = JenkinsReport(report_name)
         report.save_report_config()
         self.jenkins_reports[report_name] = report
         self.save_jenkins_config()
         print('Successfully added custom report: {}'.format(report_name))
         pause()
         self.active_report = self.get_custom_report(report_name)
         self._main_menu.go_to_jenkins_report_menu()
Ejemplo n.º 11
0
    def edit_team(self, jira_manager, team_name=None):
        # type: (JiraManager, str) -> None
        if team_name is None:
            team_name = pick_value('Edit which team?',
                                   list(self._teams.keys()), True, 'Cancel')
            if team_name is None:
                return None

        team = self._teams[team_name]
        jira_connection = jira_manager.get_jira_connection(
            team.jira_connection_name)

        while True:
            clear()
            print('-------------------------')
            print('[Edit {}]'.format(team))
            print('-------------------------')
            cmd = get_input(
                '[A]dd more members, [R]emove a member, or [Q]uit?')
            if cmd == 'a':
                assignees = jira_connection.pick_assignees(sys.maxsize)
                if assignees is None or len(assignees) == 0:
                    print('No assignees chosen. Returning.')
                    return None
                for assignee in assignees:
                    if assignee in team.member_names:
                        print(
                            'Assignee already exists in {}. Skipping.'.format(
                                team.name))
                        continue
                    else:
                        team.add_member(assignee, jira_connection)
                        print('Added {} to {}.'.format(assignee, team.name))
                        self._save_config()
            elif cmd == 'r':
                assignee = pick_value('Remove which assignee?',
                                      team.member_names, True, 'Cancel')
                if assignee is None:
                    continue
                confirm = get_input('Delete {} from {}: Are you sure?'.format(
                    assignee, team.name))
                if confirm == 'y':
                    team.delete_member(assignee)
            elif cmd == 'q':
                break
            else:
                print('Bad input. Valid input: A, R, or Q.')
                pause()
        self._save_config()
Ejemplo n.º 12
0
    def _run_report(jira_manager: 'JiraManager', team: Team, report_filter: ReportFilter) -> None:
        # We prompt for a new 'since' on each iteration of the loop in non-org reporting
        if report_filter.needs_duration:
            report_filter.since = time_utils.since_now(ReportFilter.get_since())

        report_filter.prompt_for_data()

        try:
            sorted_member_issues = sorted(team.members, key=lambda s: s.primary_name.user_name)

            while True:
                # Print out a menu of the meta information for each team member
                print_separator(40)
                report_filter.print_description()
                print_separator(40)
                print('[{}]'.format(report_filter.header))
                print(report_filter.column_headers())

                count = 1

                for member_issues in sorted_member_issues:
                    report_filter.clear()
                    # We perform pre-processing and one-off prompting for time duration in .process call
                    report_filter.process_issues(member_issues)
                    print('{:5}: {}'.format(count, report_filter.print_all_counts(member_issues.primary_name.user_name)))
                    count += 1

                print_separator(40)
                cmd = get_input('[#] Integer value to see a detailed breakdown by category. [q] to return to menu:')
                if cmd == 'q':
                    break
                selection = as_int(cmd)
                if selection is None:
                    break

                selection -= 1
                if selection < 0 or selection > len(sorted_member_issues):
                    print('Bad Selection.')
                    continue
                full_member_issues = sorted_member_issues[selection]
                TeamManager._print_member_details(jira_manager, full_member_issues, report_filter)
        except JIRAError as je:
            print('Caught a JIRAError attempting to run a query: {}'.format(je))
            pause()
Ejemplo n.º 13
0
    def run_org_report(self, jira_manager: 'JiraManager') -> None:
        """
        Sub-menu driven method to run a specific type of report across multiple teams within an organization
        """
        org_name = None

        if len(self._organizations) == 0:
            # We don't prompt for addition now since we'd have to pass in main menu context to do that from here.
            print('No organizations found. Please use the Team Management menu to define a new organization before running a report.')
            pause()
            return

        while True:
            clear()
            if org_name is None:
                print_separator(40)
                org_name = pick_value('Run reports against which organization?', list(self._organizations.keys()))
                # None return from pick_team == cancel
                if org_name is None:
                    return
                for team_name in sorted(self._organizations[org_name]):
                    active_team = self._teams[team_name]
                    print('Populating tickets for team: {}'.format(active_team.name))
                    TeamManager.populate_owned_jira_issues(jira_manager, active_team.members)

            print('---------------------')
            print('-    Org Menu      -')
            print('---------------------')
            print('t: Change active org. Current: {}'.format(org_name))
            self._print_report_menu()
            print('q: Cancel')
            print('---------------------')
            choice = get_input(':')
            if choice == 'q':
                return
            elif choice == 't':
                org_name = None
            try:
                report_type = ReportType.from_int(int(choice))
                if report_type == ReportType.UNKNOWN:
                    print('Bad input: {}. Try again.'.format(choice))
                    pause()
                else:
                    report_to_run = TeamManager.reports[report_type]
                    if TeamManager.reports[report_type].needs_duration:
                        report_to_run.since = time_utils.since_now(ReportFilter.get_since())
                    # making mypy happy
                    assert org_name is not None
                    self._run_org_report(jira_manager, org_name, report_to_run)
                    pause()
            except (ValueError, TypeError) as e:
                print('Error on input: {}. Try again'.format(e))
                traceback.print_exc()
                pause()
Ejemplo n.º 14
0
    def display_view(self, jira_manager: 'JiraManager') -> None:
        df = DisplayFilter.default()

        working_issues = list(self.get_issues().values())
        while True:
            try:
                issues = df.display_and_return_sorted_issues(
                    jira_manager, working_issues)
                print_separator(60)
                print('[JiraView operations for {}]'.format(self.name))
                input_prompt = (
                    "[f] to manually enter a substring to regex issues in the view\n"
                    "[c] to clear all regex filtering\n"
                    "[#] Integer value to open ticket in browser\n"
                    "[q] to quit\n"
                    ":")
                custom = get_input(input_prompt)
                if custom == 'q':
                    return
                elif custom == 'f':
                    string = get_input('substring to match:', lowered=False)
                    new_issues = []
                    for jira_issue in working_issues:
                        if jira_issue.matches(self.jira_connection, string):
                            new_issues.append(jira_issue)
                    working_issues = new_issues
                elif custom == 'c':
                    working_issues = list(self.get_issues().values())
                elif len(issues) == 0:
                    print(
                        'No matching jira issues found. Skipping attempt to open.'
                    )
                    pause()
                else:
                    try:
                        JiraUtils.open_issue_in_browser(
                            self.jira_connection.url,
                            issues[int(custom) - 1].issue_key)
                    except ValueError:
                        print('Bad input. Try again.')
            except JIRAError as je:
                print('Caught an error: {}'.format(je))
                traceback.print_exc()
                return
Ejemplo n.º 15
0
 def run_debug(self):
     """
     Used during development to bypass complex menu operations and try out a single new operation outside unit testing
     """
     print_separator(60)
     print('Resolving deps')
     self._resolve_issue_dependencies()
     default_filter = DisplayFilter.default()
     default_filter.open_only = True
     utils.show_dependencies = True
     utils.show_only_open_dependencies = True
     for jira_connection in self.jira_connections():
         if jira_connection.connection_name == 'ds':
             print_separator(30)
             print('Results for connection: {}'.format(jira_connection))
             for issue_list in jira_connection.cached_jira_issues:
                 default_filter.display_and_return_sorted_issues(
                     self, issue_list, 1, None)
     for dep_type in sorted(JiraDependency.unknown_dependencies):
         print('Found unknown dependency: {}'.format(dep_type))
     pause()
Ejemplo n.º 16
0
    def load_connection_config(jenkins_manager: 'JenkinsManager',
                               connection_name: str) -> None:
        config_file = build_config_file(jenkins_connections_dir,
                                        connection_name)
        if os.path.isfile(config_file):
            config_parser = RawConfigParser()
            config_parser.read(config_file)
            url = config_parser.get(SECTION_TITLE, 'url')
            auth = {}

            if config_parser.has_option(SECTION_TITLE, 'password'):
                auth['username'] = config_parser.get(SECTION_TITLE, 'username')
                auth['password'] = decode(
                    encode_password(),
                    config_parser.get(SECTION_TITLE, 'password'))

            try:
                jenkins_connection = JenkinsConnection(connection_name,
                                                       url,
                                                       auth=auth)
                if config_parser.has_option(SECTION_TITLE, 'views'):
                    view_names = config_parser.get(SECTION_TITLE,
                                                   'views').split(',')
                    print('Loading Jenkins views for connection: {}'.format(
                        connection_name))
                    for view_name in view_names:
                        JenkinsView.load_view_config(jenkins_connection,
                                                     view_name)
                jenkins_manager.jenkins_connections[
                    jenkins_connection.name] = jenkins_connection
            except Exception as e:
                print(
                    'WARNING! Error occurred during creation of Jenkins instance: {}.'
                    .format(e))
                print(
                    'Skipping addition of this instance. Check routing to url: {}'
                    .format(url))
                pause()
        else:
            'No config file for {}.'.format(connection_name)
Ejemplo n.º 17
0
    def _print_member_details(jira_manager: 'JiraManager', tickets: MemberIssuesByStatus, report_filter: ReportFilter) -> None:
        # We need to re-populate this report filter with this user for matching logic to work
        report_filter.clear()
        report_filter.process_issues(tickets)
        displayed_issues = tickets.display_member_issues(jira_manager, report_filter)

        while True:
            if len(displayed_issues) == 0:
                print('No issues found matching category.')
                pause()
                break
            cmd = get_input('[#] Integer value to open JIRA issue in browser. [q] to return to report results:')
            if cmd == 'q':
                break
            try:
                jira_issue = displayed_issues[int(cmd) - 1]
                jira_connection = jira_manager.get_jira_connection(jira_issue.jira_connection_name)
                JiraUtils.open_issue_in_browser(jira_connection.url, jira_issue.issue_key)
            except ValueError as ve:
                print('Bad input. Try again.')
                print('ValueError : {}'.format(ve))
                pause()
Ejemplo n.º 18
0
    def remove_view(self):
        if self.active_connection.jenkins_views:
            view_name = pick_value(
                'Which Jenkins view would you like to remove?',
                self.active_connection.view_names)

            if view_name:
                print('About to delete: {}'.format(view_name))
                if is_yes('Are you sure?'):
                    del self.active_connection.jenkins_views[view_name]
                    self.active_connection.save_connection_config()
                    file_name = os.path.join(jenkins_views_dir,
                                             "{}.cfg".format(view_name))
                    if os.path.exists(file_name):
                        os.remove(file_name)
                        print('{} view deleted.'.format(view_name))
                    else:
                        print('Attempted to remove view {}'.format(view_name))
                        print('View path {} does not exist'.format(file_name))
                else:
                    print('Remove aborted.')
                pause()
        else:
            print('No Jenkins views to remove.')
Ejemplo n.º 19
0
    def banners_cloud_flare(self):
        pr('Retrieving headers', '#')
        domain = self.pack_url()
        res = REQ_S.get(domain)
        if res.status_code != 200:
            pr('Bad status code: %d' % res.status_code, '!')
            return

        pr('Headers:')
        for h in res.headers.items():
            x = f'{h[0]} => {h[1]}'
            pr(x, '#')

        pr('Checking for CloudFlare in headers', '#')
        if "cloudflare" not in res.text:
            pr(self.domain + " is not using Cloudflare!")
            return

        if not pause('Attempt to bypass?', cancel=True):
            return
        pr("CloudFlare found, attempting to bypass..")

        # TODO TEST

        url = "http://www.crimeflare.biz/cgi-bin/cfsearch.cgi"
        res = REQ_S.get(url, data={'cfS': self.domain})
        reg = re.findall(r'\d+\.\d+\.\d+\.\d+', res.text)
        if reg:
            real_ip = reg[1]
        else:
            pr("CloudFlare wasn't bypassed, No real IP found", '!')
            return
        res = REQ_S.get(f"http://{real_ip}")
        if "cloudflare" not in res.text.lower():
            if real_ip:
                pr("Cloudflare Bypassed!", '#')
                pr('===============================')
                pr("Real IP ==> " + fc + real_ip + fx)
                pr('===============================')
            return
        pr("Cloudflare wasn't bypassed, Real IP blocked by CloudFlare", '!')
Ejemplo n.º 20
0
    def run_team_reports(self, jira_manager: 'JiraManager') -> None:
        """
        Sub-menu driven method to run some specific reports of interest against teams. This will take into account
        linked members and run the report for all tickets across multiple JIRA connections.
        """
        selected_team = None

        if len(self._teams) == 0:
            # We don't prompt for addition now since we'd have to pass in main menu context to do that from here.
            print('No teams found. Please use the Team Management menu to define a new team before running a report.')
            pause()
            return

        while True:
            clear()
            if selected_team is None:
                print('No active team. Please select a team:')
                selected_team = self.pick_team()
                # None return from pick_team == cancel
                if selected_team is None:
                    return
                TeamManager.populate_owned_jira_issues(jira_manager, selected_team.members)

            print('---------------------')
            print('-    Team Menu      -')
            print('---------------------')
            print('t: Change active root team. Current: {}'.format(selected_team.name))
            self._print_report_menu()
            print('q: Cancel')
            print('---------------------')
            choice = get_input(':')
            if choice == 'q':
                return
            elif choice == 't':
                selected_team = None
            try:
                report_type = ReportType.from_int(int(choice))
                if report_type == ReportType.UNKNOWN:
                    print('Bad input: {}. Try again.'.format(choice))
                    pause()
                else:
                    assert selected_team is not None
                    TeamManager._run_report(jira_manager, selected_team, TeamManager.reports[report_type])
            except (ValueError, TypeError) as e:
                print('Error on input: {}. Try again'.format(e))
                traceback.print_exc()
                pause()
Ejemplo n.º 21
0
    def __init__(self):
        # Parse arguemnts
        if len(sys.argv) > 1:
            arg = sys.argv[1]
        else:
            arg = ask('Enter domain:')
            if not arg:
                exit()

        # Verify domain integrity
        if '://' in arg:
            parsed = urlsplit(arg)
        else:
            parsed = urlsplit('http://' + arg)
        if '.' not in parsed.netloc:
            pr('Invalid domain!', '!')
            exit()

        # Verify subdomain
        self.subdomain = self.base_domain = None
        pts = parsed.netloc.split('.')
        if len(pts) > 2:
            pr('Is this the subdomain you wish to use:? ' + pts[0])
            if pause('agree', cancel=True):  # subdomain
                self.subdomain = pts[0]
                self.base_domain = '.'.join(pts[1:])
        if not self.subdomain:
            self.subdomain = 'www'
        if not self.base_domain:
            self.base_domain = parsed.netloc

        self.domain = parsed.netloc
        self.scheme = parsed.scheme if parsed.scheme else 'http'
        print()
        pr('Using domain: ' + fc + self.domain + fx)

        self.crawler = Crawler(self, parsed.path)
Ejemplo n.º 22
0
 def remove_connection(self):
     if self.jenkins_connections:
         connection_name = pick_value(
             'Which Jenkins connection would you like to remove?',
             self.connection_names)
         if connection_name:
             print('About to remove: {}'.format(connection_name))
             if is_yes('Are you sure?'):
                 self.jenkins_connections.pop(connection_name)
                 self.save_jenkins_config()
                 print('Successfully removed connection: {}'.format(
                     connection_name))
                 pause()
             else:
                 print('Remove aborted.')
                 pause()
     else:
         print('No Jenkins connections to remove.')
         pause()
Ejemplo n.º 23
0
 def update_cached_jira_project_data(self, needs_pause=True):
     for jira_connection in list(self._jira_connections.values()):
         jira_connection.update_all_cached_jira_projects()
     if needs_pause:
         pause()
Ejemplo n.º 24
0
    def _run_report(jira_manager, team, report_filter):
        # type: (JiraManager, Team, ReportFilter) -> None
        # We prompt for a new 'since' on each iteration of the loop
        if report_filter.needs_duration:
            report_filter.since = time_utils.since_now(
                ReportFilter.get_since())

        try:
            sorted_member_issues = sorted(
                team.members, key=lambda s: s.primary_name.user_name)

            while True:
                # Print out a menu of the meta information for each team member
                print_separator(40)
                print('[{}]'.format(report_filter.header))
                print(report_filter.column_headers())

                count = 1

                for member_issues in sorted_member_issues:
                    report_filter.clear()
                    # We perform pre-processing and one-off prompting for time duration in .process call
                    report_filter.process_issues(member_issues)
                    print('{:5}: {}'.format(
                        count,
                        report_filter.print_all_counts(
                            member_issues.primary_name.user_name)))
                    count += 1

                print_separator(40)
                cmd = get_input(
                    '[#] Integer value to see a detailed breakdown by category. [q] to return to menu:'
                )
                if cmd == 'q':
                    break

                # Received detailed breakdown input
                try:
                    c_input = int(cmd) - 1

                    # Pull out the MemberIssuesByStatus object for the chosen member for detailed printing
                    # We need to re-populate this report filter with this user for matching logic to work
                    full_member_issues = sorted_member_issues[c_input]
                    report_filter.clear()
                    report_filter.process_issues(full_member_issues)
                    displayed_issues = full_member_issues.display_member_issues(
                        jira_manager, report_filter)

                    while True:
                        cmd = get_input(
                            '[#] Integer value to open JIRA issue in browser. [q] to return to report results:'
                        )
                        if cmd == 'q':
                            break
                        try:
                            jira_issue = displayed_issues[int(cmd) - 1]
                            jira_connection = jira_manager.get_jira_connection(
                                jira_issue.jira_connection_name)
                            JiraUtils.open_issue_in_browser(
                                jira_connection.url, jira_issue.issue_key)
                        except ValueError as ve:
                            print('Bad input. Try again.')
                            print('ValueError : {}'.format(ve))
                            pause()
                except ValueError:
                    break
        except JIRAError as je:
            print(
                'Caught a JIRAError attempting to run a query: {}'.format(je))
            pause()
Ejemplo n.º 25
0
    def __init__(self):
        parser = optparse.OptionParser(
            description=DESCRIPTION,
            usage='Usage: %prog [options] [host [port]]',
            version='argus ' + __version__)
        parser.add_option(
            '-p',
            '--password',
            help=
            'provide local password on command-line rather than being prompted'
        )
        parser.add_option('-d',
                          '--dashboard',
                          help='name of dashboard to auto-execute into')
        parser.add_option(
            '-j',
            '--jenkins_report',
            help=
            'TODO:#106 execute and print a jenkins report, exiting upon completion',
            default=False,
            action='store_true')
        parser.add_option(
            '-n',
            '--jenkins_project_name',
            help='Name of consistent root of project names in Jenkins')
        parser.add_option(
            '-b',
            '--jenkins_branch',
            help='TODO:#107 Used with -j, specify branch to run reports against'
        )
        parser.add_option(
            '-t',
            '--jenkins_type',
            help=
            'TODO:#108 Used with -j, specify type of test [u]nit test, or [d]test to report against'
        )
        # parser.add_option('-c', '--triage_csv', help='Specifies local file containing [link, key, summary, assignee, reviewer, status, prio, repro, scope, component] triage file to update against live JIRA data')
        # parser.add_option('-o', '--triage_out', help='Output file name for updated triage data. If not provided, prints to stdout.')
        parser.add_option(
            '-u',
            '--unit_test',
            help=
            'Unit testing mode, does not connect servers, saves config changes to test/ folder',
            action='store_true',
            dest='unit_test')
        parser.add_option(
            '-v',
            '--verbose',
            help='Log verbose debug output to console and argus.log',
            action='store_true',
            dest='verbose')

        optvalues = optparse.Values()
        (options, arguments) = parser.parse_args(sys.argv[1:],
                                                 values=optvalues)

        signal.signal(signal.SIGINT, self.signal_handler)

        if hasattr(options, 'verbose'):
            utils.debug = True
            utils.argus_log = open('argus.log', 'w')

        Config.init_argus()

        # determine if this is a first run, prompt differently pending that
        msg = None
        if hasattr(options, 'password'):
            Config.MenuPass = options.password
        else:
            msg = 'Enter Argus Password (local JIRA credentials will be encrypted with this):'

        while Config.MenuPass == '':
            Config.MenuPass = getpass(msg)

        if hasattr(options, 'unit_test'):
            if os.path.exists('test'):
                shutil.rmtree('test')
            os.mkdir('test')
            os.mkdir(os.path.join('test', 'conf'))
            os.mkdir(os.path.join('test', 'data'))
            utils.unit_test = True

            # Run one-off test on time utils
            # now = time_converter.current_time()
            # print('Now is: {}'.format(now))
            #
            # four_weeks_ago = time_converter.since_now('-4w')
            # print('Four weeks ago is: {}'.format(four_weeks_ago))
            #
            # one_m_two_days_ago = time_converter.since_now('-1m -2d')
            # print('One M 2 D ago is: {}'.format(one_m_two_days_ago))
            # exit(-1)

        try:
            self._team_manager = TeamManager.from_file()
        except ConfigError as ce:
            print('ConfigError: {}. Initializing empty JiraManager'.format(ce))
            self._team_manager = TeamManager()
        self._jira_manager = JiraManager(self._team_manager)
        self._jenkins_manager = JenkinsManager(self)

        if hasattr(options, 'triage_csv'):
            jira_connections = {}
            for jira_connection in self._jira_manager.jira_connections():
                jira_connections[
                    jira_connection.connection_name] = jira_connection
            tu = TriageUpdate(
                jira_connections,
                self._jira_manager.get_all_cached_jira_projects())
            triage_out = options.triage_out if hasattr(options,
                                                       'triage_out') else None
            tu.process(options.triage_csv, triage_out)

        if hasattr(options, 'dashboard'):
            user_key = optvalues.__dict__['dashboard']
            dash_keys = list(self._jira_manager.jira_dashboards.keys())

            if user_key in dash_keys:
                self._jira_manager.jira_dashboards[user_key].display_dashboard(
                    self._jira_manager.jira_views)
            else:
                print('Oops... Error with dashboard name {}'.format(user_key))
                print('Possible dashboard names : {}'.format(
                    ','.join(dash_keys)))
                print('Starting Argus normally...')

        if hasattr(options, 'verbose'):
            utils.debug = True
            utils.argus_log = open('argus.log', 'w')

        self._display_filter = DisplayFilter()

        self.main_menu = [
            MenuOption('d',
                       'Dashboards',
                       self.go_to_dashboards_menu,
                       pause=False),
            MenuOption('v',
                       'Jira Views',
                       self.go_to_jira_views_menu,
                       pause=False),
            MenuOption('p',
                       'JiraProject Queries',
                       self.go_to_projects_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('t',
                       'Run a Team-Based Report',
                       self._run_team_report,
                       pause=False),
            MenuOption('e',
                       'View Escalations',
                       self._jira_manager.display_escalations,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('r',
                       'Generate a Pre-Determined Report',
                       self.go_to_reports_menu,
                       pause=False),
            MenuOption('m',
                       'Team Management',
                       self.go_to_teams_menu,
                       pause=False),
            MenuOption('c',
                       'Jira Connections',
                       self.go_to_jira_connections_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('j',
                       'Jenkins Menu',
                       self.go_to_jenkins_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('o',
                       'Change Options',
                       self.go_to_options_menu,
                       pause=False),
            MenuOption('x', 'Debug', self._jira_manager.run_debug,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('h', 'Help', self._display_readme, pause=False),
            MenuOption.quit_program()
        ]

        self.dashboards_menu = [
            MenuOption('l', 'List all available dashboards',
                       self._jira_manager.list_dashboards),
            MenuOption('d', 'Display a dashboard\'s results',
                       self._jira_manager.display_dashboard),
            MenuOption('c', 'Create a dashboard',
                       self._jira_manager.add_dashboard),
            MenuOption('e', 'Edit a dashboard',
                       self._jira_manager.edit_dashboard),
            MenuOption('r', 'Remove a dashboard',
                       self._jira_manager.remove_dashboard),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jira_views_menu = [
            MenuOption('l', 'List all defined JiraViews',
                       self._jira_manager.list_all_jira_views),
            MenuOption('d', 'Display a JiraView\'s results',
                       self._jira_manager.display_view),
            MenuOption('a', 'Add a JiraView', self._add_view),
            MenuOption('e', 'Edit a JiraView', self._edit_view),
            MenuOption('r', 'Remove a JiraView',
                       self._jira_manager.remove_view),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.reports_menu = [
            MenuOption(
                'f',
                'FixVersion report (release). Query all tickets with a specified FixVersion',
                self._jira_manager.report_fix_version),
            MenuOption('s',
                       'Add a single-user multi-JIRA open ticket dashboard',
                       self._add_multi_jira_dashboard),
            MenuOption('l', 'Add a label-based cross-cutting view',
                       self._jira_manager.add_label_view),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.team_menu = [
            MenuOption('l', 'List all defined Teams',
                       self._team_manager.list_teams),
            MenuOption('a', 'Add a new team', self._add_team),
            MenuOption('e', 'Edit an existing team', self._edit_team),
            MenuOption('r', 'Remove a team', self._remove_team),
            MenuOption(
                'x',
                'Link a team member to two accounts across JiraConnections',
                self.add_linked_member),
            MenuOption('d', 'Delete a cross-Jira link',
                       self._team_manager.remove_linked_member),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jira_connections_menu = [
            MenuOption('a', 'Add a JIRA connection',
                       self._jira_manager.add_connection),
            MenuOption('r', 'Remove a JIRA connection and all related views',
                       self._jira_manager.remove_connection),
            MenuOption(
                'c',
                'Cache offline ticket data for a JiraProject on a connection',
                self._jira_manager.cache_new_jira_project_data),
            MenuOption(
                'd',
                'Delete offline cached ticket data for a JiraProject on a connection',
                self._jira_manager.delete_cached_jira_project),
            MenuOption('l', 'List all configured Jiraconnections',
                       self._jira_manager.list_jira_connections),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jenkins_menu = [
            MenuOption('r',
                       'Reports Manager',
                       self.go_to_jenkins_reports_manager_menu,
                       pause=False),
            MenuOption('c',
                       'Connections Manager',
                       self.go_to_jenkins_connections_manager_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jenkins_reports_manager_menu = [
            MenuOption('o',
                       'Open custom report',
                       self._jenkins_manager.select_active_report,
                       pause=False),
            MenuOption('a',
                       'Add a custom report',
                       self._jenkins_manager.add_custom_report,
                       pause=False),
            MenuOption('r',
                       'Remove a custom report',
                       self._jenkins_manager.remove_custom_report,
                       pause=False),
            MenuOption('l', 'List custom reports',
                       self._jenkins_manager.list_custom_reports),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_jenkins_menu)
        ]

        self.jenkins_report_menu = [
            MenuOption('v', 'View report',
                       self._jenkins_manager.view_custom_report),
            MenuOption('a',
                       'Add a job',
                       self._jenkins_manager.add_custom_report_job,
                       pause=False),
            MenuOption('r',
                       'Remove a job',
                       self._jenkins_manager.remove_custom_report_job,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(
                self.go_to_jenkins_reports_manager_menu)
        ]

        self.jenkins_connections_manager_menu = [
            MenuOption('o',
                       'Open connection',
                       self._jenkins_manager.select_active_connection,
                       pause=False),
            MenuOption('a',
                       'Add a connection',
                       self._jenkins_manager.add_connection,
                       pause=False),
            MenuOption('r',
                       'Remove a connection',
                       self._jenkins_manager.remove_connection,
                       pause=False),
            MenuOption('l', 'List connections',
                       self._jenkins_manager.list_connections),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_jenkins_menu)
        ]

        self.jenkins_connection_menu = [
            MenuOption('v',
                       'View cached jobs',
                       self._jenkins_manager.view_cached_jobs,
                       pause=False),
            MenuOption('d',
                       'Download jobs to cache',
                       self._jenkins_manager.download_jobs,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('l', 'List saved views',
                       self._jenkins_manager.list_views),
            MenuOption('a',
                       'Add a view',
                       self._jenkins_manager.add_view,
                       pause=False),
            MenuOption('r',
                       'Remove a view',
                       self._jenkins_manager.remove_view,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(
                self.go_to_jenkins_connections_manager_menu)
        ]

        self.options_menu = [
            MenuOption('p', 'Change Argus password', self._change_password),
            MenuOption('b', 'Change browser', self._change_browser),
            MenuOption('v', 'Toggle Verbose/Debug', self._change_debug),
            MenuOption('d', 'Toggle Display dependencies',
                       self._change_show_dependencies),
            MenuOption('o', 'Toggle show open dependencies only',
                       self._change_dependency_type),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.projects_menu = [
            MenuOption('l',
                       'List locally cached projects',
                       self._jira_manager.list_projects,
                       pause=True),
            MenuOption('s',
                       'Search locally cached JiraIssues for a string',
                       self._jira_manager.search_projects,
                       pause=False),
            MenuOption('a',
                       'Add new JiraProject offline cache',
                       self._jira_manager.cache_new_jira_project_data,
                       pause=True),
            MenuOption(
                'd',
                'Delete offline cached ticket data for a JiraProject on a connection',
                self._jira_manager.delete_cached_jira_project),
            MenuOption('u',
                       'Update all locally cached project JIRA data',
                       self._jira_manager.update_cached_jira_project_data,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.active_menu = None
        self.menu_header = None
        self.go_to_main_menu()

        self._load_config()

        # let user read startup info
        pause()
Ejemplo n.º 26
0
    def run_debug(self) -> None:
        while True:
            print_separator(80)
            print('Debug menu:')
            print('t: print a specific ticket\'s data')
            print('l: list custom fields for a JiraProject')
            print(
                'r: (run current transient) - test print width formatting stuff'
            )
            print('q: quit back to main menu')
            print_separator(80)
            menu_choice = get_input(':')
            if menu_choice == 't':
                ticket_name = get_input(
                    'Print what ticket? Note: this will fail unless you\'ve cached this project locally:',
                    lowered=False)
                project_name = JiraIssue.get_project_from_ticket(ticket_name)

                if project_name == '' or project_name is None:
                    print(
                        'Failed to parse project name from ticket: {}. Try again.'
                        .format(ticket_name))
                    continue

                jira_project = self.maybe_get_cached_jira_project_no_url(
                    project_name)
                if jira_project is None:
                    print(
                        'Could not find cached version of {}. Add via project menu and try again.'
                        .format(project_name))
                    continue

                ticket = jira_project.get_issue(ticket_name)
                if ticket is None:
                    print(
                        'Failed to get jira issue {} from project {}. Are you sure it is correct and/or cached?'
                        .format(ticket_name, project_name))
                    continue

                if jira_project.jira_connection is not None:
                    print('Ticket: {}'.format(
                        ticket.pretty_print(jira_project.jira_connection)))
            elif menu_choice == 'r':
                print('TEST: [{:{width}.{width}}]'.format(
                    'I am testing a 5.5 thing', width=5))
            elif menu_choice == 'l':
                jira_connection = self.pick_jira_connection(
                    'Show fields for project on which connection?')
                if jira_connection is None:
                    print('Nothing selected. Continuing.')
                    continue
                project = self.get_jira_connection(
                    jira_connection.connection_name).pick_and_get_jira_project(
                    )
                if project is not None:
                    print('Showing custom fields for project: {}'.format(
                        project.project_name))
                    for key, value in project._custom_fields:
                        print('Key: {}. Value: {}'.format(key, value))
            elif menu_choice == 'q':
                break
            else:
                print('Bad choice. Try again.')
            pause()
Ejemplo n.º 27
0
    def display_dashboard(self, jira_manager: 'JiraManager',
                          jira_views: Dict[str, JiraView]) -> None:
        df = DisplayFilter.default()

        matching_issues = []
        for jira_view in list(self._jira_views.values()):
            matching_issues.extend(list(jira_view.get_issues().values()))

        filters = {}  # type: Dict[Column, str]
        while True:
            filtered_issues = df.display_and_return_sorted_issues(
                jira_manager, matching_issues, 1, filters)
            print_separator(60)
            prompt = 'Input [#] integer value to open ticket in browser, [f] to filter column by string, [c] to clear filters, [q] to quit'
            custom = get_input(prompt)
            if custom == 'q':
                return
            elif custom == 'f':
                column_name = pick_value(
                    'Filter against which column?',
                    [column.name for column in df.included_columns], True)
                if column_name is None:
                    continue
                to_match = get_input('Filter for what string?', False)

                # For now, we convert the string name to the Column object as we key by a mapping of Column to filter regex for matching
                # TODO: This should be changed to a Dict[str, List[ColumnFilter]] objects going forward and made consistent across all users
                # This will both tidy up this abstraction but also allow matching against multiple regexes per Column rather than the current one,
                # as well as enforce the 1:many relationship we're going for on filtering instead of the suboptimal many:1 our
                # data structures currently give us.
                column_list = [
                    col for col in df.included_columns
                    if col.name == column_name
                ]
                assert len(
                    column_list
                ) == 1, 'Expected only 1 match with column name {}, got {}'.format(
                    column_name, len(column_list))
                filters[column_list[0]] = to_match
            elif custom == 'c':
                filters = {}
            elif custom.isdigit():
                intval = int(custom) - 1
                issue = filtered_issues[intval]

                # As we cache JiraProject data on a JiraConnection basis, we need to reach into the JiraView, to their
                # contained JiraConnections, and check for presence of the owning JiraProject for this issuekey
                # in order to determine our base url to open a browser to this issue. I'm not in love with this.
                base_url = 'unknown'
                for jira_view in list(jira_views.values()):
                    jira_connection = jira_view.jira_connection
                    for jira_project in jira_connection.cached_projects:
                        if jira_project.owns_issue(issue):
                            base_url = jira_connection.url
                if base_url == 'unknown':
                    print(
                        'Failed to find JiraConnection for issuekey: {}. Something went wrong.'
                        .format(issue.issue_key))
                else:
                    issue_url = '{}browse/{}'.format(base_url, issue)
                    try:
                        Popen([browser(), issue_url])
                        print('Opened {}. Press enter to continue.'.format(
                            issue_url))
                        pause()
                    except OSError as oe:
                        print(
                            'Failed to open browser [{}]. Probably need to configure your environment or update from main menu. Exception: {}'
                            .format(browser(), oe))
            else:
                print('Oops... Unrecognized input. Please try again.')
                pause()
Ejemplo n.º 28
0
    def __init__(self, jira_manager: JiraManager, team_manager: TeamManager,
                 options: Dict[str, str]) -> None:
        self.jira_manager = jira_manager
        self.team_manager = team_manager

        # TODO: Clean up the coupling with main_menu.
        self.jenkins_manager = JenkinsManager(self)

        if 'triage_csv' in options:
            jira_connections = {}
            for jira_connection in self.jira_manager.jira_connections():
                argus_debug('Init connection: {}'.format(
                    jira_connection.connection_name))
                jira_connections[
                    jira_connection.connection_name] = jira_connection
            triage_update = TriageUpdate(
                jira_connections,
                self.jira_manager.get_all_cached_jira_projects())
            triage_out = options[
                'triage_out'] if 'triage_out' in options else None
            triage_update.process(options['triage_csv'], triage_out)

        if 'dashboard' in options:
            user_key = options['dashboard']
            dash_keys = list(self.jira_manager.jira_dashboards.keys())

            if user_key in dash_keys:
                self.jira_manager.jira_dashboards[user_key].display_dashboard(
                    self.jira_manager, self.jira_manager.jira_views)
            else:
                print('Oops... Error with dashboard name {}'.format(user_key))
                print('Possible dashboard names : {}'.format(
                    ','.join(dash_keys)))
                print('Starting Argus normally...')

        if 'verbose' in options:
            utils.debug = True
            utils.argus_log = open('argus.log', 'w')

        self.main_menu = [
            MenuOption('d',
                       'Dashboards',
                       self.go_to_dashboards_menu,
                       pause=False),
            MenuOption('v',
                       'Jira Views',
                       self.go_to_jira_views_menu,
                       pause=False),
            MenuOption('p',
                       'JiraProject Queries',
                       self.go_to_projects_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('t',
                       'Run a Team-Based Report',
                       self._run_team_report,
                       pause=False),
            MenuOption('u',
                       'Run an org-based Report',
                       self._run_org_report,
                       pause=False),
            MenuOption('e',
                       'View Escalations',
                       self.jira_manager.display_escalations,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('r',
                       'Generate a Pre-Determined Report',
                       self.go_to_reports_menu,
                       pause=False),
            MenuOption('m',
                       'Team Management',
                       self.go_to_teams_menu,
                       pause=False),
            MenuOption('c',
                       'Jira Connections',
                       self.go_to_jira_connections_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('j',
                       'Jenkins Menu',
                       self.go_to_jenkins_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('o',
                       'Change Options',
                       self.go_to_options_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('h', 'Help', self._display_readme, pause=False),
            MenuOption.quit_program()
        ]
        if Config.Experiment is True:
            self.main_menu.append(MenuOption.print_blank_line())
            self.main_menu.append(
                MenuOption('x',
                           'Debug',
                           self.jira_manager.run_debug,
                           pause=False))

        self.dashboards_menu = [
            MenuOption('l', 'List all available dashboards',
                       self.jira_manager.list_dashboards),
            MenuOption('d', 'Display a dashboard\'s results',
                       self.jira_manager.display_dashboard),
            MenuOption('c', 'Create a dashboard',
                       self.jira_manager.add_dashboard),
            MenuOption('e', 'Edit a dashboard',
                       self.jira_manager.edit_dashboard),
            MenuOption('r', 'Remove a dashboard',
                       self.jira_manager.remove_dashboard),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jira_views_menu = [
            MenuOption('l', 'List all defined JiraViews',
                       self.jira_manager.list_all_jira_views),
            MenuOption('d', 'Display a JiraView\'s results',
                       self.jira_manager.display_view),
            MenuOption('a', 'Add a JiraView', self._add_view),
            MenuOption('e', 'Edit a JiraView', self._edit_view),
            MenuOption('r', 'Remove a JiraView',
                       self.jira_manager.remove_view),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.reports_menu = [
            MenuOption(
                'f',
                'FixVersion report (release). Query all tickets with a specified FixVersion',
                self.jira_manager.report_fix_version),
            MenuOption('s',
                       'Add a single-user multi-JIRA open ticket dashboard',
                       self._add_multi_jira_dashboard),
            MenuOption('l', 'Add a label-based cross-cutting view',
                       self.jira_manager.add_label_view),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.team_menu = [
            MenuOption('l', 'List all defined Teams',
                       self.team_manager.list_teams),
            MenuOption('a', 'Add a new team', self._add_team),
            MenuOption('e', 'Edit an existing team', self._edit_team),
            MenuOption('r', 'Remove a team', self.team_manager.remove_team),
            MenuOption(
                'x',
                'Link a team member to two accounts across JiraConnections',
                self.add_linked_member),
            MenuOption('d', 'Delete a cross-Jira link',
                       self.team_manager.remove_linked_member),
            MenuOption('o', 'Add an organization',
                       self.team_manager.add_organization),
            MenuOption('p', 'Remove an organization',
                       self.team_manager.remove_organization),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jira_connections_menu = [
            MenuOption('a', 'Add a JIRA connection',
                       self.jira_manager.add_connection),
            MenuOption('r', 'Remove a JIRA connection and all related views',
                       self.jira_manager.remove_connection),
            MenuOption(
                'c',
                'Cache offline ticket data for a JiraProject on a connection',
                self.jira_manager.cache_new_jira_project_data),
            MenuOption(
                'd',
                'Delete offline cached ticket data for a JiraProject on a connection',
                self.jira_manager.delete_cached_jira_project),
            MenuOption('l', 'List all configured Jiraconnections',
                       self.jira_manager.list_jira_connections),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jenkins_menu = [
            MenuOption('r',
                       'Reports Manager',
                       self.go_to_jenkins_reports_manager_menu,
                       pause=False),
            MenuOption('c',
                       'Connections Manager',
                       self.go_to_jenkins_connections_manager_menu,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.jenkins_reports_manager_menu = [
            MenuOption('o',
                       'Open custom report',
                       self.jenkins_manager.select_active_report,
                       pause=False),
            MenuOption('a',
                       'Add a custom report',
                       self.jenkins_manager.add_custom_report,
                       pause=False),
            MenuOption('r',
                       'Remove a custom report',
                       self.jenkins_manager.remove_custom_report,
                       pause=False),
            MenuOption('l', 'List custom reports',
                       self.jenkins_manager.list_custom_reports),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_jenkins_menu)
        ]

        self.jenkins_report_menu = [
            MenuOption('v', 'View report',
                       self.jenkins_manager.view_custom_report),
            MenuOption('a',
                       'Add a job',
                       self.jenkins_manager.add_custom_report_job,
                       pause=False),
            MenuOption('r',
                       'Remove a job',
                       self.jenkins_manager.remove_custom_report_job,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(
                self.go_to_jenkins_reports_manager_menu)
        ]

        self.jenkins_connections_manager_menu = [
            MenuOption('o',
                       'Open connection',
                       self.jenkins_manager.select_active_connection,
                       pause=False),
            MenuOption('a',
                       'Add a connection',
                       self.jenkins_manager.add_connection,
                       pause=False),
            MenuOption('r',
                       'Remove a connection',
                       self.jenkins_manager.remove_connection,
                       pause=False),
            MenuOption('l', 'List connections',
                       self.jenkins_manager.list_connections),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_jenkins_menu)
        ]

        self.jenkins_connection_menu = [
            MenuOption('v',
                       'View cached jobs',
                       self.jenkins_manager.view_cached_jobs,
                       pause=False),
            MenuOption('d',
                       'Download jobs to cache',
                       self.jenkins_manager.download_jobs,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption('l', 'List saved views',
                       self.jenkins_manager.list_views),
            MenuOption('a',
                       'Add a view',
                       self.jenkins_manager.add_view,
                       pause=False),
            MenuOption('r',
                       'Remove a view',
                       self.jenkins_manager.remove_view,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(
                self.go_to_jenkins_connections_manager_menu)
        ]

        self.options_menu = [
            MenuOption('p', 'Change Argus password', self._change_password),
            MenuOption('b', 'Change browser', self._change_browser),
            MenuOption('v', 'Toggle Verbose/Debug', self._change_debug),
            MenuOption('d', 'Toggle Display dependencies',
                       self._change_show_dependencies),
            MenuOption('o', 'Toggle show open dependencies only',
                       self._change_dependency_type),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.projects_menu = [
            MenuOption('l',
                       'List locally cached projects',
                       self.jira_manager.list_projects,
                       pause=True),
            MenuOption('s',
                       'Search locally cached JiraIssues for a string',
                       self.jira_manager.search_projects,
                       pause=False),
            MenuOption('a',
                       'Add new JiraProject offline cache',
                       self.jira_manager.cache_new_jira_project_data,
                       pause=True),
            MenuOption(
                'd',
                'Delete offline cached ticket data for a JiraProject on a connection',
                self.jira_manager.delete_cached_jira_project),
            MenuOption('u',
                       'Update all locally cached project JIRA data',
                       self.jira_manager.update_cached_jira_project_data,
                       pause=False),
            MenuOption.print_blank_line(),
            MenuOption.return_to_previous_menu(self.go_to_main_menu)
        ]

        self.active_menu = self.main_menu  # type: List[MenuOption]
        self.menu_header = 'uninit'  # type: str
        self.go_to_main_menu()

        self._load_config()

        # let user read startup info
        pause()
Ejemplo n.º 29
0
    def run_team_reports(self, jira_manager):
        """
        Sub-menu driven method to run some specific reports of interest against teams. This will take into account
        linked members and run the report for all tickets across multiple JIRA connections.
        """
        selected_team = None

        if len(self._teams) == 0:
            # We don't prompt for addition now since we'd have to pass in main menu context to do that from here.
            print(
                'No teams found. Please use the Team Management menu to define a new team before running a report.'
            )
            pause()
            return

        reports = {
            ReportType.MOMENTUM: ReportMomentum(),
            ReportType.CURRENT_LOAD: ReportCurrentLoad(),
            ReportType.TEST_LOAD: ReportTestLoad(),
            ReportType.REVIEW_LOAD: ReportReviewLoad()
        }

        while True:
            clear()
            if selected_team is None:
                selected_team = self.pick_team()
                # None return from pick_team == cancel
                if selected_team is None:
                    return
                TeamManager.populate_owned_jira_issues(jira_manager,
                                                       selected_team.members)

            print('---------------------')
            print('-    Team Menu      -')
            print('---------------------')
            print('t: Change active root team. Current: {}'.format(
                selected_team.name))
            print(
                '{}: Run a momentum report: closed tickets, closed test tickets, closed reviews for a custom time frame'
                .format(ReportType.MOMENTUM))
            print(
                '{}: Team load report: assigned bugs, assigned tests, assigned features, assigned reviews, patch available reviews'
                .format(ReportType.CURRENT_LOAD))
            print(
                '{}: Test load report: snapshot of currently assigned tests and closed tests in a custom time frame'
                .format(ReportType.TEST_LOAD))
            print(
                '{}: Review load report: snapshot of currently assigned reviews, Patch Available reviews, and finished reviews in a custom time frame'
                .format(ReportType.REVIEW_LOAD))
            print('q: Cancel')
            print('---------------------')
            choice = get_input(':')
            if choice == 'q':
                return
            elif choice == 't':
                selected_team = None
            try:
                report_type = ReportType.from_int(int(choice))
                if report_type == ReportType.UNKNOWN:
                    print('Bad input: {}. Try again.'.format(choice))
                    pause()
                else:
                    TeamManager._run_report(jira_manager, selected_team,
                                            reports[report_type])
            except (ValueError, TypeError) as e:
                print('Error on input: {}. Try again'.format(e))
                traceback.print_exc()
                pause()