Extend project commands (#841)

gam create project [<EmailAddress>] [<ProjectID>]
gam use project [<EmailAddress>] [<ProjectID>]
gam update project [<EmailAddress>] [gam|<ProjectID>|(filter <String>)]
gam delete project [<EmailAddress>] [gam|<ProjectID>|(filter <String>)]
gam show projects [<EmailAddress>] [all|gam|<ProjectID>|(filter <String>)]
gam print projects [<EmailAddress>] [all|gam|<ProjectID>|(filter <String>)] [todrive]
This commit is contained in:
Ross Scroggs 2019-01-18 08:38:41 -08:00 committed by Jay Lee
parent 1cbe8297aa
commit 207eb0990c
3 changed files with 324 additions and 163 deletions

View File

@ -121,6 +121,7 @@ If an item contains spaces, it should be surrounded by ".
<Year>-<Month>-<Day>(<Space>|T)<Hour>:<Minute>:<Second>[.<MilliSeconds>](Z|(+|-(<Hour>:<Minute>))) |
(+|-)<Number>(m|h|d|w)
<RegularExpression> ::= <Python Regular Expression, see: https://docs.python.org/2/library/re.html>
<ProjectID> ::= <String> # Must match this Python Regular Expression: [a-z][a-z0-9-]{4,28}[a-z0-9]
<Tag> ::= <String>
<UniqueID> ::= uid:<String>
@ -774,8 +775,12 @@ An argument containing instances of ~~xxx~~ has xxx replaced by the value of fie
Example: gam csv Users.csv gam update user "~primaryEmail" address type work unstructured "~~Street~~, ~~City~~, ~~State~~ ~~ZIP~~"
Each user (~primaryEmail, e.g. foo@bar.com) would have their work address updated
gam create project [<EmailAddress>]
gam update project [<EmailAddress>]
gam create project [<EmailAddress>] [<ProjectID>]
gam use project [<EmailAddress>] [<ProjectID>]
gam update project [<EmailAddress>] [gam|<ProjectID>|(filter <String>)]
gam delete project [<EmailAddress>] [gam|<ProjectID>|(filter <String>)]
gam show projects [<EmailAddress>] [all|gam|<ProjectID>|(filter <String>)]
gam print projects [<EmailAddress>] [all|gam|<ProjectID>|(filter <String>)] [todrive]
gam oauth|oauth2 create|request [<EmailAddress>]
gam oauth|oauth2 delete|revoke

View File

@ -817,6 +817,8 @@ class GAPI_notFound(Exception):
pass
class GAPI_notImplemented(Exception):
pass
class GAPI_permissionDenied(Exception):
pass
class GAPI_resourceNotFound(Exception):
pass
class GAPI_serviceNotAvailable(Exception):
@ -842,6 +844,7 @@ GAPI_REASON_EXCEPTION_MAP = {
GAPI_MEMBER_NOT_FOUND: GAPI_memberNotFound,
GAPI_NOT_FOUND: GAPI_notFound,
GAPI_NOT_IMPLEMENTED: GAPI_notImplemented,
GAPI_PERMISSION_DENIED: GAPI_permissionDenied,
GAPI_RESOURCE_NOT_FOUND: GAPI_resourceNotFound,
GAPI_SERVICE_NOT_AVAILABLE: GAPI_serviceNotAvailable,
GAPI_USER_NOT_FOUND: GAPI_userNotFound,
@ -7113,19 +7116,6 @@ def getUserAttributes(i, cd, updateCmd):
body[u'hashFunction'] = u'crypt'
return body
VALIDEMAIL_PATTERN = re.compile(r'^[^@]+@[^@]+\.[^@]+$')
def getValidateLoginHint(login_hint):
if login_hint:
login_hint = login_hint.strip()
if VALIDEMAIL_PATTERN.match(login_hint):
return login_hint
while True:
login_hint = raw_input(u'\nWhat is your G Suite admin email address? ').strip()
if VALIDEMAIL_PATTERN.match(login_hint):
return login_hint
print u'Error: that is not a valid email address'
def getCRMService(login_hint):
scope = u'https://www.googleapis.com/auth/cloud-platform'
client_id = u'297408095146-fug707qsjv4ikron0hugpevbrjhkmsk7.apps.googleusercontent.com'
@ -7142,46 +7132,50 @@ def getCRMService(login_hint):
except httplib2.CertificateValidationUnsupported:
noPythonSSLExit()
credentials.user_agent = GAM_INFO
http = credentials.authorize(httplib2.Http(disable_ssl_certificate_validation=GC_Values[GC_NO_VERIFY_SSL],
cache=None))
http = credentials.authorize(httplib2.Http(disable_ssl_certificate_validation=GC_Values[GC_NO_VERIFY_SSL], cache=None))
return (googleapiclient.discovery.build(u'cloudresourcemanager', u'v1', http=http, cache_discovery=False), http)
def doDelProjects(login_hint=None):
# Leave undocumented. Most users should never need.
# Deletes all projects with ID gam-project-*
login_hint = getValidateLoginHint(login_hint)
crm, _ = getCRMService(login_hint)
projects = callGAPIpages(crm.projects(), u'list', u'projects')
for project in projects:
pid = project[u'projectId']
if pid.startswith(u'gam-project-'):
print u'Deleting %s...' % pid
try:
callGAPI(crm.projects(), u'delete', throw_reasons=[GAPI_FORBIDDEN], projectId=pid)
except GAPI_forbidden:
pass
def getGAMProjectAPIs():
httpObj = httplib2.Http(disable_ssl_certificate_validation=GC_Values[GC_NO_VERIFY_SSL])
_, c = httpObj.request(GAM_PROJECT_APIS, u'GET')
return httpObj, c.splitlines()
def enableProjectAPIs(simplehttp, httpObj, project_name, checkEnabled):
_, c = simplehttp.request(GAM_PROJECT_APIS, u'GET')
apis = c.splitlines()
def enableGAMProjectAPIs(GAMProjectAPIs, httpObj, projectId, checkEnabled, i=0, count=0):
apis = GAMProjectAPIs[:]
project_name = u'project:{0}'.format(projectId)
serveman = googleapiclient.discovery.build(u'servicemanagement', u'v1', http=httpObj, cache_discovery=False)
status = True
if checkEnabled:
enabledServices = callGAPIpages(serveman.services(), u'list', u'services',
try:
services = callGAPIpages(serveman.services(), u'list', u'services',
throw_reasons=[GAPI_NOT_FOUND],
consumerId=project_name, fields=u'nextPageToken,services(serviceName)')
for enabled in enabledServices:
if u'serviceName' in enabled:
if enabled[u'serviceName'] in apis:
print u' API %s already enabled...' % enabled[u'serviceName']
apis.remove(enabled[u'serviceName'])
jcount = len(services)
print u' Project: {0}, Check {1} APIs{2}'.format(projectId, jcount, currentCount(i, count))
j = 0
for service in sorted(services, key=lambda k: k[u'serviceName']):
j += 1
if u'serviceName' in service:
if service[u'serviceName'] in apis:
print u' API: {0}, Already enabled{1}'.format(service[u'serviceName'], currentCount(j, jcount))
apis.remove(service[u'serviceName'])
else:
print u' API %s (non-GAM) is enabled (which is fine)' % enabled[u'serviceName']
print u' API: {0}, Already enabled (non-GAM which is fine){1}'.format(service[u'serviceName'], currentCount(j, jcount))
except GAPI_notFound as e:
print u' Project: {0}, Update Failed: {1}{2}'.format(projectId, str(e), currentCount(i, count))
status = False
jcount = len(apis)
if status and jcount > 0:
print u' Project: {0}, Enable {1} APIs{2}'.format(projectId, jcount, currentCount(i, count))
j = 0
for api in apis:
j += 1
while True:
print u' enabling API %s...' % api
try:
callGAPI(serveman.services(), u'enable',
throw_reasons=[GAPI_FAILED_PRECONDITION],
throw_reasons=[GAPI_FAILED_PRECONDITION, GAPI_FORBIDDEN, GAPI_PERMISSION_DENIED],
serviceName=api, body={u'consumerId': project_name})
print u' API: {0}, Enabled{1}'.format(api, currentCount(j, jcount))
break
except GAPI_failedPrecondition as e:
print u'\nThere was an error enabling %s. Please resolve error as described below:' % api
@ -7189,22 +7183,12 @@ def enableProjectAPIs(simplehttp, httpObj, project_name, checkEnabled):
print u'\n%s\n' % e
print
raw_input(u'Press enter once resolved and we will try enabling the API again.')
except (GAPI_forbidden, GAPI_permissionDenied) as e:
print u' API: {0}, Enable Failed: {1}{2}'.format(api, str(e), currentCount(j, jcount))
status = False
return status
def doUpdateProject(login_hint=None):
login_hint = getValidateLoginHint(login_hint)
_, httpObj = getCRMService(login_hint)
cs_data = readFile(GC_Values[GC_CLIENT_SECRETS_JSON], mode=u'rb', continueOnError=True, displayError=True, encoding=None)
if not cs_data:
systemErrorExit(14, u'Your client secrets file:\n\n%s\n\nis missing. Please recreate the file.' % GC_Values[GC_CLIENT_SECRETS_JSON])
try:
cs_json = json.loads(cs_data)
project_name = 'project:%s' % cs_json[u'installed'][u'project_id']
except (ValueError, IndexError, KeyError):
systemErrorExit(3, u'The format of your client secrets file:\n\n%s\n\nis incorrect. Please recreate the file.' % GC_Values[GC_CLIENT_SECRETS_JSON])
simplehttp = httplib2.Http(disable_ssl_certificate_validation=GC_Values[GC_NO_VERIFY_SSL])
enableProjectAPIs(simplehttp, httpObj, project_name, True)
def doCreateProject(login_hint=None):
def _createClientSecretsOauth2service(httpObj, projectId):
def _checkClientAndSecret(simplehttp, client_id, client_secret):
url = u'https://www.googleapis.com/oauth2/v4/token'
@ -7232,24 +7216,189 @@ def doCreateProject(login_hint=None):
print u'Unknown error: %s' % content
return False
service_account_file = GC_Values[GC_OAUTH2SERVICE_JSON]
client_secrets_file = GC_Values[GC_CLIENT_SECRETS_JSON]
for a_file in [service_account_file, client_secrets_file]:
if os.path.exists(a_file):
systemErrorExit(5, '%s already exists. Please delete or rename it before attempting to create another project.' % a_file)
login_hint = getValidateLoginHint(login_hint)
login_domain = login_hint[login_hint.find(u'@')+1:]
simplehttp, GAMProjectAPIs = getGAMProjectAPIs()
enableGAMProjectAPIs(GAMProjectAPIs, httpObj, projectId, False)
iam = googleapiclient.discovery.build(u'iam', u'v1', http=httpObj, cache_discovery=False)
sa_list = callGAPI(iam.projects().serviceAccounts(), u'list',
name=u'projects/%s' % projectId)
service_account = None
if u'accounts' in sa_list:
for account in sa_list[u'accounts']:
sa_email = u'%s@%s.iam.gserviceaccount.com' % (projectId, projectId)
if sa_email in account[u'name']:
service_account = account
break
if not service_account:
print u'Creating Service Account'
service_account = callGAPI(iam.projects().serviceAccounts(), u'create',
name=u'projects/%s' % projectId,
body={u'accountId': projectId, u'serviceAccount': {u'displayName': u'GAM Project'}})
key = callGAPI(iam.projects().serviceAccounts().keys(), u'create',
name=service_account[u'name'], body={u'privateKeyType': u'TYPE_GOOGLE_CREDENTIALS_FILE', u'keyAlgorithm': u'KEY_ALG_RSA_2048'})
oauth2service_data = base64.b64decode(key[u'privateKeyData'])
writeFile(GC_Values[GC_OAUTH2SERVICE_JSON], oauth2service_data, continueOnError=False)
console_credentials_url = u'https://console.developers.google.com/apis/credentials?project=%s' % projectId
while True:
print u'''Please go to:
%s
1. Click the blue "Create credentials" button. Choose "OAuth client ID".
2. Click the blue "Configure consent screen" button. Enter "GAM" for "Application name".
3. Leave other fields blank. Click "Save" button.
3. Choose "Other". Enter a desired value for "Name". Click the blue "Create" button.
4. Copy your "client ID" value.
''' % console_credentials_url
# If you use Firefox to copy the Client ID and Secret, the data has leading and trailing newlines
# The first raw_input will get the leading newline, thus we have to issue another raw_input to get the data
# If the newlines are not present, the data is correctly read with the first raw_input
client_id = raw_input(u'Enter your Client ID: ').strip()
if not client_id:
client_id = raw_input().strip()
print u'\nNow go back to your browser and copy your client secret.'
client_secret = raw_input(u'Enter your Client Secret: ').strip()
if not client_secret:
client_secret = raw_input().strip()
client_valid = _checkClientAndSecret(simplehttp, client_id, client_secret)
if client_valid:
break
print
cs_data = u'''{
"installed": {
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"client_id": "%s",
"client_secret": "%s",
"project_id": "%s",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
` ],
"token_uri": "https://accounts.google.com/o/oauth2/token"
}
}''' % (client_id, client_secret, projectId)
writeFile(GC_Values[GC_CLIENT_SECRETS_JSON], cs_data, continueOnError=False)
print u'''Almost there! Now please switch back to your browser and:
1. Click OK to close "OAuth client" popup if it's still open.
2. Click "Manage service accounts" on the right of the screen.
3. Click the 3 dots to the right of your service account.
4. Choose Edit.
5. Click "Show Domain-Wide Delegation". Check "Enable G Suite Domain-wide Delegation", Click Save.
'''
raw_input(u'Press Enter when done...')
print u'That\'s it! Your GAM Project is created and ready to use.'
VALIDEMAIL_PATTERN = re.compile(r'^[^@]+@[^@]+\.[^@]+$')
def _getValidateLoginHint(login_hint):
while True:
if not login_hint:
login_hint = raw_input(u'\nWhat is your G Suite admin email address? ').strip()
if login_hint.find(u'@') == -1 and GC_Values[GC_DOMAIN]:
login_hint = u'{0}@{1}'.format(login_hint, GC_Values[GC_DOMAIN].lower())
if VALIDEMAIL_PATTERN.match(login_hint):
return login_hint
print '{0}Invalid email address: {1}'.format(ERROR_PREFIX, login_hint)
login_hint = None
def _getProjects(crm, pfilter):
try:
return callGAPIpages(crm.projects(), u'list', u'projects', throw_reasons=[GAPI_BAD_REQUEST], filter=pfilter)
except GAPI_badRequest as e:
systemErrorExit(2, u'Project: {0}, {1}'.format(pfilter, str(e)))
PROJECTID_PATTERN = re.compile(r'^[a-z][a-z0-9-]{4,28}[a-z0-9]$')
PROJECTID_FORMAT_REQUIRED = u'[a-z][a-z0-9-]{4,28}[a-z0-9]'
def _getLoginHintProjectId(createCmd):
login_hint = None
projectId = None
try:
login_hint = sys.argv[3]
projectId = sys.argv[4]
except IndexError:
pass
login_hint = _getValidateLoginHint(login_hint)
if projectId:
if not PROJECTID_PATTERN.match(projectId):
systemErrorExit(2, 'Invalid Project ID: {0}, expected <{1}>'.format(projectId, PROJECTID_FORMAT_REQUIRED))
elif createCmd:
projectId = u'gam-project'
for _ in range(3):
projectId += u'-{0}'.format(u''.join(random.choice(string.digits + string.ascii_lowercase) for _ in range(3)))
else:
projectId = raw_input(u'\nWhat is your API project ID? ').strip()
if not PROJECTID_PATTERN.match(projectId):
systemErrorExit(2, 'Invalid Project ID: {0}, expected <{1}>'.format(projectId, PROJECTID_FORMAT_REQUIRED))
crm, httpObj = getCRMService(login_hint)
project_id = u'gam-project'
for i in range(3):
project_id += u'-%s' % ''.join(random.choice(string.digits + string.ascii_lowercase) for i in range(3))
project_name = u'project:%s' % project_id
body = {u'projectId': project_id, u'name': u'GAM Project'}
projects = _getProjects(crm, u'id:{0}'.format(projectId))
if not createCmd:
if not projects:
systemErrorExit(2, 'User: {0}, Project ID: {1}, Does not exist'.format(login_hint, projectId))
if projects[0][u'lifecycleState'] != u'ACTIVE':
systemErrorExit(2, 'User: {0}, Project ID: {1}, Not active'.format(login_hint, projectId))
else:
if projects:
systemErrorExit(2, 'User: {0}, Project ID: {1}, Duplicate'.format(login_hint, projectId))
return (crm, httpObj, login_hint, projectId)
PROJECTID_FILTER_REQUIRED = 'gam|<ProjectID>|(filter <String>)'
def _getLoginHintProjects(printShowCmd):
login_hint = None
pfilter = None
i = 3
try:
login_hint = sys.argv[i]
i += 1
pfilter = sys.argv[i]
i += 1
except IndexError:
pass
if not pfilter:
pfilter = u'current' if not printShowCmd else u'id:gam-project-*'
elif printShowCmd and pfilter.lower() == u'all':
pfilter = None
elif pfilter.lower() == u'gam':
pfilter = u'id:gam-project-*'
elif pfilter.lower() == u'filter':
pfilter = sys.argv[i]
i += 1
elif PROJECTID_PATTERN.match(pfilter):
pfilter = u'id:{0}'.format(pfilter)
else:
systemErrorExit(2, 'Invalid Project ID: {0}, expected <{1}{2}>'.format(pfilter, [u'', u'all|'][printShowCmd], PROJECTID_FILTER_REQUIRED))
login_hint = _getValidateLoginHint(login_hint)
crm, httpObj = getCRMService(login_hint)
if pfilter == u'current':
cs_data = readFile(GC_Values[GC_CLIENT_SECRETS_JSON], mode=u'rb', continueOnError=True, displayError=True, encoding=None)
if not cs_data:
systemErrorExit(14, u'Your client secrets file:\n\n%s\n\nis missing. Please recreate the file.' % GC_Values[GC_CLIENT_SECRETS_JSON])
try:
cs_json = json.loads(cs_data)
projects = [{u'projectId': cs_json[u'installed'][u'project_id']}]
except (ValueError, IndexError, KeyError):
systemErrorExit(3, u'The format of your client secrets file:\n\n%s\n\nis incorrect. Please recreate the file.' % GC_Values[GC_CLIENT_SECRETS_JSON])
else:
projects = _getProjects(crm, pfilter)
return (crm, httpObj, login_hint, projects, i)
def _checkForExistingProjectFiles():
for a_file in [GC_Values[GC_OAUTH2SERVICE_JSON], GC_Values[GC_CLIENT_SECRETS_JSON]]:
if os.path.exists(a_file):
systemErrorExit(5, '%s already exists. Please delete or rename it before attempting to use another project.' % a_file)
def doCreateProject():
_checkForExistingProjectFiles()
crm, httpObj, login_hint, projectId = _getLoginHintProjectId(True)
login_domain = login_hint[login_hint.find(u'@')+1:]
body = {u'projectId': projectId, u'name': u'GAM Project'}
while True:
create_again = False
print u'Creating project "%s"...' % body[u'name']
create_operation = callGAPI(crm.projects(), u'create',
body=body)
create_operation = callGAPI(crm.projects(), u'create', body=body)
operation_name = create_operation[u'name']
time.sleep(5) # Google recommends always waiting at least 5 seconds
for i in range(1, 5):
@ -7314,69 +7463,76 @@ and accept the Terms of Service (ToS). As soon as you've accepted the ToS popup,
elif u'error' in status:
systemErrorExit(2, status[u'error'])
break
simplehttp = httplib2.Http(disable_ssl_certificate_validation=GC_Values[GC_NO_VERIFY_SSL])
enableProjectAPIs(simplehttp, httpObj, project_name, False)
iam = googleapiclient.discovery.build(u'iam', u'v1', http=httpObj, cache_discovery=False)
print u'Creating Service Account'
service_account = callGAPI(iam.projects().serviceAccounts(), u'create',
name=u'projects/%s' % project_id,
body={u'accountId': project_id, u'serviceAccount': {u'displayName': u'GAM Project'}})
key = callGAPI(iam.projects().serviceAccounts().keys(), u'create',
name=service_account[u'name'], body={u'privateKeyType': u'TYPE_GOOGLE_CREDENTIALS_FILE', u'keyAlgorithm': u'KEY_ALG_RSA_2048'})
oauth2service_data = base64.b64decode(key[u'privateKeyData'])
writeFile(service_account_file, oauth2service_data, continueOnError=False)
console_credentials_url = u'https://console.developers.google.com/apis/credentials?project=%s' % project_id
while True:
print u'''Please go to:
_createClientSecretsOauth2service(httpObj, projectId)
%s
def doUseProject():
_checkForExistingProjectFiles()
_, httpObj, _, projectId = _getLoginHintProjectId(False)
_createClientSecretsOauth2service(httpObj, projectId)
1. Click the blue "Create credentials" button. Choose "OAuth client ID".
2. Click the blue "Configure consent screen" button. Enter "GAM" for "Application name".
3. Leave other fields blank. Click "Save" button.
3. Choose "Other". Enter a desired value for "Name". Click the blue "Create" button.
4. Copy your "client ID" value.
def doUpdateProjects():
_, httpObj, login_hint, projects, _ = _getLoginHintProjects(False)
_, GAMProjectAPIs = getGAMProjectAPIs()
count = len(projects)
print u'User: {0}, Update {1} Projects'.format(login_hint, count)
i = 0
for project in projects:
i += 1
projectId = project[u'projectId']
enableGAMProjectAPIs(GAMProjectAPIs, httpObj, projectId, True, i, count)
''' % console_credentials_url
# If you use Firefox to copy the Client ID and Secret, the data has leading and trailing newlines
# The first raw_input will get the leading newline, thus we have to issue another raw_input to get the data
# If the newlines are not present, the data is correctly read with the first raw_input
client_id = raw_input(u'Enter your Client ID: ').strip()
if not client_id:
client_id = raw_input().strip()
print u'\nNow go back to your browser and copy your client secret.'
client_secret = raw_input(u'Enter your Client Secret: ').strip()
if not client_secret:
client_secret = raw_input().strip()
client_valid = _checkClientAndSecret(simplehttp, client_id, client_secret)
if client_valid:
break
print
cs_data = u'''{
"installed": {
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"client_id": "%s",
"client_secret": "%s",
"project_id": "%s",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
],
"token_uri": "https://accounts.google.com/o/oauth2/token"
}
}''' % (client_id, client_secret, project_id)
writeFile(client_secrets_file, cs_data, continueOnError=False)
print u'''Almost there! Now please switch back to your browser and:
def doDelProjects():
crm, _, login_hint, projects, _ = _getLoginHintProjects(False)
count = len(projects)
print u'User: {0}, Delete {1} Projects'.format(login_hint, count)
i = 0
for project in projects:
i += 1
projectId = project[u'projectId']
try:
callGAPI(crm.projects(), u'delete', throw_reasons=[GAPI_FORBIDDEN], projectId=projectId)
print u' Project: {0} Deleted{1}'.format(projectId, currentCount(i, count))
except GAPI_forbidden as e:
print u' Project: {0} Delete Failed: {1}{2}'.format(projectId, str(e), currentCount(i, count))
1. Click OK to close "OAuth client" popup if it's still open.
2. Click "Manage service accounts" on the right of the screen.
3. Click the 3 dots to the right of your service account.
4. Choose Edit.
5. Click "Show Domain-Wide Delegation". Check "Enable G Suite Domain-wide Delegation". Click Save.
'''
raw_input(u'Press Enter when done...')
print u'That\'s it! Your GAM Project is created and ready to use.'
def doPrintShowProjects(csvFormat):
_, _, login_hint, projects, i = _getLoginHintProjects(True)
if csvFormat:
csvRows = []
todrive = False
titles = [u'User', u'projectId', u'projectNumber', u'name', u'createTime', u'lifecycleState']
while i < len(sys.argv):
myarg = sys.argv[i].lower()
if csvFormat and myarg == u'todrive':
todrive = True
i += 1
else:
systemErrorExit(2, '%s is not a valid argument for "gam %s projects"' % (myarg, [u'show', u'print'][csvFormat]))
if not csvFormat:
count = len(projects)
print u'User: {0}, Show {1} Projects'.format(login_hint, count)
i = 0
for project in projects:
i += 1
print u' Project: {0}{1}'.format(project[u'projectId'], currentCount(i, count))
print u' projectNumber: {0}'.format(project[u'projectNumber'])
print u' name: {0}'.format(project[u'name'])
print u' createTime: {0}'.format(project[u'createTime'])
print u' lifecycleState: {0}'.format(project[u'lifecycleState'])
jcount = len(project.get(u'labels', []))
if jcount > 0:
print u' labels:'
for k, v in project[u'labels'].items():
print u' {0}: {1}'.format(k, v)
if u'parent' in project:
print u' parent:'
print u' type: {0}'.format(project[u'parent'][u'type'])
print u' id: {0}'.format(project[u'parent'][u'id'])
else:
for project in projects:
addRowTitlesToCSVfile(flatten_json(project, flattened={u'User': login_hint}), csvRows, titles)
writeCSVfile(csvRows, titles, u'Projects', todrive)
def doGetTeamDriveInfo(users):
teamDriveId = sys.argv[5]
@ -12201,7 +12357,7 @@ def doRequestOAuth(login_hint=None):
if scopes is None:
systemErrorExit(0, u'')
client_id, client_secret = getOAuthClientIDAndSecret()
login_hint = getValidateLoginHint(login_hint)
login_hint = _getValidateLoginHint(login_hint)
flow = oauth2client.client.OAuth2WebServerFlow(client_id=client_id,
client_secret=client_secret, scope=scopes, redirect_uri=oauth2client.client.OOB_CALLBACK_URN,
user_agent=GAM_INFO, response_type=u'code', login_hint=login_hint)
@ -12635,11 +12791,7 @@ def ProcessGAMCommand(args):
elif argument in [u'guardianinvite', u'inviteguardian', u'guardian']:
doInviteGuardian()
elif argument in [u'project', u'apiproject']:
try:
login_hint = sys.argv[3]
except IndexError:
login_hint = None
doCreateProject(login_hint)
doCreateProject()
elif argument in [u'resoldcustomer', u'resellercustomer']:
doCreateResoldCustomer()
elif argument in [u'resoldsubscription', u'resellersubscription']:
@ -12657,6 +12809,13 @@ def ProcessGAMCommand(args):
else:
systemErrorExit(2, '%s is not a valid argument for "gam create"' % argument)
sys.exit(0)
elif command == u'use':
argument = sys.argv[2].lower()
if argument in [u'project', u'apiproject']:
doUseProject()
else:
systemErrorExit(2, '%s is not a valid argument for "gam use"' % argument)
sys.exit(0)
elif command == u'update':
argument = sys.argv[2].lower()
if argument == u'user':
@ -12693,12 +12852,8 @@ def ProcessGAMCommand(args):
doUpdateVaultMatter()
elif argument in [u'hold', u'vaulthold']:
doUpdateVaultHold()
elif argument in [u'project', u'apiproject']:
try:
login_hint = sys.argv[3]
except IndexError:
login_hint = None
doUpdateProject(login_hint)
elif argument in [u'project', u'projects', u'apiproject']:
doUpdateProjects()
elif argument in [u'building']:
doUpdateBuilding()
elif argument in [u'feature']:
@ -12793,11 +12948,7 @@ def ProcessGAMCommand(args):
elif argument in [u'guardian', u'guardians']:
doDeleteGuardian()
elif argument in [u'project', u'projects']:
try:
login_hint = sys.argv[3]
except IndexError:
login_hint = None
doDelProjects(login_hint)
doDelProjects()
elif argument in [u'resoldsubscription', u'resellersubscription']:
doDeleteResoldSubscription()
elif argument in [u'matter', u'vaultmatter']:
@ -12888,6 +13039,8 @@ def ProcessGAMCommand(args):
doPrintBuildings()
elif argument in [u'feature', u'features']:
doPrintFeatures()
elif argument in [u'project', u'projects']:
doPrintShowProjects(True)
else:
systemErrorExit(2, '%s is not a valid argument for "gam print"' % argument)
sys.exit(0)
@ -12899,6 +13052,8 @@ def ProcessGAMCommand(args):
doPrintShowGuardians(False)
elif argument in [u'license', u'licenses', u'licence', u'licences']:
doShowLicenses()
elif argument in [u'project', u'projects']:
doPrintShowProjects(False)
else:
systemErrorExit(2, '%s is not a valid argument for "gam show"' % argument)
sys.exit(0)
@ -12906,7 +13061,7 @@ def ProcessGAMCommand(args):
argument = sys.argv[2].lower()
if argument in [u'request', u'create']:
try:
login_hint = sys.argv[3]
login_hint = sys.argv[3].strip()
except IndexError:
login_hint = None
doRequestOAuth(login_hint)

View File

@ -844,6 +844,7 @@ GAPI_INVALID_MEMBER = u'invalidMember'
GAPI_MEMBER_NOT_FOUND = u'memberNotFound'
GAPI_NOT_FOUND = u'notFound'
GAPI_NOT_IMPLEMENTED = u'notImplemented'
GAPI_PERMISSION_DENIED = u'permissionDenied'
GAPI_QUOTA_EXCEEDED = u'quotaExceeded'
GAPI_RATE_LIMIT_EXCEEDED = u'rateLimitExceeded'
GAPI_RESOURCE_NOT_FOUND = u'resourceNotFound'