Added variable gcp_org_id to gam.cfg #1891

This commit is contained in:
Ross Scroggs
2026-03-19 19:52:18 -07:00
parent e5562eb917
commit 327dd6d7e5
6 changed files with 81 additions and 41 deletions

View File

@@ -25,7 +25,7 @@ https://github.com/GAM-team/GAM/wiki
"""
__author__ = 'GAM Team <google-apps-manager@googlegroups.com>'
__version__ = '7.37.00'
__version__ = '7.38.00'
__license__ = 'Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)'
# pylint: disable=wrong-import-position
@@ -11991,20 +11991,39 @@ def _checkForExistingProjectFiles(projectFiles):
if os.path.exists(a_file):
systemErrorExit(JSON_ALREADY_EXISTS_RC, Msg.AUTHORIZATION_FILE_ALREADY_EXISTS.format(a_file, Act.ToPerform()))
def getGCPOrg(crm, login_hint, login_domain):
try:
getorg = callGAPI(crm.organizations(), 'search',
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
query=f'domain:{login_domain}',
pageSize=1, fields='organizations/name')
except (GAPI.invalidArgument, GAPI.permissionDenied) as e:
entityActionFailedExit([Ent.USER, login_hint, Ent.DOMAIN, login_domain], str(e))
try:
organization = getorg['organizations'][0]['name']
# sys.stdout.write(Msg.YOUR_ORGANIZATION_NAME_IS.format(organization))
return organization
except (KeyError, IndexError):
systemErrorExit(3, Msg.YOU_HAVE_NO_RIGHTS_TO_CREATE_PROJECTS_AND_YOU_ARE_NOT_A_SUPER_ADMIN)
def getCRMOrgId(forceSearch=False):
if not GC.Values[GC.GCP_ORG_ID] or forceSearch:
setTrueCustomerId()
_, crm = buildGAPIServiceObject(API.CLOUDRESOURCEMANAGER, None)
results = callGAPI(crm.organizations(), 'search',
query=f'directorycustomerid:{GC.Values[GC.CUSTOMER_ID]}',
pageSize=1, fields='organizations/name')
orgs = results.get('organizations')
if not orgs:
# return nothing and let calling API deal with it
# since caller knows what GCP role would serve best
return None
return orgs[0].get('name')
return GC.Values[GC.GCP_ORG_ID]
# gam info gcporgid
def doInfoGCPOrgId():
checkForExtraneousArguments()
writeStdout(f'{getCRMOrgId(forceSearch=True)}\n')
def getGCPOrgId(crm, login_hint, login_domain):
if not GC.Values[GC.GCP_ORG_ID]:
try:
results = callGAPI(crm.organizations(), 'search',
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
query=f'domain:{login_domain}',
pageSize=1, fields='organizations/name')
return results['organizations'][0]['name']
except (GAPI.invalidArgument, GAPI.permissionDenied) as e:
entityActionFailedExit([Ent.USER, login_hint, Ent.DOMAIN, login_domain], str(e))
except (KeyError, IndexError):
systemErrorExit(3, Msg.YOU_HAVE_NO_RIGHTS_TO_CREATE_PROJECTS_AND_YOU_ARE_NOT_A_SUPER_ADMIN)
return GC.Values[GC.GCP_ORG_ID]
# gam create gcpfolder <String>
# gam create gcpfolder [admin <EmailAddress] folder <String>
@@ -12028,7 +12047,7 @@ def doCreateGCPFolder():
login_hint = _getValidateLoginHint(login_hint)
login_domain = getEmailAddressDomain(login_hint)
_, crm = getCRMService(login_hint)
organization = getGCPOrg(crm, login_hint, login_domain)
organization = getGCPOrgId(crm, login_hint, login_domain)
try:
result = callGAPI(crm.folders(), 'create',
throwReasons=[GAPI.INVALID_ARGUMENT, GAPI.PERMISSION_DENIED],
@@ -12074,7 +12093,7 @@ def doCreateProject():
if 'error' in status:
if status['error'].get('message', '') == 'No permission to create project in organization':
sys.stdout.write(Msg.NO_RIGHTS_GOOGLE_CLOUD_ORGANIZATION)
organization = getGCPOrg(crm, login_hint, login_domain)
organization = getGCPOrgId(crm, login_hint, login_domain)
org_policy = callGAPI(crm.organizations(), 'getIamPolicy',
resource=organization)
if 'bindings' not in org_policy:
@@ -14205,6 +14224,7 @@ def doReport():
showNoActivities = False
if usageReports:
includeServices = set()
kwargs = {}
while Cmd.ArgumentsRemaining():
myarg = getArgument()
if myarg == 'todrive':
@@ -14296,6 +14316,8 @@ def doReport():
gmailEventTypes = set(getNumberRangeList())
elif activityReports and myarg == 'userisactor':
mapAdminUsersToFilter = False
elif activityReports and myarg == 'includesensitivedata':
kwargs['includeSensitiveData'] = True
elif myarg == 'addcsvdata':
getAddCSVData(addCSVData)
elif activityReports and myarg == 'shownoactivities':
@@ -14617,7 +14639,7 @@ def doReport():
actorIpAddress=actorIpAddress, orgUnitID=orgUnitId,
startTime=startEndTime.startTime, endTime=startEndTime.endTime,
eventName=eventName, filters=pfilters, groupIdFilter=groupIdFilter,
resourceDetailsFilter=resourceDetailsFilter, maxResults=maxResults)
resourceDetailsFilter=resourceDetailsFilter, maxResults=maxResults, **kwargs)
except GAPI.badRequest:
if user != 'all':
entityUnknownWarning(Ent.USER, user, i, count)
@@ -72458,7 +72480,7 @@ def _printShowTokens(entityType, users):
throwReasons=[GAPI.PERMISSION_DENIED],
projectId=result['project'])
for ancestor in results.get('ancestor', []):
if ancestor.get('resourceId', {}).get('type') == 'organization' and ancestor.get('resourceId', {}).get('id') == GC.Values['GCP_ORG_ID']:
if ancestor.get('resourceId', {}).get('type') == 'organization' and ancestor.get('resourceId', {}).get('id') == GC.Values[GC.GCP_ORG_ID]:
result['internal'] = True
internal_projects.add(result['project'])
except GAPI.permissionDenied:
@@ -72520,8 +72542,7 @@ def _printShowTokens(entityType, users):
crm1 = buildGAPIObject('cloudresourcemanagerv1')
admin_email = _getAdminEmail()
admin_domain = getEmailAddressDomain(admin_email)
if 'GCP_ORG_ID' not in GC.Values:
GC.Values['GCP_ORG_ID'] = getGCPOrg(crm, admin_email, admin_domain).split('/')[1]
GC.Values[GC.GCP_ORG_ID] = getGCPOrgId(crm, admin_email, admin_domain).split('/')[1]
fields = ','.join(TOKENS_FIELDS_TITLES)
i, count, users = getEntityArgument(users)
for user in users:
@@ -79625,30 +79646,11 @@ def printShowTagManagerTags(users):
def printShowTagManagerPermissions(users):
printShowTagManagerObjects(users, Ent.TAGMANAGER_PERMISSION)
def getCRMOrgId():
setTrueCustomerId()
_, crm = buildGAPIServiceObject(API.CLOUDRESOURCEMANAGER, None)
results = callGAPI(crm.organizations(), 'search',
query=f'directorycustomerid:{GC.Values[GC.CUSTOMER_ID]}',
pageSize=1, fields='organizations/name')
orgs = results.get('organizations')
if not orgs:
# return nothing and let calling API deal with it
# since caller knows what GCP role would serve best
return None
return orgs[0].get('name')
def CAARoleErrorExit(caa):
sa_email = caa._http.credentials.signer_email
systemErrorExit(NO_SA_ACCESS_CONTEXT_MANAGER_EDITOR_ROLE_RC,
f'Please grant service account {sa_email} the Access Context Manager Editor role in your GCP organization.')
def normalizeCAALevelName(caa, name):
if name.startswith('accessPolicies/'):
return name
ap_name = getAccessPolicy(caa)
return f'{ap_name}/accessLevels/{name}'
def buildCAAServiceObject():
_, caa = buildGAPIServiceObject(API.ACCESSCONTEXTMANAGER, None)
return caa
@@ -79672,7 +79674,13 @@ def getAccessPolicy(caa=None):
for ap in aps:
if ap.get('title') == 'Access policy created in Cloud Identity Console':
return ap['name']
systemErrorExit(ACCESS_POLICY_ERROR_RC, ' Could not find a org level access policy. That is odd.')
systemErrorExit(ACCESS_POLICY_ERROR_RC, 'Could not find a org level access policy. That is odd.')
def normalizeCAALevelName(caa, name):
if name.startswith('accessPolicies/'):
return name
ap_name = getAccessPolicy(caa)
return f'{ap_name}/accessLevels/{name}'
CAA_OS_TYPE_MAP = {
'desktopmac': 'DESKTOP_MAC',
@@ -80189,6 +80197,7 @@ MAIN_COMMANDS_WITH_OBJECTS = {
Cmd.ARG_DRIVEFILEACL: doInfoDriveFileACLs,
Cmd.ARG_DRIVELABEL: doInfoDriveLabels,
Cmd.ARG_INSTANCE: doInfoInstance,
Cmd.ARG_GCPORGID: doInfoGCPOrgId,
Cmd.ARG_GROUP: doInfoGroups,
Cmd.ARG_GROUPMEMBERS: doInfoGroupMembers,
Cmd.ARG_INBOUNDSSOASSIGNMENT: doInfoInboundSSOAssignment,

View File

@@ -177,6 +177,8 @@ ENFORCE_EXPANSIVE_ACCESS = 'enforce_expansive_access'
EVENT_MAX_RESULTS = 'event_max_results'
# Path to extra_args.txt
EXTRA_ARGS = 'extra_args'
# Google Cloud Project Organization ID
GCP_ORG_ID = 'gcp_org_id'
# Gmail CSE certificates directory
GMAIL_CSE_INCERT_DIR = 'gmail_cse_incert_dir'
# Gmail CSE KACL wrapped key files
@@ -403,6 +405,7 @@ Defaults = {
ENABLE_GCLOUD_REAUTH: FALSE,
EVENT_MAX_RESULTS: '250',
EXTRA_ARGS: '',
GCP_ORG_ID: '',
GMAIL_CSE_INCERT_DIR: '',
GMAIL_CSE_INKEY_DIR: '',
INPUT_DIR: '.',
@@ -577,6 +580,7 @@ VAR_INFO = {
ENABLE_GCLOUD_REAUTH: {VAR_TYPE: TYPE_BOOLEAN},
EVENT_MAX_RESULTS: {VAR_TYPE: TYPE_INTEGER, VAR_LIMITS: (1, 2500)},
EXTRA_ARGS: {VAR_TYPE: TYPE_FILE, VAR_SIGFILE: FN_EXTRA_ARGS_TXT, VAR_SFFT: ('', FN_EXTRA_ARGS_TXT), VAR_ACCESS: os.R_OK},
GCP_ORG_ID: {VAR_TYPE: TYPE_STRING, VAR_LIMITS: (0, None)},
GMAIL_CSE_INCERT_DIR: {VAR_TYPE: TYPE_DIRECTORY},
GMAIL_CSE_INKEY_DIR: {VAR_TYPE: TYPE_DIRECTORY},
INPUT_DIR: {VAR_TYPE: TYPE_DIRECTORY},

View File

@@ -913,6 +913,7 @@ class GamCLArgs():
ARG_FORWARDINGADDRESS = 'forwardingaddress'
ARG_FORWARDINGADDRESSES = 'forwardingaddresses'
ARG_GCPFOLDER = 'gcpfolder'
ARG_GCPORGID = 'gcporgid'
ARG_GCPSERVICEACCOUNT = 'gcpserviceaccount'
ARG_GMAIL = 'gmail'
ARG_GMAILPROFILE = 'gmailprofile'

View File

@@ -242,6 +242,7 @@ class GamEntity():
FORWARDING_ADDRESS = 'fwda'
GCP_FOLDER = 'gcpf'
GCP_FOLDER_NAME = 'gcpn'
GCP_ORG_ID = 'gcpo'
GMAIL_PROFILE = 'gmpr'
GROUP = 'grou'
GROUP_ALIAS = 'gali'
@@ -613,6 +614,7 @@ class GamEntity():
FORWARDING_ADDRESS: ['Forwarding Addresses', 'Forwarding Address'],
GCP_FOLDER: ['GCP Folders', 'GCP Folder'],
GCP_FOLDER_NAME: ['GCP Folder Names', 'GCP Folder Name'],
GCP_ORG_ID: ['GCP Organization ID', 'GCP Organization ID'],
GMAIL_PROFILE: ['Gmail Profile', 'Gmail Profile'],
GROUP: ['Groups', 'Group'],
GROUP_ALIAS: ['Group Aliases', 'Group Alias'],