reverse-diagrams 0.2.6__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,41 +1,32 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: reverse_diagrams
3
- Version: 0.2.6
4
- Summary: Continuous Documentation Tool - Documentation as Code Tool - This package create reverse diagrams based on your current state in your cloud environment
3
+ Version: 1.0.0
4
+ Summary: Continuous Documentation Tool - Documentation as Code Tool - This package create reverse diagrams based on your current state in your cloud environment using diagrams library
5
5
  Project-URL: Homepage, https://github.com/velez94/reverse_diagrams
6
6
  Project-URL: Bug Tracker, https://github.com/velez94/reverse_diagrams/issues
7
7
  Author-email: Alejandro Velez <avelez@labvel.io>
8
- License: MIT License
8
+ License: Copyright [2024] [Alejandro Velez]
9
9
 
10
- Copyright (c) [2023] [Alejandro Velez]
10
+ Licensed under the Apache License, Version 2.0 (the "License");
11
+ you may not use this file except in compliance with the License.
12
+ You may obtain a copy of the License at
11
13
 
12
- Permission is hereby granted, free of charge, to any person obtaining a copy
13
- of this software and associated documentation files (the "Software"), to deal
14
- in the Software without restriction, including without limitation the rights
15
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
- copies of the Software, and to permit persons to whom the Software is
17
- furnished to do so, subject to the following conditions:
14
+ http://www.apache.org/licenses/LICENSE-2.0
18
15
 
19
- The above copyright notice and this permission notice shall be included in all
20
- copies or substantial portions of the Software.
21
-
22
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
- SOFTWARE.
16
+ Unless required by applicable law or agreed to in writing, software
17
+ distributed under the License is distributed on an "AS IS" BASIS,
18
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ See the License for the specific language governing permissions and
20
+ limitations under the License.
29
21
  License-File: LICENSE
30
- Classifier: License :: OSI Approved :: MIT License
31
22
  Classifier: Operating System :: OS Independent
32
23
  Classifier: Programming Language :: Python :: 3
33
24
  Requires-Python: >=3.8
34
25
  Requires-Dist: boto3>=1.26.44
35
26
  Requires-Dist: colorama>=0.4.4
36
- Requires-Dist: diagrams>=0.22.0
27
+ Requires-Dist: diagrams>=0.23.4
37
28
  Requires-Dist: emoji>=2.2.0
38
- Requires-Dist: jsonschema>=3.2.0
29
+ Requires-Dist: rich>=13.7.0
39
30
  Description-Content-Type: text/markdown
40
31
 
41
32
  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
@@ -156,3 +147,25 @@ reverse_diagrams -c aws -p my-profile -i -r us-east-2
156
147
  reverse_diagrams -c aws -p my-profile -o -i -r us-east-2
157
148
  ```
158
149
 
150
+ ## Extras
151
+ ### Enable autocomplete
152
+ Argcomplete provides easy, extensible command line tab completion of arguments for your Python application.
153
+
154
+ It makes two assumptions:
155
+
156
+ * You’re using bash or zsh as your shell
157
+
158
+ * You’re using argparse to manage your command line arguments/options
159
+
160
+ Argcomplete is particularly useful if your program has lots of options or subparsers, and if your program can dynamically suggest completions for your argument/option values (for example, if the user is browsing resources over the network).
161
+ Run:
162
+ ```bash
163
+ activate-global-python-argcomplete
164
+ ```
165
+ and to make sure that bash knows about this script, you use
166
+ ```bash
167
+
168
+ echo 'eval "$(register-python-argcomplete reverse_diagrams)"' >> ~/.bashrc
169
+ source ~/.bashrc
170
+
171
+ ```
@@ -0,0 +1,20 @@
1
+ src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ src/reverse_diagrams.py,sha256=xC4alfmJ4CZcgnjShXE13ZvehhSuxSkrQxhs4LX1FVU,9496
3
+ src/version.py,sha256=GdBzLFWoHZyrTuCHs8_6o2940bb1o4TwZpxxsOIS-kI,48
4
+ src/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ src/aws/describe_identity_store.py,sha256=2mmniQowKhatfg7ekLdJASz424j0gkP9TJ-ArEeb8Po,8838
6
+ src/aws/describe_organization.py,sha256=S9r-lCy3NX1e1qpLw_gMl_-nbeE5RXcISLMdThDOp7w,4731
7
+ src/aws/describe_sso.py,sha256=LMejRRupMckB6r2akK8Nyu35AFzyvprwh4QnzAQvmoA,4832
8
+ src/banner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ src/banner/banner.py,sha256=aGFVaW7RVdhgMi8b3YeC6MQodhJd01MO3iTTHlQRw8s,979
10
+ src/dgms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ src/dgms/graph_mapper.py,sha256=vzBgjdFzO7nseqTXp0Z68-f5OgtZaDsThfMNy8Q7kjg,7402
12
+ src/dgms/graph_template.py,sha256=QMTsbYPt9uZkWS9r7h8UDc7NP7BKcCP1j523soeQrOQ,1176
13
+ src/export_report/export_csv.py,sha256=7j53bcuXK1x6ciGzq88psfyguhQWo36uVFYxp0y8p34,92
14
+ src/reports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ src/reports/save_results.py,sha256=eOYGmp1-2Kfaf5k-cUZ7UIAQoBm59ta8sxlDUoZCfK4,689
16
+ reverse_diagrams-1.0.0.dist-info/METADATA,sha256=udbRPGZhORkHUAyUOYW9DLhqjb6dt6QcjPytoEaWUTQ,5528
17
+ reverse_diagrams-1.0.0.dist-info/WHEEL,sha256=TJPnKdtrSue7xZ_AVGkp9YXcvDrobsjBds1du3Nx6dc,87
18
+ reverse_diagrams-1.0.0.dist-info/entry_points.txt,sha256=VZNkrc7qUDbddTCH3pGd83EhUT3PHTx9MzpAk6bb6qc,63
19
+ reverse_diagrams-1.0.0.dist-info/licenses/LICENSE,sha256=o6nDaQ7M9xbR0L7HSJ3A-1JbBPoZro_zhVPO4-M5CAQ,571
20
+ reverse_diagrams-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,13 @@
1
+ Copyright [2024] [Alejandro Velez]
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -1,29 +1,29 @@
1
- import boto3
2
- from .describe_sso import list_account_assignments
3
- from colorama import Fore
4
1
  import logging
5
2
 
3
+ from colorama import Fore
4
+ from rich.progress import track
5
+
6
+ from .describe_sso import client, list_account_assignments
7
+
8
+
9
+ def list_groups_pag(identity_store_id, region, next_token: str = None):
10
+ identity_client = client("identitystore", region_name=region)
6
11
 
7
- def list_groups_pag(identity_store_id, client=boto3.client('identitystore', region_name="us-east-2"),
8
- next_token: str = None):
9
- paginator = client.get_paginator('list_groups')
12
+ paginator = identity_client.get_paginator("list_groups")
10
13
  response_iterator = paginator.paginate(
11
14
  IdentityStoreId=identity_store_id,
12
- PaginationConfig={
13
- 'MaxItems': 1000,
14
- 'PageSize': 4,
15
- 'StartingToken': next_token
16
- }
15
+ PaginationConfig={"MaxItems": 1000, "PageSize": 4, "StartingToken": next_token},
17
16
  )
18
17
  response = response_iterator.build_full_result()
19
18
  logging.info(response_iterator.build_full_result())
20
19
  return response["Groups"]
21
20
 
22
21
 
23
- def list_groups(identity_store_id, client=boto3.client('identitystore', region_name="us-east-2"), ):
24
- groups = client.list_groups(
25
- IdentityStoreId=identity_store_id,
26
- MaxResults=20
22
+ def list_groups(identity_store_id, region):
23
+ identity_client = client("identitystore", region_name=region)
24
+
25
+ groups = identity_client.list_groups(
26
+ IdentityStoreId=identity_store_id, MaxResults=20
27
27
  )
28
28
 
29
29
  logging.info(groups)
@@ -32,7 +32,11 @@ def list_groups(identity_store_id, client=boto3.client('identitystore', region_n
32
32
 
33
33
  if len(groups["Groups"]) >= 20:
34
34
  logging.info("Paginating ...")
35
- ad_groups = list_groups_pag(identity_store_id=identity_store_id, client=client, next_token=groups["NextToken"])
35
+ ad_groups = list_groups_pag(
36
+ identity_store_id=identity_store_id,
37
+ region=region,
38
+ next_token=groups["NextToken"],
39
+ )
36
40
  for ad in ad_groups:
37
41
  l_groups.append(ad)
38
42
  logging.info(f"You have {len(l_groups)} Groups")
@@ -40,39 +44,62 @@ def list_groups(identity_store_id, client=boto3.client('identitystore', region_n
40
44
  return l_groups
41
45
 
42
46
 
43
- def list_users(identity_store_id, client=boto3.client('identitystore', region_name="us-east-2"), ):
44
- response = client.list_users(
47
+ # define pagination list user function
48
+ def list_users_pag(identity_store_id, region, next_token: str = None):
49
+ identity_client = client("identitystore", region_name=region)
50
+ paginator = identity_client.get_paginator("list_users")
51
+ response_iterator = paginator.paginate(
45
52
  IdentityStoreId=identity_store_id,
53
+ PaginationConfig={"MaxItems": 1000, "PageSize": 4, "StartingToken": next_token},
54
+ )
55
+ return response_iterator["Users"]
46
56
 
57
+
58
+ def list_users(identity_store_id, region):
59
+ identity_client = client("identitystore", region_name=region)
60
+
61
+ response = identity_client.list_users(
62
+ IdentityStoreId=identity_store_id,
47
63
  )
64
+ # create pagination option
65
+ users = response["Users"]
66
+ if len(users) >= 20:
67
+ logging.info("Paginating ...")
68
+ ad_users = list_users_pag(
69
+ identity_store_id=identity_store_id,
70
+ region=region,
71
+ next_token=response["NextToken"],
72
+ )
73
+ for ad in ad_users:
74
+ users.append(ad)
75
+ logging.info(f"You have {len(users)} Users")
48
76
 
49
- return response["Users"]
77
+ return users
50
78
 
51
79
 
52
- def get_members_pag(identity_store_id, client=boto3.client('identitystore', region_name="us-east-2"),
53
- next_token: str = None):
54
- paginator = client.get_paginator('list_group_memberships')
80
+ def get_members_pag(identity_store_id, region, next_token: str = None):
81
+ identity_client = client("identitystore", region_name=region)
82
+
83
+ paginator = identity_client.get_paginator("list_group_memberships")
55
84
  response_iterator = paginator.paginate(
56
85
  IdentityStoreId=identity_store_id,
57
- PaginationConfig={
58
- 'MaxItems': 1000,
59
- 'PageSize': 4,
60
- 'StartingToken': next_token
61
- }
86
+ PaginationConfig={"MaxItems": 1000, "PageSize": 4, "StartingToken": next_token},
62
87
  )
63
88
  response = response_iterator.build_full_result()
64
89
  logging.info(response_iterator.build_full_result())
65
90
  return response["GroupMemberships"]
66
91
 
67
92
 
68
- def get_members(identity_store_id, groups, client=boto3.client('identitystore', region_name="us-east-2")):
93
+ def get_members(identity_store_id, groups, region):
94
+ l_client = client("identitystore", region_name=region)
69
95
  group_members = []
70
- for g in groups:
71
- response = client.list_group_memberships(
96
+ for g, y in zip(
97
+ groups, track(range(len(groups) - 1), description="Getting groups members...")
98
+ ):
99
+ response = l_client.list_group_memberships(
72
100
  IdentityStoreId=identity_store_id,
73
101
  GroupId=g["GroupId"],
74
102
  MaxResults=20,
75
-
76
103
  )
77
104
  members = response["GroupMemberships"]
78
105
  logging.info(members)
@@ -81,18 +108,21 @@ def get_members(identity_store_id, groups, client=boto3.client('identitystore',
81
108
 
82
109
  if len(members) >= 20:
83
110
  logging.info("Paginating ...")
84
- ad_members = get_members_pag(identity_store_id=identity_store_id, client=client,
85
- next_token=response["NextToken"])
111
+ ad_members = get_members_pag(
112
+ identity_store_id=identity_store_id,
113
+ region=region,
114
+ next_token=response["NextToken"],
115
+ )
86
116
  for ad in ad_members:
87
117
  members.append(ad)
88
- logging.info(f"You have {len(ad_members)} Members")
89
- print(f"You have {len(ad_members)} Members")
118
+ logging.info(f"You have {len(ad_members)} Members")
90
119
 
91
120
  group_members.append(
92
- {"group_id": g["GroupId"],
93
- "group_name": g["DisplayName"],
94
- "members": members
95
- }
121
+ {
122
+ "group_id": g["GroupId"],
123
+ "group_name": g["DisplayName"],
124
+ "members": members,
125
+ }
96
126
  )
97
127
 
98
128
  return group_members
@@ -103,7 +133,7 @@ def list_group_memberships(identitystore_client, group_name, pagination=True):
103
133
  Lists memberships for a group in an AWS SSO identity store.
104
134
 
105
135
  Args:
106
- identitystore_client (boto3.client): Boto3 SSO identity store client
136
+ identitystore_client (client): Boto3 SSO identity store client
107
137
  group_name (str): Name of the group to list memberships for
108
138
  pagination (bool): Whether to enable result pagination (default: True)
109
139
 
@@ -111,16 +141,16 @@ def list_group_memberships(identitystore_client, group_name, pagination=True):
111
141
  list: List of member objects
112
142
  """
113
143
 
114
- params = {'GroupName': group_name}
144
+ params = {"GroupName": group_name}
115
145
  members = []
116
146
 
117
147
  if pagination:
118
- paginator = identitystore_client.get_paginator('list_group_memberships')
148
+ paginator = identitystore_client.get_paginator("list_group_memberships")
119
149
  for page in paginator.paginate(**params):
120
- members.extend(page['Members'])
150
+ members.extend(page["Members"])
121
151
  else:
122
152
  response = identitystore_client.list_group_memberships(**params)
123
- members.extend(response['Members'])
153
+ members.extend(response["Members"])
124
154
 
125
155
  return members
126
156
 
@@ -143,7 +173,7 @@ def l_groups_to_d_groups(l_groups: list = None):
143
173
  """
144
174
  names = []
145
175
  for a in l_groups:
146
- names.append(a['group_name'])
176
+ names.append(a["group_name"])
147
177
  logging.info(names)
148
178
 
149
179
  d_user_groups = dict(zip(names, l_groups))
@@ -151,36 +181,72 @@ def l_groups_to_d_groups(l_groups: list = None):
151
181
  return d_user_groups
152
182
 
153
183
 
154
- def extend_account_assignments(accounts_list, permissions_sets, store_arn,
155
- client_sso=boto3.client('identitystore', region_name="us-east-2")):
184
+ def extend_account_assignments(accounts_list, permissions_sets, store_arn, region):
156
185
  account_assignments = []
157
- for p in permissions_sets:
158
-
186
+ for p, y in zip(
187
+ permissions_sets,
188
+ track(
189
+ range(len(permissions_sets) - 1),
190
+ description="Getting account assignments ...",
191
+ ),
192
+ ):
159
193
  for ac in accounts_list:
160
- assign = list_account_assignments(instance_arn=store_arn, account_id=ac["Id"], client=client_sso,
161
- permission_set_arn=p)
194
+ assign = list_account_assignments(
195
+ instance_arn=store_arn,
196
+ account_id=ac["Id"],
197
+ region=region,
198
+ permission_set_arn=p,
199
+ )
162
200
  logging.debug(f"AccountAssignments {assign}")
163
201
  for a in assign:
164
202
  account_assignments.append(a)
165
203
  return account_assignments
166
204
 
167
205
 
168
- def add_users_and_groups_assign(account_assignments_list, user_and_group_list, user_list,
169
- list_permissions_set_arn_name):
170
- for a in account_assignments_list:
206
+ def add_users_and_groups_assign(
207
+ account_assignments_list,
208
+ user_and_group_list,
209
+ user_list,
210
+ list_permissions_set_arn_name,
211
+ ):
212
+ for a, y in zip(
213
+ account_assignments_list,
214
+ track(
215
+ range(len(account_assignments_list) - 1),
216
+ description="Create user and groups assignments ...",
217
+ ),
218
+ ):
171
219
  for g in user_and_group_list:
172
- if len(a) > 0 and a['PrincipalType'] == 'GROUP' and g["group_id"] == a['PrincipalId']:
173
- print(Fore.YELLOW +
174
- f"Account {a['AccountId']} assign to {a['PrincipalType']} {g['group_name']} with permission set {list_permissions_set_arn_name[a['PermissionSetArn']]} or {a['PermissionSetArn']}" + Fore.RESET)
175
-
176
- a["GroupName"] = g['group_name']
177
- a["PermissionSetName"] = list_permissions_set_arn_name[a['PermissionSetArn']]
220
+ if (
221
+ len(a) > 0
222
+ and a["PrincipalType"] == "GROUP"
223
+ and g["group_id"] == a["PrincipalId"]
224
+ ):
225
+ logging.info(
226
+ Fore.YELLOW
227
+ + f"Account {a['AccountId']} assign to {a['PrincipalType']} {g['group_name']} with permission set {list_permissions_set_arn_name[a['PermissionSetArn']]} or {a['PermissionSetArn']}"
228
+ + Fore.RESET
229
+ )
230
+
231
+ a["GroupName"] = g["group_name"]
232
+ a["PermissionSetName"] = list_permissions_set_arn_name[
233
+ a["PermissionSetArn"]
234
+ ]
178
235
  for u in user_list:
179
- if len(a) > 0 and a['PrincipalType'] == 'USER' and u["UserId"] == a['PrincipalId']:
180
- print(Fore.YELLOW +
181
- f"Account {a['AccountId']} assign to {a['PrincipalType']} {u['UserName']} with permission set {a['PermissionSetArn']} or {list_permissions_set_arn_name[a['PermissionSetArn']]}" + Fore.RESET)
182
- a["UserName"] = u['UserName']
183
- a["PermissionSetName"] = list_permissions_set_arn_name[a['PermissionSetArn']]
236
+ if (
237
+ len(a) > 0
238
+ and a["PrincipalType"] == "USER"
239
+ and u["UserId"] == a["PrincipalId"]
240
+ ):
241
+ logging.info(
242
+ Fore.YELLOW
243
+ + f"Account {a['AccountId']} assign to {a['PrincipalType']} {u['UserName']} with permission set {a['PermissionSetArn']} or {list_permissions_set_arn_name[a['PermissionSetArn']]}"
244
+ + Fore.RESET
245
+ )
246
+ a["UserName"] = u["UserName"]
247
+ a["PermissionSetName"] = list_permissions_set_arn_name[
248
+ a["PermissionSetArn"]
249
+ ]
184
250
  logging.debug(f"Account Assignments --> {account_assignments_list}")
185
251
  return account_assignments_list
186
252
 
@@ -190,7 +256,6 @@ def order_accounts_assignments_list(accounts_dict, account_assignments):
190
256
  for ac in accounts_dict:
191
257
  final_account_assignments[ac["Name"]] = []
192
258
  for a in account_assignments:
193
-
194
259
  if ac["Id"] == a["AccountId"]:
195
260
  final_account_assignments[ac["Name"]].append(a)
196
261
 
@@ -1,36 +1,79 @@
1
- import boto3
2
1
  import logging
3
2
 
3
+ from colorama import Fore
4
4
 
5
- def describe_organization(client=boto3.client('organizations')):
6
- organization = client.describe_organization()
5
+ from .describe_sso import client
6
+
7
+
8
+ def describe_organization(region):
9
+ """
10
+ Describe the organization.
11
+
12
+ :param region: AWS Region
13
+ :return:
14
+ """
15
+ print(f"{Fore.GREEN}❇️ Describe Organization {Fore.RESET}")
16
+ org_client = client("organizations", region_name=region)
17
+ organization = org_client.describe_organization()
7
18
  organization = organization["Organization"]
8
19
  return organization
9
20
 
10
21
 
11
- def list_roots(client=boto3.client('organizations')):
12
- roots = client.list_roots(
13
-
14
- )
22
+ def list_roots(region):
23
+ """
24
+ List the roots
25
+ :param region: AWS Region
26
+ :return:
27
+ """
28
+ org_client = client("organizations", region_name=region)
29
+ roots = org_client.list_roots()
15
30
  return roots["Roots"]
16
31
 
17
32
 
18
- def list_organizational_units(parent_id, client=boto3.client('organizations'), org_units=[]):
19
- ous = client.list_organizational_units_for_parent(
33
+ # def list organizational units pagination
34
+ def list_organizational_units_pag(parent_id, region, next_token=None):
35
+ org_client = client("organizations", region_name=region)
36
+ paginator = org_client.get_paginator("list_organizational_units_for_parent")
37
+ response_iterator = paginator.paginate(
20
38
  ParentId=parent_id,
39
+ PaginationConfig={"MaxItems": 1000, "PageSize": 4, "StartingToken": next_token},
40
+ )
41
+ return response_iterator["OrganizationalUnits"]
42
+
21
43
 
44
+ def list_organizational_units(parent_id, region, org_units=None):
45
+ org_client = client("organizations", region_name=region)
46
+ if org_units is None:
47
+ org_units = []
48
+ ous = org_client.list_organizational_units_for_parent(
49
+ ParentId=parent_id,
50
+ MaxResults=20,
22
51
  )
52
+ ous = ous["OrganizationalUnits"]
53
+
54
+ if len(ous) >= 20:
55
+ logging.info("Paginating ...")
56
+ add_ous = list_organizational_units_pag(
57
+ parent_id, region, next_token=ous["NextToken"]
58
+ )
59
+ for ou in add_ous:
60
+ ous.append(ou)
61
+ logging.debug(add_ous)
23
62
 
24
- for o in ous["OrganizationalUnits"]:
63
+ for o in ous:
25
64
  org_units.append(o)
26
- logging.debug("The parent Id is: ", parent_id)
65
+ logging.debug(
66
+ f"The parent Id is: {parent_id}",
67
+ )
27
68
  logging.debug(ous)
28
69
  if len(ous) > 0:
29
70
  for ou in ous["OrganizationalUnits"]:
30
71
  logging.debug(ou)
31
72
  if "Id" in ou.keys():
32
- logging.debug("Search nested for: ", ou["Name"])
33
- ous_next = list_organizational_units(ou["Id"], client=client, org_units=org_units)
73
+ logging.debug(f"Search nested for: {ou['Name']}")
74
+ ous_next = list_organizational_units(
75
+ ou["Id"], region=region, org_units=org_units
76
+ )
34
77
  logging.debug(ous_next)
35
78
  if len(ous_next) > 0:
36
79
  logging.debug("Find Netsted")
@@ -38,50 +81,61 @@ def list_organizational_units(parent_id, client=boto3.client('organizations'), o
38
81
  return org_units
39
82
 
40
83
 
41
- def list_parents(child_id, client=boto3.client('organizations')):
42
- response = client.list_parents(
43
- ChildId=child_id,
84
+ def list_parents(child_id, region):
85
+ """
86
+ List the parents of a child.
44
87
 
88
+ :param child_id:
89
+ :param region:
90
+ :return:
91
+ """
92
+ org_client = client("organizations", region_name=region)
93
+ response = org_client.list_parents(
94
+ ChildId=child_id,
45
95
  )
46
96
  return response["Parents"]
47
97
 
48
98
 
49
- def index_ous(list_ous, client=boto3.client('organizations')):
99
+ def index_ous(list_ous, region):
100
+ """
101
+ Index the parents of a child.
102
+
103
+ :param list_ous:
104
+ :param region:
105
+ :return list_ous:
106
+
107
+ """
108
+ org_client = client("organizations", region_name=region)
50
109
  for ou in list_ous:
51
110
  if "Id" in ou.keys() and len(ou) > 0:
52
- response = client.list_parents(
111
+ response = org_client.list_parents(
53
112
  ChildId=ou["Id"],
54
-
55
113
  )
56
114
  logging.debug(response["Parents"])
57
115
  ou["Parents"] = response["Parents"]
58
116
  return list_ous
59
117
 
60
118
 
61
- def list_accounts_pag(client=boto3.client('organizations'), next_token: str = None):
62
- paginator = client.get_paginator('list_accounts')
119
+ def list_accounts_pag(region, next_token: str = None):
120
+ org_client = client("organizations", region_name=region)
121
+ paginator = org_client.get_paginator("list_accounts")
63
122
  response_iterator = paginator.paginate(
64
- PaginationConfig={
65
- 'MaxItems': 1000,
66
- 'PageSize': 20,
67
- 'StartingToken': next_token
68
- }
123
+ PaginationConfig={"MaxItems": 1000, "PageSize": 20, "StartingToken": next_token}
69
124
  )
70
125
  response = response_iterator.build_full_result()
71
126
  logging.info(response_iterator.build_full_result())
72
127
  return response["Accounts"]
73
128
 
74
129
 
75
- def list_accounts(client=boto3.client('organizations')):
76
- accounts = client.list_accounts(
77
-
78
- )
130
+ def list_accounts(region):
131
+ org_client = client("organizations", region_name=region)
132
+ accounts = org_client.list_accounts()
79
133
  logging.info(accounts)
80
134
  l_account = accounts["Accounts"]
81
135
  logging.info(len(accounts["Accounts"]))
82
136
  if len(accounts["Accounts"]) >= 20:
83
137
  logging.info("Paginating ...")
84
- ad_accounts = list_accounts_pag(client=client, next_token=accounts["NextToken"])
138
+ ad_accounts = list_accounts_pag(region=region, next_token=accounts["NextToken"])
85
139
  for ad in ad_accounts:
86
140
  l_account.append(ad)
87
141
  logging.info(f"You Organizations have {len(l_account)} Accounts")
@@ -89,14 +143,15 @@ def list_accounts(client=boto3.client('organizations')):
89
143
  return l_account
90
144
 
91
145
 
92
- def index_accounts(list_account):
146
+ def index_accounts(list_account, region):
93
147
  accounts = []
94
- client = boto3.client('organizations')
148
+ org_client = client("organizations", region_name=region)
95
149
  for a in list_account:
96
- response = client.list_parents(
150
+ response = org_client.list_parents(
97
151
  ChildId=a["Id"],
98
-
99
152
  )
100
153
 
101
- accounts.append({"account": a["Id"], "name": a["Name"], "parents": response["Parents"]})
154
+ accounts.append(
155
+ {"account": a["Id"], "name": a["Name"], "parents": response["Parents"]}
156
+ )
102
157
  return accounts