"""Translate terraform to cypher.""" import argparse import glob import cypher import hcl2 def main(): """Entrypoint.""" parser = argparse.ArgumentParser() parser.add_argument( 'dir', help='location of terraform-infra directory' ) parser.add_argument( '-f', action='store_true', help='delete existing data' ) args = parser.parse_args() reset_db = args.f terraform_dir = args.dir users_dir = f'{terraform_dir}/prod/iam/users' users = read_users(users_dir) groups_dir = f'{terraform_dir}/prod/iam/groups' groups = read_groups(groups_dir) if reset_db: print(cypher.FULL_RESET) # create employee nodes create_user_query = [] for user in users: create_user_query.append( cypher.EMPLOYEE_NODE.format( name=user['name'], username=user.get('username'), role=user.get('role', 'Unknown'), company=user.get('company') ) ) print('CREATE ' + ','.join(create_user_query) + ' RETURN null;') # create groups, find app families app_families = set() create_group_query = [] for group in groups: create_group_query.append(cypher.GROUP_NODE.format(name=group['name'])) app_families.update(group['app_families']) print('CREATE ' + ','.join(create_group_query) + ' RETURN null;') # create app family nodes create_app_family_query = [] for family in app_families: create_app_family_query.append(cypher.APP_FAMILY_NODE.format(name=family)) # noqa:E501 print('CREATE ' + ','.join(create_app_family_query) + ' RETURN null;') # connect group and app families to users for group in groups: for app_family in group['app_families']: print( cypher.CONNECT_GROUP_TO_FAMILY.format( app_family_name=app_family, group_name=group['name'] ) ) for username in group['usernames']: print( cypher.CONNECT_GROUP_TO_EMPLOYEE.format( username=username, group_name=group['name'] ) ) # connect employees to their manager(s) for user in users: for manager in user['managers']: print( cypher.CONNECT_MANAGERS.format( manager_name=manager, employee_username=user['username'] ) ) def read_users(directory): """Turn users in terraform into objects.""" files = glob.glob(f'{directory}/**/variables.tf', recursive=True) variable_names = ( 'users_with_console_access', 'users_without_console_access' ) users = [] for filename in files: with open(filename, 'r') as f: data = hcl2.load(f) for var_name in variable_names: users += sum([ x[var_name]['default'] for x in data['variable'] if var_name in x ], []) # sanitize user data for user in users: user['managers'] = user['manager'].split('/') if user['manager'] else [] # noqa:E501 user['role'] = user['role'].title() # group data to find managers with no username all_names = set() manager_names = set() for user in users: manager_names.update(user['managers']) all_names.add(user['name']) # add "missing" managers to user list for manager in manager_names: if manager not in all_names: users.append({'name': manager, 'managers': []}) return users def read_groups(directory): """Turn groups in terraform into objects.""" files = glob.glob(f'{directory}/**/main.tf') groups = [] for filename in files: with open(filename, 'r') as f: data = hcl2.load(f) raw_groups = [ x['group_with_attachments'] for x in data.get('module', []) if 'group_with_attachments' in x ] for group in raw_groups: groups.append({ 'name': group['group_name'], 'usernames': group['users'], 'app_families': group['application_families_to_access'] }) return groups if __name__ == '__main__': main()