reverse-diagrams 0.2.5__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.
src/reverse_diagrams.py CHANGED
@@ -1,169 +1,325 @@
1
- import os
2
-
3
- import boto3
4
- import argparse
5
- import logging
6
- import emoji
7
- from colorama import Fore
8
- from datetime import datetime
9
- from .aws.describe_organization import describe_organization, \
10
- list_accounts, index_accounts, list_roots, list_organizational_units, index_ous
11
- from .aws.describe_identity_store import order_accounts_assignments_list, extend_account_assignments, \
12
- list_groups, get_members, list_users, complete_group_members, add_users_and_groups_assign, l_groups_to_d_groups
13
- from .aws.describe_sso import list_instances, extends_permissions_set, list_permissions_set
14
- from .dgms.graph_mapper import create_mapper, create_sso_mapper_complete, create_sso_mapper, create_file
15
- from .dgms.graph_template import graph_template, graph_template_sso, graph_template_sso_complete
16
- from .banner.banner import get_version
17
-
18
- __version__ = "0.2.5"
19
-
20
-
21
- def main() -> int:
22
- """
23
- Crete architecture diagram from your current state
24
- :return:
25
- """
26
-
27
- # Initialize parser
28
- parser = argparse.ArgumentParser()
29
- parser.add_argument("-c", "--cloud",
30
- help="Cloud Provider, aws, gcp, azure", default="aws")
31
- parser.add_argument("-p", "--profile",
32
- help="AWS cli profile for Access Analyzer Api", default=None)
33
- parser.add_argument("-od", "--output_dir_path",
34
- help="Name of folder to save the diagrams python code files", default=None)
35
- parser.add_argument("-r", "--region",
36
- help="AWS cli profile for Access Analyzer Api", default="us-east-2")
37
- parser.add_argument("-o", "--graph_organization",
38
- help="Set if you want to create graph for your organization", action='store_true')
39
- parser.add_argument("-i", "--graph_identity",
40
- help="Set if you want to create graph for your IAM Center", action='store_true')
41
-
42
- parser.add_argument("-v", "--version",
43
- help="Show version", action='store_true')
44
- parser.add_argument("-d", "--debug",
45
- help="Debug Mode", action='store_true')
46
-
47
- # Read arguments from command line
48
- args = parser.parse_args()
49
- logging.info(f"The arguments are {args}")
50
- if args.debug:
51
- logging.basicConfig(level=logging.DEBUG)
52
-
53
- if args.output_dir_path:
54
- diagrams_path = args.output_dir_path
55
- else:
56
- diagrams_path = "."
57
-
58
- if args.cloud == "aws":
59
- if args.profile:
60
- profile = args.profile
61
- if profile is not None:
62
- boto3.setup_default_session(profile_name=profile)
63
-
64
- logging.info(f"Profile is: {profile}")
65
- if args.region:
66
- region = args.region
67
-
68
- if args.graph_organization:
69
- create_file(template_content=graph_template, file_name="graph_org.py", directory_path=diagrams_path)
70
-
71
- client_org = boto3.client('organizations')
72
- organization = describe_organization(client_org)
73
- print(Fore.BLUE + emoji.emojize(":sparkle: Getting Organization Info" + Fore.RESET))
74
- logging.debug(organization)
75
- logging.debug("The Roots Info")
76
- roots = list_roots(client=client_org)
77
- logging.debug(roots)
78
- print(Fore.BLUE + emoji.emojize(":sparkle: The Organizational Units list " + Fore.RESET))
79
- logging.debug("The Organizational Units list ")
80
- ous = list_organizational_units(parent_id=roots[0]["Id"], client=client_org)
81
- logging.debug(ous)
82
- logging.debug("The Organizational Units list with parents info")
83
- i_ous = index_ous(ous, client=client_org)
84
- logging.debug(i_ous)
85
- print(Fore.BLUE + emoji.emojize(":sparkle: Getting the Account list info" + Fore.RESET))
86
- l_accounts = list_accounts(client_org)
87
- logging.debug(l_accounts)
88
- logging.debug("The Account list with parents info")
89
- print(Fore.YELLOW + emoji.emojize(
90
- f":information: There are {len(l_accounts)} Accounts in your organization" + Fore.RESET))
91
- i_accounts = index_accounts(l_accounts)
92
- logging.debug(i_accounts)
93
-
94
- create_mapper(template_file="graph_org.py", org=organization, root_id=roots[0]["Id"], list_ous=ous,
95
- list_accounts=i_accounts)
96
-
97
- print(
98
- Fore.YELLOW + emoji.emojize(f":sparkles: Run -> python3 {diagrams_path}/graph_org.py " + Fore.RESET))
99
-
100
- if args.graph_identity:
101
- create_file(template_content=graph_template_sso, file_name="graph_sso.py", directory_path=diagrams_path)
102
- create_file(template_content=graph_template_sso_complete, file_name="graph_sso_complete.py",
103
- directory_path=diagrams_path)
104
-
105
- client_identity = boto3.client('identitystore', region_name=region)
106
- client_sso = boto3.client('sso-admin', region_name=region)
107
-
108
- store_instances = list_instances(client=client_sso)
109
- print(Fore.BLUE + emoji.emojize(":sparkle: Getting Identity store instance info" + Fore.RESET))
110
- logging.debug(store_instances)
111
- store_id = store_instances[0]["IdentityStoreId"]
112
- store_arn = store_instances[0]["InstanceArn"]
113
- print(Fore.BLUE + emoji.emojize(":sparkle: List groups" + Fore.RESET))
114
- l_groups = list_groups(store_id, client=client_identity)
115
- logging.debug(l_groups)
116
- print(Fore.YELLOW + emoji.emojize(
117
- f":information: There are {len(l_groups)} Groups in your Identity Store" + Fore.RESET))
118
-
119
- print(Fore.BLUE + emoji.emojize(":sparkle: Get groups and Users info" + Fore.RESET))
120
-
121
- m_groups = get_members(store_id, l_groups, client=client_identity)
122
-
123
- logging.debug(m_groups)
124
-
125
- logging.debug("Extend Group Members")
126
- l_users = list_users(store_id, client=client_identity)
127
- logging.debug(l_users)
128
- c_users_and_groups = complete_group_members(m_groups, l_users)
129
- d_groups = l_groups_to_d_groups(l_groups=c_users_and_groups)
130
-
131
- logging.debug(c_users_and_groups)
132
- # Get Account assingments
133
- permissions_set = list_permissions_set(instance_arn=store_arn, client=client_sso)
134
- l_permissions_set_arn_name = extends_permissions_set(permissions_sets=permissions_set, store_arn=store_arn,
135
- client_sso=client_sso)
136
-
137
- client_org = boto3.client('organizations')
138
- l_accounts = list_accounts(client_org)
139
- account_assignments = extend_account_assignments(accounts_list=l_accounts,
140
- permissions_sets=l_permissions_set_arn_name,
141
- client_sso=client_sso,
142
- store_arn=store_arn)
143
-
144
- account_assignments = add_users_and_groups_assign(account_assignments_list=account_assignments,
145
- user_and_group_list=c_users_and_groups,
146
- user_list=l_users,
147
- list_permissions_set_arn_name=l_permissions_set_arn_name)
148
- print(Fore.BLUE + emoji.emojize(":sparkle: Getting account assignments, users and groups" + Fore.RESET))
149
- f_accounts = order_accounts_assignments_list(accounts_dict=l_accounts,
150
- account_assignments=account_assignments)
151
- f_path= os.path.join(diagrams_path, "graph_sso_complete.py")
152
- create_sso_mapper_complete(template_file=f_path,
153
- acc_assignments=f_accounts,
154
- d_groups=d_groups)
155
-
156
- f_path = os.path.join(diagrams_path, "graph_sso.py")
157
- create_sso_mapper(template_file=f_path, group_and_members=c_users_and_groups)
158
- print(Fore.YELLOW + emoji.emojize(
159
- f":sparkles: Run -> python3 {diagrams_path}/graph_sso_complete.py " + Fore.RESET))
160
- else:
161
- print(Fore.RED + emoji.emojize(":warning: " + f"The cloud provider {args.cloud} is no available" + Fore.RESET))
162
- if args.version:
163
- get_version(version=__version__)
164
-
165
- return 0
166
-
167
-
168
- if __name__ == '__main__':
169
- main()
1
+ import argparse
2
+ import logging
3
+ import os
4
+
5
+ import argcomplete
6
+ import emoji
7
+ from boto3 import setup_default_session
8
+ from colorama import Fore
9
+
10
+ from .aws.describe_identity_store import (
11
+ add_users_and_groups_assign,
12
+ complete_group_members,
13
+ extend_account_assignments,
14
+ get_members,
15
+ l_groups_to_d_groups,
16
+ list_groups,
17
+ list_users,
18
+ order_accounts_assignments_list,
19
+ )
20
+ from .aws.describe_organization import (
21
+ describe_organization,
22
+ index_accounts,
23
+ index_ous,
24
+ list_accounts,
25
+ list_organizational_units,
26
+ list_roots,
27
+ )
28
+ from .aws.describe_sso import (
29
+ extends_permissions_set,
30
+ list_instances,
31
+ list_permissions_set,
32
+ )
33
+ from .banner.banner import get_version
34
+ from .dgms.graph_mapper import (
35
+ create_file,
36
+ create_mapper,
37
+ create_sso_mapper,
38
+ create_sso_mapper_complete,
39
+ )
40
+ from .dgms.graph_template import (
41
+ graph_template,
42
+ graph_template_sso,
43
+ graph_template_sso_complete,
44
+ )
45
+ from .reports.save_results import save_results
46
+ from .version import __version__
47
+
48
+
49
+ def graph_organizations(diagrams_path, region, auto):
50
+ """
51
+ Create organizations Graph.
52
+
53
+ :param diagrams_path:
54
+ :param region:
55
+ :return:
56
+ """
57
+ template_file = "graph_org.py"
58
+ code_path = f"{diagrams_path}/code"
59
+ json_path = f"{diagrams_path}/json"
60
+ create_file(
61
+ template_content=graph_template,
62
+ file_name=template_file,
63
+ directory_path=code_path,
64
+ )
65
+
66
+ organization = describe_organization(region=region)
67
+ print(Fore.BLUE + emoji.emojize(":sparkle: Getting Organization Info" + Fore.RESET))
68
+ logging.debug(organization)
69
+ logging.debug("The Roots Info")
70
+ roots = list_roots(region=region)
71
+ logging.debug(roots)
72
+
73
+ print(
74
+ Fore.BLUE
75
+ + emoji.emojize(":sparkle: Listing Organizational Units " + Fore.RESET)
76
+ )
77
+ logging.debug("The Organizational Units list ")
78
+ ous = list_organizational_units(parent_id=roots[0]["Id"], region=region)
79
+ logging.debug(ous)
80
+ logging.debug("The Organizational Units list with parents info")
81
+ i_ous = index_ous(ous, region=region)
82
+ logging.debug(i_ous)
83
+
84
+ print(
85
+ Fore.BLUE
86
+ + emoji.emojize(":sparkle: Getting the Account list info" + Fore.RESET)
87
+ )
88
+ l_accounts = list_accounts(region=region)
89
+ logging.debug(l_accounts)
90
+ logging.debug("The Account list with parents info")
91
+
92
+ print(
93
+ Fore.YELLOW
94
+ + emoji.emojize(
95
+ f":information: There are {len(l_accounts)} Accounts in your organization"
96
+ + Fore.RESET
97
+ )
98
+ )
99
+ i_accounts = index_accounts(l_accounts, region=region)
100
+ logging.debug(i_accounts)
101
+
102
+ file_name = "organizations.json"
103
+ save_results(results=i_accounts, filename=file_name, directory_path=json_path)
104
+
105
+ create_mapper(
106
+ template_file=f"{code_path}/{template_file}",
107
+ org=organization,
108
+ root_id=roots[0]["Id"],
109
+ list_ous=ous,
110
+ list_accounts=i_accounts,
111
+ )
112
+ if auto:
113
+ print(f"{Fore.GREEN} ❇️ Creating diagrams in {code_path}")
114
+ command = os.system(f"cd {code_path} && python3 {template_file}")
115
+ if command != 0:
116
+ print(Fore.RED + "❌ Error creating diagrams")
117
+ print(command)
118
+ else:
119
+ print(
120
+ Fore.YELLOW
121
+ + emoji.emojize(
122
+ f":sparkles: Run -> python3 {code_path}/graph_org.py " + Fore.RESET
123
+ )
124
+ )
125
+
126
+
127
+ def graph_identity_center(diagrams_path, region, auto):
128
+ """
129
+ Create Identity center diagram.
130
+
131
+ :param diagrams_path:
132
+ :param region:
133
+ :return:
134
+ """
135
+
136
+ template_file = "graph_sso.py"
137
+ template_file_complete = "graph_sso_complete.py"
138
+
139
+ code_path = f"{diagrams_path}/code"
140
+ json_path = f"{diagrams_path}/json"
141
+
142
+ create_file(
143
+ template_content=graph_template_sso,
144
+ file_name=template_file,
145
+ directory_path=code_path,
146
+ )
147
+ create_file(
148
+ template_content=graph_template_sso_complete,
149
+ file_name=template_file_complete,
150
+ directory_path=code_path,
151
+ )
152
+
153
+ store_instances = list_instances(region=region)
154
+ print(
155
+ Fore.BLUE
156
+ + emoji.emojize(":sparkle: Getting Identity store instance info" + Fore.RESET)
157
+ )
158
+ logging.debug(store_instances)
159
+ store_id = store_instances[0]["IdentityStoreId"]
160
+ store_arn = store_instances[0]["InstanceArn"]
161
+
162
+ print(Fore.BLUE + emoji.emojize(":sparkle: List groups" + Fore.RESET))
163
+ l_groups = list_groups(store_id, region=region)
164
+ logging.debug(l_groups)
165
+ print(
166
+ Fore.YELLOW
167
+ + emoji.emojize(
168
+ f":information: There are {len(l_groups)} Groups in your Identity Store"
169
+ + Fore.RESET
170
+ )
171
+ )
172
+
173
+ print(Fore.BLUE + emoji.emojize(":sparkle: Get groups and Users info" + Fore.RESET))
174
+ m_groups = get_members(store_id, l_groups, region=region)
175
+ logging.debug(m_groups)
176
+ logging.debug("Extend Group Members")
177
+ l_users = list_users(store_id, region=region)
178
+ logging.debug(l_users)
179
+ c_users_and_groups = complete_group_members(m_groups, l_users)
180
+ d_groups = l_groups_to_d_groups(l_groups=c_users_and_groups)
181
+
182
+ logging.debug(c_users_and_groups)
183
+ # Get Account assignments
184
+ permissions_set = list_permissions_set(instance_arn=store_arn, region=region)
185
+ l_permissions_set_arn_name = extends_permissions_set(
186
+ permissions_sets=permissions_set, store_arn=store_arn, region=region
187
+ )
188
+
189
+ l_accounts = list_accounts(region=region)
190
+ account_assignments = extend_account_assignments(
191
+ accounts_list=l_accounts,
192
+ permissions_sets=l_permissions_set_arn_name,
193
+ region=region,
194
+ store_arn=store_arn,
195
+ )
196
+
197
+ account_assignments = add_users_and_groups_assign(
198
+ account_assignments_list=account_assignments,
199
+ user_and_group_list=c_users_and_groups,
200
+ user_list=l_users,
201
+ list_permissions_set_arn_name=l_permissions_set_arn_name,
202
+ )
203
+
204
+ print(
205
+ Fore.BLUE
206
+ + emoji.emojize(
207
+ ":sparkle: Getting account assignments, users and groups" + Fore.RESET
208
+ )
209
+ )
210
+ f_accounts = order_accounts_assignments_list(
211
+ accounts_dict=l_accounts, account_assignments=account_assignments
212
+ )
213
+ f_path = os.path.join(code_path, template_file_complete)
214
+ create_sso_mapper_complete(
215
+ template_file=f_path, acc_assignments=f_accounts, d_groups=d_groups
216
+ )
217
+
218
+ save_results(
219
+ results=f_accounts,
220
+ filename="account_assignments.json",
221
+ directory_path=json_path,
222
+ )
223
+ save_results(results=d_groups, filename="groups.json", directory_path=json_path)
224
+
225
+ f_path = os.path.join(code_path, template_file)
226
+
227
+ create_sso_mapper(template_file=f_path, group_and_members=c_users_and_groups)
228
+
229
+ if auto:
230
+ print(f"{Fore.GREEN} ❇️ Creating diagrams in {code_path}")
231
+ command_1 = os.system(f"cd {code_path} && python3 {template_file}")
232
+ command = os.system(f"cd {code_path} && python3 {template_file_complete}")
233
+
234
+ if command != 0 or command_1 != 0:
235
+ print(Fore.RED + "❌ Error creating diagrams")
236
+ print(command)
237
+ else:
238
+ print(
239
+ Fore.YELLOW
240
+ + emoji.emojize(
241
+ f":sparkles: Run -> python3 {code_path}/{template_file_complete}"
242
+ f" or python3 {code_path}/{template_file}" + Fore.RESET
243
+ )
244
+ )
245
+
246
+
247
+ def main() -> int:
248
+ """
249
+ Crete architecture diagram from your current state.
250
+
251
+ :return:
252
+ """
253
+
254
+ # Initialize parser
255
+ parser = argparse.ArgumentParser()
256
+
257
+ parser.add_argument(
258
+ "-p", "--profile", help="AWS cli profile for AWS Apis", default=None
259
+ )
260
+ parser.add_argument(
261
+ "-od",
262
+ "--output_dir_path",
263
+ help="Name of folder to save the diagrams python code files",
264
+ default="diagrams",
265
+ )
266
+ parser.add_argument("-r", "--region", help="AWS region", default="us-east-2")
267
+ parser.add_argument(
268
+ "-o",
269
+ "--graph_organization",
270
+ help="Set if you want to create graph for your organization",
271
+ action="store_true",
272
+ )
273
+ parser.add_argument(
274
+ "-i",
275
+ "--graph_identity",
276
+ help="Set if you want to create graph for your IAM Center",
277
+ action="store_true",
278
+ )
279
+ parser.add_argument(
280
+ "-a",
281
+ "--auto_create",
282
+ help="Create Automatically diagrams",
283
+ action="store_true",
284
+ default=True,
285
+ )
286
+ parser.add_argument("-v", "--version", help="Show version", action="store_true")
287
+ parser.add_argument("-d", "--debug", help="Debug Mode", action="store_true")
288
+
289
+ # Read arguments from command line
290
+ args = parser.parse_args()
291
+ # Add autocomplete
292
+ argcomplete.autocomplete(parser)
293
+ logging.info(f"The arguments are {args}")
294
+ if args.debug:
295
+ logging.basicConfig(level=logging.DEBUG)
296
+
297
+ diagrams_path = args.output_dir_path
298
+
299
+ region = args.region
300
+
301
+ if args.profile:
302
+ profile = args.profile
303
+ if profile is not None:
304
+ setup_default_session(profile_name=profile)
305
+
306
+ logging.info(f"Profile is: {profile}")
307
+
308
+ if args.graph_organization:
309
+ graph_organizations(
310
+ diagrams_path=diagrams_path, region=region, auto=args.auto_create
311
+ )
312
+
313
+ if args.graph_identity:
314
+ graph_identity_center(
315
+ diagrams_path=diagrams_path, region=region, auto=args.auto_create
316
+ )
317
+
318
+ if args.version:
319
+ get_version(version=__version__)
320
+
321
+ return 0
322
+
323
+
324
+ if __name__ == "__main__":
325
+ main()
src/version.py ADDED
@@ -0,0 +1,2 @@
1
+ """Set version file."""
2
+ __version__ = "1.0.0"
docs/graph_org.py DELETED
@@ -1,8 +0,0 @@
1
-
2
- from diagrams import Diagram, Cluster
3
-
4
- from diagrams.aws.management import Organizations, OrganizationsAccount, OrganizationsOrganizationalUnit
5
-
6
- with Diagram("Organizations-State", show=False, direction="TB"):
7
- ou = OrganizationsOrganizationalUnit("OU")
8
- oa = OrganizationsAccount("Account")
docs/graph_sso.py DELETED
@@ -1,39 +0,0 @@
1
-
2
- from diagrams import Diagram, Cluster
3
-
4
- from diagrams.aws.management import Organizations, OrganizationsAccount, OrganizationsOrganizationalUnit
5
- from diagrams.aws.general import Users, User
6
-
7
- with Diagram("SSO-State", show=False, direction="TB"):
8
- gg = Users("Group")
9
- uu= User("User")
10
-
11
- with Cluster('Groups'):
12
-
13
- with Cluster("AWSAccountFactory"):
14
-
15
- gg_0= [User("velez94@protonma\nil.com"),]
16
-
17
- gg_1= Users("AWSAuditAccountA\ndmins")
18
-
19
- gg_2= Users("AWSLogArchiveAdm\nins")
20
-
21
- with Cluster("AWSControlTowerAdmins"):
22
-
23
- gg_3= [User("velez94@protonma\nil.com"),]
24
-
25
- gg_4= Users("AWSLogArchiveVie\nwers")
26
-
27
- gg_5= Users("AWSSecurityAudit\nors")
28
-
29
- gg_6= Users("AWSSecurityAudit\nPowerUsers")
30
-
31
- with Cluster("DevSecOps_Admins"):
32
-
33
- gg_7= [User("DevSecOpsAdm"),]
34
-
35
- gg_8= Users("AWSServiceCatalo\ngAdmins")
36
-
37
- with Cluster("SecOps_Adms"):
38
-
39
- gg_9= [User("w.alejovl+secops\n-labs@gmail.com"),]