cartography 0.102.0rc2__py3-none-any.whl → 0.103.0rc1__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.

Potentially problematic release.


This version of cartography might be problematic. Click here for more details.

Files changed (251) hide show
  1. cartography/__main__.py +1 -2
  2. cartography/_version.py +2 -2
  3. cartography/cli.py +302 -253
  4. cartography/client/core/tx.py +39 -18
  5. cartography/config.py +4 -0
  6. cartography/driftdetect/__main__.py +1 -2
  7. cartography/driftdetect/add_shortcut.py +10 -2
  8. cartography/driftdetect/cli.py +71 -75
  9. cartography/driftdetect/detect_deviations.py +7 -3
  10. cartography/driftdetect/get_states.py +20 -8
  11. cartography/driftdetect/model.py +5 -5
  12. cartography/driftdetect/serializers.py +8 -6
  13. cartography/driftdetect/storage.py +2 -2
  14. cartography/graph/cleanupbuilder.py +35 -15
  15. cartography/graph/job.py +46 -17
  16. cartography/graph/querybuilder.py +165 -80
  17. cartography/graph/statement.py +35 -26
  18. cartography/intel/analysis.py +4 -1
  19. cartography/intel/aws/__init__.py +114 -55
  20. cartography/intel/aws/apigateway.py +134 -63
  21. cartography/intel/aws/cloudtrail.py +127 -0
  22. cartography/intel/aws/config.py +56 -20
  23. cartography/intel/aws/dynamodb.py +108 -40
  24. cartography/intel/aws/ec2/__init__.py +2 -2
  25. cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
  26. cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
  27. cartography/intel/aws/ec2/images.py +49 -20
  28. cartography/intel/aws/ec2/instances.py +234 -136
  29. cartography/intel/aws/ec2/internet_gateways.py +40 -11
  30. cartography/intel/aws/ec2/key_pairs.py +44 -20
  31. cartography/intel/aws/ec2/launch_templates.py +101 -59
  32. cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
  33. cartography/intel/aws/ec2/load_balancers.py +82 -42
  34. cartography/intel/aws/ec2/network_acls.py +89 -65
  35. cartography/intel/aws/ec2/network_interfaces.py +146 -87
  36. cartography/intel/aws/ec2/reserved_instances.py +45 -16
  37. cartography/intel/aws/ec2/route_tables.py +138 -98
  38. cartography/intel/aws/ec2/security_groups.py +71 -21
  39. cartography/intel/aws/ec2/snapshots.py +61 -22
  40. cartography/intel/aws/ec2/subnets.py +54 -18
  41. cartography/intel/aws/ec2/tgw.py +100 -34
  42. cartography/intel/aws/ec2/util.py +1 -1
  43. cartography/intel/aws/ec2/volumes.py +69 -41
  44. cartography/intel/aws/ec2/vpc.py +37 -12
  45. cartography/intel/aws/ec2/vpc_peerings.py +83 -24
  46. cartography/intel/aws/ecr.py +88 -32
  47. cartography/intel/aws/ecs.py +83 -47
  48. cartography/intel/aws/eks.py +55 -29
  49. cartography/intel/aws/elasticache.py +42 -18
  50. cartography/intel/aws/elasticsearch.py +57 -20
  51. cartography/intel/aws/emr.py +61 -23
  52. cartography/intel/aws/iam.py +401 -145
  53. cartography/intel/aws/iam_instance_profiles.py +22 -22
  54. cartography/intel/aws/identitycenter.py +71 -37
  55. cartography/intel/aws/inspector.py +159 -89
  56. cartography/intel/aws/kms.py +92 -38
  57. cartography/intel/aws/lambda_function.py +103 -34
  58. cartography/intel/aws/organizations.py +30 -10
  59. cartography/intel/aws/permission_relationships.py +133 -51
  60. cartography/intel/aws/rds.py +249 -85
  61. cartography/intel/aws/redshift.py +107 -46
  62. cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
  63. cartography/intel/aws/resources.py +53 -46
  64. cartography/intel/aws/route53.py +108 -61
  65. cartography/intel/aws/s3.py +168 -83
  66. cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
  67. cartography/intel/aws/secretsmanager.py +24 -12
  68. cartography/intel/aws/securityhub.py +20 -9
  69. cartography/intel/aws/sns.py +166 -0
  70. cartography/intel/aws/sqs.py +60 -28
  71. cartography/intel/aws/ssm.py +70 -30
  72. cartography/intel/aws/util/arns.py +7 -7
  73. cartography/intel/aws/util/common.py +31 -4
  74. cartography/intel/azure/__init__.py +78 -19
  75. cartography/intel/azure/compute.py +101 -27
  76. cartography/intel/azure/cosmosdb.py +496 -170
  77. cartography/intel/azure/sql.py +296 -105
  78. cartography/intel/azure/storage.py +322 -113
  79. cartography/intel/azure/subscription.py +39 -23
  80. cartography/intel/azure/tenant.py +13 -4
  81. cartography/intel/azure/util/credentials.py +95 -55
  82. cartography/intel/bigfix/__init__.py +2 -2
  83. cartography/intel/bigfix/computers.py +93 -65
  84. cartography/intel/create_indexes.py +3 -2
  85. cartography/intel/crowdstrike/__init__.py +11 -9
  86. cartography/intel/crowdstrike/endpoints.py +5 -1
  87. cartography/intel/crowdstrike/spotlight.py +8 -3
  88. cartography/intel/cve/__init__.py +46 -13
  89. cartography/intel/cve/feed.py +48 -12
  90. cartography/intel/digitalocean/__init__.py +22 -13
  91. cartography/intel/digitalocean/compute.py +75 -108
  92. cartography/intel/digitalocean/management.py +44 -80
  93. cartography/intel/digitalocean/platform.py +48 -43
  94. cartography/intel/dns.py +36 -10
  95. cartography/intel/duo/__init__.py +21 -16
  96. cartography/intel/duo/api_host.py +14 -9
  97. cartography/intel/duo/endpoints.py +50 -45
  98. cartography/intel/duo/groups.py +18 -14
  99. cartography/intel/duo/phones.py +37 -34
  100. cartography/intel/duo/tokens.py +26 -23
  101. cartography/intel/duo/users.py +54 -50
  102. cartography/intel/duo/web_authn_credentials.py +30 -25
  103. cartography/intel/entra/__init__.py +25 -7
  104. cartography/intel/entra/ou.py +112 -0
  105. cartography/intel/entra/users.py +69 -63
  106. cartography/intel/gcp/__init__.py +185 -49
  107. cartography/intel/gcp/compute.py +418 -231
  108. cartography/intel/gcp/crm.py +96 -43
  109. cartography/intel/gcp/dns.py +60 -19
  110. cartography/intel/gcp/gke.py +72 -38
  111. cartography/intel/gcp/iam.py +61 -41
  112. cartography/intel/gcp/storage.py +84 -55
  113. cartography/intel/github/__init__.py +13 -11
  114. cartography/intel/github/repos.py +270 -137
  115. cartography/intel/github/teams.py +170 -88
  116. cartography/intel/github/users.py +70 -39
  117. cartography/intel/github/util.py +36 -34
  118. cartography/intel/gsuite/__init__.py +47 -26
  119. cartography/intel/gsuite/api.py +73 -30
  120. cartography/intel/jamf/__init__.py +19 -1
  121. cartography/intel/jamf/computers.py +30 -7
  122. cartography/intel/jamf/util.py +7 -2
  123. cartography/intel/kandji/__init__.py +6 -3
  124. cartography/intel/kandji/devices.py +14 -8
  125. cartography/intel/kubernetes/namespaces.py +7 -4
  126. cartography/intel/kubernetes/pods.py +7 -4
  127. cartography/intel/kubernetes/services.py +8 -4
  128. cartography/intel/lastpass/__init__.py +2 -2
  129. cartography/intel/lastpass/users.py +23 -12
  130. cartography/intel/oci/__init__.py +44 -11
  131. cartography/intel/oci/iam.py +134 -38
  132. cartography/intel/oci/organizations.py +13 -6
  133. cartography/intel/oci/utils.py +43 -20
  134. cartography/intel/okta/__init__.py +66 -15
  135. cartography/intel/okta/applications.py +42 -20
  136. cartography/intel/okta/awssaml.py +93 -33
  137. cartography/intel/okta/factors.py +16 -4
  138. cartography/intel/okta/groups.py +56 -29
  139. cartography/intel/okta/organization.py +5 -1
  140. cartography/intel/okta/origins.py +6 -2
  141. cartography/intel/okta/roles.py +15 -5
  142. cartography/intel/okta/users.py +20 -8
  143. cartography/intel/okta/utils.py +6 -4
  144. cartography/intel/pagerduty/__init__.py +8 -7
  145. cartography/intel/pagerduty/escalation_policies.py +18 -6
  146. cartography/intel/pagerduty/schedules.py +12 -4
  147. cartography/intel/pagerduty/services.py +11 -4
  148. cartography/intel/pagerduty/teams.py +8 -3
  149. cartography/intel/pagerduty/users.py +3 -1
  150. cartography/intel/pagerduty/vendors.py +3 -1
  151. cartography/intel/semgrep/__init__.py +24 -6
  152. cartography/intel/semgrep/dependencies.py +50 -28
  153. cartography/intel/semgrep/deployment.py +3 -1
  154. cartography/intel/semgrep/findings.py +42 -18
  155. cartography/intel/snipeit/__init__.py +17 -3
  156. cartography/intel/snipeit/asset.py +12 -6
  157. cartography/intel/snipeit/user.py +8 -5
  158. cartography/intel/snipeit/util.py +9 -4
  159. cartography/models/aws/apigateway.py +21 -17
  160. cartography/models/aws/apigatewaycertificate.py +28 -22
  161. cartography/models/aws/apigatewayresource.py +28 -20
  162. cartography/models/aws/apigatewaystage.py +33 -25
  163. cartography/models/aws/cloudtrail/__init__.py +0 -0
  164. cartography/models/aws/cloudtrail/trail.py +61 -0
  165. cartography/models/aws/dynamodb/gsi.py +30 -22
  166. cartography/models/aws/dynamodb/tables.py +25 -17
  167. cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
  168. cartography/models/aws/ec2/images.py +36 -34
  169. cartography/models/aws/ec2/instances.py +51 -45
  170. cartography/models/aws/ec2/keypair.py +21 -16
  171. cartography/models/aws/ec2/keypair_instance.py +28 -21
  172. cartography/models/aws/ec2/launch_configurations.py +30 -26
  173. cartography/models/aws/ec2/launch_template_versions.py +48 -38
  174. cartography/models/aws/ec2/launch_templates.py +21 -17
  175. cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
  176. cartography/models/aws/ec2/load_balancers.py +47 -37
  177. cartography/models/aws/ec2/network_acl_rules.py +38 -30
  178. cartography/models/aws/ec2/network_acls.py +38 -29
  179. cartography/models/aws/ec2/networkinterface_instance.py +52 -39
  180. cartography/models/aws/ec2/networkinterfaces.py +53 -37
  181. cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
  182. cartography/models/aws/ec2/reservations.py +18 -14
  183. cartography/models/aws/ec2/route_table_associations.py +44 -34
  184. cartography/models/aws/ec2/route_tables.py +50 -43
  185. cartography/models/aws/ec2/routes.py +45 -37
  186. cartography/models/aws/ec2/securitygroup_instance.py +29 -20
  187. cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
  188. cartography/models/aws/ec2/subnet_instance.py +24 -19
  189. cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
  190. cartography/models/aws/ec2/volumes.py +47 -40
  191. cartography/models/aws/eks/clusters.py +23 -21
  192. cartography/models/aws/emr.py +32 -30
  193. cartography/models/aws/iam/instanceprofile.py +33 -24
  194. cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
  195. cartography/models/aws/identitycenter/awspermissionset.py +37 -29
  196. cartography/models/aws/identitycenter/awsssouser.py +23 -21
  197. cartography/models/aws/inspector/findings.py +77 -65
  198. cartography/models/aws/inspector/packages.py +35 -29
  199. cartography/models/aws/s3/__init__.py +0 -0
  200. cartography/models/aws/s3/account_public_access_block.py +51 -0
  201. cartography/models/aws/sns/__init__.py +0 -0
  202. cartography/models/aws/sns/topic.py +50 -0
  203. cartography/models/aws/ssm/instance_information.py +51 -39
  204. cartography/models/aws/ssm/instance_patch.py +32 -26
  205. cartography/models/bigfix/bigfix_computer.py +42 -38
  206. cartography/models/bigfix/bigfix_root.py +3 -3
  207. cartography/models/core/common.py +12 -10
  208. cartography/models/core/nodes.py +5 -2
  209. cartography/models/core/relationships.py +14 -6
  210. cartography/models/crowdstrike/hosts.py +37 -35
  211. cartography/models/cve/cve.py +34 -32
  212. cartography/models/cve/cve_feed.py +6 -6
  213. cartography/models/digitalocean/__init__.py +0 -0
  214. cartography/models/digitalocean/account.py +21 -0
  215. cartography/models/digitalocean/droplet.py +56 -0
  216. cartography/models/digitalocean/project.py +48 -0
  217. cartography/models/duo/api_host.py +3 -3
  218. cartography/models/duo/endpoint.py +43 -41
  219. cartography/models/duo/group.py +14 -14
  220. cartography/models/duo/phone.py +27 -27
  221. cartography/models/duo/token.py +16 -16
  222. cartography/models/duo/user.py +46 -44
  223. cartography/models/duo/web_authn_credential.py +27 -19
  224. cartography/models/entra/ou.py +48 -0
  225. cartography/models/entra/tenant.py +24 -18
  226. cartography/models/entra/user.py +64 -48
  227. cartography/models/gcp/iam.py +23 -23
  228. cartography/models/github/orgs.py +5 -4
  229. cartography/models/github/teams.py +37 -31
  230. cartography/models/github/users.py +34 -23
  231. cartography/models/kandji/device.py +22 -16
  232. cartography/models/kandji/tenant.py +6 -4
  233. cartography/models/lastpass/tenant.py +3 -3
  234. cartography/models/lastpass/user.py +32 -28
  235. cartography/models/semgrep/dependencies.py +36 -24
  236. cartography/models/semgrep/deployment.py +5 -5
  237. cartography/models/semgrep/findings.py +58 -42
  238. cartography/models/semgrep/locations.py +27 -21
  239. cartography/models/snipeit/asset.py +30 -21
  240. cartography/models/snipeit/tenant.py +6 -4
  241. cartography/models/snipeit/user.py +19 -12
  242. cartography/stats.py +3 -3
  243. cartography/sync.py +107 -31
  244. cartography/util.py +84 -62
  245. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/METADATA +3 -14
  246. cartography-0.103.0rc1.dist-info/RECORD +396 -0
  247. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/WHEEL +1 -1
  248. cartography-0.102.0rc2.dist-info/RECORD +0 -381
  249. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/entry_points.txt +0 -0
  250. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/licenses/LICENSE +0 -0
  251. {cartography-0.102.0rc2.dist-info → cartography-0.103.0rc1.dist-info}/top_level.txt +0 -0
@@ -24,17 +24,19 @@ from cartography.util import run_analysis_job
24
24
  from cartography.util import timeit
25
25
 
26
26
  logger = logging.getLogger(__name__)
27
- Resources = namedtuple('Resources', 'compute container crm_v1 crm_v2 dns storage serviceusage iam')
27
+ Resources = namedtuple(
28
+ "Resources", "compute container crm_v1 crm_v2 dns storage serviceusage iam"
29
+ )
28
30
 
29
31
  # Mapping of service short names to their full names as in docs. See https://developers.google.com/apis-explorer,
30
32
  # and https://cloud.google.com/service-usage/docs/reference/rest/v1/services#ServiceConfig
31
- Services = namedtuple('Services', 'compute storage gke dns iam')
33
+ Services = namedtuple("Services", "compute storage gke dns iam")
32
34
  service_names = Services(
33
- compute='compute.googleapis.com',
34
- storage='storage.googleapis.com',
35
- gke='container.googleapis.com',
36
- dns='dns.googleapis.com',
37
- iam='iam.googleapis.com',
35
+ compute="compute.googleapis.com",
36
+ storage="storage.googleapis.com",
37
+ gke="container.googleapis.com",
38
+ dns="dns.googleapis.com",
39
+ iam="iam.googleapis.com",
38
40
  )
39
41
 
40
42
 
@@ -47,7 +49,12 @@ def _get_crm_resource_v1(credentials: GoogleCredentials) -> Resource:
47
49
  """
48
50
  # cache_discovery=False to suppress extra warnings.
49
51
  # See https://github.com/googleapis/google-api-python-client/issues/299#issuecomment-268915510 and related issues
50
- return googleapiclient.discovery.build('cloudresourcemanager', 'v1', credentials=credentials, cache_discovery=False)
52
+ return googleapiclient.discovery.build(
53
+ "cloudresourcemanager",
54
+ "v1",
55
+ credentials=credentials,
56
+ cache_discovery=False,
57
+ )
51
58
 
52
59
 
53
60
  def _get_crm_resource_v2(credentials: GoogleCredentials) -> Resource:
@@ -57,7 +64,12 @@ def _get_crm_resource_v2(credentials: GoogleCredentials) -> Resource:
57
64
  :param credentials: The GoogleCredentials object
58
65
  :return: A CRM v2 resource object
59
66
  """
60
- return googleapiclient.discovery.build('cloudresourcemanager', 'v2', credentials=credentials, cache_discovery=False)
67
+ return googleapiclient.discovery.build(
68
+ "cloudresourcemanager",
69
+ "v2",
70
+ credentials=credentials,
71
+ cache_discovery=False,
72
+ )
61
73
 
62
74
 
63
75
  def _get_compute_resource(credentials: GoogleCredentials) -> Resource:
@@ -67,7 +79,12 @@ def _get_compute_resource(credentials: GoogleCredentials) -> Resource:
67
79
  :param credentials: The GoogleCredentials object
68
80
  :return: A Compute resource object
69
81
  """
70
- return googleapiclient.discovery.build('compute', 'v1', credentials=credentials, cache_discovery=False)
82
+ return googleapiclient.discovery.build(
83
+ "compute",
84
+ "v1",
85
+ credentials=credentials,
86
+ cache_discovery=False,
87
+ )
71
88
 
72
89
 
73
90
  def _get_storage_resource(credentials: GoogleCredentials) -> Resource:
@@ -79,7 +96,12 @@ def _get_storage_resource(credentials: GoogleCredentials) -> Resource:
79
96
  :param credentials: The GoogleCredentials object
80
97
  :return: A Storage resource object
81
98
  """
82
- return googleapiclient.discovery.build('storage', 'v1', credentials=credentials, cache_discovery=False)
99
+ return googleapiclient.discovery.build(
100
+ "storage",
101
+ "v1",
102
+ credentials=credentials,
103
+ cache_discovery=False,
104
+ )
83
105
 
84
106
 
85
107
  def _get_container_resource(credentials: GoogleCredentials) -> Resource:
@@ -90,7 +112,12 @@ def _get_container_resource(credentials: GoogleCredentials) -> Resource:
90
112
  :param credentials: The GoogleCredentials object
91
113
  :return: A Container resource object
92
114
  """
93
- return googleapiclient.discovery.build('container', 'v1', credentials=credentials, cache_discovery=False)
115
+ return googleapiclient.discovery.build(
116
+ "container",
117
+ "v1",
118
+ credentials=credentials,
119
+ cache_discovery=False,
120
+ )
94
121
 
95
122
 
96
123
  def _get_dns_resource(credentials: GoogleCredentials) -> Resource:
@@ -101,7 +128,12 @@ def _get_dns_resource(credentials: GoogleCredentials) -> Resource:
101
128
  :param credentials: The GoogleCredentials object
102
129
  :return: A DNS resource object
103
130
  """
104
- return googleapiclient.discovery.build('dns', 'v1', credentials=credentials, cache_discovery=False)
131
+ return googleapiclient.discovery.build(
132
+ "dns",
133
+ "v1",
134
+ credentials=credentials,
135
+ cache_discovery=False,
136
+ )
105
137
 
106
138
 
107
139
  def _get_serviceusage_resource(credentials: GoogleCredentials) -> Resource:
@@ -112,14 +144,21 @@ def _get_serviceusage_resource(credentials: GoogleCredentials) -> Resource:
112
144
  :param credentials: The GoogleCredentials object
113
145
  :return: A serviceusage resource object
114
146
  """
115
- return googleapiclient.discovery.build('serviceusage', 'v1', credentials=credentials, cache_discovery=False)
147
+ return googleapiclient.discovery.build(
148
+ "serviceusage",
149
+ "v1",
150
+ credentials=credentials,
151
+ cache_discovery=False,
152
+ )
116
153
 
117
154
 
118
155
  def _get_iam_resource(credentials: GoogleCredentials) -> Resource:
119
156
  """
120
157
  Instantiates a Google IAM resource object to call the IAM API.
121
158
  """
122
- return googleapiclient.discovery.build('iam', 'v1', credentials=credentials, cache_discovery=False)
159
+ return googleapiclient.discovery.build(
160
+ "iam", "v1", credentials=credentials, cache_discovery=False
161
+ )
123
162
 
124
163
 
125
164
  def _initialize_resources(credentials: GoogleCredentials) -> Resource:
@@ -150,16 +189,22 @@ def _services_enabled_on_project(serviceusage: Resource, project_id: str) -> Set
150
189
  :return: A set of services that are enabled on the project
151
190
  """
152
191
  try:
153
- req = serviceusage.services().list(parent=f'projects/{project_id}', filter='state:ENABLED')
192
+ req = serviceusage.services().list(
193
+ parent=f"projects/{project_id}",
194
+ filter="state:ENABLED",
195
+ )
154
196
  services = set()
155
197
  while req is not None:
156
198
  res = req.execute()
157
- if 'services' in res:
158
- services.update({svc['config']['name'] for svc in res['services']})
159
- req = serviceusage.services().list_next(previous_request=req, previous_response=res)
199
+ if "services" in res:
200
+ services.update({svc["config"]["name"] for svc in res["services"]})
201
+ req = serviceusage.services().list_next(
202
+ previous_request=req,
203
+ previous_response=res,
204
+ )
160
205
  return services
161
206
  except googleapiclient.discovery.HttpError as http_error:
162
- http_error = json.loads(http_error.content.decode('utf-8'))
207
+ http_error = json.loads(http_error.content.decode("utf-8"))
163
208
  # This is set to log-level `info` because Google creates many projects under the hood that cartography cannot
164
209
  # audit (e.g. adding a script to a Google spreadsheet causes a project to get created) and we don't need to emit
165
210
  # a warning for these projects.
@@ -172,7 +217,10 @@ def _services_enabled_on_project(serviceusage: Resource, project_id: str) -> Set
172
217
 
173
218
 
174
219
  def _sync_single_project_compute(
175
- neo4j_session: neo4j.Session, resources: Resource, project_id: str, gcp_update_tag: int,
220
+ neo4j_session: neo4j.Session,
221
+ resources: Resource,
222
+ project_id: str,
223
+ gcp_update_tag: int,
176
224
  common_job_parameters: Dict,
177
225
  ) -> None:
178
226
  """
@@ -189,11 +237,20 @@ def _sync_single_project_compute(
189
237
  enabled_services = _services_enabled_on_project(resources.serviceusage, project_id)
190
238
  compute_cred = _get_compute_resource(get_gcp_credentials())
191
239
  if service_names.compute in enabled_services:
192
- compute.sync(neo4j_session, compute_cred, project_id, gcp_update_tag, common_job_parameters)
240
+ compute.sync(
241
+ neo4j_session,
242
+ compute_cred,
243
+ project_id,
244
+ gcp_update_tag,
245
+ common_job_parameters,
246
+ )
193
247
 
194
248
 
195
249
  def _sync_single_project_storage(
196
- neo4j_session: neo4j.Session, resources: Resource, project_id: str, gcp_update_tag: int,
250
+ neo4j_session: neo4j.Session,
251
+ resources: Resource,
252
+ project_id: str,
253
+ gcp_update_tag: int,
197
254
  common_job_parameters: Dict,
198
255
  ) -> None:
199
256
  """
@@ -210,11 +267,20 @@ def _sync_single_project_storage(
210
267
  enabled_services = _services_enabled_on_project(resources.serviceusage, project_id)
211
268
  storage_cred = _get_storage_resource(get_gcp_credentials())
212
269
  if service_names.storage in enabled_services:
213
- storage.sync_gcp_buckets(neo4j_session, storage_cred, project_id, gcp_update_tag, common_job_parameters)
270
+ storage.sync_gcp_buckets(
271
+ neo4j_session,
272
+ storage_cred,
273
+ project_id,
274
+ gcp_update_tag,
275
+ common_job_parameters,
276
+ )
214
277
 
215
278
 
216
279
  def _sync_single_project_gke(
217
- neo4j_session: neo4j.Session, resources: Resource, project_id: str, gcp_update_tag: int,
280
+ neo4j_session: neo4j.Session,
281
+ resources: Resource,
282
+ project_id: str,
283
+ gcp_update_tag: int,
218
284
  common_job_parameters: Dict,
219
285
  ) -> None:
220
286
  """
@@ -231,11 +297,20 @@ def _sync_single_project_gke(
231
297
  enabled_services = _services_enabled_on_project(resources.serviceusage, project_id)
232
298
  container_cred = _get_container_resource(get_gcp_credentials())
233
299
  if service_names.gke in enabled_services:
234
- gke.sync_gke_clusters(neo4j_session, container_cred, project_id, gcp_update_tag, common_job_parameters)
300
+ gke.sync_gke_clusters(
301
+ neo4j_session,
302
+ container_cred,
303
+ project_id,
304
+ gcp_update_tag,
305
+ common_job_parameters,
306
+ )
235
307
 
236
308
 
237
309
  def _sync_single_project_dns(
238
- neo4j_session: neo4j.Session, resources: Resource, project_id: str, gcp_update_tag: int,
310
+ neo4j_session: neo4j.Session,
311
+ resources: Resource,
312
+ project_id: str,
313
+ gcp_update_tag: int,
239
314
  common_job_parameters: Dict,
240
315
  ) -> None:
241
316
  """
@@ -252,7 +327,13 @@ def _sync_single_project_dns(
252
327
  enabled_services = _services_enabled_on_project(resources.serviceusage, project_id)
253
328
  dns_cred = _get_dns_resource(get_gcp_credentials())
254
329
  if service_names.dns in enabled_services:
255
- dns.sync(neo4j_session, dns_cred, project_id, gcp_update_tag, common_job_parameters)
330
+ dns.sync(
331
+ neo4j_session,
332
+ dns_cred,
333
+ project_id,
334
+ gcp_update_tag,
335
+ common_job_parameters,
336
+ )
256
337
 
257
338
 
258
339
  def _sync_single_project_iam(
@@ -276,12 +357,17 @@ def _sync_single_project_iam(
276
357
  enabled_services = _services_enabled_on_project(resources.serviceusage, project_id)
277
358
  iam_cred = _get_iam_resource(get_gcp_credentials())
278
359
  if service_names.iam in enabled_services:
279
- iam.sync(neo4j_session, iam_cred, project_id, gcp_update_tag, common_job_parameters)
360
+ iam.sync(
361
+ neo4j_session, iam_cred, project_id, gcp_update_tag, common_job_parameters
362
+ )
280
363
 
281
364
 
282
365
  def _sync_multiple_projects(
283
- neo4j_session: neo4j.Session, resources: Resource, projects: List[Dict],
284
- gcp_update_tag: int, common_job_parameters: Dict,
366
+ neo4j_session: neo4j.Session,
367
+ resources: Resource,
368
+ projects: List[Dict],
369
+ gcp_update_tag: int,
370
+ common_job_parameters: Dict,
285
371
  ) -> None:
286
372
  """
287
373
  Handles graph sync for multiple GCP projects.
@@ -296,36 +382,67 @@ def _sync_multiple_projects(
296
382
  :return: Nothing
297
383
  """
298
384
  logger.info("Syncing %d GCP projects.", len(projects))
299
- crm.sync_gcp_projects(neo4j_session, projects, gcp_update_tag, common_job_parameters)
385
+ crm.sync_gcp_projects(
386
+ neo4j_session,
387
+ projects,
388
+ gcp_update_tag,
389
+ common_job_parameters,
390
+ )
300
391
  # Compute data sync
301
392
  for project in projects:
302
- project_id = project['projectId']
393
+ project_id = project["projectId"]
303
394
  logger.info("Syncing GCP project %s for Compute.", project_id)
304
- _sync_single_project_compute(neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters)
395
+ _sync_single_project_compute(
396
+ neo4j_session,
397
+ resources,
398
+ project_id,
399
+ gcp_update_tag,
400
+ common_job_parameters,
401
+ )
305
402
 
306
403
  # Storage data sync
307
404
  for project in projects:
308
- project_id = project['projectId']
405
+ project_id = project["projectId"]
309
406
  logger.info("Syncing GCP project %s for Storage", project_id)
310
- _sync_single_project_storage(neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters)
407
+ _sync_single_project_storage(
408
+ neo4j_session,
409
+ resources,
410
+ project_id,
411
+ gcp_update_tag,
412
+ common_job_parameters,
413
+ )
311
414
 
312
415
  # GKE data sync
313
416
  for project in projects:
314
- project_id = project['projectId']
417
+ project_id = project["projectId"]
315
418
  logger.info("Syncing GCP project %s for GKE", project_id)
316
- _sync_single_project_gke(neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters)
419
+ _sync_single_project_gke(
420
+ neo4j_session,
421
+ resources,
422
+ project_id,
423
+ gcp_update_tag,
424
+ common_job_parameters,
425
+ )
317
426
 
318
427
  # DNS data sync
319
428
  for project in projects:
320
- project_id = project['projectId']
429
+ project_id = project["projectId"]
321
430
  logger.info("Syncing GCP project %s for DNS", project_id)
322
- _sync_single_project_dns(neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters)
431
+ _sync_single_project_dns(
432
+ neo4j_session,
433
+ resources,
434
+ project_id,
435
+ gcp_update_tag,
436
+ common_job_parameters,
437
+ )
323
438
 
324
439
  # IAM data sync
325
440
  for project in projects:
326
- project_id = project['projectId']
441
+ project_id = project["projectId"]
327
442
  logger.info("Syncing GCP project %s for IAM", project_id)
328
- _sync_single_project_iam(neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters)
443
+ _sync_single_project_iam(
444
+ neo4j_session, resources, project_id, gcp_update_tag, common_job_parameters
445
+ )
329
446
 
330
447
 
331
448
  @timeit
@@ -341,7 +458,10 @@ def get_gcp_credentials() -> Optional[GoogleCredentials]:
341
458
  credentials, project_id = default()
342
459
  return credentials
343
460
  except DefaultCredentialsError as e:
344
- logger.debug("Error occurred calling GoogleCredentials.get_application_default().", exc_info=True)
461
+ logger.debug(
462
+ "Error occurred calling GoogleCredentials.get_application_default().",
463
+ exc_info=True,
464
+ )
345
465
  logger.error(
346
466
  (
347
467
  "Unable to initialize Google Compute Platform creds. If you don't have GCP data or don't want to load "
@@ -376,27 +496,43 @@ def start_gcp_ingestion(neo4j_session: neo4j.Session, config: Config) -> None:
376
496
  resources = _initialize_resources(credentials)
377
497
 
378
498
  # If we don't have perms to pull Orgs or Folders from GCP, we will skip safely
379
- crm.sync_gcp_organizations(neo4j_session, resources.crm_v1, config.update_tag, common_job_parameters)
380
- crm.sync_gcp_folders(neo4j_session, resources.crm_v2, config.update_tag, common_job_parameters)
499
+ crm.sync_gcp_organizations(
500
+ neo4j_session,
501
+ resources.crm_v1,
502
+ config.update_tag,
503
+ common_job_parameters,
504
+ )
505
+ crm.sync_gcp_folders(
506
+ neo4j_session,
507
+ resources.crm_v2,
508
+ config.update_tag,
509
+ common_job_parameters,
510
+ )
381
511
 
382
512
  projects = crm.get_gcp_projects(resources.crm_v1)
383
513
 
384
- _sync_multiple_projects(neo4j_session, resources, projects, config.update_tag, common_job_parameters)
514
+ _sync_multiple_projects(
515
+ neo4j_session,
516
+ resources,
517
+ projects,
518
+ config.update_tag,
519
+ common_job_parameters,
520
+ )
385
521
 
386
522
  run_analysis_job(
387
- 'gcp_compute_asset_inet_exposure.json',
523
+ "gcp_compute_asset_inet_exposure.json",
388
524
  neo4j_session,
389
525
  common_job_parameters,
390
526
  )
391
527
 
392
528
  run_analysis_job(
393
- 'gcp_gke_asset_exposure.json',
529
+ "gcp_gke_asset_exposure.json",
394
530
  neo4j_session,
395
531
  common_job_parameters,
396
532
  )
397
533
 
398
534
  run_analysis_job(
399
- 'gcp_gke_basic_auth.json',
535
+ "gcp_gke_basic_auth.json",
400
536
  neo4j_session,
401
537
  common_job_parameters,
402
538
  )