示例#1
0
def get_hooks(hooks_list: List[str]) -> RepokidHooks:
    """
    Output should be a dictionary with keys as the names of hooks and values as a list of functions (in order) to call

    Args:
        hooks_list: A list of paths to load hooks from

    Returns:
        dict: Keys are hooks by name (AFTER_SCHEDULE_REPO) and values are a list of functions to execute
    """
    # hooks is a temporary dictionary of priority/RepokidHook tuples
    hooks: DefaultDict[str, List[Tuple[
        int, RepokidHook]]] = collections.defaultdict(list)

    for hook in hooks_list:
        module = import_string(hook)
        # get members retrieves all the functions from a given module
        all_funcs = inspect.getmembers(module, inspect.isfunction)
        # first argument is the function name (which we don't need)
        for (_, func) in all_funcs:
            # we only look at functions that have been decorated with _implements_hook
            if hasattr(func, "_implements_hook"):
                h: Tuple[int,
                         RepokidHook] = (func._implements_hook["priority"],
                                         func)
                # append to the dictionary in whatever order we see them, we'll sort later. Dictionary value should be
                # a list of tuples (priority, function)
                hooks[func._implements_hook["hook_name"]].append(h)

    # sort by priority
    for k in hooks.keys():
        hooks[k] = sorted(hooks[k], key=lambda priority: int(priority[0]))
    # get rid of the priority - we don't need it anymore
    # save to a new dict that conforms to the RepokidHooks spec
    final_hooks: RepokidHooks = RepokidHooks()
    for k in hooks.keys():
        final_hooks[k] = [func_tuple[1] for func_tuple in hooks[k]]

    return final_hooks
示例#2
0
    def test_repo_all_roles(
        self,
        mock_time,
        mock_repo_role,
        mock_iam_datasource_seed,
        mock_aa_datasource,
        mock_role_list_fetch_all,
        mock_role_list_from_ids,
        mock_call_hooks,
    ):
        hooks = RepokidHooks()
        mock_iam_datasource_seed.return_value = [
            "AROAABCDEFGHIJKLMNOPA",
            "AROAABCDEFGHIJKLMNOPB",
            "AROAABCDEFGHIJKLMNOPC",
        ]
        roles = RoleList(
            [
                Role(
                    **{
                        "Arn": "arn:aws:iam::123456789012:role/ROLE_A",
                        "RoleId": "AROAABCDEFGHIJKLMNOPA",
                        "Active": True,
                        "RoleName": "ROLE_A",
                        "RepoScheduled": 100,
                        "CreateDate": datetime.datetime.now()
                        - datetime.timedelta(days=100),
                    }
                ),
                Role(
                    **{
                        "Arn": "arn:aws:iam::123456789012:role/ROLE_B",
                        "RoleId": "AROAABCDEFGHIJKLMNOPB",
                        "Active": True,
                        "RoleName": "ROLE_B",
                        "RepoScheduled": 0,
                        "CreateDate": datetime.datetime.now()
                        - datetime.timedelta(days=100),
                    }
                ),
                Role(
                    **{
                        "Arn": "arn:aws:iam::123456789012:role/ROLE_C",
                        "RoleId": "AROAABCDEFGHIJKLMNOPC",
                        "Active": True,
                        "RoleName": "ROLE_C",
                        "RepoScheduled": 5,
                        "CreateDate": datetime.datetime.now()
                        - datetime.timedelta(days=100),
                    }
                ),
            ]
        )

        # time is past ROLE_C but before ROLE_A
        mock_time.return_value = 10

        mock_role_list_from_ids.return_value = RoleList(
            [
                roles[0],
                roles[1],
                roles[2],
            ]
        )
        mock_repo_role.return_value = None

        # repo all roles in the account, should call repo with all roles
        repokid.commands.repo._repo_all_roles("", {}, hooks, scheduled=False)
        # repo only scheduled, should only call repo role with role C
        repokid.commands.repo._repo_all_roles("", {}, hooks, scheduled=True)

        assert mock_repo_role.mock_calls == [
            call(hooks, commit=False, scheduled=False),
            call(hooks, commit=False, scheduled=False),
            call(hooks, commit=False, scheduled=False),
            call(hooks, commit=False, scheduled=True),
        ]

        assert mock_call_hooks.mock_calls == [
            call(
                hooks,
                "BEFORE_REPO_ROLES",
                {"account_number": "", "roles": roles},
            ),
            call(
                hooks,
                "AFTER_REPO_ROLES",
                {"account_number": "", "roles": roles, "errors": []},
            ),
            call(
                hooks,
                "BEFORE_REPO_ROLES",
                {"account_number": "", "roles": RoleList([roles[2]])},
            ),
            call(
                hooks,
                "AFTER_REPO_ROLES",
                {
                    "account_number": "",
                    "roles": RoleList([roles[2]]),
                    "errors": [],
                },
            ),
        ]