Ejemplo n.º 1
0
def main():
    BOARD_NAME = 'DFG-Workflows-Stein-Dev'
    # BZ Queries

    config = configuration.get_config()

    board_manager = boards.BoardManager(config['trello'], BOARD_NAME)

    board_manager.update(config)
Ejemplo n.º 2
0
def health(board):

    try:
        config = configuration.get_config()
    except Exception as err:
        click.echo(err)
        sys.exit(1)

    board_manager = boards.BoardManager(config['trello'], board)
    duplicates = {}
    no_sources = []

    lists = [item.id for item in board_manager.board.open_lists() if
             item.name != "Meta"]
    cards = [card for card in board_manager.board.all_cards()
             if card.idList in lists]
    sources = list(
        itertools.chain(*[[(field.value, card) for field in card.customFields
                           if field.name == 'source'] for card in cards]))

    counts = collections.Counter([x for (x, y) in sources])
    dups = [(x, y) for (x, y) in counts.most_common() if y > 1]
    dup_urls = [name for (name, url) in dups]

    for source in sources:
        if source[0] == '':
            no_sources.append(source[1])
        else:
            if source[0] in dup_urls:
                if source[0] not in duplicates:
                    duplicates[source[0]] = []
                duplicates[source[0]].append(source[1])

    # display the cards that have more than one instance of the source
    if len(duplicates) > 0:
        click.echo(click.style("Duplicate Cards", bg='red', fg='black'))
        for url, dup_cards in duplicates.iteritems():
            print("%s(%s)" % (url, len(dup_cards)))
            dup_cards.sort(key=lambda x: x.list_labels.count, reverse=True)
            pprint([card_item.shortUrl for card_item in dup_cards[1:]])
    else:
        click.echo(
            click.style(u"\u2713 No Duplicate Cards", bg='green', fg='black'))

    # display the cards without sources
    if len(no_sources) > 0:
        click.echo(click.style("Cards Without Sources", bg='red', fg='black'))
        pprint(no_sources)
    else:
        click.echo(
            click.style(u"\u2713 All Cards Have Source URLs", bg='green', fg='black'))
Ejemplo n.º 3
0
def main():
    BOARD_NAME = 'My-Example-Board'
    # BZ Queries

    config = configuration.get_config()

    board_manager = boards.BoardManager(config['trello'], BOARD_NAME)

    # planned Work Labels
    # Planning is something that needs to be reviewed by PM/UA/TC
    # Planned is confirmed work for the cycle
    board_manager.add_labels_by_color("yellow", ["Planning"])
    board_manager.add_labels_by_color("yellow", ["Planned"])

    board_manager.import_cards()
Ejemplo n.º 4
0
def reports(report, template, output, board, list_name):
    try:
        config = configuration.get_config()
    except peeves.MissingConfigurationSettingException as missing_section:
        click.echo(str(missing_section))
        sys.exit(1)
    except peeves.MissingConfigurationSectionException as missing_setting:
        click.echo('Trello config section required.')
        click.echo(str(missing_setting))
        sys.exit(1)

    # choose the report query
    if report == "board":
        if not board:
            click.echo('If board report is indicated, you must '
                       'include a board argument. (--board or -b)')
            sys.exit(1)
        else:
            board_manager = boards.BoardManager(config['trello'], board)
            # create board context
            context = {'board': board_manager.board}
    else:
        click.echo('Unsupported report type requested.')
        sys.exit(1)

    # if there is a template present for the output, then merge the template
    # with the data
    if template:
        with open(template, 'r') as template_file:
            template_data = template_file.read()
            # Render the j2 template
            raw_template = jinja2.Environment().from_string(
                template_data)
            r_template = raw_template.render(**context)
            # if there is an output arg, write to a file of that name.
            if output:
                with open(output, 'w') as output_file:
                    output_file.write(r_template)
            else:
                # else, just print report to terminal
                click.echo(pprint(r_template))
    else:
        click.echo(pprint(context))
Ejemplo n.º 5
0
def importer(service, id, url, host, user, password, project, board,
             labels, list_name):
    try:
        config = configuration.get_config()
    except Exception as err:
        click.echo(err)
        sys.exit(1)

    trello_key = config['trello']['api_key']
    trello_token = config['trello']['access_token']
    if not board:
        if 'default_board' not in config['trello']:
            click.echo("No default_board exists in ~/filch.conf")
            click.echo("You must either set a default_board in ~/filch.conf "
                       "or use the --board_name option.")
            sys.exit(1)
        else:
            board = config['trello']['default_board']

    trello_api = trelloclient.TrelloClient(
        api_key=config['trello']['api_key'],
        token=config['trello']['access_token']
    )

    board_obj = [b for b in trello_api.list_boards()
                 if b.name == board][0]

    # ensure labels being used are actually in the board
    card_labels = [label for label in board_obj.get_labels()
                      if label.name in list(labels)]

    # ensure list name exists in board
    board_list = [trello_list for trello_list in board_obj.open_lists()
                if trello_list.name == list_name][0]

    if service == 'gerrit':
        # default to upstream openstack
        # if host is present then use that
        # if url is present then use that
        gerrit_url = "https://review.openstack.org"
        if host:
            gerrit_url = config['gerrit'][host]['url']
        if url:
            gerrit_url = url

        gerrit_api = GerritRestAPI(url=gerrit_url, auth=None)
        for change_id in list(id):
            change = gerrit_api.get("/changes/%s" % change_id)
            cards.create_card(
                board_list,
                change['subject'],
                constants.GERRIT_CARD_DESC.format(**change),
                labels=card_labels,
                due="null",
            )
            click.echo(
                'You have successfully imported "%s"' % change['subject'])

    if service == 'blueprint':
        if not project:
            click.echo('To import a blueprint you must provide a project.')
            sys.exit(1)
        for bp_id in list(id):
            blueprint = utils.get_blueprint(project, bp_id)
            cards.create_card(
                board_list,
                blueprint['title'],
                constants.BLUEPRINT_CARD_DESC.format(**blueprint),
                labels=card_labels,
                due="null",
            )
            click.echo(
                'You have successfully imported "%s"' % blueprint['title'])

    if service == 'bug':
        for bug_id in list(id):
            bug = utils.get_launchpad_bug(bug_id)
            cards.create_card(
                board_list,
                bug['title'],
                constants.BUG_CARD_DESC.format(**bug),
                labels=card_labels,
                due="null",
            )
            click.echo(
                'You have successfully imported "%s"' % bug['title'])

    if service == 'story':
        for story_id in list(id):
            story = utils.get_storyboard_story(story_id)
            cards.create_card(
                board_list,
                story['title'],
                constants.STORY_CARD_DESC.format(**story),
                labels=card_labels,
                due="null",
            )
            click.echo(
                'You have successfully imported "%s"' % story['title'])

    if service in ['bz', 'bugzilla']:
        if url:
            # also need user & password.  sslverify is optional
            if not user or not password:
                click.echo("If using a url for Bugzilla, you must also "
                           "provide a user and password.")
                sys.exit(1)

        # if host arg is not used, use first host from
        # configuration as default
        if not host:
            # check to ensure a host for bugzilla exists in config
            if len(config['bugzilla'].keys()) == 0:
                click.echo("No Bugzilla data configuration file.  Please "
                           "add configuration data or pass url, user and "
                           "password arguments.")
                sys.exit(1)
            else:
                host = list(config['bugzilla'].keys())[0]

        url = config['bugzilla'][host]['url']
        user = config['bugzilla'][host]['user']

        sslverify = config['bugzilla'][host].get('sslverify', True)

        for bz_id in list(id):
            try:
                bug = utils.get_bz(bz_id, url=url, user=user, password=password,
                                   sslverify=sslverify)

                if len(bug.comments) > 0:
                    bug.description = bug.comments[0]['text']

                bug_card = cards.create_card(
                    board_list,
                    bug.summary,
                    constants.BZ_CARD_DESC.format(**bug.__dict__),
                    labels=card_labels,
                    due="null",
                )

                # adds comments to a card
                if len(bug.comments) > 1:
                    for comment in bug.comments[1:]:
                        bug_card.comment(constants.COMMENT_TEXT.format(
                            text=comment['text'],
                            author=comment['author'],
                            create_time=comment['creation_time'],
                            is_private=constants.COMMENT_PRIVACY[
                                comment['is_private']
                            ],
                        ))

                # adds external trackers to card
                if len(bug.external_bugs) > 0:
                    external_trackers = []
                    for ext_bug in bug.external_bugs:
                        external_trackers.append(
                            os.path.join(ext_bug['type']['url'],
                                         ext_bug['ext_bz_bug_id'])
                        )
                    bug_card.add_checklist(
                        'External Trackers',
                        external_trackers
                    )

                click.echo('You have successfully imported "%s"' % bug.summary)
            except Exception as err:
                click.echo(err)

    if service == 'debug':
        ids = list(id)
        print(ids)
Ejemplo n.º 6
0
 def test_get_config_missing_setting(self, mock_open_file):
     mock_open_file.return_value = config_data_missing_setting
     with pytest.raises(peeves.MissingConfigurationSettingException):
         configuration.get_config()
Ejemplo n.º 7
0
 def test_get_config(self, mock_open_file):
     mock_open_file.return_value = good_config_data
     result = configuration.get_config()
     assert result == good_config_obj
Ejemplo n.º 8
0
def importer(service, id, url, host, user, password, project, board, labels,
             list_name):
    config = configuration.get_config()
    trello_key = config['trello']['api_key']
    trello_token = config['trello']['access_token']
    if not board:
        if 'default_board' not in config['trello']:
            click.echo("No default_board exists in ~/filch.conf")
            click.echo("You must either set a default_board in ~/filch.conf "
                       "or use the --board_name option.")
            sys.exit(1)
        else:
            board = config['trello']['default_board']

    if service == 'gerrit':
        # default to upstream openstack
        # if host is present then use that
        # if url is present then use that
        gerrit_url = "https://review.openstack.org"
        if host:
            gerrit_url = config['gerrit'][host]['url']
        if url:
            gerrit_url = url

        gerrit_api = GerritRestAPI(url=gerrit_url, auth=None)
        for change_id in list(id):
            change = gerrit_api.get("/changes/%s" % change_id)
            cards.create_card(trello_key,
                              trello_token,
                              board,
                              change['subject'],
                              constants.GERRIT_CARD_DESC.format(**change),
                              card_labels=list(labels),
                              card_due="null",
                              list_name=list_name)
            click.echo('You have successfully imported "%s"' %
                       change['subject'])

    if service == 'blueprint':
        if not project:
            click.echo('To import a blueprint you must provide a project.')
            sys.exit(1)
        for bp_id in list(id):
            blueprint = utils.get_blueprint(project, bp_id)
            cards.create_card(
                trello_key,
                trello_token,
                board,
                blueprint['title'],
                constants.BLUEPRINT_CARD_DESC.format(**blueprint),
                card_labels=list(labels),
                card_due="null",
                list_name=list_name)
            click.echo('You have successfully imported "%s"' %
                       blueprint['title'])

    if service == 'bug':
        for bug_id in list(id):
            bug = utils.get_launchpad_bug(bug_id)
            cards.create_card(trello_key,
                              trello_token,
                              board,
                              bug['title'],
                              constants.BUG_CARD_DESC.format(**bug),
                              card_labels=list(labels),
                              card_due="null",
                              list_name=list_name)
            click.echo('You have successfully imported "%s"' % bug['title'])

    if service in ['bz', 'bugzilla']:
        if url:
            # also need user & password.  sslverify is optional
            if not user or not password:
                click.echo("If using a url for Bugzilla, you must also "
                           "provide a user and password.")
                sys.exit(1)

        # if host arg is not used, use first host from
        # configuration as default
        if not host:
            # check to ensure a host for bugzilla exists in config
            if len(config['bugzilla'].keys()) == 0:
                click.echo("No Bugzilla data configuration file.  Please "
                           "add configuration data or pass url, user and "
                           "password arguments.")
                sys.exit(1)
            else:
                host = config['bugzilla'].keys()[0]

        url = config['bugzilla'][host]['url']
        user = config['bugzilla'][host]['user']

        sslverify = config['bugzilla'][host].get('sslverify', True)

        for bz_id in list(id):
            try:
                bug = utils.get_bz(bz_id,
                                   url=url,
                                   user=user,
                                   password=password,
                                   sslverify=sslverify)

                if len(bug.comments) > 0:
                    bug.description = bug.comments[0]['text']

                cards.create_card(
                    trello_key,
                    trello_token,
                    board,
                    bug.summary,
                    constants.BZ_CARD_DESC.format(**bug.__dict__),
                    card_labels=list(labels),
                    card_due="null",
                    list_name=list_name)
                click.echo('You have successfully imported "%s"' % bug.summary)
            except Exception as err:
                click.echo(err)

    if service == 'debug':
        ids = list(id)
        print(ids)
Ejemplo n.º 9
0
def importer(service, id, url, host, user, password, project, board, labels,
             list_name):
    try:
        config = configuration.get_config()
    except Exception as err:
        click.echo(err)
        sys.exit(1)

    trello_key = config['trello']['api_key']
    trello_token = config['trello']['access_token']
    if not board:
        if 'default_board' not in config['trello']:
            click.echo("No default_board exists in ~/filch.conf")
            click.echo("You must either set a default_board in ~/filch.conf "
                       "or use the --board_name option.")
            sys.exit(1)
        else:
            board = config['trello']['default_board']

    trello_api = trelloclient.TrelloClient(
        api_key=config['trello']['api_key'],
        token=config['trello']['access_token'])

    board_obj = [b for b in trello_api.list_boards() if b.name == board][0]

    # ensure labels being used are actually in the board
    card_labels = [
        label for label in board_obj.get_labels() if label.name in list(labels)
    ]

    # ensure list name exists in board
    board_list = [
        trello_list for trello_list in board_obj.open_lists()
        if trello_list.name == list_name
    ][0]

    if service == 'gerrit':
        # default to upstream openstack
        # if host is present then use that
        # if url is present then use that
        gerrit_url = "https://review.openstack.org"
        if host:
            gerrit_url = config['gerrit'][host]['url']
        if url:
            gerrit_url = url

        gerrit_api = GerritRestAPI(url=gerrit_url, auth=None)
        for change_id in list(id):
            change = gerrit_api.get("/changes/%s" % change_id)
            cards.create_card(
                board_list,
                change['subject'],
                constants.GERRIT_CARD_DESC.format(**change),
                labels=card_labels,
                due="null",
            )
            click.echo('You have successfully imported "%s"' %
                       change['subject'])

    if service == 'blueprint':
        if not project:
            click.echo('To import a blueprint you must provide a project.')
            sys.exit(1)
        for bp_id in list(id):
            blueprint = utils.get_blueprint(project, bp_id)
            cards.create_card(
                board_list,
                blueprint['title'],
                constants.BLUEPRINT_CARD_DESC.format(**blueprint),
                labels=card_labels,
                due="null",
            )
            click.echo('You have successfully imported "%s"' %
                       blueprint['title'])

    if service == 'bug':
        for bug_id in list(id):
            bug = utils.get_launchpad_bug(bug_id)
            cards.create_card(
                board_list,
                bug['title'],
                constants.BUG_CARD_DESC.format(**bug),
                labels=card_labels,
                due="null",
            )
            click.echo('You have successfully imported "%s"' % bug['title'])

    if service == 'story':
        for story_id in list(id):
            story = utils.get_storyboard_story(story_id)
            cards.create_card(
                board_list,
                story['title'],
                constants.STORY_CARD_DESC.format(**story),
                labels=card_labels,
                due="null",
            )
            click.echo('You have successfully imported "%s"' % story['title'])

    if service in ['bz', 'bugzilla']:
        if url:
            # also need user & password.  sslverify is optional
            if not user or not password:
                click.echo("If using a url for Bugzilla, you must also "
                           "provide a user and password.")
                sys.exit(1)

        # if host arg is not used, use first host from
        # configuration as default
        if not host:
            # check to ensure a host for bugzilla exists in config
            if len(config['bugzilla'].keys()) == 0:
                click.echo("No Bugzilla data configuration file.  Please "
                           "add configuration data or pass url, user and "
                           "password arguments.")
                sys.exit(1)
            else:
                host = list(config['bugzilla'].keys())[0]

        url = config['bugzilla'][host]['url']
        user = config['bugzilla'][host]['user']

        sslverify = config['bugzilla'][host].get('sslverify', True)

        for bz_id in list(id):
            try:
                bug = utils.get_bz(bz_id,
                                   url=url,
                                   user=user,
                                   password=password,
                                   sslverify=sslverify)

                if len(bug.comments) > 0:
                    bug.description = bug.comments[0]['text']

                bug_card = cards.create_card(
                    board_list,
                    bug.summary,
                    constants.BZ_CARD_DESC.format(**bug.__dict__),
                    labels=card_labels,
                    due="null",
                )

                # adds comments to a card
                if len(bug.comments) > 1:
                    for comment in bug.comments[1:]:
                        bug_card.comment(
                            constants.COMMENT_TEXT.format(
                                text=comment['text'],
                                author=comment['author'],
                                create_time=comment['creation_time'],
                                is_private=constants.COMMENT_PRIVACY[
                                    comment['is_private']],
                            ))

                # adds external trackers to card
                if len(bug.external_bugs) > 0:
                    external_trackers = []
                    for ext_bug in bug.external_bugs:
                        external_trackers.append(
                            os.path.join(ext_bug['type']['url'],
                                         ext_bug['ext_bz_bug_id']))
                    bug_card.add_checklist('External Trackers',
                                           external_trackers)

                click.echo('You have successfully imported "%s"' % bug.summary)
            except Exception as err:
                click.echo(err)

    if service == 'debug':
        ids = list(id)
        print(ids)
Ejemplo n.º 10
0
def main():
    BOARD_NAME = 'DFG-Component'
    # BZ Queries
    OPEN_UNTRIAGED_BUGS = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&chfield=%5BBug%20creation%5D&chfieldto=Now&f1=product&f10=flagtypes.name&f11=CP&f12=cf_internal_whiteboard&f2=cf_internal_whiteboard&f3=component&f4=cf_conditional_nak&f5=cf_qe_conditional_nak&f6=OP&f7=keywords&f8=priority&f9=bug_severity&keywords=FutureFeature%2C%20Tracking%2C%20Documentation%2C%20&keywords_type=nowords&list_id=8303834&n6=1&o1=equals&o10=substring&o12=equals&o2=substring&o3=notsubstring&o4=isempty&o5=isempty&o7=substring&o8=notsubstring&o9=notsubstring&saved_report_id=1948&v1=Red%20Hat%20OpenStack&v10=rhos&v12=DFG%3AWorkflows&v2=DFG%3A&v3=doc&v7=Triaged&v8=unspecified&v9=unspecified'
    BUG_BACKLOG_BY_RELEASE = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&f2=component&f3=cf_internal_whiteboard&f4=product&f5=cf_internal_whiteboard&keywords=FutureFeature%2C%20Tracking%2C%20Documentation%2C%20&keywords_type=nowords&list_id=8303843&o2=notsubstring&o3=substring&o4=equals&o5=equals&v2=doc&v3=DFG%3A&v4=Red%20Hat%20OpenStack&v5=DFG%3AWorkflows'
    RFE_BACKLOG_BY_RELEASE = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&f2=component&f3=cf_internal_whiteboard&f4=product&f5=keywords&f6=cf_internal_whiteboard&keywords=Tracking%2C%20Documentation%2C%20&keywords_type=nowords&list_id=8303849&o2=notsubstring&o3=substring&o4=equals&o5=substring&o6=equals&v2=doc&v3=DFG%3A&v4=Red%20Hat%20OpenStack&v5=FutureFeature&v6=DFG%3AWorkflows'

    # BZ fields to include in the queries
    BZ_INCLUDE_FIELDS = ["id", "summary", "version", "status", "priority",
                         "comments", "weburl", "information_type",
                         "external_bugs", "keywords"]

    # filch configuration data
    config = configuration.get_config()

    # add bugzilla sources from the queries above
    bug_backlog = data.BugzillaURISource(
        config['bugzilla']['redhat'],
        BUG_BACKLOG_BY_RELEASE,
        BZ_INCLUDE_FIELDS,
        default_labels=['Bug']
    )

    open_untriaged_bzs = data.BugzillaURISource(
        config['bugzilla']['redhat'],
        OPEN_UNTRIAGED_BUGS,
        BZ_INCLUDE_FIELDS,
        default_labels=['Bug']
    )

    rfe_backlog = data.BugzillaURISource(
        config['bugzilla']['redhat'],
        RFE_BACKLOG_BY_RELEASE,
        BZ_INCLUDE_FIELDS,
        default_labels=['RFE']
    )

    # launchpad blueprints don't have tags to associate them with specific
    # projects.  adding them manually seems to be the only way to ensure
    # specific blueprints are tracked.
    tripleo_blueprints = data.ManualBlueprintSource(
        "tripleo", ['tripleo-common-enhance-list-roles-action',
                    'tripleo-common-list-available-roles-action',
                    'tripleo-common-select-roles-workflow',
                    'update-roles-action', 'validate-roles-networks',
                    'get-networks-action', 'update-networks-action'],
        default_labels=['RFE']
    )

    board_manager = boards.BoardManager(config['trello'], BOARD_NAME)

    # add DFG-specific customizations to the board
    # add labels needed for our purposes
    # there are 11 label color options available
    # yellow, purple, blue, red, green, orange,
    # black, sky, pink, lime, null

    # Warning Status Labels (Red)
    # These labels denote something impeding progress
    board_manager.add_labels_by_color("red",
                                      ['UNTRIAGED', 'BLOCKED', 'CI-BLOCKED'])
    # Type Labels (Black)
    board_manager.add_labels_by_color("black", ["RFE", "Bug"])

    # Unplanned Work Labels (Orange)
    board_manager.add_labels_by_color("orange", ["Unplanned"])

    # Sprint Labels (Purple)
    board_manager.add_labels_by_color("purple", ["Sprint 1", "Sprint 2",
                                                 "Sprint 3", "Sprint 4"])

    # add the sources of external artifacts
    board_manager.sources.append(bug_backlog)
    board_manager.sources.append(open_untriaged_bzs)
    board_manager.sources.append(rfe_backlog)
    board_manager.sources.append(tripleo_blueprints)

    # execute the board manager logic
    board_manager.run()
Ejemplo n.º 11
0
 def test_get_config_missing_setting(self):
     mock_open = mock.mock_open()
     mock_open().read.return_value = config_data_missing_setting
     with mock.patch('six.moves.builtins.open', mock_open):
         with pytest.raises(peeves.MissingConfigurationSettingException):
             configuration.get_config()
Ejemplo n.º 12
0
 def test_get_config(self):
     mock_open = mock.mock_open()
     mock_open().read.return_value = good_config_data
     with mock.patch('six.moves.builtins.open', mock_open):
         result = configuration.get_config()
         assert result == good_config_obj
Ejemplo n.º 13
0
def main():
    BOARD_NAME = 'DFG-Component'
    # BZ Queries
    OPEN_UNTRIAGED_BUGS = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&chfield=%5BBug%20creation%5D&chfieldto=Now&f1=product&f10=flagtypes.name&f11=CP&f12=cf_internal_whiteboard&f2=cf_internal_whiteboard&f3=component&f4=cf_conditional_nak&f5=cf_qe_conditional_nak&f6=OP&f7=keywords&f8=priority&f9=bug_severity&keywords=FutureFeature%2C%20Tracking%2C%20Documentation%2C%20&keywords_type=nowords&list_id=8303834&n6=1&o1=equals&o10=substring&o12=equals&o2=substring&o3=notsubstring&o4=isempty&o5=isempty&o7=substring&o8=notsubstring&o9=notsubstring&saved_report_id=1948&v1=Red%20Hat%20OpenStack&v10=rhos&v12=DFG%3AWorkflows&v2=DFG%3A&v3=doc&v7=Triaged&v8=unspecified&v9=unspecified'
    BUG_BACKLOG_BY_RELEASE = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&f2=component&f3=cf_internal_whiteboard&f4=product&f5=cf_internal_whiteboard&keywords=FutureFeature%2C%20Tracking%2C%20Documentation%2C%20&keywords_type=nowords&list_id=8303843&o2=notsubstring&o3=substring&o4=equals&o5=equals&v2=doc&v3=DFG%3A&v4=Red%20Hat%20OpenStack&v5=DFG%3AWorkflows'
    RFE_BACKLOG_BY_RELEASE = 'https://bugzilla.redhat.com/buglist.cgi?action=wrap&bug_status=NEW&bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&f2=component&f3=cf_internal_whiteboard&f4=product&f5=keywords&f6=cf_internal_whiteboard&keywords=Tracking%2C%20Documentation%2C%20&keywords_type=nowords&list_id=8303849&o2=notsubstring&o3=substring&o4=equals&o5=substring&o6=equals&v2=doc&v3=DFG%3A&v4=Red%20Hat%20OpenStack&v5=FutureFeature&v6=DFG%3AWorkflows'

    # BZ fields to include in the queries
    BZ_INCLUDE_FIELDS = [
        "id", "summary", "version", "status", "priority", "comments", "weburl",
        "information_type", "external_bugs", "keywords"
    ]

    # filch configuration data
    config = configuration.get_config()

    # add bugzilla sources from the queries above
    bug_backlog = data.BugzillaURISource(config['bugzilla']['redhat'],
                                         BUG_BACKLOG_BY_RELEASE,
                                         BZ_INCLUDE_FIELDS,
                                         default_labels=['Bug'])

    open_untriaged_bzs = data.BugzillaURISource(config['bugzilla']['redhat'],
                                                OPEN_UNTRIAGED_BUGS,
                                                BZ_INCLUDE_FIELDS,
                                                default_labels=['Bug'])

    rfe_backlog = data.BugzillaURISource(config['bugzilla']['redhat'],
                                         RFE_BACKLOG_BY_RELEASE,
                                         BZ_INCLUDE_FIELDS,
                                         default_labels=['RFE'])

    # launchpad blueprints don't have tags to associate them with specific
    # projects.  adding them manually seems to be the only way to ensure
    # specific blueprints are tracked.
    tripleo_blueprints = data.ManualBlueprintSource("tripleo", [
        'tripleo-common-enhance-list-roles-action',
        'tripleo-common-list-available-roles-action',
        'tripleo-common-select-roles-workflow', 'update-roles-action',
        'validate-roles-networks', 'get-networks-action',
        'update-networks-action'
    ],
                                                    default_labels=['RFE'])

    board_manager = boards.BoardManager(config['trello'], BOARD_NAME)

    # add DFG-specific customizations to the board
    # add labels needed for our purposes
    # there are 11 label color options available
    # yellow, purple, blue, red, green, orange,
    # black, sky, pink, lime, null

    # Warning Status Labels (Red)
    # These labels denote something impeding progress
    board_manager.add_labels_by_color("red",
                                      ['UNTRIAGED', 'BLOCKED', 'CI-BLOCKED'])
    # Type Labels (Black)
    board_manager.add_labels_by_color("black", ["RFE", "Bug"])

    # Unplanned Work Labels (Orange)
    board_manager.add_labels_by_color("orange", ["Unplanned"])

    # Sprint Labels (Purple)
    board_manager.add_labels_by_color(
        "purple", ["Sprint 1", "Sprint 2", "Sprint 3", "Sprint 4"])

    # add the sources of external artifacts
    board_manager.sources.append(bug_backlog)
    board_manager.sources.append(open_untriaged_bzs)
    board_manager.sources.append(rfe_backlog)
    board_manager.sources.append(tripleo_blueprints)

    # execute the board manager logic
    board_manager.run()