cartography 0.102.0rc1__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.
- cartography/__main__.py +1 -2
- cartography/_version.py +2 -2
- cartography/cli.py +302 -253
- cartography/client/core/tx.py +39 -18
- cartography/config.py +4 -0
- cartography/driftdetect/__main__.py +1 -2
- cartography/driftdetect/add_shortcut.py +10 -2
- cartography/driftdetect/cli.py +71 -75
- cartography/driftdetect/detect_deviations.py +7 -3
- cartography/driftdetect/get_states.py +20 -8
- cartography/driftdetect/model.py +5 -5
- cartography/driftdetect/serializers.py +8 -6
- cartography/driftdetect/storage.py +2 -2
- cartography/graph/cleanupbuilder.py +35 -15
- cartography/graph/job.py +46 -17
- cartography/graph/querybuilder.py +165 -80
- cartography/graph/statement.py +35 -26
- cartography/intel/analysis.py +4 -1
- cartography/intel/aws/__init__.py +114 -55
- cartography/intel/aws/apigateway.py +134 -63
- cartography/intel/aws/cloudtrail.py +127 -0
- cartography/intel/aws/config.py +56 -20
- cartography/intel/aws/dynamodb.py +108 -40
- cartography/intel/aws/ec2/__init__.py +2 -2
- cartography/intel/aws/ec2/auto_scaling_groups.py +181 -78
- cartography/intel/aws/ec2/elastic_ip_addresses.py +41 -13
- cartography/intel/aws/ec2/images.py +49 -20
- cartography/intel/aws/ec2/instances.py +234 -136
- cartography/intel/aws/ec2/internet_gateways.py +40 -11
- cartography/intel/aws/ec2/key_pairs.py +44 -20
- cartography/intel/aws/ec2/launch_templates.py +101 -59
- cartography/intel/aws/ec2/load_balancer_v2s.py +104 -39
- cartography/intel/aws/ec2/load_balancers.py +82 -42
- cartography/intel/aws/ec2/network_acls.py +89 -65
- cartography/intel/aws/ec2/network_interfaces.py +146 -87
- cartography/intel/aws/ec2/reserved_instances.py +45 -16
- cartography/intel/aws/ec2/route_tables.py +327 -0
- cartography/intel/aws/ec2/security_groups.py +71 -21
- cartography/intel/aws/ec2/snapshots.py +61 -22
- cartography/intel/aws/ec2/subnets.py +54 -18
- cartography/intel/aws/ec2/tgw.py +100 -34
- cartography/intel/aws/ec2/util.py +1 -1
- cartography/intel/aws/ec2/volumes.py +69 -41
- cartography/intel/aws/ec2/vpc.py +37 -12
- cartography/intel/aws/ec2/vpc_peerings.py +83 -24
- cartography/intel/aws/ecr.py +88 -32
- cartography/intel/aws/ecs.py +83 -47
- cartography/intel/aws/eks.py +55 -29
- cartography/intel/aws/elasticache.py +42 -18
- cartography/intel/aws/elasticsearch.py +57 -20
- cartography/intel/aws/emr.py +61 -23
- cartography/intel/aws/iam.py +401 -145
- cartography/intel/aws/iam_instance_profiles.py +22 -22
- cartography/intel/aws/identitycenter.py +71 -37
- cartography/intel/aws/inspector.py +159 -89
- cartography/intel/aws/kms.py +92 -38
- cartography/intel/aws/lambda_function.py +103 -34
- cartography/intel/aws/organizations.py +30 -10
- cartography/intel/aws/permission_relationships.py +133 -51
- cartography/intel/aws/rds.py +249 -85
- cartography/intel/aws/redshift.py +107 -46
- cartography/intel/aws/resourcegroupstaggingapi.py +120 -66
- cartography/intel/aws/resources.py +53 -44
- cartography/intel/aws/route53.py +108 -61
- cartography/intel/aws/s3.py +168 -83
- cartography/intel/aws/s3accountpublicaccessblock.py +157 -0
- cartography/intel/aws/secretsmanager.py +24 -12
- cartography/intel/aws/securityhub.py +20 -9
- cartography/intel/aws/sns.py +166 -0
- cartography/intel/aws/sqs.py +60 -28
- cartography/intel/aws/ssm.py +70 -30
- cartography/intel/aws/util/arns.py +7 -7
- cartography/intel/aws/util/common.py +31 -4
- cartography/intel/azure/__init__.py +78 -19
- cartography/intel/azure/compute.py +101 -27
- cartography/intel/azure/cosmosdb.py +496 -170
- cartography/intel/azure/sql.py +296 -105
- cartography/intel/azure/storage.py +322 -113
- cartography/intel/azure/subscription.py +39 -23
- cartography/intel/azure/tenant.py +13 -4
- cartography/intel/azure/util/credentials.py +95 -55
- cartography/intel/bigfix/__init__.py +2 -2
- cartography/intel/bigfix/computers.py +93 -65
- cartography/intel/create_indexes.py +3 -2
- cartography/intel/crowdstrike/__init__.py +11 -9
- cartography/intel/crowdstrike/endpoints.py +5 -1
- cartography/intel/crowdstrike/spotlight.py +8 -3
- cartography/intel/cve/__init__.py +46 -13
- cartography/intel/cve/feed.py +48 -12
- cartography/intel/digitalocean/__init__.py +22 -13
- cartography/intel/digitalocean/compute.py +75 -108
- cartography/intel/digitalocean/management.py +44 -80
- cartography/intel/digitalocean/platform.py +48 -43
- cartography/intel/dns.py +36 -10
- cartography/intel/duo/__init__.py +21 -16
- cartography/intel/duo/api_host.py +14 -9
- cartography/intel/duo/endpoints.py +50 -45
- cartography/intel/duo/groups.py +18 -14
- cartography/intel/duo/phones.py +37 -34
- cartography/intel/duo/tokens.py +26 -23
- cartography/intel/duo/users.py +54 -50
- cartography/intel/duo/web_authn_credentials.py +30 -25
- cartography/intel/entra/__init__.py +25 -7
- cartography/intel/entra/ou.py +112 -0
- cartography/intel/entra/users.py +69 -63
- cartography/intel/gcp/__init__.py +185 -49
- cartography/intel/gcp/compute.py +418 -231
- cartography/intel/gcp/crm.py +96 -43
- cartography/intel/gcp/dns.py +60 -19
- cartography/intel/gcp/gke.py +72 -38
- cartography/intel/gcp/iam.py +61 -41
- cartography/intel/gcp/storage.py +84 -55
- cartography/intel/github/__init__.py +13 -11
- cartography/intel/github/repos.py +270 -137
- cartography/intel/github/teams.py +170 -88
- cartography/intel/github/users.py +70 -39
- cartography/intel/github/util.py +36 -34
- cartography/intel/gsuite/__init__.py +47 -26
- cartography/intel/gsuite/api.py +73 -30
- cartography/intel/jamf/__init__.py +19 -1
- cartography/intel/jamf/computers.py +30 -7
- cartography/intel/jamf/util.py +7 -2
- cartography/intel/kandji/__init__.py +6 -3
- cartography/intel/kandji/devices.py +14 -8
- cartography/intel/kubernetes/namespaces.py +7 -4
- cartography/intel/kubernetes/pods.py +7 -4
- cartography/intel/kubernetes/services.py +8 -4
- cartography/intel/lastpass/__init__.py +2 -2
- cartography/intel/lastpass/users.py +23 -12
- cartography/intel/oci/__init__.py +44 -11
- cartography/intel/oci/iam.py +134 -38
- cartography/intel/oci/organizations.py +13 -6
- cartography/intel/oci/utils.py +43 -20
- cartography/intel/okta/__init__.py +66 -15
- cartography/intel/okta/applications.py +42 -20
- cartography/intel/okta/awssaml.py +93 -33
- cartography/intel/okta/factors.py +16 -4
- cartography/intel/okta/groups.py +56 -29
- cartography/intel/okta/organization.py +5 -1
- cartography/intel/okta/origins.py +6 -2
- cartography/intel/okta/roles.py +15 -5
- cartography/intel/okta/users.py +20 -8
- cartography/intel/okta/utils.py +6 -4
- cartography/intel/pagerduty/__init__.py +8 -7
- cartography/intel/pagerduty/escalation_policies.py +18 -6
- cartography/intel/pagerduty/schedules.py +12 -4
- cartography/intel/pagerduty/services.py +11 -4
- cartography/intel/pagerduty/teams.py +8 -3
- cartography/intel/pagerduty/users.py +3 -1
- cartography/intel/pagerduty/vendors.py +3 -1
- cartography/intel/semgrep/__init__.py +24 -6
- cartography/intel/semgrep/dependencies.py +50 -28
- cartography/intel/semgrep/deployment.py +3 -1
- cartography/intel/semgrep/findings.py +42 -18
- cartography/intel/snipeit/__init__.py +17 -3
- cartography/intel/snipeit/asset.py +12 -6
- cartography/intel/snipeit/user.py +8 -5
- cartography/intel/snipeit/util.py +9 -4
- cartography/models/aws/apigateway.py +21 -17
- cartography/models/aws/apigatewaycertificate.py +28 -22
- cartography/models/aws/apigatewayresource.py +28 -20
- cartography/models/aws/apigatewaystage.py +33 -25
- cartography/models/aws/cloudtrail/__init__.py +0 -0
- cartography/models/aws/cloudtrail/trail.py +61 -0
- cartography/models/aws/dynamodb/gsi.py +30 -22
- cartography/models/aws/dynamodb/tables.py +25 -17
- cartography/models/aws/ec2/auto_scaling_groups.py +102 -82
- cartography/models/aws/ec2/images.py +36 -34
- cartography/models/aws/ec2/instances.py +51 -45
- cartography/models/aws/ec2/keypair.py +21 -16
- cartography/models/aws/ec2/keypair_instance.py +28 -21
- cartography/models/aws/ec2/launch_configurations.py +30 -26
- cartography/models/aws/ec2/launch_template_versions.py +48 -38
- cartography/models/aws/ec2/launch_templates.py +21 -17
- cartography/models/aws/ec2/load_balancer_listeners.py +27 -23
- cartography/models/aws/ec2/load_balancers.py +47 -37
- cartography/models/aws/ec2/network_acl_rules.py +38 -30
- cartography/models/aws/ec2/network_acls.py +38 -29
- cartography/models/aws/ec2/networkinterface_instance.py +52 -39
- cartography/models/aws/ec2/networkinterfaces.py +53 -37
- cartography/models/aws/ec2/privateip_networkinterface.py +32 -22
- cartography/models/aws/ec2/reservations.py +18 -14
- cartography/models/aws/ec2/route_table_associations.py +97 -0
- cartography/models/aws/ec2/route_tables.py +128 -0
- cartography/models/aws/ec2/routes.py +85 -0
- cartography/models/aws/ec2/securitygroup_instance.py +29 -20
- cartography/models/aws/ec2/securitygroup_networkinterface.py +24 -15
- cartography/models/aws/ec2/subnet_instance.py +24 -19
- cartography/models/aws/ec2/subnet_networkinterface.py +40 -31
- cartography/models/aws/ec2/volumes.py +47 -40
- cartography/models/aws/eks/clusters.py +23 -21
- cartography/models/aws/emr.py +32 -30
- cartography/models/aws/iam/instanceprofile.py +33 -24
- cartography/models/aws/identitycenter/awsidentitycenter.py +18 -14
- cartography/models/aws/identitycenter/awspermissionset.py +37 -29
- cartography/models/aws/identitycenter/awsssouser.py +23 -21
- cartography/models/aws/inspector/findings.py +77 -65
- cartography/models/aws/inspector/packages.py +35 -29
- cartography/models/aws/s3/__init__.py +0 -0
- cartography/models/aws/s3/account_public_access_block.py +51 -0
- cartography/models/aws/sns/__init__.py +0 -0
- cartography/models/aws/sns/topic.py +50 -0
- cartography/models/aws/ssm/instance_information.py +51 -39
- cartography/models/aws/ssm/instance_patch.py +32 -26
- cartography/models/bigfix/bigfix_computer.py +42 -38
- cartography/models/bigfix/bigfix_root.py +3 -3
- cartography/models/core/common.py +12 -10
- cartography/models/core/nodes.py +5 -2
- cartography/models/core/relationships.py +14 -6
- cartography/models/crowdstrike/hosts.py +37 -35
- cartography/models/cve/cve.py +34 -32
- cartography/models/cve/cve_feed.py +6 -6
- cartography/models/digitalocean/__init__.py +0 -0
- cartography/models/digitalocean/account.py +21 -0
- cartography/models/digitalocean/droplet.py +56 -0
- cartography/models/digitalocean/project.py +48 -0
- cartography/models/duo/api_host.py +3 -3
- cartography/models/duo/endpoint.py +43 -41
- cartography/models/duo/group.py +14 -14
- cartography/models/duo/phone.py +27 -27
- cartography/models/duo/token.py +16 -16
- cartography/models/duo/user.py +46 -44
- cartography/models/duo/web_authn_credential.py +27 -19
- cartography/models/entra/ou.py +48 -0
- cartography/models/entra/tenant.py +24 -18
- cartography/models/entra/user.py +64 -48
- cartography/models/gcp/iam.py +23 -23
- cartography/models/github/orgs.py +5 -4
- cartography/models/github/teams.py +37 -31
- cartography/models/github/users.py +34 -23
- cartography/models/kandji/device.py +22 -16
- cartography/models/kandji/tenant.py +6 -4
- cartography/models/lastpass/tenant.py +3 -3
- cartography/models/lastpass/user.py +32 -28
- cartography/models/semgrep/dependencies.py +36 -24
- cartography/models/semgrep/deployment.py +5 -5
- cartography/models/semgrep/findings.py +58 -42
- cartography/models/semgrep/locations.py +27 -21
- cartography/models/snipeit/asset.py +30 -21
- cartography/models/snipeit/tenant.py +6 -4
- cartography/models/snipeit/user.py +19 -12
- cartography/stats.py +3 -3
- cartography/sync.py +107 -31
- cartography/util.py +84 -62
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/METADATA +3 -14
- cartography-0.103.0rc1.dist-info/RECORD +396 -0
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/WHEEL +1 -1
- cartography-0.102.0rc1.dist-info/RECORD +0 -377
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/entry_points.txt +0 -0
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -6,38 +6,47 @@ import boto3
|
|
|
6
6
|
import botocore
|
|
7
7
|
import neo4j
|
|
8
8
|
|
|
9
|
-
from .util import get_botocore_config
|
|
10
9
|
from cartography.util import aws_handle_regions
|
|
11
10
|
from cartography.util import run_cleanup_job
|
|
12
11
|
from cartography.util import timeit
|
|
13
12
|
|
|
13
|
+
from .util import get_botocore_config
|
|
14
|
+
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
@timeit
|
|
18
19
|
@aws_handle_regions
|
|
19
|
-
def get_load_balancer_v2_listeners(
|
|
20
|
-
|
|
20
|
+
def get_load_balancer_v2_listeners(
|
|
21
|
+
client: botocore.client.BaseClient,
|
|
22
|
+
load_balancer_arn: str,
|
|
23
|
+
) -> List[Dict]:
|
|
24
|
+
paginator = client.get_paginator("describe_listeners")
|
|
21
25
|
listeners: List[Dict] = []
|
|
22
26
|
for page in paginator.paginate(LoadBalancerArn=load_balancer_arn):
|
|
23
|
-
listeners.extend(page[
|
|
27
|
+
listeners.extend(page["Listeners"])
|
|
24
28
|
|
|
25
29
|
return listeners
|
|
26
30
|
|
|
27
31
|
|
|
28
32
|
@timeit
|
|
29
|
-
def get_load_balancer_v2_target_groups(
|
|
30
|
-
|
|
33
|
+
def get_load_balancer_v2_target_groups(
|
|
34
|
+
client: botocore.client.BaseClient,
|
|
35
|
+
load_balancer_arn: str,
|
|
36
|
+
) -> List[Dict]:
|
|
37
|
+
paginator = client.get_paginator("describe_target_groups")
|
|
31
38
|
target_groups: List[Dict] = []
|
|
32
39
|
for page in paginator.paginate(LoadBalancerArn=load_balancer_arn):
|
|
33
|
-
target_groups.extend(page[
|
|
40
|
+
target_groups.extend(page["TargetGroups"])
|
|
34
41
|
|
|
35
42
|
# Add instance data
|
|
36
43
|
for target_group in target_groups:
|
|
37
|
-
target_group[
|
|
38
|
-
target_health = client.describe_target_health(
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
target_group["Targets"] = []
|
|
45
|
+
target_health = client.describe_target_health(
|
|
46
|
+
TargetGroupArn=target_group["TargetGroupArn"],
|
|
47
|
+
)
|
|
48
|
+
for target_health_description in target_health["TargetHealthDescriptions"]:
|
|
49
|
+
target_group["Targets"].append(target_health_description["Target"]["Id"])
|
|
41
50
|
|
|
42
51
|
return target_groups
|
|
43
52
|
|
|
@@ -45,22 +54,35 @@ def get_load_balancer_v2_target_groups(client: botocore.client.BaseClient, load_
|
|
|
45
54
|
@timeit
|
|
46
55
|
@aws_handle_regions
|
|
47
56
|
def get_loadbalancer_v2_data(boto3_session: boto3.Session, region: str) -> List[Dict]:
|
|
48
|
-
client = boto3_session.client(
|
|
49
|
-
|
|
57
|
+
client = boto3_session.client(
|
|
58
|
+
"elbv2",
|
|
59
|
+
region_name=region,
|
|
60
|
+
config=get_botocore_config(),
|
|
61
|
+
)
|
|
62
|
+
paginator = client.get_paginator("describe_load_balancers")
|
|
50
63
|
elbv2s: List[Dict] = []
|
|
51
64
|
for page in paginator.paginate():
|
|
52
|
-
elbv2s.extend(page[
|
|
65
|
+
elbv2s.extend(page["LoadBalancers"])
|
|
53
66
|
|
|
54
67
|
# Make extra calls to get listeners
|
|
55
68
|
for elbv2 in elbv2s:
|
|
56
|
-
elbv2[
|
|
57
|
-
|
|
69
|
+
elbv2["Listeners"] = get_load_balancer_v2_listeners(
|
|
70
|
+
client,
|
|
71
|
+
elbv2["LoadBalancerArn"],
|
|
72
|
+
)
|
|
73
|
+
elbv2["TargetGroups"] = get_load_balancer_v2_target_groups(
|
|
74
|
+
client,
|
|
75
|
+
elbv2["LoadBalancerArn"],
|
|
76
|
+
)
|
|
58
77
|
return elbv2s
|
|
59
78
|
|
|
60
79
|
|
|
61
80
|
@timeit
|
|
62
81
|
def load_load_balancer_v2s(
|
|
63
|
-
neo4j_session: neo4j.Session,
|
|
82
|
+
neo4j_session: neo4j.Session,
|
|
83
|
+
data: List[Dict],
|
|
84
|
+
region: str,
|
|
85
|
+
current_aws_account_id: str,
|
|
64
86
|
update_tag: int,
|
|
65
87
|
) -> None:
|
|
66
88
|
ingest_load_balancer_v2 = """
|
|
@@ -95,10 +117,16 @@ def load_load_balancer_v2s(
|
|
|
95
117
|
|
|
96
118
|
if lb["AvailabilityZones"]:
|
|
97
119
|
az = lb["AvailabilityZones"]
|
|
98
|
-
load_load_balancer_v2_subnets(
|
|
120
|
+
load_load_balancer_v2_subnets(
|
|
121
|
+
neo4j_session,
|
|
122
|
+
load_balancer_id,
|
|
123
|
+
az,
|
|
124
|
+
region,
|
|
125
|
+
update_tag,
|
|
126
|
+
)
|
|
99
127
|
|
|
100
128
|
# NLB's don't have SecurityGroups, so check for one first.
|
|
101
|
-
if
|
|
129
|
+
if "SecurityGroups" in lb and lb["SecurityGroups"]:
|
|
102
130
|
ingest_load_balancer_v2_security_group = """
|
|
103
131
|
MATCH (elbv2:LoadBalancerV2{id: $ID}),
|
|
104
132
|
(group:EC2SecurityGroup{groupid: $GROUP_ID})
|
|
@@ -114,20 +142,31 @@ def load_load_balancer_v2s(
|
|
|
114
142
|
update_tag=update_tag,
|
|
115
143
|
)
|
|
116
144
|
|
|
117
|
-
if lb[
|
|
118
|
-
load_load_balancer_v2_listeners(
|
|
145
|
+
if lb["Listeners"]:
|
|
146
|
+
load_load_balancer_v2_listeners(
|
|
147
|
+
neo4j_session,
|
|
148
|
+
load_balancer_id,
|
|
149
|
+
lb["Listeners"],
|
|
150
|
+
update_tag,
|
|
151
|
+
)
|
|
119
152
|
|
|
120
|
-
if lb[
|
|
153
|
+
if lb["TargetGroups"]:
|
|
121
154
|
load_load_balancer_v2_target_groups(
|
|
122
|
-
neo4j_session,
|
|
123
|
-
|
|
155
|
+
neo4j_session,
|
|
156
|
+
load_balancer_id,
|
|
157
|
+
lb["TargetGroups"],
|
|
158
|
+
current_aws_account_id,
|
|
159
|
+
update_tag,
|
|
124
160
|
)
|
|
125
161
|
|
|
126
162
|
|
|
127
163
|
@timeit
|
|
128
164
|
def load_load_balancer_v2_subnets(
|
|
129
|
-
neo4j_session: neo4j.Session,
|
|
130
|
-
|
|
165
|
+
neo4j_session: neo4j.Session,
|
|
166
|
+
load_balancer_id: str,
|
|
167
|
+
az_data: List[Dict],
|
|
168
|
+
region: str,
|
|
169
|
+
update_tag: int,
|
|
131
170
|
) -> None:
|
|
132
171
|
ingest_load_balancer_subnet = """
|
|
133
172
|
MATCH (elbv2:LoadBalancerV2{id: $ID})
|
|
@@ -143,7 +182,7 @@ def load_load_balancer_v2_subnets(
|
|
|
143
182
|
neo4j_session.run(
|
|
144
183
|
ingest_load_balancer_subnet,
|
|
145
184
|
ID=load_balancer_id,
|
|
146
|
-
SubnetId=az[
|
|
185
|
+
SubnetId=az["SubnetId"],
|
|
147
186
|
region=region,
|
|
148
187
|
update_tag=update_tag,
|
|
149
188
|
)
|
|
@@ -151,7 +190,10 @@ def load_load_balancer_v2_subnets(
|
|
|
151
190
|
|
|
152
191
|
@timeit
|
|
153
192
|
def load_load_balancer_v2_target_groups(
|
|
154
|
-
neo4j_session: neo4j.Session,
|
|
193
|
+
neo4j_session: neo4j.Session,
|
|
194
|
+
load_balancer_id: str,
|
|
195
|
+
target_groups: List[Dict],
|
|
196
|
+
current_aws_account_id: str,
|
|
155
197
|
update_tag: int,
|
|
156
198
|
) -> None:
|
|
157
199
|
ingest_instances = """
|
|
@@ -169,7 +211,7 @@ def load_load_balancer_v2_target_groups(
|
|
|
169
211
|
"""
|
|
170
212
|
for target_group in target_groups:
|
|
171
213
|
|
|
172
|
-
if not target_group[
|
|
214
|
+
if not target_group["TargetType"] == "instance":
|
|
173
215
|
# Only working on EC2 Instances now. TODO: Add IP & Lambda EXPOSE.
|
|
174
216
|
continue
|
|
175
217
|
|
|
@@ -179,16 +221,18 @@ def load_load_balancer_v2_target_groups(
|
|
|
179
221
|
ID=load_balancer_id,
|
|
180
222
|
INSTANCE_ID=instance,
|
|
181
223
|
AWS_ACCOUNT_ID=current_aws_account_id,
|
|
182
|
-
TARGET_GROUP_ARN=target_group.get(
|
|
183
|
-
PORT=target_group.get(
|
|
184
|
-
PROTOCOL=target_group.get(
|
|
224
|
+
TARGET_GROUP_ARN=target_group.get("TargetGroupArn"),
|
|
225
|
+
PORT=target_group.get("Port"),
|
|
226
|
+
PROTOCOL=target_group.get("Protocol"),
|
|
185
227
|
update_tag=update_tag,
|
|
186
228
|
)
|
|
187
229
|
|
|
188
230
|
|
|
189
231
|
@timeit
|
|
190
232
|
def load_load_balancer_v2_listeners(
|
|
191
|
-
neo4j_session: neo4j.Session,
|
|
233
|
+
neo4j_session: neo4j.Session,
|
|
234
|
+
load_balancer_id: str,
|
|
235
|
+
listener_data: List[Dict],
|
|
192
236
|
update_tag: int,
|
|
193
237
|
) -> None:
|
|
194
238
|
ingest_listener = """
|
|
@@ -215,18 +259,39 @@ def load_load_balancer_v2_listeners(
|
|
|
215
259
|
|
|
216
260
|
|
|
217
261
|
@timeit
|
|
218
|
-
def cleanup_load_balancer_v2s(
|
|
262
|
+
def cleanup_load_balancer_v2s(
|
|
263
|
+
neo4j_session: neo4j.Session,
|
|
264
|
+
common_job_parameters: Dict,
|
|
265
|
+
) -> None:
|
|
219
266
|
"""Delete elbv2's and dependent resources in the DB without the most recent lastupdated tag."""
|
|
220
|
-
run_cleanup_job(
|
|
267
|
+
run_cleanup_job(
|
|
268
|
+
"aws_ingest_load_balancers_v2_cleanup.json",
|
|
269
|
+
neo4j_session,
|
|
270
|
+
common_job_parameters,
|
|
271
|
+
)
|
|
221
272
|
|
|
222
273
|
|
|
223
274
|
@timeit
|
|
224
275
|
def sync_load_balancer_v2s(
|
|
225
|
-
neo4j_session: neo4j.Session,
|
|
226
|
-
|
|
276
|
+
neo4j_session: neo4j.Session,
|
|
277
|
+
boto3_session: boto3.session.Session,
|
|
278
|
+
regions: List[str],
|
|
279
|
+
current_aws_account_id: str,
|
|
280
|
+
update_tag: int,
|
|
281
|
+
common_job_parameters: Dict,
|
|
227
282
|
) -> None:
|
|
228
283
|
for region in regions:
|
|
229
|
-
logger.info(
|
|
284
|
+
logger.info(
|
|
285
|
+
"Syncing EC2 load balancers v2 for region '%s' in account '%s'.",
|
|
286
|
+
region,
|
|
287
|
+
current_aws_account_id,
|
|
288
|
+
)
|
|
230
289
|
data = get_loadbalancer_v2_data(boto3_session, region)
|
|
231
|
-
load_load_balancer_v2s(
|
|
290
|
+
load_load_balancer_v2s(
|
|
291
|
+
neo4j_session,
|
|
292
|
+
data,
|
|
293
|
+
region,
|
|
294
|
+
current_aws_account_id,
|
|
295
|
+
update_tag,
|
|
296
|
+
)
|
|
232
297
|
cleanup_load_balancer_v2s(neo4j_session, common_job_parameters)
|
|
@@ -3,7 +3,6 @@ import logging
|
|
|
3
3
|
import boto3
|
|
4
4
|
import neo4j
|
|
5
5
|
|
|
6
|
-
from .util import get_botocore_config
|
|
7
6
|
from cartography.client.core.tx import load
|
|
8
7
|
from cartography.graph.job import GraphJob
|
|
9
8
|
from cartography.models.aws.ec2.load_balancer_listeners import ELBListenerSchema
|
|
@@ -11,6 +10,8 @@ from cartography.models.aws.ec2.load_balancers import LoadBalancerSchema
|
|
|
11
10
|
from cartography.util import aws_handle_regions
|
|
12
11
|
from cartography.util import timeit
|
|
13
12
|
|
|
13
|
+
from .util import get_botocore_config
|
|
14
|
+
|
|
14
15
|
logger = logging.getLogger(__name__)
|
|
15
16
|
|
|
16
17
|
|
|
@@ -29,7 +30,9 @@ def _get_listener_id(load_balancer_id: str, port: int, protocol: str) -> str:
|
|
|
29
30
|
return f"{load_balancer_id}{port}{protocol}"
|
|
30
31
|
|
|
31
32
|
|
|
32
|
-
def transform_load_balancer_listener_data(
|
|
33
|
+
def transform_load_balancer_listener_data(
|
|
34
|
+
load_balancer_id: str, listener_data: list[dict]
|
|
35
|
+
) -> list[dict]:
|
|
33
36
|
"""
|
|
34
37
|
Transform load balancer listener data into a format suitable for cartography ingestion.
|
|
35
38
|
|
|
@@ -42,21 +45,27 @@ def transform_load_balancer_listener_data(load_balancer_id: str, listener_data:
|
|
|
42
45
|
"""
|
|
43
46
|
transformed = []
|
|
44
47
|
for listener in listener_data:
|
|
45
|
-
listener_info = listener[
|
|
48
|
+
listener_info = listener["Listener"]
|
|
46
49
|
transformed_listener = {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
"id": _get_listener_id(
|
|
51
|
+
load_balancer_id,
|
|
52
|
+
listener_info["LoadBalancerPort"],
|
|
53
|
+
listener_info["Protocol"],
|
|
54
|
+
),
|
|
55
|
+
"port": listener_info.get("LoadBalancerPort"),
|
|
56
|
+
"protocol": listener_info.get("Protocol"),
|
|
57
|
+
"instance_port": listener_info.get("InstancePort"),
|
|
58
|
+
"instance_protocol": listener_info.get("InstanceProtocol"),
|
|
59
|
+
"policy_names": listener.get("PolicyNames", []),
|
|
60
|
+
"LoadBalancerId": load_balancer_id,
|
|
54
61
|
}
|
|
55
62
|
transformed.append(transformed_listener)
|
|
56
63
|
return transformed
|
|
57
64
|
|
|
58
65
|
|
|
59
|
-
def transform_load_balancer_data(
|
|
66
|
+
def transform_load_balancer_data(
|
|
67
|
+
load_balancers: list[dict],
|
|
68
|
+
) -> tuple[list[dict], list[dict]]:
|
|
60
69
|
"""
|
|
61
70
|
Transform load balancer data into a format suitable for cartography ingestion.
|
|
62
71
|
|
|
@@ -70,35 +79,38 @@ def transform_load_balancer_data(load_balancers: list[dict]) -> tuple[list[dict]
|
|
|
70
79
|
listener_data = []
|
|
71
80
|
|
|
72
81
|
for lb in load_balancers:
|
|
73
|
-
load_balancer_id = lb[
|
|
82
|
+
load_balancer_id = lb["DNSName"]
|
|
74
83
|
transformed_lb = {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
"id": load_balancer_id,
|
|
85
|
+
"name": lb["LoadBalancerName"],
|
|
86
|
+
"dnsname": lb["DNSName"],
|
|
87
|
+
"canonicalhostedzonename": lb.get("CanonicalHostedZoneName"),
|
|
88
|
+
"canonicalhostedzonenameid": lb.get("CanonicalHostedZoneNameID"),
|
|
89
|
+
"scheme": lb.get("Scheme"),
|
|
90
|
+
"createdtime": str(lb["CreatedTime"]),
|
|
91
|
+
"GROUP_NAME": lb.get("SourceSecurityGroup", {}).get("GroupName"),
|
|
92
|
+
"GROUP_IDS": [str(group) for group in lb.get("SecurityGroups", [])],
|
|
93
|
+
"INSTANCE_IDS": [
|
|
94
|
+
instance["InstanceId"] for instance in lb.get("Instances", [])
|
|
95
|
+
],
|
|
96
|
+
"LISTENER_IDS": [
|
|
86
97
|
_get_listener_id(
|
|
87
98
|
load_balancer_id,
|
|
88
|
-
listener[
|
|
89
|
-
listener[
|
|
90
|
-
)
|
|
99
|
+
listener["Listener"]["LoadBalancerPort"],
|
|
100
|
+
listener["Listener"]["Protocol"],
|
|
101
|
+
)
|
|
102
|
+
for listener in lb.get("ListenerDescriptions", [])
|
|
91
103
|
],
|
|
92
104
|
}
|
|
93
105
|
transformed.append(transformed_lb)
|
|
94
106
|
|
|
95
107
|
# Classic ELB listeners are not returned anywhere else in AWS, so we must parse them out
|
|
96
108
|
# of the describe_load_balancers response.
|
|
97
|
-
if lb.get(
|
|
109
|
+
if lb.get("ListenerDescriptions"):
|
|
98
110
|
listener_data.extend(
|
|
99
111
|
transform_load_balancer_listener_data(
|
|
100
112
|
load_balancer_id,
|
|
101
|
-
lb.get(
|
|
113
|
+
lb.get("ListenerDescriptions", []),
|
|
102
114
|
),
|
|
103
115
|
)
|
|
104
116
|
|
|
@@ -107,18 +119,25 @@ def transform_load_balancer_data(load_balancers: list[dict]) -> tuple[list[dict]
|
|
|
107
119
|
|
|
108
120
|
@timeit
|
|
109
121
|
@aws_handle_regions
|
|
110
|
-
def get_loadbalancer_data(
|
|
111
|
-
|
|
112
|
-
|
|
122
|
+
def get_loadbalancer_data(
|
|
123
|
+
boto3_session: boto3.session.Session, region: str
|
|
124
|
+
) -> list[dict]:
|
|
125
|
+
client = boto3_session.client(
|
|
126
|
+
"elb", region_name=region, config=get_botocore_config()
|
|
127
|
+
)
|
|
128
|
+
paginator = client.get_paginator("describe_load_balancers")
|
|
113
129
|
elbs: list[dict] = []
|
|
114
130
|
for page in paginator.paginate():
|
|
115
|
-
elbs.extend(page[
|
|
131
|
+
elbs.extend(page["LoadBalancerDescriptions"])
|
|
116
132
|
return elbs
|
|
117
133
|
|
|
118
134
|
|
|
119
135
|
@timeit
|
|
120
136
|
def load_load_balancers(
|
|
121
|
-
neo4j_session: neo4j.Session,
|
|
137
|
+
neo4j_session: neo4j.Session,
|
|
138
|
+
data: list[dict],
|
|
139
|
+
region: str,
|
|
140
|
+
current_aws_account_id: str,
|
|
122
141
|
update_tag: int,
|
|
123
142
|
) -> None:
|
|
124
143
|
load(
|
|
@@ -133,7 +152,10 @@ def load_load_balancers(
|
|
|
133
152
|
|
|
134
153
|
@timeit
|
|
135
154
|
def load_load_balancer_listeners(
|
|
136
|
-
neo4j_session: neo4j.Session,
|
|
155
|
+
neo4j_session: neo4j.Session,
|
|
156
|
+
data: list[dict],
|
|
157
|
+
region: str,
|
|
158
|
+
current_aws_account_id: str,
|
|
137
159
|
update_tag: int,
|
|
138
160
|
) -> None:
|
|
139
161
|
load(
|
|
@@ -147,22 +169,40 @@ def load_load_balancer_listeners(
|
|
|
147
169
|
|
|
148
170
|
|
|
149
171
|
@timeit
|
|
150
|
-
def cleanup_load_balancers(
|
|
151
|
-
|
|
152
|
-
|
|
172
|
+
def cleanup_load_balancers(
|
|
173
|
+
neo4j_session: neo4j.Session, common_job_parameters: dict
|
|
174
|
+
) -> None:
|
|
175
|
+
GraphJob.from_node_schema(ELBListenerSchema(), common_job_parameters).run(
|
|
176
|
+
neo4j_session
|
|
177
|
+
)
|
|
178
|
+
GraphJob.from_node_schema(LoadBalancerSchema(), common_job_parameters).run(
|
|
179
|
+
neo4j_session
|
|
180
|
+
)
|
|
153
181
|
|
|
154
182
|
|
|
155
183
|
@timeit
|
|
156
184
|
def sync_load_balancers(
|
|
157
|
-
neo4j_session: neo4j.Session,
|
|
158
|
-
|
|
185
|
+
neo4j_session: neo4j.Session,
|
|
186
|
+
boto3_session: boto3.session.Session,
|
|
187
|
+
regions: list[str],
|
|
188
|
+
current_aws_account_id: str,
|
|
189
|
+
update_tag: int,
|
|
190
|
+
common_job_parameters: dict,
|
|
159
191
|
) -> None:
|
|
160
192
|
for region in regions:
|
|
161
|
-
logger.info(
|
|
193
|
+
logger.info(
|
|
194
|
+
"Syncing EC2 load balancers for region '%s' in account '%s'.",
|
|
195
|
+
region,
|
|
196
|
+
current_aws_account_id,
|
|
197
|
+
)
|
|
162
198
|
data = get_loadbalancer_data(boto3_session, region)
|
|
163
199
|
transformed_data, listener_data = transform_load_balancer_data(data)
|
|
164
200
|
|
|
165
|
-
load_load_balancers(
|
|
166
|
-
|
|
201
|
+
load_load_balancers(
|
|
202
|
+
neo4j_session, transformed_data, region, current_aws_account_id, update_tag
|
|
203
|
+
)
|
|
204
|
+
load_load_balancer_listeners(
|
|
205
|
+
neo4j_session, listener_data, region, current_aws_account_id, update_tag
|
|
206
|
+
)
|
|
167
207
|
|
|
168
208
|
cleanup_load_balancers(neo4j_session, common_job_parameters)
|