1
+ import requests
2
+ from datetime import datetime
3
+ import logging
4
+ import json
5
+ import os
6
+ from dotenv import load_dotenv
7
+
8
+ load_dotenv ('/app/.env' ) #.env location
9
+
10
+ # DD API settings
11
+
12
+ DD_API_KEY = os .getenv ('DD_API_KEY' ) # DD Token
13
+ DD_APP_KEY = os .getenv ('DD_APP_KEY' ) # DD Application Key
14
+
15
+ # Authomize API settings
16
+ AUTHOMIZE_DD_TOKEN = os .getenv ('AUTHOMIZE_DD_TOKEN' ) #Authomize API Token
17
+ AUTHOMIZE_APP_ID = os .getenv ('AUTHOMIZE_DD_APPID' ) #Authomize Connector ID (appId)
18
+ authomize_batch_size = int (os .getenv ('authomize_batch_size' )) # Authomize Max POST Batch Size
19
+
20
+ #Authomize URLs
21
+ user_url = f"https://api.authomize.com/v2/apps/{ AUTHOMIZE_APP_ID } /accounts/users"
22
+ role_url = f"https://api.authomize.com/v2/apps/{ AUTHOMIZE_APP_ID } /access/grouping"
23
+ user_to_role_url = f"https://api.authomize.com/v2/apps/{ AUTHOMIZE_APP_ID } /association/accounts"
24
+ create_privileges_url = f"https://api.authomize.com/v2/apps/{ AUTHOMIZE_APP_ID } /privileges"
25
+ permission_url = f"https://api.authomize.com/v2/apps/{ AUTHOMIZE_APP_ID } /access/permissions"
26
+
27
+ # Headers for DD
28
+ dd_headers = {
29
+ "Accept" : "application/json" ,
30
+ "DD-API-KEY" : f"{ DD_API_KEY } " ,
31
+ "DD-APPLICATION-KEY" : f"{ DD_APP_KEY } " ,
32
+ }
33
+
34
+ # Authomize header
35
+ authomize_headers = {
36
+ 'Content-Type' : 'application/json' ,
37
+ 'Authorization' : f'{ AUTHOMIZE_DD_TOKEN } '
38
+ }
39
+
40
+ logging .basicConfig (filename = '/app/datadog/datadog.log' , level = logging .INFO , format = "%(asctime)s - %(levelname)s - %(message)s" , filemode = 'w' )
41
+
42
+ dd_accounts_url = "https://api.datadoghq.com/api/v2/users"
43
+ page_size = 10
44
+ page_number = 0 #start from page 0
45
+ total_filtered_count = None
46
+ user_data = []
47
+ role_data = []
48
+ permission_data = []
49
+
50
+ while total_filtered_count is None or (page_number - 1 ) * page_size < total_filtered_count :
51
+ params = {
52
+ "page[size]" : page_size ,
53
+ "page[number]" : page_number ,
54
+ }
55
+ response = requests .get (dd_accounts_url , headers = dd_headers , params = params )
56
+
57
+ if response .status_code == 200 :
58
+ json_data = response .json ()
59
+
60
+ for user in json_data .get ("data" , []):
61
+ if user ['type' ] == 'users' :
62
+ user_data .append (user )
63
+
64
+ for role in json_data .get ("included" , []):
65
+ if role ['type' ] == 'roles' :
66
+ role_data .append (role )
67
+
68
+ for permission in json_data .get ("included" , []):
69
+ if permission ['type' ] == 'permissions' :
70
+ permission_data .append (permission )
71
+
72
+ total_filtered_count = json_data ["meta" ]["page" ]["total_filtered_count" ]
73
+ page_number += 1
74
+ else :
75
+ print (f"Error - Status Code: { response .status_code } Response Text: { response .text } " )
76
+ break
77
+
78
+ dd_users = []
79
+ user_to_role = []
80
+
81
+ for user in user_data :
82
+ user_info = {
83
+ 'uniqueId' : user ['id' ],
84
+ 'originId' : user ['id' ],
85
+ 'name' : user ['attributes' ]['name' ],
86
+ 'email' : user ['attributes' ]['email' ],
87
+ }
88
+
89
+ if user ['attributes' ]['disabled' ]:
90
+ status = 'Disabled'
91
+ elif user ['attributes' ]['status' ] == 'Active' :
92
+ status = 'Enabled'
93
+ else :
94
+ status = 'Unknown'
95
+
96
+ user_info ['status' ] = status
97
+ dd_users .append (user_info )
98
+
99
+ for user_role in user ['relationships' ]['roles' ]['data' ]:
100
+ user_relationship = {
101
+ 'sourceId' : user ['id' ],
102
+ 'targetId' : user_role ['id' ],
103
+ }
104
+ user_to_role .append (user_relationship )
105
+
106
+ roles = []
107
+ role_to_permission = []
108
+
109
+ for role in role_data :
110
+ if role ['type' ] == 'roles' :
111
+ role_dict = {
112
+ 'uniqueId' : role ['id' ],
113
+ 'originId' : role ['id' ],
114
+ 'name' : role ['attributes' ]['name' ],
115
+ 'originType' : 'Role' ,
116
+ 'type' : 'Group' ,
117
+ 'isRole' : True
118
+ }
119
+ if role_dict not in roles :
120
+ roles .append (role_dict )
121
+
122
+ for role_permission in role ['relationships' ]['permissions' ]['data' ]:
123
+ permission_dict = {
124
+ 'sourceUniqueId' : role ['id' ],
125
+ 'sourceType' : "Grouping" ,
126
+ 'privilegeId' : role_permission ['id' ]
127
+ }
128
+ if permission_dict not in role_to_permission :
129
+ role_to_permission .append (permission_dict )
130
+
131
+ privileges = []
132
+
133
+ for privilege in permission_data :
134
+ if privilege ['type' ] == 'permissions' :
135
+ uniqueId = privilege ['id' ]
136
+ originId = privilege ['id' ]
137
+ display_type = privilege ['attributes' ]['display_type' ]
138
+ if display_type == 'read' :
139
+ type = "Read"
140
+ elif display_type == 'write' :
141
+ type = "Write"
142
+ else :
143
+ type = "Unknown"
144
+
145
+ originName = privilege ['attributes' ]['display_name' ]
146
+ privilege_info = {'uniqueId' : uniqueId , 'originId' : originId , 'type' : type , 'originName' : originName }
147
+
148
+ if privilege_info not in privileges :
149
+ privileges .append (privilege_info )
150
+
151
+ accepted_timestamps = []
152
+
153
+ def post_authomize_data (url , data ):
154
+ for i in range (0 , len (data ), authomize_batch_size ):
155
+ batch = data [i :i + authomize_batch_size ]
156
+ payload = {
157
+ 'data' : batch ,
158
+ 'validateOnly' : False
159
+ }
160
+ try :
161
+ response = requests .post (url , headers = authomize_headers , json = payload )
162
+ response .raise_for_status ()
163
+ # Log the response for both versions of the function
164
+ logging .info ("Authomize API Response for %s (Batch %d): %s" , url , i // authomize_batch_size + 1 , response .text )
165
+ # Handle the accepted_timestamp only if it's present in the response
166
+ response_json = response .json ()
167
+ accepted_timestamp = response_json .get ("acceptedTimestamp" )
168
+ if accepted_timestamp :
169
+ accepted_timestamps .append (accepted_timestamp )
170
+ except requests .exceptions .RequestException as e :
171
+ logging .error ("Error occurred while sending data to Authomize API (Batch %d): %s" , i // authomize_batch_size + 1 , e )
172
+ logging .error ("Response body: %s" , response .text ) # Log the response body when an error occurs
173
+ logging .error ("Data causing the issue: %s" , batch ) # Add this line to log the problematic data
174
+
175
+
176
+ # Post users and write to file for troubleshooting
177
+ with open ('/app/datadog/users_list.json' , 'w' ) as file :
178
+ file .write (json .dumps (dd_users ))
179
+ post_authomize_data (user_url , dd_users )
180
+
181
+ # Post roles and write to file for troubleshooting
182
+ with open ('/app/datadog/roles_list.json' , 'w' ) as file :
183
+ file .write (json .dumps (roles ))
184
+ post_authomize_data (role_url , roles )
185
+
186
+ # Post users to roles and write to file for troubleshooting
187
+ with open ('/app/datadog/user_to_role_list.json' , 'w' ) as file :
188
+ file .write (json .dumps (user_to_role ))
189
+ post_authomize_data (user_to_role_url , user_to_role )
190
+
191
+ # Post privileges and write to file for troubleshooting
192
+ with open ('/app/datadog/privilege_list.json' , 'w' ) as file :
193
+ file .write (json .dumps (privileges ))
194
+ post_authomize_data (create_privileges_url , privileges )
195
+
196
+ # Post privileges and write to file for troubleshooting
197
+ with open ('/app/datadog/permission_list.json' , 'w' ) as file :
198
+ file .write (json .dumps (role_to_permission ))
199
+ post_authomize_data (permission_url , role_to_permission )
200
+
201
+ # take first accepted timestamp
202
+ timestamp = accepted_timestamps [0 ][:- 6 ]
203
+ delete_url = f'https://api.authomize.com/v2/apps/{ AUTHOMIZE_APP_ID } /data?modifiedBefore={ timestamp } '
204
+ delete_response = requests .delete (delete_url , headers = authomize_headers )
205
+ logging .info ("Authomize Delete Response for: %s: %s" , delete_url , delete_response .text )
0 commit comments