def run(dry_run): users = queries.get_users() single_path_ok = validate_users_single_path(users) gpg_ok = validate_users_gpg_key(users) ok = single_path_ok and gpg_ok if not ok: sys.exit(1)
def run(dry_run, thread_pool_size=10): users = queries.get_users() single_path_ok = validate_users_single_path(users) gpg_ok = validate_users_gpg_key(users) github_ok = validate_users_github(users, thread_pool_size) ok = single_path_ok and gpg_ok and github_ok if not ok: sys.exit(1)
def init_users(): app_int_users = queries.get_users() users = defaultdict(list) for user in app_int_users: u = user['org_username'] p = 'data' + user['path'] users[u].append(p) return [{'username': username, 'paths': paths} for username, paths in users.items()]
def get_desired_state(slack_map): gqlapi = gql.get_api() roles = gqlapi.query(ROLES_QUERY)['roles'] all_users = queries.get_users() desired_state = [] for r in roles: for p in r['permissions']: if p['service'] != 'slack-usergroup': continue workspace = p['workspace'] managed_usergroups = workspace['managedUsergroups'] if managed_usergroups is None: continue workspace_name = workspace['name'] usergroup = p['handle'] description = p['description'] if usergroup not in managed_usergroups: logging.warning( '[{}] usergroup {} not in managed usergroups {}'.format( workspace_name, usergroup, managed_usergroups)) continue slack = slack_map[workspace_name]['slack'] ugid = slack.get_usergroup_id(usergroup) user_names = [get_slack_username(u) for u in r['users']] slack_usernames_pagerduty = \ get_slack_usernames_from_pagerduty(p['pagerduty'], all_users, usergroup) user_names.extend(slack_usernames_pagerduty) slack_usernames_repo = get_slack_usernames_from_owners( p['ownersFromRepos'], all_users, usergroup) user_names.extend(slack_usernames_repo) users = slack.get_users_by_names(user_names) channel_names = [] if p['channels'] is None else p['channels'] channels = slack.get_channels_by_names(channel_names) desired_state.append({ "workspace": workspace_name, "usergroup": usergroup, "usergroup_id": ugid, "users": users, "channels": channels, "description": description, }) return desired_state
def init_users(): app_int_users = queries.get_users(refs=True) users = defaultdict(set) for user in app_int_users: u = user['org_username'] p = 'data' + user['path'] users[u].add(p) for r in user.get('requests'): users[u].add('data' + r['path']) for q in user.get('queries'): users[u].add('data' + q['path']) return [{'username': username, 'paths': paths} for username, paths in users.items()]
def validate_repos_and_admins(jjb): jjb_repos = jjb.get_repos() app_int_repos = queries.get_repos() missing_repos = [r for r in jjb_repos if r not in app_int_repos] if missing_repos: msg = 'repos are missing from codeComponents: ' + missing_repos raise Exception(msg) jjb_admins = jjb.get_admins() app_int_users = queries.get_users() app_int_bots = queries.get_bots() github_usernames = \ [u.get('github_username') for u in app_int_users] + \ [b.get('github_username') for b in app_int_bots] unknown_admins = [a for a in jjb_admins if a not in github_usernames] if unknown_admins: logging.warning('user file not found for: {}'.format(unknown_admins))
def validate_repos_and_admins(jjb): jjb_repos = jjb.get_repos() app_int_repos = queries.get_repos() missing_repos = [r for r in jjb_repos if r not in app_int_repos] for r in missing_repos: logging.error('repo is missing from codeComponents: {}'.format(r)) jjb_admins = jjb.get_admins() app_int_users = queries.get_users() app_int_bots = queries.get_bots() github_usernames = \ [u.get('github_username') for u in app_int_users] + \ [b.get('github_username') for b in app_int_bots] unknown_admins = [a for a in jjb_admins if a not in github_usernames] for a in unknown_admins: logging.warning('admin is missing from users: {}'.format(a)) if missing_repos: sys.exit(1)
def init_users(): app_int_users = queries.get_users(refs=True) users = defaultdict(list) for user in app_int_users: u = user["org_username"] item = {"type": PathTypes.USER, "path": "data" + user["path"]} users[u].append(item) for r in user.get("requests"): item = {"type": PathTypes.REQUEST, "path": "data" + r["path"]} users[u].append(item) for q in user.get("queries"): item = {"type": PathTypes.QUERY, "path": "data" + q["path"]} users[u].append(item) for g in user.get("gabi_instances"): item = {"type": PathTypes.GABI, "path": "data" + g["path"]} users[u].append(item) return [{"username": username, "paths": paths} for username, paths in users.items()]
def validate_repos_and_admins(jjb, additional_repo_urls): jjb_repos = jjb.get_repos() jjb_repos.update(additional_repo_urls) app_int_repos = queries.get_repos() missing_repos = [r for r in jjb_repos if r not in app_int_repos] for r in missing_repos: logging.error(f"repo is missing from codeComponents: {r}") jjb_admins = jjb.get_admins() app_int_users = queries.get_users() app_int_bots = queries.get_bots() external_users = queries.get_external_users() github_usernames = ([u.get("github_username") for u in app_int_users] + [b.get("github_username") for b in app_int_bots] + [u.get("github_username") for u in external_users]) unknown_admins = [a for a in jjb_admins if a not in github_usernames] for a in unknown_admins: logging.warning("admin is missing from users: {}".format(a)) if missing_repos: sys.exit(1)
def init_users(): app_int_users = queries.get_users(refs=True) users = defaultdict(list) for user in app_int_users: u = user['org_username'] item = {'type': PathTypes.USER, 'path': 'data' + user['path']} users[u].append(item) for r in user.get('requests'): item = {'type': PathTypes.REQUEST, 'path': 'data' + r['path']} users[u].append(item) for q in user.get('queries'): item = {'type': PathTypes.QUERY, 'path': 'data' + q['path']} users[u].append(item) for g in user.get('gabi_instances'): item = {'type': PathTypes.GABI, 'path': 'data' + g['path']} users[u].append(item) return [{ 'username': username, 'paths': paths } for username, paths in users.items()]
def ai_get_user(self, _, args): """Show a single user from app-interface""" if len(args) < 1: return "Must supply a search argument" term = args[0].lower() server = self.config['gql_server'] token = self.config['gql_token'] gql.init(server, token) users = queries.get_users() found = None for user in users: if term == user['org_username'].lower(): found = user break if not found: return f"User {term} not found." return {'user': found}
def run(dry_run): settings = queries.get_app_interface_settings() accounts = queries.get_aws_accounts() users = queries.get_users() state = State( integration=QONTRACT_INTEGRATION, accounts=accounts, settings=settings ) mails = smtp_client.get_mails( criteria='SUBJECT "Sentry Access Request"', folder='[Gmail]/Sent Mail', settings=settings ) user_names = get_sentry_users_from_mails(mails) if not dry_run: slack = init_slack_workspace(QONTRACT_INTEGRATION, init_usergroups=False) for user_name in user_names: guesses = guess_user(user_name, users) if not guesses: logging.debug(f'no users guessed for {user_name}') continue slack_username = \ guesses[0].get('slack_username') or guesses[0]['org_username'] if state.exists(slack_username): continue logging.info(['help_user', slack_username]) if not dry_run: state.add(slack_username) slack.chat_post_message( f'yo <@{slack_username}>! it appears that you have ' + 'requested access to a project in Sentry. ' + 'access is managed automatically via app-interface. ' 'checkout https://url.corp.redhat.com/sentry-help')
def get_desired_state(slack_map, pagerduty_map): """ Get the desired state of Slack usergroups. :param slack_map: Slack data from app-interface :type slack_map: dict :param pagerduty_map: PagerDuty instance data :type pagerduty_map: reconcile.utils.pagerduty_api.PagerDutyMap :return: current state data, keys are workspace -> usergroup (ex. state['coreos']['app-sre-ic'] :rtype: dict """ permissions = queries.get_permissions_for_slack_usergroup() all_users = queries.get_users() desired_state = {} for p in permissions: if p["service"] != "slack-usergroup": continue skip_flag = p["skip"] if skip_flag: continue workspace = p["workspace"] managed_usergroups = workspace["managedUsergroups"] if managed_usergroups is None: continue workspace_name = workspace["name"] usergroup = p["handle"] description = p["description"] if usergroup not in managed_usergroups: raise KeyError(f"[{workspace_name}] usergroup {usergroup} \ not in managed usergroups {managed_usergroups}") slack = slack_map[workspace_name]["slack"] ugid = slack.get_usergroup_id(usergroup) all_user_names = [ get_slack_username(u) for r in p["roles"] for u in r["users"] ] slack_usernames_pagerduty = get_slack_usernames_from_pagerduty( p["pagerduty"], all_users, usergroup, pagerduty_map) all_user_names.extend(slack_usernames_pagerduty) slack_usernames_repo = get_slack_usernames_from_owners( p["ownersFromRepos"], all_users, usergroup) all_user_names.extend(slack_usernames_repo) slack_usernames_schedule = get_slack_usernames_from_schedule( p["schedule"]) all_user_names.extend(slack_usernames_schedule) user_names = list(set(all_user_names)) users = slack.get_users_by_names(user_names) channel_names = [] if p["channels"] is None else p["channels"] channels = slack.get_channels_by_names(channel_names) try: desired_state[workspace_name][usergroup]["users"].update(users) except KeyError: desired_state.setdefault(workspace_name, {})[usergroup] = { "workspace": workspace_name, "usergroup": usergroup, "usergroup_id": ugid, "users": users, "channels": channels, "description": description, } return desired_state
def collect_to(to): """Collect audience to send email to from to object Arguments: to {dict} -- AppInterfaceEmailAudience_v1 object Raises: AttributeError: Unknown alias Returns: set -- Audience to send email to """ audience = set() aliases = to.get('aliases') if aliases: for alias in aliases: if alias == 'all-users': users = queries.get_users() to['users'] = users elif alias == 'all-service-owners': services = queries.get_apps() to['services'] = services else: raise AttributeError(f"unknown alias: {alias}") services = to.get('services') if services: for service in services: service_owners = service.get('serviceOwners') if not service_owners: continue for service_owner in service_owners: audience.add(service_owner['email']) clusters = to.get('clusters') if clusters: # TODO: implement this for cluster in clusters: pass namespaces = to.get('namespaces') if namespaces: # TODO: implement this for namespace in namespaces: pass aws_accounts = to.get('aws_accounts') if aws_accounts: for account in aws_accounts: account_owners = account.get('accountOwners') if not account_owners: continue for account_owner in account_owners: audience.add(account_owner['email']) roles = to.get('roles') if roles: for role in roles: users = role.get('users') if not users: continue for user in users: audience.add(user['org_username']) users = to.get('users') if users: for user in users: audience.add(user['org_username']) return audience
def collect_to(to): """Collect audience to send email to from to object Arguments: to {dict} -- AppInterfaceEmailAudience_v1 object Raises: AttributeError: Unknown alias Returns: set -- Audience to send email to """ audience = set() aliases = to.get("aliases") if aliases: for alias in aliases: if alias == "all-users": users = queries.get_users() to["users"] = users elif alias == "all-service-owners": services = queries.get_apps() to["services"] = services else: raise AttributeError(f"unknown alias: {alias}") services = to.get("services") if services: for service in services: service_owners = service.get("serviceOwners") if not service_owners: continue for service_owner in service_owners: audience.add(service_owner["email"]) # TODO: implement clusters and namespaces aws_accounts = to.get("aws_accounts") if aws_accounts: for account in aws_accounts: account_owners = account.get("accountOwners") if not account_owners: continue for account_owner in account_owners: audience.add(account_owner["email"]) roles = to.get("roles") if roles: for role in roles: users = role.get("users") if not users: continue for user in users: audience.add(user["org_username"]) users = to.get("users") if users: for user in users: audience.add(user["org_username"]) return audience