in tools/custom-role-manager/main.py [0:0]
def process_role(logger, service, role, output_terraform=False):
global TERRAFORM_PRE, TERRAFORM_TEMPLATES, TERRAFORM_RESOURCES
if 'source' not in role:
logger.error('Source not defined for role.', extra={'role': role['id']})
sys.exit(2)
role_exists = True
role_name = '%s/roles/%s' % (role['parent'], role['id'])
if role['parent'].startswith('organizations/'):
role_request = service.organizations().roles().get(name=role_name)
else:
role_request = service.projects().roles().get(name=role_name)
try:
role_response = role_request.execute()
except googleapiclient.errors.HttpError as e:
if e.resp.status == 404 or e.resp.status == 400:
role_exists = False
else:
raise e
if not isinstance(role['source'], list):
sources = [role['source']]
else:
sources = role['source']
permissions_to_grant = []
for source in sources:
if source.startswith('roles/'):
source_request = service.roles().get(name=source)
source_response = source_request.execute()
for p in source_response['includedPermissions']:
permissions_to_grant = process_permission(
logger, role, permissions_to_grant, p)
if source.startswith('//'):
next_page_token = None
while True:
permissions = service.permissions().queryTestablePermissions(
body={
'fullResourceName': source,
'pageToken': next_page_token
}).execute()
for p in permissions['permissions']:
if ('stage' not in p or p['stage'] != 'DEPRECATED') and (
'customRolesSupportLevel' not in p or
p['customRolesSupportLevel'] != 'NOT_SUPPORTED'):
permissions_to_grant = process_permission(
logger, role, permissions_to_grant, p['name'])
else:
if 'stage' in p and p['stage'] == 'DEPRECATED':
logger.info('Permission %s is deprecated.' %
(p['name']),
extra={
'permission': p['name'],
})
if 'customRolesSupportLevel' in p and p[
'customRolesSupportLevel'] == 'NOT_SUPPORTED':
logger.info(
'Permission %s is not supported in custom roles.' %
(p['name']),
extra={
'permission': p['name'],
})
if 'nextPageToken' in permissions:
next_page_token = permissions['nextPageToken']
else:
break
if 'append' in role:
for permission in role['append']:
permissions_to_grant.append(permission)
logger.info('%d permissions determined for role %s.' %
(len(permissions_to_grant), role['id']),
extra={
'role': role['id'],
'permissions': permissions_to_grant
})
if output_terraform:
if not TERRAFORM_PRE:
print(TERRAFORM_TEMPLATES['pre'])
TERRAFORM_PRE = True
organization_id = ''
project_id = ''
terraform_id = role['tfId'] if 'tfId' in role else role['id']
tf_template = 'project'
if 'organizations/' in role['parent']:
organization_id = role['parent'].replace('organizations/', '')
tf_template = 'organization'
TERRAFORM_RESOURCES[
terraform_id] = 'google_organization_iam_custom_role.%s' % (
terraform_id)
else:
project_id = role['parent'].replace('projects/', '')
TERRAFORM_RESOURCES[
terraform_id] = 'google_project_iam_custom_role.%s' % (
terraform_id)
role_id = role['id']
role_title = role['title'] if 'title' in role else ''
role_description = role['description'] if 'description' in role else ''
role_permissions = str(permissions_to_grant).replace('\'', '"')
print(TERRAFORM_TEMPLATES[tf_template].format(
role_id=role_id,
terraform_id=terraform_id,
organization_id=organization_id,
project_id=project_id,
role_title=role_title.replace('"', '\\"'),
role_description=role_description.replace('"', '\\"'),
role_permissions=role_permissions))
elif not role_exists:
logger.info('Creating role: %s' % (role['id']),
extra={
'role': role['id'],
})
create_role_request_body = {
'roleId': role['id'],
'role': {
'title': role['title'],
'description': role['description'],
'includedPermissions': permissions_to_grant,
'stage': role['stage'],
}
}
if role['parent'].startswith('organizations/'):
role_create_request = service.organizations().roles().create(
parent=role['parent'], body=create_role_request_body)
else:
role_create_request = service.projects().roles().create(
parent=role['parent'], body=create_role_request_body)
role_create_response = role_create_request.execute()
logger.warning('Role created: %s' % (role['id']),
extra={
'role': role['id'],
'role_name': role_create_response['name'],
'etag': role_create_response['etag']
})
elif not output_terraform:
if 'includedPermissions' not in role_response:
role_response['includedPermissions'] = []
added_permissions = set(permissions_to_grant) - set(
role_response['includedPermissions'])
removed_permissions = set(
role_response['includedPermissions']) - set(permissions_to_grant)
if len(added_permissions) > 0 or len(removed_permissions) > 0:
logger.info('Permissions changed for role: %s' % (role['id']),
extra={
'role': role['id'],
'role_name': role_response['name'],
'added_permissions': list(added_permissions),
'removed_permissions': list(removed_permissions),
'etag': role_response['etag']
})
patch_role_request_body = {
'name': role_response['name'],
'title': role['title'],
'description': role['description'],
'includedPermissions': permissions_to_grant,
'stage': role['stage'],
'etag': role_response['etag']
}
if role['parent'].startswith('organizations/'):
role_patch_request = service.organizations().roles().patch(
name=role_response['name'], body=patch_role_request_body)
else:
role_patch_request = service.projects().roles().patch(
name=role_response['name'], body=patch_role_request_body)
role_patch_response = role_patch_request.execute()
logger.warning('Role updated: %s' % (role['id']),
extra={
'role': role['id'],
'role_name': role_patch_response['name'],
'added_permissions': list(added_permissions),
'removed_permissions': list(removed_permissions),
'etag': role_patch_response['etag']
})
else:
logger.info('Permissions unchanged for role: %s' % (role['id']),
extra={
'role': role['id'],
'role_name': role_response['name'],
'etag': role_response['etag']
})