From 4da423e33e64bd95f70c7324e4bd43831b983e17 Mon Sep 17 00:00:00 2001 From: KuetTai Date: Thu, 15 Aug 2024 13:43:30 +0800 Subject: [PATCH 1/2] Merged --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 627aecd..1137954 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ netaddr~=0.9.0 requests~=2.31.0 openpyxl~=3.1.2 multiprocess~=0.70 +simple-term-menu~=1.6.4 -e . From b948ee263b826ab2d4e0d24c8adbe7243e474cbc Mon Sep 17 00:00:00 2001 From: KuetTai Date: Thu, 15 Aug 2024 13:42:04 +0800 Subject: [PATCH 2/2] Helper features for Organization Accounts scan --- organizationAccountsInit.py | 92 +++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 organizationAccountsInit.py diff --git a/organizationAccountsInit.py b/organizationAccountsInit.py new file mode 100644 index 0000000..8bc4086 --- /dev/null +++ b/organizationAccountsInit.py @@ -0,0 +1,92 @@ +import boto3, botocore, json +from simple_term_menu import TerminalMenu + +## Setting +defaultOrgazinationAccountAccessRole = 'OrganizationAccountAccessRole' + +org = boto3.client('organizations') +acctLists = [] + +sts = boto3.client('sts') +resp = sts.get_caller_identity() +myAccountId = resp.get('Account') + + +## Welcome +print("Welcome to Service-Screener-v2 helper: OrganizationAccountsJson Generator") +print("You are currently in this account: \033[4m{}\033[0m, which will be automatically included in the scan".format(myAccountId)) +print() +print("Select the accounts to be included into the list") + +params = {} +hasNextToken = True +while(hasNextToken): + try: + resp = org.list_accounts(**params) + accts = resp.get('Accounts') + acctLists = acctLists + accts + + hasNextToken = resp.get('NextToken') + params['NextToken'] = hasNextToken + except botocore.exceptions.ClientError as e: + print(e.response['Error']['Code']) + exit() + +# Build multiselect cli +print("=================================================") +mlist = [f"{acct['Id']}::{acct['Name']}" for acct in acctLists if acct['Status'] == 'ACTIVE' and acct['Id'] != myAccountId] + +# print(mlist) +tMenu = TerminalMenu( + mlist, + multi_select=True, + show_multi_select_hint=True +) + +tControl = tMenu.show() +accounts = tMenu.chosen_menu_entries + +# print +accessRole = input("Enter organization cross accounts role (Leave it blank to use the default role: [{}]): ".format(defaultOrgazinationAccountAccessRole)) + +## check if accessRole is empty after trim +if accessRole.strip() == '': + accessRole = defaultOrgazinationAccountAccessRole + +# print(accessRole) + +#Get ExternalId +externalId = input("Enter your external id (leave it blank if NONE): ") +# print(externalId) + +#Summary before general the JSON files + + +print() +print("===================Summary=======================") +print("({}) Accounts selected, they are: {}".format(len(accounts), accounts)) +print("OrganizationAccessRole: {}".format(accessRole)) +print("ExternalId: {}".format(externalId)) +print("=================================================") +confirm = input("Confirm to proceed JSON output creation? (y/n) ") +if confirm.upper() == 'N': + print("User decided not to proceed, operation cancelled") +else: + selected = {} + for acct in accounts: + acctId = acct.split('::')[0] + selected[acctId] = {} + + general = { + 'IncludeThisAccount': True, + 'RoleName': accessRole, + 'ExternalId': externalId + } + + crossAccountsJson = {'general': general, 'accountLists': selected} + ## write the JSON into a filepath + with open('crossAccounts.json', 'w') as outfile: + json.dump(crossAccountsJson, outfile, indent=4) + + print("JSON file generated: crossAccounts.json") + print("You can now run ``` screener --regions ALL --crossAccounts 1 ``` to perform cross accounts scan") \ No newline at end of file