Beispiel #1
0
def add_pr_labels(pull, labels):
    """Adds PR labels"""
    if not labels or Config().DRY_RUN:
        return
    print("Add PR labels:", labels)
    for label in labels:
        pull.add_to_labels(label)
Beispiel #2
0
def set_pr_labels(pull, labels):
    """Sets new PR labels (all previously set labels are removed)"""
    if not labels or Config().DRY_RUN:
        return
    print("Set PR labels:", labels)
    # set_labels() should accept list but fails with empty "AssertionError:"
    pull.set_labels(labels)
Beispiel #3
0
def _test():
    """Test and debug"""
    Config(cli_args=["DRY_RUN=True"])
    dev_emails = get_dev_emails()
    print("dev_emails:", dev_emails)

    gh_api = GithubOrgApi()
    gh_api.get_org_emails()
Beispiel #4
0
 def __init__(self):
     self._cfg = Config()
     self.server = Server(self._cfg.LDAP_SERVER, get_info=ALL)
     self.connection = Connection(self.server,
                                  user=self._cfg.LDAP_USER,
                                  password=self._cfg.LDAP_PASSWORD,
                                  auto_bind=True)
     self.connection.bind()
Beispiel #5
0
 def __init__(self):
     self._cfg = Config()
     self.github = Github(self._cfg.GITHUB_TOKEN)
     self.github_org = self.github.get_organization(self._cfg.GITHUB_ORGANIZATION)
     self.repo = self.github.get_repo(f"{self._cfg.GITHUB_ORGANIZATION}/{self._cfg.GITHUB_REPO}")
     self.github_users_by_email = {}
     self.org_members_by_login = {}
     self.members_to_remove = set()
     self.members_to_fix_name = set()
Beispiel #6
0
def remove_members(gh_api, cfg_emails, org_emails, dev_emails,
                   org_emails_no_in_ldap):
    """Checks and remove members"""
    print(
        f"\n{'=' * 10} Check accounts below and remove from the GitHub organization or "
        f"configuration {'=' * 10}")

    cfg_emails_no_in_org = sorted(cfg_emails.difference(org_emails))
    print(
        f"\nCfg developer emails - absent in GitHub organization {len(cfg_emails_no_in_org)}:",
        "; ".join(cfg_emails_no_in_org),
    )

    non_member_ignored_logins = set(Config().IGNORE_LOGINS).difference(
        set(gh_api.org_members_by_login.keys()))
    print(
        f"\nIgnored logins - absent in GitHub organization {len(non_member_ignored_logins)}:\n",
        "\n".join(non_member_ignored_logins),
    )

    org_emails_no_in_dev = sorted(org_emails.difference(dev_emails))
    print(
        f"\nOrg member emails - absent in cfg and LDAP PDLs {len(org_emails_no_in_dev)}:",
        "; ".join(org_emails_no_in_dev),
    )

    print(
        f"\nOrg member emails - absent in LDAP at all {len(org_emails_no_in_ldap)}:",
        "; ".join(sorted(org_emails_no_in_ldap)),
    )

    print("\nOrg members - no real name:")
    members_to_fix_name = sorted(gh_api.members_to_fix_name,
                                 key=lambda member: member.email)
    print_users(members_to_fix_name)
    print(
        "\nOrg member emails - no real name:",
        "; ".join([member.email.lower() for member in members_to_fix_name]),
    )

    print("\nOrg members - no Intel emails:")
    print_users(gh_api.members_to_remove)

    gh_api.remove_users(org_emails_no_in_ldap | gh_api.members_to_remove)
Beispiel #7
0
def get_dev_emails():
    """
    Read a file with developer emails. Supported email formats
    [email protected]
    Import from Outlook: Last_name, First_name <*****@*****.**>
    """
    re_email = re.compile(r".+<(.+)>")
    emails = set()
    cfg = Config()
    with open(cfg.properties["EMAILS_FILE_PATH"]) as file_obj:
        for line in file_obj:
            line = line.strip().lower()
            if not line or line.startswith("#"):
                continue
            re_outlook_email = re_email.match(line)
            if re_outlook_email:
                line = re_outlook_email.group(1).strip()
            if not is_intel_email(line):
                print(f'Wrong email in {cfg.properties["EMAILS_FILE_PATH"]}: {line}')
                continue
            emails.add(line)
    return emails
Beispiel #8
0
def is_user_ignored(user):
    """Checks that user should be ignored"""
    if is_valid_user(user) and user.login.lower() not in Config().IGNORE_LOGINS:
        return False
    return True
Beispiel #9
0
def get_label_by_team_name_map(team_name):
    """Generates label by PR reviwer team name using config map"""
    return Config().TEAM_TO_LABEL.get(team_name)
Beispiel #10
0
def main():
    """The main entry point function"""
    arg_parser = ArgumentParser()
    arg_parser.add_argument(
        "--cfg-file",
        metavar="PATH",
        default=Config.default_cfg_path,
        help=f"Path to json configuration file, e.g. {Config.default_cfg_path}",
    )
    arg_parser.add_argument(
        "--pr", metavar="NUMBER", help="Get GitHub pull request with the number"
    )
    arg_parser.add_argument(
        "--pr-state",
        default="open",
        choices=["open", "closed"],
        help="Set GitHub pull request state",
    )
    arg_parser.add_argument(
        "--newer", metavar="MINUTES", help="Get newly created GitHub pull request only"
    )
    arg_parser.add_argument(
        "--check-commits",
        action="store_true",
        help="Check and compare git commit email with GitHub account email",
    )
    args, unknown_args = arg_parser.parse_known_args()

    Config(args.cfg_file, unknown_args)
    gh_api = github_api.GithubOrgApi()

    if args.pr:
        pulls = [gh_api.repo.get_pull(int(args.pr))]
    else:
        pulls = gh_api.repo.get_pulls(state=args.pr_state)
        print(f"\nPRs count ({args.pr_state}):", pulls.totalCount)

    if args.newer:
        pr_created_after = (
            datetime.datetime.now() - datetime.timedelta(minutes=int(args.newer))
        ).astimezone()
        print("Checking PRs created after:", pr_created_after)

    non_org_intel_pr_users = set()
    non_org_pr_users = set()
    wrong_pulls = {}

    for pull in pulls:
        pr_created_at = pull.created_at.replace(tzinfo=datetime.timezone.utc).astimezone()
        if args.newer and pr_created_at <= pr_created_after:
            print(f"\nIGNORE: {get_pr_info_str(pull)}")
            continue

        print(f"\n{get_pr_info_str(pull)}")
        if args.check_commits:
            wrong_commits = get_wrong_commits(pull)
            if wrong_commits:
                wrong_pulls[pull.number] = wrong_commits
        else:
            update_labels(gh_api, pull, non_org_intel_pr_users, non_org_pr_users)

    if wrong_pulls:
        for pull_number, wrong_commits in wrong_pulls.items():
            print(
                f"\nERROR: Remove or replace wrong commits in the PR {pull_number}:\n   ",
                "\n    ".join(wrong_commits),
            )
        print(
            "\nAbout commit signature verification:\n    ",
            "https://docs.github.com/en/github/authenticating-to-github/"
            "managing-commit-signature-verification/about-commit-signature-verification",
        )
        sys.exit(1)

    if non_org_intel_pr_users:
        print("\nNon org user with Intel email or company:")
        github_api.print_users(non_org_intel_pr_users)
    if non_org_pr_users:
        print("\nNon org user with NO Intel email or company:")
        github_api.print_users(non_org_pr_users)
Beispiel #11
0
def main():
    """The main entry point function"""
    arg_parser = ArgumentParser()
    arg_parser.add_argument(
        "--cfg-file",
        metavar="PATH",
        default=Config.default_cfg_path,
        help=f"Path to json configuration file, e.g. {Config.default_cfg_path}",
    )
    arg_parser.add_argument("--teams",
                            action="store_true",
                            help="Check GitHub teams")
    arg_parser.add_argument("--no-ldap",
                            action="store_true",
                            help="Don't use LDAP info")
    args, unknown_args = arg_parser.parse_known_args()

    Config(args.cfg_file, unknown_args)
    gh_api = GithubOrgApi()

    if args.teams:
        gh_api.get_org_teams()
        return

    cfg_emails = get_dev_emails()
    print(f"\nCfg developer emails {len(cfg_emails)}:",
          "; ".join(sorted(cfg_emails)))

    dev_emails = set()
    dev_emails.update(cfg_emails)

    if not args.no_ldap:
        ldap_api = LdapApi()
        ldap_emails = ldap_api.get_user_emails()
        dev_emails.update(ldap_emails)
        print(f"\nLDAP developer emails {len(ldap_emails)}:",
              "; ".join(sorted(ldap_emails)))

        cfg_emails_no_in_ldap = ldap_api.get_absent_emails(cfg_emails)
        print(
            f"\nCfg developer emails - absent in LDAP at all {len(cfg_emails_no_in_ldap)}:",
            "; ".join(sorted(cfg_emails_no_in_ldap)),
        )

        cfg_ldap_inters = cfg_emails.intersection(ldap_emails)
        print(
            f"\nCfg developer emails - present in LDAP developers {len(cfg_ldap_inters)}:",
            "; ".join(sorted(cfg_ldap_inters)),
        )

    org_emails = gh_api.get_org_emails()
    print(f"\nOrg emails {len(org_emails)}:", "; ".join(sorted(org_emails)))

    org_emails_no_in_ldap = set()
    if not args.no_ldap:
        org_ldap_diff = org_emails.difference(ldap_emails)
        print(
            f"\nOrg member emails - absent in LDAP developers {len(org_ldap_diff)}:",
            "; ".join(sorted(org_ldap_diff)),
        )

        for email in org_ldap_diff:
            user_info = ldap_api.get_user_info_by_email(email)
            if user_info:
                print_user_info(user_info, InfoLevel.PDL)
            else:
                org_emails_no_in_ldap.add(email)

    org_pendig_invitation_emails = gh_api.get_org_invitation_emails()
    invite_emails = dev_emails.difference(org_emails).difference(
        org_pendig_invitation_emails)
    print(f"\nInvite emails {len(invite_emails)}:",
          "; ".join(sorted(invite_emails)))

    valid_github_users = gh_api.get_valid_github_users(invite_emails)
    gh_api.invite_users(valid_github_users)

    remove_members(gh_api, cfg_emails, org_emails, dev_emails,
                   org_emails_no_in_ldap)