Skip to content

Commit

Permalink
inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
t_watts committed Oct 19, 2020
0 parents commit 6c2bed9
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.json
settings.py
88 changes: 88 additions & 0 deletions get_folders.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import subprocess
import json
from settings import ORGANIZATION_ID

FOLDER_LIST_CMD = 'gcloud resource-manager folders list --format json'
FOLDER_IAM_CMD = 'gcloud resource-manager folders get-iam-policy --format json'

def get_reverse_path(folder_id, path):
displayName = folders[folder_id]['displayName']
parent = folders[folder_id]['parent']

parts = parent.split('/')
type = parts[0]
parent_id = parts[1]
if type == 'folders':
return get_reverse_path(folder_id=parent_id,
path=(path + '/' + displayName))
else:
return path + '/' + displayName
return parent_id


def get_proper_path(reverse_path):
parts = reverse_path.split('/')
parts.reverse()

path = ''
for part in parts:
if part:
path = path + '/' + part

return path


def get_path(folder_id):
displayName = folders[folder_id]['displayName']
parent = folders[folder_id]['parent']

parts = parent.split('/')
type = parts[0]
parent_id = parts[1]
if type != 'folders':
return '/' + displayName

parent_path = folders[parent_id].get('path')
if parent_path:
return parent_path + '/' + displayName

reverse_path = get_reverse_path(folder_id=folder_id, path='')
return get_proper_path(reverse_path=reverse_path)


def get_folders(folder_id,
type_flag='--folder'):

list_cmd = FOLDER_LIST_CMD + ' ' + type_flag + '=' + str(folder_id)
folder_list = json.loads(subprocess.check_output(list_cmd,
shell=True,
stderr=subprocess.STDOUT))

for folder in folder_list:
name = folder['name']
id = name.split('/')[1]
iam_cmd = FOLDER_IAM_CMD + ' ' + id
folder['perm'] = json.loads(subprocess.check_output(iam_cmd,
shell=True,
stderr=subprocess.STDOUT))
folders[id] = folder
get_folders(folder_id=id)

return folders


def add_paths():
for folder_id in folders:
folder = folders[folder_id]
# reverse_path = get_reverse_path(folder_id=folder_id, path='')
folder['path'] = get_path(folder_id=folder_id)


folders = {}
folders = get_folders(folder_id=ORGANIZATION_ID,
type_flag='--organization')

add_paths()

with open('folders.json', 'w') as outfile:
json.dump(folders, outfile, ensure_ascii=False)
53 changes: 53 additions & 0 deletions get_projects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import subprocess
import json
from settings import APPS_SCRIPT_FOLDER_ID, EXCLUDED_PROJECTS

IAM_POLICY_CMD = 'gcloud projects get-iam-policy --format json'

def init_projects():
projects = {}
project_list_cmd = 'gcloud projects list --format json'

print('initializing projects')
proj_list = json.loads(subprocess.check_output(project_list_cmd,
shell=True,
stderr=subprocess.STDOUT))
for proj in proj_list:
project_id = proj['projectId']
if proj['parent']['id'] != APPS_SCRIPT_FOLDER_ID:
projects[project_id] = {
'project': proj
}
return projects


def write_projects(projects):
with open('projects.json', 'w') as outfile:
json.dump(projects, outfile, ensure_ascii=False)


def read_projects():
try:
with open('projects.json', 'r') as jsonfile:
return json.load(jsonfile)
except Exception:
projects = init_projects()
write_projects(projects=projects)
return projects


def get_iam_policy(project_id):
if project_id not in EXCLUDED_PROJECTS:
get_iam_policy_cmd = IAM_POLICY_CMD + ' ' + project_id
return json.loads(subprocess.check_output(get_iam_policy_cmd,
shell=True,
stderr=subprocess.STDOUT))


projects = read_projects()
for project_id in projects:
proj = projects[project_id]
if not proj.get('iam_policy'):
print('reading iam_policy for ' + project_id)
proj['iam_policy'] = get_iam_policy(project_id=project_id)
write_projects(projects=projects)
78 changes: 78 additions & 0 deletions owner_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import json
import time
import pandas as pd

def get_entry(member, role, project):
parts = member.split(':')
type = parts[0]
email = parts[1]

entry = {
'project': project,
'role': role,
'type': type,
'email': email
}

if project['parent']['type'] == 'folder':
parent_id = project['parent']['id']
folder = folders.get(parent_id)
entry['project']['parent']['folder'] = folder['displayName']
entry['project']['parent']['path'] = folder['path']

return entry


projects_by_user = {}
entries = []
folders = {}

df = pd.DataFrame()

with open('folders.json', 'r') as jsonfile:
folders = json.load(jsonfile)

with open('projects.json', 'r') as jsonfile:
projects = json.load(jsonfile)

for project_id in projects.keys():
proj = projects[project_id]

try:
for binding in proj['iam_policy']['bindings']:
for member in binding['members']:
entry = get_entry(member=member,
role=binding['role'],
project=proj['project'])


entry_df = pd.json_normalize(entry)
entries.append(entry_df)

#local_part = entry['email'].split('@')[0].lower()
#if not projects_by_user.get(local_part):
# projects_by_user[local_part] = []

#projects_by_user[local_part].append(entry)
except:
pass

#print(json.dumps(projects_by_user))
df = df.append(other=entries)

# get rid of the .'s in the column names created by json_normalize
df.columns = df.columns.str.replace(r".", "_")
df.columns = df.columns.str.replace("-", "_")

# add the date of the audit so we can create a time series
df['audit_time'] = pd.Timestamp.now().isoformat()

# convert all field values to string type
df = df.astype(str)

# workaround for pandas v1.1.1, due to the fact that astype(str) will convert a np.nan to the literal string 'nan'....
# so we'll just flip it back to a none type....
df = df.replace(['nan'], [None])

#output to row delimited json
df.to_json(path_or_buf='owners_nldj.json',orient='records', lines=True, date_format='iso')
10 changes: 10 additions & 0 deletions settings.default
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# the org id for the domain
# found at Google Cloud Platform -> [Select Domain] -> IAM & Admin -> Settings
ORGANIZATION_ID = ''

# apps script project id.
# create a new app script project at script.google.com
APPS_SCRIPT_FOLDER_ID = ''

# projects to exclude in the audit
EXCLUDED_PROJECTS = []

0 comments on commit 6c2bed9

Please sign in to comment.