mirror of
https://github.com/GAM-team/GAM.git
synced 2026-07-05 05:11:35 +00:00
Phase 5b - SetGlobalVariables modernization and single func size reduction
This commit is contained in:
@@ -217,6 +217,23 @@ def _getIAMSigner(service_account_info):
|
||||
return google.auth.iam.Signer(request, credentials,
|
||||
service_account_info['client_email'])
|
||||
|
||||
def _getSigner(service_account_info):
|
||||
'''Return a signer for the given key_type, or None for default keys.
|
||||
|
||||
key_type is read from service_account_info:
|
||||
- "default": Returns None (caller should use from_service_account_info)
|
||||
- "yubikey": Returns a YubiKey hardware signer
|
||||
- "signjwt": Returns an IAM signBlob signer via ADC
|
||||
'''
|
||||
key_type = service_account_info.get('key_type', 'default')
|
||||
if key_type == 'default':
|
||||
return None
|
||||
if key_type == 'yubikey':
|
||||
return yubikey.YubiKey(service_account_info)
|
||||
if key_type == 'signjwt':
|
||||
return _getIAMSigner(service_account_info)
|
||||
return None
|
||||
|
||||
def handleOAuthTokenError(e, softErrors, displayError=False, i=0, count=0):
|
||||
errMsg = str(e).replace('.', '')
|
||||
if ((errMsg in API.OAUTH2_TOKEN_ERRORS) or
|
||||
@@ -258,15 +275,10 @@ def getOauth2TxtCredentials(exitOnError=True, api=None, noDASA=False, refreshOnl
|
||||
jsonDict = json.loads(jsonData)
|
||||
api, _, _ = API.getVersion(api)
|
||||
audience = f'https://{api}.googleapis.com/'
|
||||
key_type = jsonDict.get('key_type', 'default')
|
||||
if key_type == 'default':
|
||||
signer = _getSigner(jsonDict)
|
||||
if signer is None:
|
||||
return (True, JWTCredentials.from_service_account_info(jsonDict, audience=audience))
|
||||
if key_type == 'yubikey':
|
||||
yksigner = yubikey.YubiKey(jsonDict)
|
||||
return (True, JWTCredentials._from_signer_and_info(yksigner, jsonDict, audience=audience))
|
||||
if key_type == 'signjwt':
|
||||
sjsigner = _getIAMSigner(jsonDict)
|
||||
return (True, JWTCredentials._from_signer_and_info(sjsigner, jsonDict, audience=audience))
|
||||
return (True, JWTCredentials._from_signer_and_info(signer, jsonDict, audience=audience))
|
||||
except (IndexError, KeyError, SyntaxError, TypeError, ValueError) as e:
|
||||
invalidOauth2serviceJsonExit(str(e))
|
||||
invalidOauth2serviceJsonExit(Msg.NO_DATA)
|
||||
@@ -615,19 +627,14 @@ def getSvcAcctCredentials(scopesOrAPI, userEmail, softErrors=False, forceOauth=F
|
||||
else:
|
||||
GM.Globals[GM.CURRENT_SVCACCT_API] = ''
|
||||
GM.Globals[GM.CURRENT_SVCACCT_API_SCOPES] = scopesOrAPI
|
||||
key_type = GM.Globals[GM.OAUTH2SERVICE_JSON_DATA].get('key_type', 'default')
|
||||
svcacct_info = GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]
|
||||
signer = _getSigner(svcacct_info)
|
||||
if not GM.Globals[GM.CURRENT_SVCACCT_API] or scopesOrAPI not in API.JWT_APIS or forceOauth:
|
||||
try:
|
||||
if key_type == 'default':
|
||||
credentials = google.oauth2.service_account.Credentials.from_service_account_info(GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
elif key_type == 'yubikey':
|
||||
yksigner = yubikey.YubiKey(GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
credentials = google.oauth2.service_account.Credentials._from_signer_and_info(yksigner,
|
||||
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
elif key_type == 'signjwt':
|
||||
sjsigner = _getIAMSigner(GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
credentials = google.oauth2.service_account.Credentials._from_signer_and_info(sjsigner,
|
||||
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
if signer is None:
|
||||
credentials = google.oauth2.service_account.Credentials.from_service_account_info(svcacct_info)
|
||||
else:
|
||||
credentials = google.oauth2.service_account.Credentials._from_signer_and_info(signer, svcacct_info)
|
||||
except (ValueError, IndexError, KeyError) as e:
|
||||
if softErrors:
|
||||
return None
|
||||
@@ -636,19 +643,10 @@ def getSvcAcctCredentials(scopesOrAPI, userEmail, softErrors=False, forceOauth=F
|
||||
else:
|
||||
audience = f'https://{scopesOrAPI}.googleapis.com/'
|
||||
try:
|
||||
if key_type == 'default':
|
||||
credentials = JWTCredentials.from_service_account_info(GM.Globals[GM.OAUTH2SERVICE_JSON_DATA],
|
||||
audience=audience)
|
||||
elif key_type == 'yubikey':
|
||||
yksigner = yubikey.YubiKey(GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
credentials = JWTCredentials._from_signer_and_info(yksigner,
|
||||
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA],
|
||||
audience=audience)
|
||||
elif key_type == 'signjwt':
|
||||
sjsigner = _getIAMSigner(GM.Globals[GM.OAUTH2SERVICE_JSON_DATA])
|
||||
credentials = JWTCredentials._from_signer_and_info(sjsigner,
|
||||
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA],
|
||||
audience=audience)
|
||||
if signer is None:
|
||||
credentials = JWTCredentials.from_service_account_info(svcacct_info, audience=audience)
|
||||
else:
|
||||
credentials = JWTCredentials._from_signer_and_info(signer, svcacct_info, audience=audience)
|
||||
credentials.project_id = GM.Globals[GM.OAUTH2SERVICE_JSON_DATA]['project_id']
|
||||
except (ValueError, IndexError, KeyError) as e:
|
||||
if softErrors:
|
||||
|
||||
@@ -60,8 +60,18 @@ from gam.constants import (
|
||||
FN_GAM_CFG, GAM,
|
||||
)
|
||||
|
||||
|
||||
def SetGlobalVariables():
|
||||
REGEX_CHARS = '^$*+|$[{('
|
||||
ROW_FILTER_ANY_ALL_PATTERN = re.compile(r'^(any:|all:)(.+)$', re.IGNORECASE)
|
||||
ROW_FILTER_COMP_PATTERN = re.compile(r'^(date|time|count|length|number)\s*([<>]=?|=|!=)(.+)$', re.IGNORECASE)
|
||||
ROW_FILTER_RANGE_PATTERN = re.compile(r'^(daterange|timerange|countrange|lengthrange|numberrange)(=|!=)(\S+)/(\S+)$', re.IGNORECASE)
|
||||
ROW_FILTER_TIMEOFDAYRANGE_PATTERN = re.compile(r'^(timeofdayrange)(=|!=)(\d\d):(\d\d)/(\d\d):(\d\d)$', re.IGNORECASE)
|
||||
ROW_FILTER_BOOL_PATTERN = re.compile(r'^(boolean):(.+)$', re.IGNORECASE)
|
||||
ROW_FILTER_TEXT_PATTERN = re.compile(r'^(text)([<>]=?|=|!=)(.*)$', re.IGNORECASE)
|
||||
ROW_FILTER_TEXTRANGE_PATTERN = re.compile(r'^(textrange)(=|!=)(.*)/(.*)$', re.IGNORECASE)
|
||||
ROW_FILTER_RE_PATTERN = re.compile(r'^(regex|regexcs|notregex|notregexcs):(.*)$', re.IGNORECASE)
|
||||
ROW_FILTER_DATA_PATTERN = re.compile(r'^(data|notdata):(list|file|csvfile) +(.+)$', re.IGNORECASE)
|
||||
MULTIPROCESS_EXIT_COMP_PATTERN = re.compile(r'^rc([<>]=?|=|!=)(.+)$', re.IGNORECASE)
|
||||
MULTIPROCESS_EXIT_RANGE_PATTERN = re.compile(r'^rcrange(=|!=)(\S+)/(\S+)$', re.IGNORECASE)
|
||||
|
||||
|
||||
def _stringInQuotes(value):
|
||||
@@ -110,7 +120,7 @@ def SetGlobalVariables():
|
||||
Cmd.Backup()
|
||||
usageErrorExit(formatKeyValueList('', [Ent.Singular(Ent.SECTION), value, Msg.NOT_FOUND], ''))
|
||||
|
||||
def _showSections():
|
||||
def _showSections(sectionName):
|
||||
printKeyValueList([Ent.Singular(Ent.CONFIG_FILE), GM.Globals[GM.GAM_CFG_FILE]])
|
||||
Ind.Increment()
|
||||
for section in [configparser.DEFAULTSECT]+sorted(GM.Globals[GM.PARSER].sections()):
|
||||
@@ -139,7 +149,7 @@ def SetGlobalVariables():
|
||||
if (data is not None) and writeFile(dstFile, data, continueOnError=True):
|
||||
printKeyValueList([Act.PerformedName(Act.COPY), srcFile, Msg.TO, dstFile])
|
||||
|
||||
def _printValueError(sectionName, itemName, value, errMessage, sysRC=CONFIG_ERROR_RC):
|
||||
def _printValueError(status, sectionName, itemName, value, errMessage, sysRC=CONFIG_ERROR_RC):
|
||||
kvlMsg = formatKeyValueList('',
|
||||
[Ent.Singular(Ent.CONFIG_FILE), GM.Globals[GM.GAM_CFG_FILE],
|
||||
Ent.Singular(Ent.SECTION), sectionName,
|
||||
@@ -153,16 +163,16 @@ def SetGlobalVariables():
|
||||
else:
|
||||
writeStderr(formatKeyValueList(Ind.Spaces(), [WARNING, kvlMsg], '\n'))
|
||||
|
||||
def _getCfgBoolean(sectionName, itemName):
|
||||
def _getCfgBoolean(status, sectionName, itemName):
|
||||
value = GM.Globals[GM.PARSER].get(sectionName, itemName).lower()
|
||||
if value in TRUE_VALUES:
|
||||
return True
|
||||
if value in FALSE_VALUES:
|
||||
return False
|
||||
_printValueError(sectionName, itemName, value, f'{Msg.EXPECTED}: {formatChoiceList(TRUE_FALSE)}')
|
||||
_printValueError(status, sectionName, itemName, value, f'{Msg.EXPECTED}: {formatChoiceList(TRUE_FALSE)}')
|
||||
return False
|
||||
|
||||
def _getCfgCharacter(sectionName, itemName):
|
||||
def _getCfgCharacter(status, sectionName, itemName):
|
||||
value = codecs.escape_decode(bytes(_stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName)), UTF8))[0].decode(UTF8)
|
||||
if not value and (itemName == 'csv_output_field_delimiter'):
|
||||
return ' '
|
||||
@@ -170,25 +180,25 @@ def SetGlobalVariables():
|
||||
return None
|
||||
if len(value) == 1:
|
||||
return value
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {integerLimits(1, 1, Msg.STRING_LENGTH)}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {integerLimits(1, 1, Msg.STRING_LENGTH)}')
|
||||
return ''
|
||||
|
||||
def _getCfgChoice(sectionName, itemName):
|
||||
def _getCfgChoice(status, sectionName, itemName):
|
||||
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName)).lower()
|
||||
choices = GC.VAR_INFO[itemName][GC.VAR_CHOICES]
|
||||
if value in choices:
|
||||
return choices[value]
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {",".join(choices)}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {",".join(choices)}')
|
||||
return ''
|
||||
|
||||
def _getCfgLocale(sectionName, itemName):
|
||||
def _getCfgLocale(status, sectionName, itemName):
|
||||
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName)).lower().replace('_', '-')
|
||||
if value in LOCALE_CODES_MAP:
|
||||
return LOCALE_CODES_MAP[value]
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {",".join(LOCALE_CODES_MAP)}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {",".join(LOCALE_CODES_MAP)}')
|
||||
return ''
|
||||
|
||||
def _getCfgNumber(sectionName, itemName):
|
||||
def _getCfgNumber(status, sectionName, itemName):
|
||||
value = GM.Globals[GM.PARSER].get(sectionName, itemName)
|
||||
minVal, maxVal = GC.VAR_INFO[itemName][GC.VAR_LIMITS]
|
||||
try:
|
||||
@@ -199,14 +209,14 @@ def SetGlobalVariables():
|
||||
number = minVal
|
||||
else:
|
||||
number = maxVal
|
||||
_printValueError(sectionName, itemName, value, f'{Msg.EXPECTED}: {integerLimits(minVal, maxVal)}, {Msg.USED}: {number}', sysRC=0)
|
||||
_printValueError(status, sectionName, itemName, value, f'{Msg.EXPECTED}: {integerLimits(minVal, maxVal)}, {Msg.USED}: {number}', sysRC=0)
|
||||
return number
|
||||
except ValueError:
|
||||
pass
|
||||
_printValueError(sectionName, itemName, value, f'{Msg.EXPECTED}: {integerLimits(minVal, maxVal)}')
|
||||
_printValueError(status, sectionName, itemName, value, f'{Msg.EXPECTED}: {integerLimits(minVal, maxVal)}')
|
||||
return 0
|
||||
|
||||
def _getCfgHeaderFilter(sectionName, itemName):
|
||||
def _getCfgHeaderFilter(status, sectionName, itemName):
|
||||
value = GM.Globals[GM.PARSER].get(sectionName, itemName)
|
||||
headerFilters = []
|
||||
if not value or (len(value) == 2 and _stringInQuotes(value)):
|
||||
@@ -217,32 +227,22 @@ def SetGlobalVariables():
|
||||
try:
|
||||
headerFilters.append(re.compile(filterStr, re.IGNORECASE))
|
||||
except re.error as e:
|
||||
_printValueError(sectionName, itemName, f'"{filterStr}"', f'{Msg.INVALID_RE}: {e}')
|
||||
_printValueError(status, sectionName, itemName, f'"{filterStr}"', f'{Msg.INVALID_RE}: {e}')
|
||||
else:
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.INVALID_LIST}: {filters}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.INVALID_LIST}: {filters}')
|
||||
return headerFilters
|
||||
|
||||
def _getCfgHeaderFilterFromForce(sectionName, itemName):
|
||||
def _getCfgHeaderFilterFromForce(status, sectionName, itemName):
|
||||
headerFilters = []
|
||||
for filterStr in GC.Values[itemName]:
|
||||
try:
|
||||
headerFilters.append(re.compile(fr'^{filterStr}$'))
|
||||
except re.error as e:
|
||||
_printValueError(sectionName, itemName, f'"{filterStr}"', f'{Msg.INVALID_RE}: {e}')
|
||||
_printValueError(status, sectionName, itemName, f'"{filterStr}"', f'{Msg.INVALID_RE}: {e}')
|
||||
return headerFilters
|
||||
|
||||
ROW_FILTER_ANY_ALL_PATTERN = re.compile(r'^(any:|all:)(.+)$', re.IGNORECASE)
|
||||
ROW_FILTER_COMP_PATTERN = re.compile(r'^(date|time|count|length|number)\s*([<>]=?|=|!=)(.+)$', re.IGNORECASE)
|
||||
ROW_FILTER_RANGE_PATTERN = re.compile(r'^(daterange|timerange|countrange|lengthrange|numberrange)(=|!=)(\S+)/(\S+)$', re.IGNORECASE)
|
||||
ROW_FILTER_TIMEOFDAYRANGE_PATTERN = re.compile(r'^(timeofdayrange)(=|!=)(\d\d):(\d\d)/(\d\d):(\d\d)$', re.IGNORECASE)
|
||||
ROW_FILTER_BOOL_PATTERN = re.compile(r'^(boolean):(.+)$', re.IGNORECASE)
|
||||
ROW_FILTER_TEXT_PATTERN = re.compile(r'^(text)([<>]=?|=|!=)(.*)$', re.IGNORECASE)
|
||||
ROW_FILTER_TEXTRANGE_PATTERN = re.compile(r'^(textrange)(=|!=)(.*)/(.*)$', re.IGNORECASE)
|
||||
ROW_FILTER_RE_PATTERN = re.compile(r'^(regex|regexcs|notregex|notregexcs):(.*)$', re.IGNORECASE)
|
||||
ROW_FILTER_DATA_PATTERN = re.compile(r'^(data|notdata):(list|file|csvfile) +(.+)$', re.IGNORECASE)
|
||||
REGEX_CHARS = '^$*+|$[{('
|
||||
|
||||
def _getCfgRowFilter(sectionName, itemName):
|
||||
def _getCfgRowFilter(status, sectionName, itemName):
|
||||
value = GM.Globals[GM.PARSER].get(sectionName, itemName)
|
||||
rowFilters = []
|
||||
if not value:
|
||||
@@ -251,13 +251,13 @@ def SetGlobalVariables():
|
||||
try:
|
||||
filterDict = json.loads(value.encode('unicode-escape').decode(UTF8))
|
||||
except (IndexError, KeyError, SyntaxError, TypeError, ValueError) as e:
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.FAILED_TO_PARSE_AS_JSON}: {str(e)}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.FAILED_TO_PARSE_AS_JSON}: {str(e)}')
|
||||
return rowFilters
|
||||
else:
|
||||
filterDict = {}
|
||||
status, filterList = shlexSplitListStatus(value)
|
||||
if not status:
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.FAILED_TO_PARSE_AS_LIST}: {str(filterList)}')
|
||||
splitOk, filterList = shlexSplitListStatus(value)
|
||||
if not splitOk:
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.FAILED_TO_PARSE_AS_LIST}: {str(filterList)}')
|
||||
return rowFilters
|
||||
for filterVal in filterList:
|
||||
if not filterVal:
|
||||
@@ -267,7 +267,7 @@ def SetGlobalVariables():
|
||||
column = filterTokens[0]
|
||||
filterStr = ':'.join(filterTokens[1:])
|
||||
except ValueError:
|
||||
_printValueError(sectionName, itemName, f'"{filterVal}"', f'{Msg.EXPECTED}: column:filter')
|
||||
_printValueError(status, sectionName, itemName, f'"{filterVal}"', f'{Msg.EXPECTED}: column:filter')
|
||||
continue
|
||||
filterDict[column] = filterStr
|
||||
for column, filterStr in filterDict.items():
|
||||
@@ -280,7 +280,7 @@ def SetGlobalVariables():
|
||||
try:
|
||||
columnPat = re.compile(columnPat, re.IGNORECASE)
|
||||
except re.error as e:
|
||||
_printValueError(sectionName, itemName, f'"{column}"', f'{Msg.INVALID_RE}: {e}')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}"', f'{Msg.INVALID_RE}: {e}')
|
||||
continue
|
||||
anyMatch = True
|
||||
mg = ROW_FILTER_ANY_ALL_PATTERN.match(filterStr)
|
||||
@@ -298,12 +298,12 @@ def SetGlobalVariables():
|
||||
if valid:
|
||||
rowFilters.append((columnPat, anyMatch, filterType, mg.group(2), filterValue))
|
||||
else:
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: {filterValue}')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: {filterValue}')
|
||||
else: # filterType in {'count', 'length', 'number'}:
|
||||
if mg.group(3).isdigit():
|
||||
rowFilters.append((columnPat, anyMatch, filterType, mg.group(2), int(mg.group(3))))
|
||||
else:
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <Number>')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <Number>')
|
||||
continue
|
||||
mg = ROW_FILTER_TEXT_PATTERN.match(filterStr)
|
||||
if mg:
|
||||
@@ -328,12 +328,12 @@ def SetGlobalVariables():
|
||||
if valid1 and valid2:
|
||||
rowFilters.append((columnPat, anyMatch, filterType, mg.group(2), filterValue1, filterValue2))
|
||||
else:
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: {filterValue1}/{filterValue2}')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: {filterValue1}/{filterValue2}')
|
||||
else: #countrange|lengthrange|numberrange
|
||||
if mg.group(3).isdigit() and mg.group(4).isdigit():
|
||||
rowFilters.append((columnPat, anyMatch, filterType, mg.group(2), int(mg.group(3)), int(mg.group(4))))
|
||||
else:
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <Number>/<Number>')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <Number>/<Number>')
|
||||
continue
|
||||
mg = ROW_FILTER_TIMEOFDAYRANGE_PATTERN.match(filterStr)
|
||||
if mg:
|
||||
@@ -357,7 +357,7 @@ def SetGlobalVariables():
|
||||
elif filterValue in FALSE_VALUES:
|
||||
rowFilters.append((columnPat, anyMatch, filterType, False))
|
||||
else:
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <Boolean>')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <Boolean>')
|
||||
continue
|
||||
mg = ROW_FILTER_RE_PATTERN.match(filterStr)
|
||||
if mg:
|
||||
@@ -370,7 +370,7 @@ def SetGlobalVariables():
|
||||
flags = re.IGNORECASE
|
||||
rowFilters.append((columnPat, anyMatch, filterType, re.compile(mg.group(2), flags)))
|
||||
except re.error as e:
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.INVALID_RE}: {e}')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.INVALID_RE}: {e}')
|
||||
continue
|
||||
mg = ROW_FILTER_DATA_PATTERN.match(filterStr)
|
||||
if mg:
|
||||
@@ -386,19 +386,19 @@ def SetGlobalVariables():
|
||||
rowFilters.append((columnPat, anyMatch, filterType, getEntitiesFromCSVFile(False, returnSet=True)))
|
||||
Cmd.RestoreArguments()
|
||||
continue
|
||||
_printValueError(sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <RowValueFilter>')
|
||||
_printValueError(status, sectionName, itemName, f'"{column}": "{filterStr}"', f'{Msg.EXPECTED}: <RowValueFilter>')
|
||||
return rowFilters
|
||||
|
||||
def _getCfgSection(sectionName, itemName):
|
||||
def _getCfgSection(status, sectionName, itemName):
|
||||
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName))
|
||||
if (not value) or (value.upper() == configparser.DEFAULTSECT):
|
||||
return configparser.DEFAULTSECT
|
||||
if GM.Globals[GM.PARSER].has_section(value):
|
||||
return value
|
||||
_printValueError(sectionName, itemName, value, Msg.NOT_FOUND)
|
||||
_printValueError(status, sectionName, itemName, value, Msg.NOT_FOUND)
|
||||
return configparser.DEFAULTSECT
|
||||
|
||||
def _getCfgPassword(sectionName, itemName):
|
||||
def _getCfgPassword(status, sectionName, itemName):
|
||||
value = GM.Globals[GM.PARSER].get(sectionName, itemName)
|
||||
if isinstance(value, bytes):
|
||||
return value
|
||||
@@ -409,59 +409,59 @@ def SetGlobalVariables():
|
||||
return value
|
||||
return ''
|
||||
|
||||
def _validateLicenseSKUs(sectionName, itemName, skuList):
|
||||
def _validateLicenseSKUs(status, sectionName, itemName, skuList):
|
||||
GM.Globals[GM.LICENSE_SKUS] = []
|
||||
for sku in skuList.split(','):
|
||||
if '/' not in sku:
|
||||
productId, sku = SKU.getProductAndSKU(sku)
|
||||
if not productId:
|
||||
_printValueError(sectionName, itemName, sku, f'{Msg.EXPECTED}: {",".join(SKU.getSortedSKUList())}')
|
||||
_printValueError(status, sectionName, itemName, sku, f'{Msg.EXPECTED}: {",".join(SKU.getSortedSKUList())}')
|
||||
else:
|
||||
(productId, sku) = sku.split('/')
|
||||
if (productId, sku) not in GM.Globals[GM.LICENSE_SKUS]:
|
||||
GM.Globals[GM.LICENSE_SKUS].append((productId, sku))
|
||||
|
||||
def _validateDeveloperPreviewAPIs(sectionName, itemName, apiList):
|
||||
def _validateDeveloperPreviewAPIs(status, sectionName, itemName, apiList):
|
||||
GM.Globals[GM.DEVELOPER_PREVIEW_APIS] = set()
|
||||
validAPIs = API.getAPIsList()
|
||||
for api in apiList.split(','):
|
||||
if api in validAPIs:
|
||||
GM.Globals[GM.DEVELOPER_PREVIEW_APIS].add(api)
|
||||
else:
|
||||
_printValueError(sectionName, itemName, api, f'{Msg.EXPECTED}: {",".join(sorted(validAPIs))}')
|
||||
_printValueError(status, sectionName, itemName, api, f'{Msg.EXPECTED}: {",".join(sorted(validAPIs))}')
|
||||
|
||||
def _validateGCPOrgId(sectionName, itemName, gcpOrgId):
|
||||
def _validateGCPOrgId(status, sectionName, itemName, gcpOrgId):
|
||||
mg = re.match(r'organizations/\d+', gcpOrgId)
|
||||
if not mg:
|
||||
_printValueError(sectionName, itemName, gcpOrgId, f'{Msg.EXPECTED}: "organizations/<Number>"')
|
||||
_printValueError(status, sectionName, itemName, gcpOrgId, f'{Msg.EXPECTED}: "organizations/<Number>"')
|
||||
|
||||
def _getCfgString(sectionName, itemName):
|
||||
def _getCfgString(status, sectionName, itemName):
|
||||
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName))
|
||||
if itemName == GC.DOMAIN:
|
||||
value = value.strip()
|
||||
minLen, maxLen = GC.VAR_INFO[itemName].get(GC.VAR_LIMITS, (None, None))
|
||||
if ((minLen is None) or (len(value) >= minLen)) and ((maxLen is None) or (len(value) <= maxLen)):
|
||||
if itemName == GC.LICENSE_SKUS and value:
|
||||
_validateLicenseSKUs(sectionName, itemName, value)
|
||||
_validateLicenseSKUs(status, sectionName, itemName, value)
|
||||
elif itemName == GC.DEVELOPER_PREVIEW_APIS and value:
|
||||
_validateDeveloperPreviewAPIs(sectionName, itemName, value.lower())
|
||||
_validateDeveloperPreviewAPIs(status, sectionName, itemName, value.lower())
|
||||
elif itemName == GC.GCP_ORG_ID and value:
|
||||
_validateGCPOrgId(sectionName, itemName, value)
|
||||
_validateGCPOrgId(status, sectionName, itemName, value)
|
||||
return value
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {integerLimits(minLen, maxLen, Msg.STRING_LENGTH)}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.EXPECTED}: {integerLimits(minLen, maxLen, Msg.STRING_LENGTH)}')
|
||||
return ''
|
||||
|
||||
def _getCfgStringList(sectionName, itemName):
|
||||
def _getCfgStringList(status, sectionName, itemName):
|
||||
value = GM.Globals[GM.PARSER].get(sectionName, itemName)
|
||||
stringlist = []
|
||||
if not value or (len(value) == 2 and _stringInQuotes(value)):
|
||||
return stringlist
|
||||
splitStatus, stringlist = shlexSplitListStatus(value)
|
||||
if not splitStatus:
|
||||
_printValueError(sectionName, itemName, f'"{value}"', f'{Msg.INVALID_LIST}: {stringlist}')
|
||||
_printValueError(status, sectionName, itemName, f'"{value}"', f'{Msg.INVALID_LIST}: {stringlist}')
|
||||
return stringlist
|
||||
|
||||
def _getCfgTimezone(sectionName, itemName):
|
||||
def _getCfgTimezone(status, sectionName, itemName):
|
||||
value = _stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName))
|
||||
if value.lower() in {'utc', 'z'}:
|
||||
GM.Globals[GM.CONVERT_TO_LOCAL_TIME] = False
|
||||
@@ -472,11 +472,11 @@ def SetGlobalVariables():
|
||||
try:
|
||||
return arrow.now(value).tzinfo
|
||||
except (arrow.parser.ParserError, OverflowError):
|
||||
_printValueError(sectionName, itemName, value, f'{Msg.EXPECTED}: {TIMEZONE_FORMAT_REQUIRED}')
|
||||
_printValueError(status, sectionName, itemName, value, f'{Msg.EXPECTED}: {TIMEZONE_FORMAT_REQUIRED}')
|
||||
GM.Globals[GM.CONVERT_TO_LOCAL_TIME] = False
|
||||
return arrow.now('utc').tzinfo
|
||||
|
||||
def _getCfgDirectory(sectionName, itemName):
|
||||
def _getCfgDirectory(status, sectionName, itemName):
|
||||
dirPath = os.path.expanduser(_stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName)))
|
||||
if (not dirPath) and (itemName in {GC.GMAIL_CSE_INCERT_DIR, GC.GMAIL_CSE_INKEY_DIR, GC.INPUT_DIR}):
|
||||
return dirPath
|
||||
@@ -487,10 +487,10 @@ def SetGlobalVariables():
|
||||
dirPath = os.path.join(GM.Globals[GM.GAM_CFG_PATH], dirPath)
|
||||
return dirPath
|
||||
|
||||
def _getCfgFile(sectionName, itemName):
|
||||
def _getCfgFile(status, sectionName, itemName):
|
||||
value = os.path.expanduser(_stripStringQuotes(GM.Globals[GM.PARSER].get(sectionName, itemName)))
|
||||
if value and not os.path.isabs(value):
|
||||
value = os.path.expanduser(os.path.join(_getCfgDirectory(sectionName, GC.CONFIG_DIR), value))
|
||||
value = os.path.expanduser(os.path.join(_getCfgDirectory(status, sectionName, GC.CONFIG_DIR), value))
|
||||
elif not value and itemName == GC.CACERTS_PEM:
|
||||
value = os.path.join(GM.Globals[GM.GAM_PATH], GC.FN_CACERTS_PEM)
|
||||
return value
|
||||
@@ -541,11 +541,11 @@ def SetGlobalVariables():
|
||||
elif varType not in [GC.TYPE_BOOLEAN, GC.TYPE_INTEGER, GC.TYPE_FLOAT, GC.TYPE_PASSWORD]:
|
||||
cfgValue = _quoteStringIfLeadingTrailingBlanks(cfgValue)
|
||||
if varType == GC.TYPE_FILE:
|
||||
expdValue = _getCfgFile(sectName, itemName)
|
||||
expdValue = _getCfgFile(None, sectName, itemName)
|
||||
if cfgValue not in ("''", expdValue):
|
||||
cfgValue = f'{cfgValue} ; {expdValue}'
|
||||
elif varType == GC.TYPE_DIRECTORY:
|
||||
expdValue = _getCfgDirectory(sectName, itemName)
|
||||
expdValue = _getCfgDirectory(None, sectName, itemName)
|
||||
if cfgValue not in ("''", expdValue):
|
||||
cfgValue = f'{cfgValue} ; {expdValue}'
|
||||
elif (itemName == GC.SECTION) and (sectName != configparser.DEFAULTSECT):
|
||||
@@ -568,7 +568,7 @@ def SetGlobalVariables():
|
||||
Msg.INVALID_PATH],
|
||||
'\n'))
|
||||
|
||||
def _chkCfgFiles(sectionName):
|
||||
def _chkCfgFiles(status, sectionName):
|
||||
for itemName, itemEntry in GC.VAR_INFO.items():
|
||||
if itemEntry[GC.VAR_TYPE] == GC.TYPE_FILE:
|
||||
fileName = GC.Values[itemName]
|
||||
@@ -644,9 +644,6 @@ def SetGlobalVariables():
|
||||
GM.Globals[stdtype][GM.REDIRECT_MULTIPROCESS] = multi
|
||||
GM.Globals[stdtype][GM.REDIRECT_QUEUE] = 'stdout' if stdtype == GM.STDOUT else 'stderr'
|
||||
|
||||
MULTIPROCESS_EXIT_COMP_PATTERN = re.compile(r'^rc([<>]=?|=|!=)(.+)$', re.IGNORECASE)
|
||||
MULTIPROCESS_EXIT_RANGE_PATTERN = re.compile(r'^rcrange(=|!=)(\S+)/(\S+)$', re.IGNORECASE)
|
||||
|
||||
def _setMultiprocessExit():
|
||||
rcStr = getString(Cmd.OB_STRING)
|
||||
mg = MULTIPROCESS_EXIT_COMP_PATTERN.match(rcStr)
|
||||
@@ -663,6 +660,26 @@ def SetGlobalVariables():
|
||||
return
|
||||
usageErrorExit(f'{Msg.EXPECTED}: (rc<Operator><Value>)|(rcrange<Operator><Value>/Value>)')
|
||||
|
||||
|
||||
_CFG_TYPE_HANDLERS = {
|
||||
GC.TYPE_BOOLEAN: _getCfgBoolean,
|
||||
GC.TYPE_CHARACTER: _getCfgCharacter,
|
||||
GC.TYPE_CHOICE: _getCfgChoice,
|
||||
GC.TYPE_INTEGER: _getCfgNumber,
|
||||
GC.TYPE_FLOAT: _getCfgNumber,
|
||||
GC.TYPE_HEADERFILTER: _getCfgHeaderFilter,
|
||||
GC.TYPE_LOCALE: _getCfgLocale,
|
||||
GC.TYPE_PASSWORD: _getCfgPassword,
|
||||
GC.TYPE_STRING: _getCfgString,
|
||||
GC.TYPE_STRINGLIST: _getCfgStringList,
|
||||
GC.TYPE_HEADERFORCEREQUIRED: _getCfgStringList,
|
||||
GC.TYPE_HEADERORDER: _getCfgStringList,
|
||||
GC.TYPE_FILE: _getCfgFile,
|
||||
}
|
||||
|
||||
|
||||
def _initConfigParser():
|
||||
"""Initialize config parser if not already done."""
|
||||
if not GM.Globals[GM.PARSER]:
|
||||
homePath = os.path.expanduser('~')
|
||||
GM.Globals[GM.GAM_CFG_PATH] = os.environ.get(EV_GAMCFGDIR, None)
|
||||
@@ -694,7 +711,13 @@ def SetGlobalVariables():
|
||||
else:
|
||||
GM.Globals[GM.PARSER] = configparser.RawConfigParser(defaults=collections.OrderedDict(sorted(list(GC.Defaults.items()), key=lambda t: t[0])))
|
||||
_readGamCfgFile(GM.Globals[GM.PARSER], GM.Globals[GM.GAM_CFG_FILE])
|
||||
status = {'errors': False}
|
||||
|
||||
|
||||
def _selectConfigSection(status):
|
||||
"""Determine which config section to use and process select/filter commands.
|
||||
|
||||
Returns (sectionName, inputFilterSectionName, outputFilterSectionName).
|
||||
"""
|
||||
inputFilterSectionName = outputFilterSectionName = None
|
||||
GM.Globals[GM.GAM_CFG_SECTION] = os.environ.get(EV_GAMCFGSECTION, None)
|
||||
if GM.Globals[GM.GAM_CFG_SECTION]:
|
||||
@@ -706,7 +729,7 @@ def SetGlobalVariables():
|
||||
Cmd.Backup()
|
||||
usageErrorExit(formatKeyValueList('', [EV_GAMCFGSECTION, sectionName, 'select', Msg.NOT_ALLOWED], ''))
|
||||
else:
|
||||
sectionName = _getCfgSection(configparser.DEFAULTSECT, GC.SECTION)
|
||||
sectionName = _getCfgSection(status, configparser.DEFAULTSECT, GC.SECTION)
|
||||
# select <SectionName> [save] [verify [variables <RESearchPattern>]]
|
||||
if checkArgumentPresent(Cmd.SELECT_CMD):
|
||||
sectionName = _selectSection()
|
||||
@@ -728,7 +751,7 @@ def SetGlobalVariables():
|
||||
GM.Globals[GM.GAM_CFG_SECTION_NAME] = sectionName
|
||||
# showsections
|
||||
if checkArgumentPresent(Cmd.SHOWSECTIONS_CMD):
|
||||
_showSections()
|
||||
_showSections(sectionName)
|
||||
# selectfilter|selectoutputfilter|selectinputfilter <SectionName>
|
||||
while True:
|
||||
filterCommand = getChoice([Cmd.SELECTFILTER_CMD, Cmd.SELECTOUTPUTFILTER_CMD, Cmd.SELECTINPUTFILTER_CMD], defaultChoice=None)
|
||||
@@ -738,21 +761,26 @@ def SetGlobalVariables():
|
||||
outputFilterSectionName = _selectSection()
|
||||
else:
|
||||
inputFilterSectionName = _selectSection()
|
||||
return sectionName, inputFilterSectionName, outputFilterSectionName
|
||||
|
||||
|
||||
def _fixupTodriveAndConfig(status, sectionName, inputFilterSectionName, outputFilterSectionName):
|
||||
"""Handle todrive defaults, fix mistyped keywords, and process config command."""
|
||||
# Handle todrive_nobrowser and todrive_noemail if not present
|
||||
value = GM.Globals[GM.PARSER].get(configparser.DEFAULTSECT, GC.TODRIVE_NOBROWSER)
|
||||
if value == '':
|
||||
GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.TODRIVE_NOBROWSER, str(_getCfgBoolean(configparser.DEFAULTSECT, GC.NO_BROWSER)).lower())
|
||||
GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.TODRIVE_NOBROWSER, str(_getCfgBoolean(status, configparser.DEFAULTSECT, GC.NO_BROWSER)).lower())
|
||||
value = GM.Globals[GM.PARSER].get(configparser.DEFAULTSECT, GC.TODRIVE_NOEMAIL)
|
||||
if value == '':
|
||||
GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.TODRIVE_NOEMAIL, str(not _getCfgBoolean(configparser.DEFAULTSECT, GC.NO_BROWSER)).lower())
|
||||
GM.Globals[GM.PARSER].set(configparser.DEFAULTSECT, GC.TODRIVE_NOEMAIL, str(not _getCfgBoolean(status, configparser.DEFAULTSECT, GC.NO_BROWSER)).lower())
|
||||
# Handle todrive_sheet_timestamp and todrive_sheet_timeformat if not present
|
||||
for section in [sectionName, configparser.DEFAULTSECT]:
|
||||
value = GM.Globals[GM.PARSER].get(section, GC.TODRIVE_SHEET_TIMESTAMP)
|
||||
if value == 'copy':
|
||||
GM.Globals[GM.PARSER].set(section, GC.TODRIVE_SHEET_TIMESTAMP, str(_getCfgBoolean(section, GC.TODRIVE_TIMESTAMP)).lower())
|
||||
GM.Globals[GM.PARSER].set(section, GC.TODRIVE_SHEET_TIMESTAMP, str(_getCfgBoolean(status, section, GC.TODRIVE_TIMESTAMP)).lower())
|
||||
value = GM.Globals[GM.PARSER].get(section, GC.TODRIVE_SHEET_TIMEFORMAT)
|
||||
if value == 'copy':
|
||||
GM.Globals[GM.PARSER].set(section, GC.TODRIVE_SHEET_TIMEFORMAT, _getCfgString(section, GC.TODRIVE_TIMEFORMAT))
|
||||
GM.Globals[GM.PARSER].set(section, GC.TODRIVE_SHEET_TIMEFORMAT, _getCfgString(status, section, GC.TODRIVE_TIMEFORMAT))
|
||||
# Fix mistyped keyword cmdlog_max__backups
|
||||
for section in [configparser.DEFAULTSECT, sectionName]:
|
||||
if GM.Globals[GM.PARSER].has_option(section, GC.CMDLOG_MAX__BACKUPS):
|
||||
@@ -771,96 +799,88 @@ def SetGlobalVariables():
|
||||
break
|
||||
itemEntry = GC.VAR_INFO[itemName]
|
||||
checkArgumentPresent('=')
|
||||
varType = itemEntry[GC.VAR_TYPE]
|
||||
if varType == GC.TYPE_BOOLEAN:
|
||||
match varType:
|
||||
case GC.TYPE_BOOLEAN:
|
||||
value = TRUE if getBoolean(None) else FALSE
|
||||
elif varType == GC.TYPE_CHARACTER:
|
||||
case GC.TYPE_CHARACTER:
|
||||
value = getCharacter()
|
||||
elif varType == GC.TYPE_CHOICE:
|
||||
case GC.TYPE_CHOICE:
|
||||
value = getChoice(itemEntry[GC.VAR_CHOICES])
|
||||
elif varType == GC.TYPE_INTEGER:
|
||||
case GC.TYPE_INTEGER:
|
||||
minVal, maxVal = itemEntry[GC.VAR_LIMITS]
|
||||
value = str(getInteger(minVal=minVal, maxVal=maxVal))
|
||||
elif varType == GC.TYPE_FLOAT:
|
||||
case GC.TYPE_FLOAT:
|
||||
minVal, maxVal = itemEntry[GC.VAR_LIMITS]
|
||||
value = str(getFloat(minVal=minVal, maxVal=maxVal))
|
||||
elif varType == GC.TYPE_LOCALE:
|
||||
case GC.TYPE_LOCALE:
|
||||
value = getLanguageCode(LOCALE_CODES_MAP)
|
||||
elif varType == GC.TYPE_PASSWORD:
|
||||
case GC.TYPE_PASSWORD:
|
||||
minLen, maxLen = itemEntry[GC.VAR_LIMITS]
|
||||
value = getString(Cmd.OB_STRING, checkBlank=True, minLen=minLen, maxLen=maxLen)
|
||||
if value and value.startswith("b'") and value.endswith("'"):
|
||||
value = bytes(value[2:-1], UTF8)
|
||||
elif varType == GC.TYPE_TIMEZONE:
|
||||
case GC.TYPE_TIMEZONE:
|
||||
value = getString(Cmd.OB_STRING, checkBlank=True)
|
||||
else: # GC.TYPE_STRING, GC.TYPE_STRINGLIST
|
||||
case _: # GC.TYPE_STRING, GC.TYPE_STRINGLIST
|
||||
minLen, maxLen = itemEntry.get(GC.VAR_LIMITS, (0, None))
|
||||
value = _quoteStringIfLeadingTrailingBlanks(getString(Cmd.OB_STRING, minLen=minLen, maxLen=maxLen))
|
||||
GM.Globals[GM.PARSER].set(sectionName, itemName, value)
|
||||
|
||||
|
||||
def _assignConfigValues(status, sectionName, inputFilterSectionName, outputFilterSectionName):
|
||||
"""Assign all GC.Values from config: directories, timezone, types, row filters, filter overrides."""
|
||||
prevExtraArgsTxt = GC.Values.get(GC.EXTRA_ARGS, None)
|
||||
prevOauth2serviceJson = GC.Values.get(GC.OAUTH2SERVICE_JSON, None)
|
||||
# Assign global variables, directories, timezone first as other variables depend on them
|
||||
for itemName, itemEntry in sorted(GC.VAR_INFO.items()):
|
||||
varType = itemEntry[GC.VAR_TYPE]
|
||||
if varType == GC.TYPE_DIRECTORY:
|
||||
GC.Values[itemName] = _getCfgDirectory(sectionName, itemName)
|
||||
GC.Values[itemName] = _getCfgDirectory(status, sectionName, itemName)
|
||||
elif varType == GC.TYPE_TIMEZONE:
|
||||
GC.Values[itemName] = _getCfgTimezone(sectionName, itemName)
|
||||
GC.Values[itemName] = _getCfgTimezone(status, sectionName, itemName)
|
||||
GM.Globals[GM.DATETIME_NOW] = arrow.now(GC.Values[GC.TIMEZONE])
|
||||
# Everything else except row filters
|
||||
for itemName, itemEntry in sorted(GC.VAR_INFO.items()):
|
||||
varType = itemEntry[GC.VAR_TYPE]
|
||||
if varType == GC.TYPE_BOOLEAN:
|
||||
GC.Values[itemName] = _getCfgBoolean(sectionName, itemName)
|
||||
elif varType == GC.TYPE_CHARACTER:
|
||||
GC.Values[itemName] = _getCfgCharacter(sectionName, itemName)
|
||||
elif varType == GC.TYPE_CHOICE:
|
||||
GC.Values[itemName] = _getCfgChoice(sectionName, itemName)
|
||||
elif varType in [GC.TYPE_INTEGER, GC.TYPE_FLOAT]:
|
||||
GC.Values[itemName] = _getCfgNumber(sectionName, itemName)
|
||||
elif varType == GC.TYPE_HEADERFILTER:
|
||||
GC.Values[itemName] = _getCfgHeaderFilter(sectionName, itemName)
|
||||
elif varType == GC.TYPE_LOCALE:
|
||||
GC.Values[itemName] = _getCfgLocale(sectionName, itemName)
|
||||
elif varType == GC.TYPE_PASSWORD:
|
||||
GC.Values[itemName] = _getCfgPassword(sectionName, itemName)
|
||||
elif varType == GC.TYPE_STRING:
|
||||
GC.Values[itemName] = _getCfgString(sectionName, itemName)
|
||||
elif varType in {GC.TYPE_STRINGLIST, GC.TYPE_HEADERFORCEREQUIRED, GC.TYPE_HEADERORDER}:
|
||||
GC.Values[itemName] = _getCfgStringList(sectionName, itemName)
|
||||
elif varType == GC.TYPE_FILE:
|
||||
GC.Values[itemName] = _getCfgFile(sectionName, itemName)
|
||||
handler = _CFG_TYPE_HANDLERS.get(varType)
|
||||
if handler:
|
||||
GC.Values[itemName] = handler(status, sectionName, itemName)
|
||||
# Row filters
|
||||
for itemName, itemEntry in sorted(GC.VAR_INFO.items()):
|
||||
varType = itemEntry[GC.VAR_TYPE]
|
||||
if varType == GC.TYPE_ROWFILTER:
|
||||
GC.Values[itemName] = _getCfgRowFilter(sectionName, itemName)
|
||||
GC.Values[itemName] = _getCfgRowFilter(status, sectionName, itemName)
|
||||
# Process selectfilter|selectoutputfilter|selectinputfilter
|
||||
if inputFilterSectionName:
|
||||
GC.Values[GC.CSV_INPUT_ROW_FILTER] = _getCfgRowFilter(inputFilterSectionName, GC.CSV_INPUT_ROW_FILTER)
|
||||
GC.Values[GC.CSV_INPUT_ROW_FILTER_MODE] = _getCfgChoice(inputFilterSectionName, GC.CSV_INPUT_ROW_FILTER_MODE)
|
||||
GC.Values[GC.CSV_INPUT_ROW_DROP_FILTER] = _getCfgRowFilter(inputFilterSectionName, GC.CSV_INPUT_ROW_DROP_FILTER)
|
||||
GC.Values[GC.CSV_INPUT_ROW_DROP_FILTER_MODE] = _getCfgChoice(inputFilterSectionName, GC.CSV_INPUT_ROW_DROP_FILTER_MODE)
|
||||
GC.Values[GC.CSV_INPUT_ROW_LIMIT] = _getCfgNumber(inputFilterSectionName, GC.CSV_INPUT_ROW_LIMIT)
|
||||
GC.Values[GC.CSV_INPUT_ROW_FILTER] = _getCfgRowFilter(status, inputFilterSectionName, GC.CSV_INPUT_ROW_FILTER)
|
||||
GC.Values[GC.CSV_INPUT_ROW_FILTER_MODE] = _getCfgChoice(status, inputFilterSectionName, GC.CSV_INPUT_ROW_FILTER_MODE)
|
||||
GC.Values[GC.CSV_INPUT_ROW_DROP_FILTER] = _getCfgRowFilter(status, inputFilterSectionName, GC.CSV_INPUT_ROW_DROP_FILTER)
|
||||
GC.Values[GC.CSV_INPUT_ROW_DROP_FILTER_MODE] = _getCfgChoice(status, inputFilterSectionName, GC.CSV_INPUT_ROW_DROP_FILTER_MODE)
|
||||
GC.Values[GC.CSV_INPUT_ROW_LIMIT] = _getCfgNumber(status, inputFilterSectionName, GC.CSV_INPUT_ROW_LIMIT)
|
||||
if outputFilterSectionName:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FORCE] = _getCfgStringList(outputFilterSectionName, GC.CSV_OUTPUT_HEADER_FORCE)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FORCE] = _getCfgStringList(status, outputFilterSectionName, GC.CSV_OUTPUT_HEADER_FORCE)
|
||||
if GC.Values[GC.CSV_OUTPUT_HEADER_FORCE]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = _getCfgHeaderFilterFromForce(outputFilterSectionName, GC.CSV_OUTPUT_HEADER_FORCE)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = _getCfgHeaderFilterFromForce(status, outputFilterSectionName, GC.CSV_OUTPUT_HEADER_FORCE)
|
||||
else:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = _getCfgHeaderFilter(outputFilterSectionName, GC.CSV_OUTPUT_HEADER_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_DROP_FILTER] = _getCfgHeaderFilter(outputFilterSectionName, GC.CSV_OUTPUT_HEADER_DROP_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_ORDER] = _getCfgStringList(outputFilterSectionName, GC.CSV_OUTPUT_HEADER_ORDER)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_REQUIRED] = _getCfgStringList(outputFilterSectionName, GC.CSV_OUTPUT_HEADER_REQUIRED)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_FILTER] = _getCfgRowFilter(outputFilterSectionName, GC.CSV_OUTPUT_ROW_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE] = _getCfgChoice(outputFilterSectionName, GC.CSV_OUTPUT_ROW_FILTER_MODE)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_DROP_FILTER] = _getCfgRowFilter(outputFilterSectionName, GC.CSV_OUTPUT_ROW_DROP_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_DROP_FILTER_MODE] = _getCfgChoice(outputFilterSectionName, GC.CSV_OUTPUT_ROW_DROP_FILTER_MODE)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_LIMIT] = _getCfgNumber(outputFilterSectionName, GC.CSV_OUTPUT_ROW_LIMIT)
|
||||
GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = _getCfgStringList(outputFilterSectionName, GC.CSV_OUTPUT_SORT_HEADERS)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = _getCfgHeaderFilter(status, outputFilterSectionName, GC.CSV_OUTPUT_HEADER_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_DROP_FILTER] = _getCfgHeaderFilter(status, outputFilterSectionName, GC.CSV_OUTPUT_HEADER_DROP_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_ORDER] = _getCfgStringList(status, outputFilterSectionName, GC.CSV_OUTPUT_HEADER_ORDER)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_REQUIRED] = _getCfgStringList(status, outputFilterSectionName, GC.CSV_OUTPUT_HEADER_REQUIRED)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_FILTER] = _getCfgRowFilter(status, outputFilterSectionName, GC.CSV_OUTPUT_ROW_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE] = _getCfgChoice(status, outputFilterSectionName, GC.CSV_OUTPUT_ROW_FILTER_MODE)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_DROP_FILTER] = _getCfgRowFilter(status, outputFilterSectionName, GC.CSV_OUTPUT_ROW_DROP_FILTER)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_DROP_FILTER_MODE] = _getCfgChoice(status, outputFilterSectionName, GC.CSV_OUTPUT_ROW_DROP_FILTER_MODE)
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_LIMIT] = _getCfgNumber(status, outputFilterSectionName, GC.CSV_OUTPUT_ROW_LIMIT)
|
||||
GC.Values[GC.CSV_OUTPUT_SORT_HEADERS] = _getCfgStringList(status, outputFilterSectionName, GC.CSV_OUTPUT_SORT_HEADERS)
|
||||
elif GC.Values[GC.CSV_OUTPUT_HEADER_FORCE]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = _getCfgHeaderFilterFromForce(sectionName, GC.CSV_OUTPUT_HEADER_FORCE)
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = _getCfgHeaderFilterFromForce(status, sectionName, GC.CSV_OUTPUT_HEADER_FORCE)
|
||||
if status['errors']:
|
||||
sys.exit(CONFIG_ERROR_RC)
|
||||
return prevExtraArgsTxt, prevOauth2serviceJson
|
||||
|
||||
|
||||
def _applyRuntimeDefaults(prevExtraArgsTxt, prevOauth2serviceJson):
|
||||
"""Apply runtime defaults: domain cleanup, inheritance, lockfile, debug, extra args."""
|
||||
# Global values cleanup
|
||||
GC.Values[GC.DOMAIN] = GC.Values[GC.DOMAIN].lower()
|
||||
if not GC.Values[GC.SMTP_FQDN]:
|
||||
@@ -894,6 +914,10 @@ def SetGlobalVariables():
|
||||
GM.Globals[GM.OAUTH2SERVICE_JSON_DATA] = {}
|
||||
GM.Globals[GM.OAUTH2SERVICE_CLIENT_ID] = None
|
||||
Cmd.SetEncoding(GM.Globals[GM.SYS_ENCODING])
|
||||
|
||||
|
||||
def _processRedirects(sectionName):
|
||||
"""Process multiprocessexit and redirect csv/stdout/stderr commands."""
|
||||
# multiprocessexit (rc<Operator><Number>)|(rcrange=<Number>/<Number>)|(rcrange!=<Number>/<Number>)
|
||||
if checkArgumentPresent(Cmd.MULTIPROCESSEXIT_CMD):
|
||||
_setMultiprocessExit()
|
||||
@@ -909,7 +933,8 @@ def SetGlobalVariables():
|
||||
while checkArgumentPresent(Cmd.REDIRECT_CMD):
|
||||
myarg = getChoice(['csv', 'stdout', 'stderr'])
|
||||
filename = re.sub(r'{{Section}}', sectionName, getString(Cmd.OB_FILE_NAME, checkBlank=True))
|
||||
if myarg == 'csv':
|
||||
match myarg:
|
||||
case 'csv':
|
||||
multi = False
|
||||
mode = DEFAULT_FILE_WRITE_MODE
|
||||
writeHeader = True
|
||||
@@ -947,7 +972,7 @@ def SetGlobalVariables():
|
||||
if checkArgumentPresent('todrive'):
|
||||
GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF].GetTodriveParameters()
|
||||
GM.Globals[GM.CSV_TODRIVE] = GM.Globals[GM.CSVFILE][GM.REDIRECT_QUEUE_CSVPF].todrive.copy()
|
||||
elif myarg == 'stdout':
|
||||
case 'stdout':
|
||||
if filename.lower() == 'null':
|
||||
multi = checkArgumentPresent('multiprocess')
|
||||
_setSTDFile(GM.STDOUT, 'null', DEFAULT_FILE_WRITE_MODE, multi)
|
||||
@@ -955,7 +980,7 @@ def SetGlobalVariables():
|
||||
multi = checkArgumentPresent('multiprocess')
|
||||
mode = DEFAULT_FILE_APPEND_MODE if checkArgumentPresent('append') else DEFAULT_FILE_WRITE_MODE
|
||||
_setSTDFile(GM.STDOUT, filename, mode, multi)
|
||||
else: # myarg == 'stderr'
|
||||
case 'stderr':
|
||||
if filename.lower() == 'null':
|
||||
multi = checkArgumentPresent('multiprocess')
|
||||
_setSTDFile(GM.STDERR, 'null', DEFAULT_FILE_WRITE_MODE, multi)
|
||||
@@ -983,6 +1008,10 @@ def SetGlobalVariables():
|
||||
elif not GM.Globals[GM.CSVFILE]:
|
||||
_setCSVFile('-', GM.Globals[GM.STDOUT].get(GM.REDIRECT_MODE, DEFAULT_FILE_WRITE_MODE), GC.Values[GC.CHARSET], True, False, False)
|
||||
initAPICallsRateCheck()
|
||||
|
||||
|
||||
def _finalizeConfig(status, sectionName):
|
||||
"""Finalize config: filter inheritance, DASA validation, env vars, return."""
|
||||
# Main process
|
||||
# Clear input row filters/limit from parser, children can define but shouldn't inherit global value
|
||||
# Clear output header/row filters/limit from parser, children can define or they will inherit global value if not defined
|
||||
@@ -996,16 +1025,16 @@ def SetGlobalVariables():
|
||||
# Child process
|
||||
# Inherit main process output header/row filters/limit, print defaults if not locally defined
|
||||
else:
|
||||
if not GC.Values[GC.CSV_OUTPUT_HEADER_FILTER]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FILTER] = GM.Globals[GM.CSV_OUTPUT_HEADER_FILTER][:]
|
||||
if not GC.Values[GC.CSV_OUTPUT_HEADER_DROP_FILTER]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_DROP_FILTER] = GM.Globals[GM.CSV_OUTPUT_HEADER_DROP_FILTER][:]
|
||||
if not GC.Values[GC.CSV_OUTPUT_HEADER_FORCE]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_FORCE] = GM.Globals[GM.CSV_OUTPUT_HEADER_FORCE][:]
|
||||
if not GC.Values[GC.CSV_OUTPUT_HEADER_ORDER]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_ORDER] = GM.Globals[GM.CSV_OUTPUT_HEADER_ORDER][:]
|
||||
if not GC.Values[GC.CSV_OUTPUT_HEADER_REQUIRED]:
|
||||
GC.Values[GC.CSV_OUTPUT_HEADER_REQUIRED] = GM.Globals[GM.CSV_OUTPUT_HEADER_REQUIRED][:]
|
||||
_CHILD_INHERIT_LIST_ITEMS = [
|
||||
(GC.CSV_OUTPUT_HEADER_FILTER, GM.CSV_OUTPUT_HEADER_FILTER),
|
||||
(GC.CSV_OUTPUT_HEADER_DROP_FILTER, GM.CSV_OUTPUT_HEADER_DROP_FILTER),
|
||||
(GC.CSV_OUTPUT_HEADER_FORCE, GM.CSV_OUTPUT_HEADER_FORCE),
|
||||
(GC.CSV_OUTPUT_HEADER_ORDER, GM.CSV_OUTPUT_HEADER_ORDER),
|
||||
(GC.CSV_OUTPUT_HEADER_REQUIRED, GM.CSV_OUTPUT_HEADER_REQUIRED),
|
||||
]
|
||||
for gcItem, gmItem in _CHILD_INHERIT_LIST_ITEMS:
|
||||
if not GC.Values[gcItem]:
|
||||
GC.Values[gcItem] = GM.Globals[gmItem][:]
|
||||
if not GC.Values[GC.CSV_OUTPUT_ROW_FILTER]:
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_FILTER] = GM.Globals[GM.CSV_OUTPUT_ROW_FILTER][:]
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_FILTER_MODE] = GM.Globals[GM.CSV_OUTPUT_ROW_FILTER_MODE]
|
||||
@@ -1014,12 +1043,14 @@ def SetGlobalVariables():
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_DROP_FILTER_MODE] = GM.Globals[GM.CSV_OUTPUT_ROW_DROP_FILTER_MODE]
|
||||
if not GC.Values[GC.CSV_OUTPUT_ROW_LIMIT]:
|
||||
GC.Values[GC.CSV_OUTPUT_ROW_LIMIT] = GM.Globals[GM.CSV_OUTPUT_ROW_LIMIT]
|
||||
if not GC.Values[GC.PRINT_AGU_DOMAINS]:
|
||||
GC.Values[GC.PRINT_AGU_DOMAINS] = GM.Globals[GM.PRINT_AGU_DOMAINS]
|
||||
if not GC.Values[GC.PRINT_CROS_OUS]:
|
||||
GC.Values[GC.PRINT_CROS_OUS] = GM.Globals[GM.PRINT_CROS_OUS]
|
||||
if not GC.Values[GC.PRINT_CROS_OUS_AND_CHILDREN]:
|
||||
GC.Values[GC.PRINT_CROS_OUS_AND_CHILDREN] = GM.Globals[GM.PRINT_CROS_OUS_AND_CHILDREN]
|
||||
_CHILD_INHERIT_SCALAR_ITEMS = [
|
||||
(GC.PRINT_AGU_DOMAINS, GM.PRINT_AGU_DOMAINS),
|
||||
(GC.PRINT_CROS_OUS, GM.PRINT_CROS_OUS),
|
||||
(GC.PRINT_CROS_OUS_AND_CHILDREN, GM.PRINT_CROS_OUS_AND_CHILDREN),
|
||||
]
|
||||
for gcItem, gmItem in _CHILD_INHERIT_SCALAR_ITEMS:
|
||||
if not GC.Values[gcItem]:
|
||||
GC.Values[gcItem] = GM.Globals[gmItem]
|
||||
GC.Values[GC.SHOW_GETTINGS] = GM.Globals[GM.SHOW_GETTINGS]
|
||||
GC.Values[GC.SHOW_GETTINGS_GOT_NL] = GM.Globals[GM.SHOW_GETTINGS_GOT_NL]
|
||||
# customer_id, domain and admin_email must be set when enable_dasa = true
|
||||
@@ -1042,7 +1073,7 @@ def SetGlobalVariables():
|
||||
if (Cmd.Location() == 1) or (Cmd.ArgumentsRemaining()):
|
||||
_chkCfgDirectories(sectionName)
|
||||
if not Cmd.PeekArgumentPresent(['checkconn', 'checkconnection', 'comment', 'oauth', 'oauth2', 'version']):
|
||||
_chkCfgFiles(sectionName)
|
||||
_chkCfgFiles(status, sectionName)
|
||||
if status['errors']:
|
||||
sys.exit(CONFIG_ERROR_RC)
|
||||
if GC.Values[GC.NO_CACHE]:
|
||||
@@ -1066,3 +1097,15 @@ def SetGlobalVariables():
|
||||
# We're done, nothing else to do
|
||||
return False
|
||||
|
||||
|
||||
def SetGlobalVariables():
|
||||
_initConfigParser()
|
||||
status = {'errors': False}
|
||||
sectionName, inputFilterSectionName, outputFilterSectionName = _selectConfigSection(status)
|
||||
_fixupTodriveAndConfig(status, sectionName, inputFilterSectionName, outputFilterSectionName)
|
||||
prevExtraArgsTxt, prevOauth2serviceJson = _assignConfigValues(status, sectionName, inputFilterSectionName, outputFilterSectionName)
|
||||
_applyRuntimeDefaults(prevExtraArgsTxt, prevOauth2serviceJson)
|
||||
_processRedirects(sectionName)
|
||||
return _finalizeConfig(status, sectionName)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user