cartography 0.102.0rc1__py3-none-any.whl → 0.103.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.
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 +376 -249
- cartography/client/core/tx.py +39 -18
- cartography/config.py +28 -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/cloudwatch.py +93 -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/efs.py +93 -0
- 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 +57 -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/cloudflare/__init__.py +74 -0
- cartography/intel/cloudflare/accounts.py +57 -0
- cartography/intel/cloudflare/dnsrecords.py +64 -0
- cartography/intel/cloudflare/members.py +75 -0
- cartography/intel/cloudflare/roles.py +65 -0
- cartography/intel/cloudflare/zones.py +64 -0
- 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/openai/__init__.py +86 -0
- cartography/intel/openai/adminapikeys.py +90 -0
- cartography/intel/openai/apikeys.py +96 -0
- cartography/intel/openai/projects.py +94 -0
- cartography/intel/openai/serviceaccounts.py +82 -0
- cartography/intel/openai/users.py +78 -0
- cartography/intel/openai/util.py +29 -0
- 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/intel/tailscale/__init__.py +77 -0
- cartography/intel/tailscale/acls.py +146 -0
- cartography/intel/tailscale/devices.py +127 -0
- cartography/intel/tailscale/postureintegrations.py +81 -0
- cartography/intel/tailscale/tailnets.py +76 -0
- cartography/intel/tailscale/users.py +80 -0
- cartography/intel/tailscale/utils.py +132 -0
- 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/cloudwatch/__init__.py +0 -0
- cartography/models/aws/cloudwatch/loggroup.py +52 -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/efs/__init__.py +0 -0
- cartography/models/aws/efs/mount_target.py +52 -0
- 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/cloudflare/__init__.py +0 -0
- cartography/models/cloudflare/account.py +25 -0
- cartography/models/cloudflare/dnsrecord.py +55 -0
- cartography/models/cloudflare/member.py +82 -0
- cartography/models/cloudflare/role.py +44 -0
- cartography/models/cloudflare/zone.py +59 -0
- 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/openai/__init__.py +0 -0
- cartography/models/openai/adminapikey.py +90 -0
- cartography/models/openai/apikey.py +84 -0
- cartography/models/openai/organization.py +17 -0
- cartography/models/openai/project.py +70 -0
- cartography/models/openai/serviceaccount.py +50 -0
- cartography/models/openai/user.py +49 -0
- 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/models/tailscale/__init__.py +0 -0
- cartography/models/tailscale/device.py +95 -0
- cartography/models/tailscale/group.py +86 -0
- cartography/models/tailscale/postureintegration.py +58 -0
- cartography/models/tailscale/tag.py +102 -0
- cartography/models/tailscale/tailnet.py +29 -0
- cartography/models/tailscale/user.py +52 -0
- cartography/stats.py +3 -3
- cartography/sync.py +113 -31
- cartography/util.py +84 -62
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/METADATA +8 -15
- cartography-0.103.0.dist-info/RECORD +442 -0
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/WHEEL +1 -1
- cartography-0.102.0rc1.dist-info/RECORD +0 -377
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/licenses/LICENSE +0 -0
- {cartography-0.102.0rc1.dist-info → cartography-0.103.0.dist-info}/top_level.txt +0 -0
|
@@ -8,20 +8,28 @@ from typing import List
|
|
|
8
8
|
import boto3
|
|
9
9
|
import neo4j
|
|
10
10
|
|
|
11
|
-
from .util import get_botocore_config
|
|
12
11
|
from cartography.client.core.tx import load
|
|
13
12
|
from cartography.graph.job import GraphJob
|
|
14
13
|
from cartography.models.aws.ec2.networkinterfaces import EC2NetworkInterfaceSchema
|
|
15
|
-
from cartography.models.aws.ec2.privateip_networkinterface import
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
from cartography.models.aws.ec2.privateip_networkinterface import (
|
|
15
|
+
EC2PrivateIpNetworkInterfaceSchema,
|
|
16
|
+
)
|
|
17
|
+
from cartography.models.aws.ec2.securitygroup_networkinterface import (
|
|
18
|
+
EC2SecurityGroupNetworkInterfaceSchema,
|
|
19
|
+
)
|
|
20
|
+
from cartography.models.aws.ec2.subnet_networkinterface import (
|
|
21
|
+
EC2SubnetNetworkInterfaceSchema,
|
|
22
|
+
)
|
|
18
23
|
from cartography.util import aws_handle_regions
|
|
19
24
|
from cartography.util import timeit
|
|
20
25
|
|
|
26
|
+
from .util import get_botocore_config
|
|
27
|
+
|
|
21
28
|
logger = logging.getLogger(__name__)
|
|
22
29
|
|
|
23
30
|
Ec2NetworkData = namedtuple(
|
|
24
|
-
"Ec2NetworkData",
|
|
31
|
+
"Ec2NetworkData",
|
|
32
|
+
[
|
|
25
33
|
"network_interface_list",
|
|
26
34
|
"private_ip_list",
|
|
27
35
|
"sg_list",
|
|
@@ -32,16 +40,26 @@ Ec2NetworkData = namedtuple(
|
|
|
32
40
|
|
|
33
41
|
@timeit
|
|
34
42
|
@aws_handle_regions
|
|
35
|
-
def get_network_interface_data(
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
def get_network_interface_data(
|
|
44
|
+
boto3_session: boto3.session.Session,
|
|
45
|
+
region: str,
|
|
46
|
+
) -> List[Dict[str, Any]]:
|
|
47
|
+
client = boto3_session.client(
|
|
48
|
+
"ec2",
|
|
49
|
+
region_name=region,
|
|
50
|
+
config=get_botocore_config(),
|
|
51
|
+
)
|
|
52
|
+
paginator = client.get_paginator("describe_network_interfaces")
|
|
38
53
|
subnets: List[Dict] = []
|
|
39
54
|
for page in paginator.paginate():
|
|
40
|
-
subnets.extend(page[
|
|
55
|
+
subnets.extend(page["NetworkInterfaces"])
|
|
41
56
|
return subnets
|
|
42
57
|
|
|
43
58
|
|
|
44
|
-
def transform_network_interface_data(
|
|
59
|
+
def transform_network_interface_data(
|
|
60
|
+
data_list: List[Dict[str, Any]],
|
|
61
|
+
region: str,
|
|
62
|
+
) -> Ec2NetworkData:
|
|
45
63
|
network_interface_list = []
|
|
46
64
|
private_ip_list = []
|
|
47
65
|
sg_list = []
|
|
@@ -52,45 +70,52 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
|
|
|
52
70
|
# https://aws.amazon.com/premiumsupport/knowledge-center/elb-find-load-balancer-IP/
|
|
53
71
|
elb_v1_id = None
|
|
54
72
|
elb_v2_id = None
|
|
55
|
-
elb_match = re.match(
|
|
73
|
+
elb_match = re.match(
|
|
74
|
+
r"^ELB (?:net|app)/([^\/]+)\/(.*)",
|
|
75
|
+
network_interface.get("Description", ""),
|
|
76
|
+
)
|
|
56
77
|
if elb_match:
|
|
57
|
-
elb_v1_id = f
|
|
78
|
+
elb_v1_id = f"{elb_match[1]}-{elb_match[2]}.elb.{region}.amazonaws.com"
|
|
58
79
|
else:
|
|
59
|
-
elb_match = re.match(r
|
|
80
|
+
elb_match = re.match(r"^ELB (.*)", network_interface.get("Description", ""))
|
|
60
81
|
if elb_match:
|
|
61
82
|
elb_v2_id = elb_match[1]
|
|
62
83
|
# TODO issue #1024 change this to arn when ready
|
|
63
|
-
network_interface_id = network_interface[
|
|
84
|
+
network_interface_id = network_interface["NetworkInterfaceId"]
|
|
64
85
|
network_interface_list.append(
|
|
65
86
|
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
"Id": network_interface_id,
|
|
88
|
+
"NetworkInterfaceId": network_interface["NetworkInterfaceId"],
|
|
89
|
+
"Description": network_interface["Description"],
|
|
90
|
+
"InstanceId": network_interface.get("Attachment", {}).get("InstanceId"),
|
|
91
|
+
"InterfaceType": network_interface["InterfaceType"],
|
|
92
|
+
"MacAddress": network_interface["MacAddress"],
|
|
93
|
+
"PrivateDnsName": network_interface.get("PrivateDnsName"),
|
|
94
|
+
"PrivateIpAddress": network_interface["PrivateIpAddress"],
|
|
95
|
+
"PublicIp": network_interface.get("Association", {}).get("PublicIp"),
|
|
96
|
+
"RequesterId": network_interface.get("RequesterId"),
|
|
97
|
+
"RequesterManaged": network_interface["RequesterManaged"],
|
|
98
|
+
"SourceDestCheck": network_interface["SourceDestCheck"],
|
|
99
|
+
"Status": network_interface["Status"],
|
|
100
|
+
"SubnetId": network_interface["SubnetId"],
|
|
101
|
+
"ElbV1Id": elb_v1_id,
|
|
102
|
+
"ElbV2Id": elb_v2_id,
|
|
82
103
|
},
|
|
83
104
|
)
|
|
84
|
-
if network_interface.get(
|
|
85
|
-
for private_ip_address in network_interface[
|
|
105
|
+
if network_interface.get("PrivateIpAddresses"):
|
|
106
|
+
for private_ip_address in network_interface["PrivateIpAddresses"]:
|
|
86
107
|
private_ip_list.append(
|
|
87
108
|
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
109
|
+
"Id": f"{network_interface['NetworkInterfaceId']}:{private_ip_address['PrivateIpAddress']}",
|
|
110
|
+
"NetworkInterfaceId": network_interface["NetworkInterfaceId"],
|
|
111
|
+
"IpOwnerId": private_ip_address.get("Association", {}).get(
|
|
112
|
+
"IpOwnerId",
|
|
113
|
+
),
|
|
114
|
+
"Primary": private_ip_address["Primary"],
|
|
115
|
+
"PrivateIpAddress": private_ip_address["PrivateIpAddress"],
|
|
116
|
+
"PublicIp": private_ip_address.get("Association", {}).get(
|
|
117
|
+
"PublicIp",
|
|
118
|
+
),
|
|
94
119
|
},
|
|
95
120
|
)
|
|
96
121
|
|
|
@@ -98,19 +123,19 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
|
|
|
98
123
|
for group in network_interface["Groups"]:
|
|
99
124
|
sg_list.append(
|
|
100
125
|
{
|
|
101
|
-
|
|
102
|
-
|
|
126
|
+
"GroupId": group["GroupId"],
|
|
127
|
+
"NetworkInterfaceId": network_interface_id,
|
|
103
128
|
},
|
|
104
129
|
)
|
|
105
130
|
|
|
106
|
-
subnet_id = network_interface.get(
|
|
131
|
+
subnet_id = network_interface.get("SubnetId")
|
|
107
132
|
if subnet_id:
|
|
108
133
|
subnet_list.append(
|
|
109
134
|
{
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
135
|
+
"NetworkInterfaceId": network_interface_id,
|
|
136
|
+
"SubnetId": subnet_id,
|
|
137
|
+
"ElbV1Id": elb_v1_id,
|
|
138
|
+
"ElbV2Id": elb_v2_id,
|
|
114
139
|
},
|
|
115
140
|
)
|
|
116
141
|
|
|
@@ -124,11 +149,11 @@ def transform_network_interface_data(data_list: List[Dict[str, Any]], region: st
|
|
|
124
149
|
|
|
125
150
|
@timeit
|
|
126
151
|
def load_network_interfaces(
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
152
|
+
neo4j_session: neo4j.Session,
|
|
153
|
+
data: List[Dict[str, Any]],
|
|
154
|
+
region: str,
|
|
155
|
+
aws_account_id: str,
|
|
156
|
+
update_tag: int,
|
|
132
157
|
) -> None:
|
|
133
158
|
logger.info(f"Loading {len(data)} network interfaces in {region}.")
|
|
134
159
|
load(
|
|
@@ -143,11 +168,11 @@ def load_network_interfaces(
|
|
|
143
168
|
|
|
144
169
|
@timeit
|
|
145
170
|
def load_private_ip_network_interface(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
171
|
+
neo4j_session: neo4j.Session,
|
|
172
|
+
data: List[Dict[str, Any]],
|
|
173
|
+
region: str,
|
|
174
|
+
aws_account_id: str,
|
|
175
|
+
update_tag: int,
|
|
151
176
|
) -> None:
|
|
152
177
|
"""
|
|
153
178
|
Private IPs as known by describe-network-interfaces.
|
|
@@ -165,11 +190,11 @@ def load_private_ip_network_interface(
|
|
|
165
190
|
|
|
166
191
|
@timeit
|
|
167
192
|
def load_security_group_network_interface(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
193
|
+
neo4j_session: neo4j.Session,
|
|
194
|
+
data: List[Dict[str, Any]],
|
|
195
|
+
region: str,
|
|
196
|
+
aws_account_id: str,
|
|
197
|
+
update_tag: int,
|
|
173
198
|
) -> None:
|
|
174
199
|
"""
|
|
175
200
|
Security groups as known by describe-network-interfaces.
|
|
@@ -187,11 +212,11 @@ def load_security_group_network_interface(
|
|
|
187
212
|
|
|
188
213
|
@timeit
|
|
189
214
|
def load_subnet_network_interface(
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
215
|
+
neo4j_session: neo4j.Session,
|
|
216
|
+
data: List[Dict[str, Any]],
|
|
217
|
+
region: str,
|
|
218
|
+
aws_account_id: str,
|
|
219
|
+
update_tag: int,
|
|
195
220
|
) -> None:
|
|
196
221
|
"""
|
|
197
222
|
Subnets as known by describe-network-interfaces.
|
|
@@ -208,38 +233,72 @@ def load_subnet_network_interface(
|
|
|
208
233
|
|
|
209
234
|
|
|
210
235
|
def load_network_data(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
236
|
+
neo4j_session: neo4j.Session,
|
|
237
|
+
region: str,
|
|
238
|
+
current_aws_account_id: str,
|
|
239
|
+
update_tag: int,
|
|
240
|
+
network_interface_list: List[Dict[str, Any]],
|
|
241
|
+
private_ip_list: List[Dict[str, Any]],
|
|
242
|
+
subnet_list: List[Dict[str, Any]],
|
|
243
|
+
sg_list: List[Dict[str, Any]],
|
|
219
244
|
) -> None:
|
|
220
|
-
load_network_interfaces(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
245
|
+
load_network_interfaces(
|
|
246
|
+
neo4j_session,
|
|
247
|
+
network_interface_list,
|
|
248
|
+
region,
|
|
249
|
+
current_aws_account_id,
|
|
250
|
+
update_tag,
|
|
251
|
+
)
|
|
252
|
+
load_private_ip_network_interface(
|
|
253
|
+
neo4j_session,
|
|
254
|
+
private_ip_list,
|
|
255
|
+
region,
|
|
256
|
+
current_aws_account_id,
|
|
257
|
+
update_tag,
|
|
258
|
+
)
|
|
259
|
+
load_subnet_network_interface(
|
|
260
|
+
neo4j_session,
|
|
261
|
+
subnet_list,
|
|
262
|
+
region,
|
|
263
|
+
current_aws_account_id,
|
|
264
|
+
update_tag,
|
|
265
|
+
)
|
|
266
|
+
load_security_group_network_interface(
|
|
267
|
+
neo4j_session,
|
|
268
|
+
sg_list,
|
|
269
|
+
region,
|
|
270
|
+
current_aws_account_id,
|
|
271
|
+
update_tag,
|
|
272
|
+
)
|
|
224
273
|
|
|
225
274
|
|
|
226
275
|
@timeit
|
|
227
|
-
def cleanup_network_interfaces(
|
|
228
|
-
|
|
229
|
-
|
|
276
|
+
def cleanup_network_interfaces(
|
|
277
|
+
neo4j_session: neo4j.Session,
|
|
278
|
+
common_job_parameters: Dict,
|
|
279
|
+
) -> None:
|
|
280
|
+
GraphJob.from_node_schema(EC2NetworkInterfaceSchema(), common_job_parameters).run(
|
|
281
|
+
neo4j_session,
|
|
282
|
+
)
|
|
283
|
+
GraphJob.from_node_schema(
|
|
284
|
+
EC2PrivateIpNetworkInterfaceSchema(),
|
|
285
|
+
common_job_parameters,
|
|
286
|
+
).run(neo4j_session)
|
|
230
287
|
|
|
231
288
|
|
|
232
289
|
@timeit
|
|
233
290
|
def sync_network_interfaces(
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
291
|
+
neo4j_session: neo4j.Session,
|
|
292
|
+
boto3_session: boto3.session.Session,
|
|
293
|
+
regions: List[str],
|
|
294
|
+
current_aws_account_id: str,
|
|
295
|
+
update_tag: int,
|
|
296
|
+
common_job_parameters: Dict,
|
|
240
297
|
) -> None:
|
|
241
298
|
for region in regions:
|
|
242
|
-
logger.info(
|
|
299
|
+
logger.info(
|
|
300
|
+
f"Syncing EC2 network interfaces for region '{region}' in account '{current_aws_account_id}'.",
|
|
301
|
+
)
|
|
243
302
|
data = get_network_interface_data(boto3_session, region)
|
|
244
303
|
ec2_network_data = transform_network_interface_data(data, region)
|
|
245
304
|
load_network_data(
|
|
@@ -6,30 +6,43 @@ import boto3
|
|
|
6
6
|
import neo4j
|
|
7
7
|
from botocore.exceptions import ClientError
|
|
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_reserved_instances(
|
|
20
|
-
|
|
20
|
+
def get_reserved_instances(
|
|
21
|
+
boto3_session: boto3.session.Session,
|
|
22
|
+
region: str,
|
|
23
|
+
) -> List[Dict]:
|
|
24
|
+
client = boto3_session.client(
|
|
25
|
+
"ec2",
|
|
26
|
+
region_name=region,
|
|
27
|
+
config=get_botocore_config(),
|
|
28
|
+
)
|
|
21
29
|
try:
|
|
22
|
-
reserved_instances = client.describe_reserved_instances()[
|
|
30
|
+
reserved_instances = client.describe_reserved_instances()["ReservedInstances"]
|
|
23
31
|
except ClientError as e:
|
|
24
|
-
logger.warning(
|
|
32
|
+
logger.warning(
|
|
33
|
+
f"Failed retrieve reserved instances for region - {region}. Error - {e}",
|
|
34
|
+
)
|
|
25
35
|
raise
|
|
26
36
|
return reserved_instances
|
|
27
37
|
|
|
28
38
|
|
|
29
39
|
@timeit
|
|
30
40
|
def load_reserved_instances(
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
neo4j_session: neo4j.Session,
|
|
42
|
+
data: List[Dict],
|
|
43
|
+
region: str,
|
|
44
|
+
current_aws_account_id: str,
|
|
45
|
+
update_tag: int,
|
|
33
46
|
) -> None:
|
|
34
47
|
ingest_reserved_instances = """
|
|
35
48
|
UNWIND $reserved_instances_list as res
|
|
@@ -48,8 +61,8 @@ def load_reserved_instances(
|
|
|
48
61
|
"""
|
|
49
62
|
|
|
50
63
|
for r_instance in data:
|
|
51
|
-
r_instance[
|
|
52
|
-
r_instance[
|
|
64
|
+
r_instance["Start"] = str(r_instance["Start"])
|
|
65
|
+
r_instance["End"] = str(r_instance["End"])
|
|
53
66
|
|
|
54
67
|
neo4j_session.run(
|
|
55
68
|
ingest_reserved_instances,
|
|
@@ -61,9 +74,12 @@ def load_reserved_instances(
|
|
|
61
74
|
|
|
62
75
|
|
|
63
76
|
@timeit
|
|
64
|
-
def cleanup_reserved_instances(
|
|
77
|
+
def cleanup_reserved_instances(
|
|
78
|
+
neo4j_session: neo4j.Session,
|
|
79
|
+
common_job_parameters: Dict,
|
|
80
|
+
) -> None:
|
|
65
81
|
run_cleanup_job(
|
|
66
|
-
|
|
82
|
+
"aws_import_reserved_instances_cleanup.json",
|
|
67
83
|
neo4j_session,
|
|
68
84
|
common_job_parameters,
|
|
69
85
|
)
|
|
@@ -71,12 +87,25 @@ def cleanup_reserved_instances(neo4j_session: neo4j.Session, common_job_paramete
|
|
|
71
87
|
|
|
72
88
|
@timeit
|
|
73
89
|
def sync_ec2_reserved_instances(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
90
|
+
neo4j_session: neo4j.Session,
|
|
91
|
+
boto3_session: boto3.session.Session,
|
|
92
|
+
regions: List[str],
|
|
93
|
+
current_aws_account_id: str,
|
|
94
|
+
update_tag: int,
|
|
95
|
+
common_job_parameters: Dict,
|
|
77
96
|
) -> None:
|
|
78
97
|
for region in regions:
|
|
79
|
-
logger.debug(
|
|
98
|
+
logger.debug(
|
|
99
|
+
"Syncing reserved instances for region '%s' in account '%s'.",
|
|
100
|
+
region,
|
|
101
|
+
current_aws_account_id,
|
|
102
|
+
)
|
|
80
103
|
data = get_reserved_instances(boto3_session, region)
|
|
81
|
-
load_reserved_instances(
|
|
104
|
+
load_reserved_instances(
|
|
105
|
+
neo4j_session,
|
|
106
|
+
data,
|
|
107
|
+
region,
|
|
108
|
+
current_aws_account_id,
|
|
109
|
+
update_tag,
|
|
110
|
+
)
|
|
82
111
|
cleanup_reserved_instances(neo4j_session, common_job_parameters)
|