cartography 0.95.0__py3-none-any.whl → 0.96.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/cli.py +15 -0
- cartography/client/core/tx.py +1 -1
- cartography/config.py +6 -2
- cartography/data/indexes.cypher +1 -2
- cartography/data/jobs/cleanup/aws_import_identity_center_cleanup.json +16 -0
- cartography/data/jobs/cleanup/{github_users_cleanup.json → github_org_and_users_cleanup.json} +5 -0
- cartography/data/jobs/cleanup/github_repos_cleanup.json +25 -0
- cartography/graph/querybuilder.py +4 -0
- cartography/intel/aws/apigateway.py +3 -3
- cartography/intel/aws/ec2/auto_scaling_groups.py +147 -185
- cartography/intel/aws/ec2/instances.py +2 -0
- cartography/intel/aws/ec2/network_acls.py +209 -0
- cartography/intel/aws/ec2/subnets.py +2 -0
- cartography/intel/aws/iam.py +4 -3
- cartography/intel/aws/identitycenter.py +307 -0
- cartography/intel/aws/resources.py +4 -0
- cartography/intel/cve/__init__.py +1 -1
- cartography/intel/cve/feed.py +10 -7
- cartography/intel/github/repos.py +176 -27
- cartography/intel/github/users.py +156 -39
- cartography/intel/okta/users.py +2 -1
- cartography/intel/semgrep/__init__.py +1 -1
- cartography/intel/semgrep/dependencies.py +54 -22
- cartography/models/aws/ec2/auto_scaling_groups.py +204 -0
- cartography/models/aws/ec2/launch_configurations.py +55 -0
- cartography/models/aws/ec2/network_acl_rules.py +98 -0
- cartography/models/aws/ec2/network_acls.py +86 -0
- cartography/models/aws/identitycenter/__init__.py +0 -0
- cartography/models/aws/identitycenter/awsidentitycenter.py +44 -0
- cartography/models/aws/identitycenter/awspermissionset.py +84 -0
- cartography/models/aws/identitycenter/awsssouser.py +68 -0
- cartography/models/core/common.py +18 -1
- cartography/models/github/orgs.py +26 -0
- cartography/models/github/users.py +119 -0
- cartography/models/semgrep/dependencies.py +13 -0
- cartography-0.96.0.dist-info/METADATA +53 -0
- {cartography-0.95.0.dist-info → cartography-0.96.0.dist-info}/RECORD +41 -28
- {cartography-0.95.0.dist-info → cartography-0.96.0.dist-info}/WHEEL +1 -1
- cartography-0.95.0.dist-info/METADATA +0 -53
- {cartography-0.95.0.dist-info → cartography-0.96.0.dist-info}/LICENSE +0 -0
- {cartography-0.95.0.dist-info → cartography-0.96.0.dist-info}/entry_points.txt +0 -0
- {cartography-0.95.0.dist-info → cartography-0.96.0.dist-info}/top_level.txt +0 -0
|
@@ -12,6 +12,7 @@ from requests.exceptions import ReadTimeout
|
|
|
12
12
|
from cartography.client.core.tx import load
|
|
13
13
|
from cartography.graph.job import GraphJob
|
|
14
14
|
from cartography.models.semgrep.dependencies import SemgrepGoLibrarySchema
|
|
15
|
+
from cartography.models.semgrep.dependencies import SemgrepNpmLibrarySchema
|
|
15
16
|
from cartography.stats import get_stats_client
|
|
16
17
|
from cartography.util import merge_module_sync_metadata
|
|
17
18
|
from cartography.util import timeit
|
|
@@ -22,16 +23,38 @@ _PAGE_SIZE = 10000
|
|
|
22
23
|
_TIMEOUT = (60, 60)
|
|
23
24
|
_MAX_RETRIES = 3
|
|
24
25
|
|
|
26
|
+
# The keys in this dictionary must be in Semgrep's list of supported ecosystems, defined here:
|
|
27
|
+
# https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/semgrep_app.products.sca.handlers.dependency.list_dependencies_conexxion
|
|
28
|
+
ECOSYSTEM_TO_SCHEMA: Dict = {
|
|
29
|
+
'gomod': SemgrepGoLibrarySchema,
|
|
30
|
+
'npm': SemgrepNpmLibrarySchema,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def parse_and_validate_semgrep_ecosystems(ecosystems: str) -> List[str]:
|
|
35
|
+
validated_ecosystems: List[str] = []
|
|
36
|
+
for ecosystem in ecosystems.split(','):
|
|
37
|
+
ecosystem = ecosystem.strip().lower()
|
|
38
|
+
|
|
39
|
+
if ecosystem in ECOSYSTEM_TO_SCHEMA:
|
|
40
|
+
validated_ecosystems.append(ecosystem)
|
|
41
|
+
else:
|
|
42
|
+
valid_ecosystems: str = ','.join(ECOSYSTEM_TO_SCHEMA.keys())
|
|
43
|
+
raise ValueError(
|
|
44
|
+
f'Error parsing `semgrep-dependency-ecosystems`. You specified "{ecosystems}". '
|
|
45
|
+
f'Please check that your input is formatted as comma-separated values, e.g. "gomod,npm". '
|
|
46
|
+
f'Full list of supported ecosystems: {valid_ecosystems}.',
|
|
47
|
+
)
|
|
48
|
+
return validated_ecosystems
|
|
49
|
+
|
|
25
50
|
|
|
26
51
|
@timeit
|
|
27
|
-
def get_dependencies(semgrep_app_token: str, deployment_id: str,
|
|
52
|
+
def get_dependencies(semgrep_app_token: str, deployment_id: str, ecosystem: str) -> List[Dict[str, Any]]:
|
|
28
53
|
"""
|
|
29
|
-
Gets all dependencies for the given
|
|
54
|
+
Gets all dependencies for the given ecosystem within the given Semgrep deployment ID.
|
|
30
55
|
param: semgrep_app_token: The Semgrep App token to use for authentication.
|
|
31
56
|
param: deployment_id: The Semgrep deployment ID to use for retrieving dependencies.
|
|
32
|
-
param:
|
|
33
|
-
The list of supported ecosystems is defined here:
|
|
34
|
-
https://semgrep.dev/api/v1/docs/#tag/SupplyChainService/operation/semgrep_app.products.sca.handlers.dependency.list_dependencies_conexxion
|
|
57
|
+
param: ecosystem: The ecosystem to import dependencies from, e.g. "gomod" or "npm".
|
|
35
58
|
"""
|
|
36
59
|
all_deps = []
|
|
37
60
|
deps_url = f"https://semgrep.dev/api/v1/deployments/{deployment_id}/dependencies"
|
|
@@ -46,31 +69,31 @@ def get_dependencies(semgrep_app_token: str, deployment_id: str, ecosystems: Lis
|
|
|
46
69
|
request_data: dict[str, Any] = {
|
|
47
70
|
"pageSize": _PAGE_SIZE,
|
|
48
71
|
"dependencyFilter": {
|
|
49
|
-
"ecosystem":
|
|
72
|
+
"ecosystem": [ecosystem],
|
|
50
73
|
},
|
|
51
74
|
}
|
|
52
75
|
|
|
53
|
-
logger.info(f"Retrieving Semgrep dependencies for deployment '{deployment_id}'.")
|
|
76
|
+
logger.info(f"Retrieving Semgrep {ecosystem} dependencies for deployment '{deployment_id}'.")
|
|
54
77
|
while has_more:
|
|
55
78
|
try:
|
|
56
79
|
response = requests.post(deps_url, json=request_data, headers=headers, timeout=_TIMEOUT)
|
|
57
80
|
response.raise_for_status()
|
|
58
81
|
data = response.json()
|
|
59
82
|
except (ReadTimeout, HTTPError):
|
|
60
|
-
logger.warning(f"Failed to retrieve Semgrep dependencies for page {page}. Retrying...")
|
|
83
|
+
logger.warning(f"Failed to retrieve Semgrep {ecosystem} dependencies for page {page}. Retrying...")
|
|
61
84
|
retries += 1
|
|
62
85
|
if retries >= _MAX_RETRIES:
|
|
63
86
|
raise
|
|
64
87
|
continue
|
|
65
88
|
deps = data.get("dependencies", [])
|
|
66
89
|
has_more = data.get("hasMore", False)
|
|
67
|
-
logger.info(f"Processed page {page} of Semgrep dependencies.")
|
|
90
|
+
logger.info(f"Processed page {page} of Semgrep {ecosystem} dependencies.")
|
|
68
91
|
all_deps.extend(deps)
|
|
69
92
|
retries = 0
|
|
70
93
|
page += 1
|
|
71
94
|
request_data["cursor"] = data.get("cursor")
|
|
72
95
|
|
|
73
|
-
logger.info(f"Retrieved {len(all_deps)} Semgrep dependencies in {page} pages.")
|
|
96
|
+
logger.info(f"Retrieved {len(all_deps)} Semgrep {ecosystem} dependencies in {page} pages.")
|
|
74
97
|
return all_deps
|
|
75
98
|
|
|
76
99
|
|
|
@@ -157,19 +180,18 @@ def load_dependencies(
|
|
|
157
180
|
@timeit
|
|
158
181
|
def cleanup(
|
|
159
182
|
neo4j_session: neo4j.Session,
|
|
183
|
+
dependency_schema: Callable,
|
|
160
184
|
common_job_parameters: Dict[str, Any],
|
|
161
185
|
) -> None:
|
|
162
|
-
logger.info("Running Semgrep
|
|
163
|
-
|
|
164
|
-
SemgrepGoLibrarySchema(), common_job_parameters,
|
|
165
|
-
)
|
|
166
|
-
go_libraries_cleanup_job.run(neo4j_session)
|
|
186
|
+
logger.info(f"Running Semgrep Dependencies cleanup job for {dependency_schema().label}.")
|
|
187
|
+
GraphJob.from_node_schema(dependency_schema(), common_job_parameters).run(neo4j_session)
|
|
167
188
|
|
|
168
189
|
|
|
169
190
|
@timeit
|
|
170
191
|
def sync_dependencies(
|
|
171
192
|
neo4j_session: neo4j.Session,
|
|
172
193
|
semgrep_app_token: str,
|
|
194
|
+
ecosystems_str: str,
|
|
173
195
|
update_tag: int,
|
|
174
196
|
common_job_parameters: Dict[str, Any],
|
|
175
197
|
) -> None:
|
|
@@ -177,19 +199,29 @@ def sync_dependencies(
|
|
|
177
199
|
deployment_id = common_job_parameters.get("DEPLOYMENT_ID")
|
|
178
200
|
if not deployment_id:
|
|
179
201
|
logger.warning(
|
|
180
|
-
"Missing Semgrep deployment ID, ensure that sync_deployment() has been called."
|
|
202
|
+
"Missing Semgrep deployment ID, ensure that sync_deployment() has been called. "
|
|
181
203
|
"Skipping Semgrep dependencies sync job.",
|
|
182
204
|
)
|
|
183
205
|
return
|
|
184
206
|
|
|
185
|
-
|
|
207
|
+
if not ecosystems_str:
|
|
208
|
+
logger.warning(
|
|
209
|
+
"Semgrep is not configured to import dependencies for any ecosystems, see docs to configure. "
|
|
210
|
+
"Skipping Semgrep dependencies sync job.",
|
|
211
|
+
)
|
|
212
|
+
return
|
|
213
|
+
|
|
214
|
+
# We don't expect an error here since we've already validated the input in cli.py
|
|
215
|
+
ecosystems = parse_and_validate_semgrep_ecosystems(ecosystems_str)
|
|
186
216
|
|
|
187
|
-
|
|
188
|
-
raw_go_deps = get_dependencies(semgrep_app_token, deployment_id, ecosystems=["gomod"])
|
|
189
|
-
go_deps = transform_dependencies(raw_go_deps)
|
|
190
|
-
load_dependencies(neo4j_session, SemgrepGoLibrarySchema, go_deps, deployment_id, update_tag)
|
|
217
|
+
logger.info("Running Semgrep dependencies sync job.")
|
|
191
218
|
|
|
192
|
-
|
|
219
|
+
for ecosystem in ecosystems:
|
|
220
|
+
schema = ECOSYSTEM_TO_SCHEMA[ecosystem]
|
|
221
|
+
raw_deps = get_dependencies(semgrep_app_token, deployment_id, ecosystem)
|
|
222
|
+
deps = transform_dependencies(raw_deps)
|
|
223
|
+
load_dependencies(neo4j_session, schema, deps, deployment_id, update_tag)
|
|
224
|
+
cleanup(neo4j_session, schema, common_job_parameters)
|
|
193
225
|
|
|
194
226
|
merge_module_sync_metadata(
|
|
195
227
|
neo4j_session=neo4j_session,
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class AutoScalingGroupNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef('AutoScalingGroupARN')
|
|
17
|
+
arn: PropertyRef = PropertyRef('AutoScalingGroupARN')
|
|
18
|
+
capacityrebalance: PropertyRef = PropertyRef('CapacityRebalance')
|
|
19
|
+
createdtime: PropertyRef = PropertyRef('CreatedTime')
|
|
20
|
+
defaultcooldown: PropertyRef = PropertyRef('DefaultCooldown')
|
|
21
|
+
desiredcapacity: PropertyRef = PropertyRef('DesiredCapacity')
|
|
22
|
+
healthcheckgraceperiod: PropertyRef = PropertyRef('HealthCheckGracePeriod')
|
|
23
|
+
healthchecktype: PropertyRef = PropertyRef('HealthCheckType')
|
|
24
|
+
launchconfigurationname: PropertyRef = PropertyRef('LaunchConfigurationName')
|
|
25
|
+
launchtemplatename: PropertyRef = PropertyRef('LaunchTemplateName')
|
|
26
|
+
launchtemplateid: PropertyRef = PropertyRef('LaunchTemplateId')
|
|
27
|
+
launchtemplateversion: PropertyRef = PropertyRef('LaunchTemplateVersion')
|
|
28
|
+
maxinstancelifetime: PropertyRef = PropertyRef('MaxInstanceLifetime')
|
|
29
|
+
maxsize: PropertyRef = PropertyRef('MaxSize')
|
|
30
|
+
minsize: PropertyRef = PropertyRef('MinSize')
|
|
31
|
+
name: PropertyRef = PropertyRef('AutoScalingGroupName')
|
|
32
|
+
newinstancesprotectedfromscalein: PropertyRef = PropertyRef('NewInstancesProtectedFromScaleIn')
|
|
33
|
+
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
|
|
34
|
+
status: PropertyRef = PropertyRef('Status')
|
|
35
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# EC2 to AutoScalingGroup
|
|
39
|
+
@dataclass(frozen=True)
|
|
40
|
+
class EC2InstanceToAwsAccountRelProperties(CartographyRelProperties):
|
|
41
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(frozen=True)
|
|
45
|
+
class EC2InstanceToAWSAccount(CartographyRelSchema):
|
|
46
|
+
target_node_label: str = 'AWSAccount'
|
|
47
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
48
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
49
|
+
)
|
|
50
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
51
|
+
rel_label: str = "RESOURCE"
|
|
52
|
+
properties: EC2InstanceToAwsAccountRelProperties = EC2InstanceToAwsAccountRelProperties()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@dataclass(frozen=True)
|
|
56
|
+
class EC2InstanceToAutoScalingGroupRelProperties(CartographyRelProperties):
|
|
57
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@dataclass(frozen=True)
|
|
61
|
+
class EC2InstanceToAutoScalingGroup(CartographyRelSchema):
|
|
62
|
+
target_node_label: str = 'AutoScalingGroup'
|
|
63
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
64
|
+
{'id': PropertyRef('AutoScalingGroupARN')},
|
|
65
|
+
)
|
|
66
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
67
|
+
rel_label: str = "MEMBER_AUTO_SCALE_GROUP"
|
|
68
|
+
properties: EC2InstanceToAutoScalingGroupRelProperties = EC2InstanceToAutoScalingGroupRelProperties()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass(frozen=True)
|
|
72
|
+
class EC2InstanceAutoScalingGroupProperties(CartographyNodeProperties):
|
|
73
|
+
id: PropertyRef = PropertyRef('InstanceId')
|
|
74
|
+
instanceid: PropertyRef = PropertyRef('InstanceId', extra_index=True)
|
|
75
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
76
|
+
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@dataclass(frozen=True)
|
|
80
|
+
class EC2InstanceAutoScalingGroupSchema(CartographyNodeSchema):
|
|
81
|
+
label: str = 'EC2Instance'
|
|
82
|
+
properties: EC2InstanceAutoScalingGroupProperties = EC2InstanceAutoScalingGroupProperties()
|
|
83
|
+
sub_resource_relationship: EC2InstanceToAWSAccount = EC2InstanceToAWSAccount()
|
|
84
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
85
|
+
[
|
|
86
|
+
EC2InstanceToAutoScalingGroup(),
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# EC2Subnet to AutoScalingGroup
|
|
92
|
+
@dataclass(frozen=True)
|
|
93
|
+
class EC2SubnetToAwsAccountRelProperties(CartographyRelProperties):
|
|
94
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@dataclass(frozen=True)
|
|
98
|
+
class EC2SubnetToAWSAccount(CartographyRelSchema):
|
|
99
|
+
target_node_label: str = 'AWSAccount'
|
|
100
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
101
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
102
|
+
)
|
|
103
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
104
|
+
rel_label: str = "RESOURCE"
|
|
105
|
+
properties: EC2SubnetToAwsAccountRelProperties = EC2SubnetToAwsAccountRelProperties()
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@dataclass(frozen=True)
|
|
109
|
+
class EC2SubnetToAutoScalingGroupRelProperties(CartographyRelProperties):
|
|
110
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@dataclass(frozen=True)
|
|
114
|
+
class EC2SubnetToAutoScalingGroup(CartographyRelSchema):
|
|
115
|
+
target_node_label: str = 'AutoScalingGroup'
|
|
116
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
117
|
+
{'id': PropertyRef('AutoScalingGroupARN')},
|
|
118
|
+
)
|
|
119
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
120
|
+
rel_label: str = "VPC_IDENTIFIER"
|
|
121
|
+
properties: EC2SubnetToAutoScalingGroupRelProperties = EC2SubnetToAutoScalingGroupRelProperties()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@dataclass(frozen=True)
|
|
125
|
+
class EC2SubnetAutoScalingGroupNodeProperties(CartographyNodeProperties):
|
|
126
|
+
id: PropertyRef = PropertyRef('VPCZoneIdentifier')
|
|
127
|
+
subnetid: PropertyRef = PropertyRef('VPCZoneIdentifier', extra_index=True)
|
|
128
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@dataclass(frozen=True)
|
|
132
|
+
class EC2SubnetAutoScalingGroupSchema(CartographyNodeSchema):
|
|
133
|
+
label: str = 'EC2Subnet'
|
|
134
|
+
properties: EC2SubnetAutoScalingGroupNodeProperties = EC2SubnetAutoScalingGroupNodeProperties()
|
|
135
|
+
sub_resource_relationship: EC2SubnetToAWSAccount = EC2SubnetToAWSAccount()
|
|
136
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
137
|
+
[
|
|
138
|
+
EC2SubnetToAutoScalingGroup(),
|
|
139
|
+
],
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# AutoScalingGroup
|
|
144
|
+
@dataclass(frozen=True)
|
|
145
|
+
class AutoScalingGroupToAwsAccountRelProperties(CartographyRelProperties):
|
|
146
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@dataclass(frozen=True)
|
|
150
|
+
class AutoScalingGroupToAWSAccount(CartographyRelSchema):
|
|
151
|
+
target_node_label: str = 'AWSAccount'
|
|
152
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
153
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
154
|
+
)
|
|
155
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
156
|
+
rel_label: str = "RESOURCE"
|
|
157
|
+
properties: AutoScalingGroupToAwsAccountRelProperties = AutoScalingGroupToAwsAccountRelProperties()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@dataclass(frozen=True)
|
|
161
|
+
class AutoScalingGroupToLaunchTemplateRelProperties(CartographyRelProperties):
|
|
162
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@dataclass(frozen=True)
|
|
166
|
+
class AutoScalingGroupToLaunchTemplate(CartographyRelSchema):
|
|
167
|
+
target_node_label: str = 'LaunchTemplate'
|
|
168
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
169
|
+
{'id': PropertyRef('LaunchTemplateId')},
|
|
170
|
+
)
|
|
171
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
172
|
+
rel_label: str = "HAS_LAUNCH_TEMPLATE"
|
|
173
|
+
properties: AutoScalingGroupToLaunchTemplateRelProperties = AutoScalingGroupToLaunchTemplateRelProperties()
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dataclass(frozen=True)
|
|
177
|
+
class AutoScalingGroupToLaunchConfigurationRelProperties(CartographyRelProperties):
|
|
178
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dataclass(frozen=True)
|
|
182
|
+
class AutoScalingGroupToLaunchConfiguration(CartographyRelSchema):
|
|
183
|
+
target_node_label: str = 'LaunchConfiguration'
|
|
184
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
185
|
+
{'name': PropertyRef('LaunchConfigurationName')},
|
|
186
|
+
)
|
|
187
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
188
|
+
rel_label: str = "HAS_LAUNCH_CONFIG"
|
|
189
|
+
properties: AutoScalingGroupToLaunchConfigurationRelProperties = (
|
|
190
|
+
AutoScalingGroupToLaunchConfigurationRelProperties()
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@dataclass(frozen=True)
|
|
195
|
+
class AutoScalingGroupSchema(CartographyNodeSchema):
|
|
196
|
+
label: str = 'AutoScalingGroup'
|
|
197
|
+
properties: AutoScalingGroupNodeProperties = AutoScalingGroupNodeProperties()
|
|
198
|
+
sub_resource_relationship: AutoScalingGroupToAWSAccount = AutoScalingGroupToAWSAccount()
|
|
199
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
200
|
+
[
|
|
201
|
+
AutoScalingGroupToLaunchTemplate(),
|
|
202
|
+
AutoScalingGroupToLaunchConfiguration(),
|
|
203
|
+
],
|
|
204
|
+
)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class LaunchConfigurationNodeProperties(CartographyNodeProperties):
|
|
15
|
+
id: PropertyRef = PropertyRef('LaunchConfigurationARN')
|
|
16
|
+
arn: PropertyRef = PropertyRef('LaunchConfigurationARN')
|
|
17
|
+
created_time = PropertyRef('CreatedTime')
|
|
18
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
19
|
+
image_id: PropertyRef = PropertyRef('ImageId')
|
|
20
|
+
key_name: PropertyRef = PropertyRef('KeyName')
|
|
21
|
+
name: PropertyRef = PropertyRef('LaunchConfigurationName')
|
|
22
|
+
security_groups: PropertyRef = PropertyRef('SecurityGroups')
|
|
23
|
+
instance_type: PropertyRef = PropertyRef('InstanceType')
|
|
24
|
+
kernel_id: PropertyRef = PropertyRef('KernelId')
|
|
25
|
+
ramdisk_id: PropertyRef = PropertyRef('RamdiskId')
|
|
26
|
+
instance_monitoring_enabled: PropertyRef = PropertyRef('InstanceMonitoringEnabled')
|
|
27
|
+
spot_price: PropertyRef = PropertyRef('SpotPrice')
|
|
28
|
+
iam_instance_profile: PropertyRef = PropertyRef('IamInstanceProfile')
|
|
29
|
+
ebs_optimized: PropertyRef = PropertyRef('EbsOptimized')
|
|
30
|
+
associate_public_ip_address: PropertyRef = PropertyRef('AssociatePublicIpAddress')
|
|
31
|
+
placement_tenancy: PropertyRef = PropertyRef('PlacementTenancy')
|
|
32
|
+
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass(frozen=True)
|
|
36
|
+
class LaunchConfigurationToAwsAccountRelProperties(CartographyRelProperties):
|
|
37
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class LaunchConfigurationToAwsAccount(CartographyRelSchema):
|
|
42
|
+
target_node_label: str = 'AWSAccount'
|
|
43
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
44
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
45
|
+
)
|
|
46
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
47
|
+
rel_label: str = "RESOURCE"
|
|
48
|
+
properties: LaunchConfigurationToAwsAccountRelProperties = LaunchConfigurationToAwsAccountRelProperties()
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@dataclass(frozen=True)
|
|
52
|
+
class LaunchConfigurationSchema(CartographyNodeSchema):
|
|
53
|
+
label: str = 'LaunchConfiguration'
|
|
54
|
+
properties: LaunchConfigurationNodeProperties = LaunchConfigurationNodeProperties()
|
|
55
|
+
sub_resource_relationship: LaunchConfigurationToAwsAccount = LaunchConfigurationToAwsAccount()
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.nodes import ExtraNodeLabels
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
8
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
9
|
+
from cartography.models.core.relationships import LinkDirection
|
|
10
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
11
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
12
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True)
|
|
16
|
+
class EC2NetworkAclRuleNodeProperties(CartographyNodeProperties):
|
|
17
|
+
id: PropertyRef = PropertyRef('Id')
|
|
18
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
19
|
+
network_acl_id: PropertyRef = PropertyRef('NetworkAclId')
|
|
20
|
+
protocol: PropertyRef = PropertyRef('Protocol')
|
|
21
|
+
fromport: PropertyRef = PropertyRef('FromPort')
|
|
22
|
+
toport: PropertyRef = PropertyRef('ToPort')
|
|
23
|
+
cidrblock: PropertyRef = PropertyRef('CidrBlock')
|
|
24
|
+
ipv6cidrblock: PropertyRef = PropertyRef('Ipv6CidrBlock')
|
|
25
|
+
egress: PropertyRef = PropertyRef('Egress')
|
|
26
|
+
rulenumber: PropertyRef = PropertyRef('RuleNumber')
|
|
27
|
+
ruleaction: PropertyRef = PropertyRef('RuleAction')
|
|
28
|
+
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True)
|
|
32
|
+
class EC2NetworkAclRuleAclRelProperties(CartographyRelProperties):
|
|
33
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True)
|
|
37
|
+
class EC2NetworkAclRuleToAcl(CartographyRelSchema):
|
|
38
|
+
target_node_label: str = 'EC2NetworkAcl'
|
|
39
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
40
|
+
{'network_acl_id': PropertyRef('NetworkAclId')},
|
|
41
|
+
)
|
|
42
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
43
|
+
rel_label: str = "MEMBER_OF_NACL"
|
|
44
|
+
properties: EC2NetworkAclRuleAclRelProperties = EC2NetworkAclRuleAclRelProperties()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@dataclass(frozen=True)
|
|
48
|
+
class EC2NetworkAclRuleToAwsAccountRelProperties(CartographyRelProperties):
|
|
49
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True)
|
|
53
|
+
class EC2NetworkAclRuleToAWSAccount(CartographyRelSchema):
|
|
54
|
+
target_node_label: str = 'AWSAccount'
|
|
55
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
56
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
57
|
+
)
|
|
58
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
59
|
+
rel_label: str = "RESOURCE"
|
|
60
|
+
properties: EC2NetworkAclRuleToAwsAccountRelProperties = EC2NetworkAclRuleToAwsAccountRelProperties()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(frozen=True)
|
|
64
|
+
class EC2NetworkAclInboundRuleSchema(CartographyNodeSchema):
|
|
65
|
+
"""
|
|
66
|
+
Network interface as known by describe-network-interfaces.
|
|
67
|
+
"""
|
|
68
|
+
label: str = 'EC2NetworkAclRule'
|
|
69
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(
|
|
70
|
+
['IpPermissionInbound'],
|
|
71
|
+
)
|
|
72
|
+
properties: EC2NetworkAclRuleNodeProperties = EC2NetworkAclRuleNodeProperties()
|
|
73
|
+
sub_resource_relationship: EC2NetworkAclRuleToAWSAccount = EC2NetworkAclRuleToAWSAccount()
|
|
74
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
75
|
+
[
|
|
76
|
+
EC2NetworkAclRuleToAcl(),
|
|
77
|
+
],
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True)
|
|
82
|
+
class EC2NetworkAclEgressRuleSchema(CartographyNodeSchema):
|
|
83
|
+
"""
|
|
84
|
+
Network interface as known by describe-network-interfaces.
|
|
85
|
+
"""
|
|
86
|
+
label: str = 'EC2NetworkAclRule'
|
|
87
|
+
extra_node_labels: ExtraNodeLabels = ExtraNodeLabels(
|
|
88
|
+
[
|
|
89
|
+
'IpPermissionEgress',
|
|
90
|
+
],
|
|
91
|
+
)
|
|
92
|
+
properties: EC2NetworkAclRuleNodeProperties = EC2NetworkAclRuleNodeProperties()
|
|
93
|
+
sub_resource_relationship: EC2NetworkAclRuleToAWSAccount = EC2NetworkAclRuleToAWSAccount()
|
|
94
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
95
|
+
[
|
|
96
|
+
EC2NetworkAclRuleToAcl(),
|
|
97
|
+
],
|
|
98
|
+
)
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import OtherRelationships
|
|
11
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class EC2NetworkAclNodeProperties(CartographyNodeProperties):
|
|
16
|
+
id: PropertyRef = PropertyRef('Arn')
|
|
17
|
+
arn: PropertyRef = PropertyRef('Arn')
|
|
18
|
+
network_acl_id: PropertyRef = PropertyRef('Id')
|
|
19
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
20
|
+
is_default: PropertyRef = PropertyRef('IsDefault')
|
|
21
|
+
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
|
|
22
|
+
vpc_id: PropertyRef = PropertyRef('VpcId')
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@dataclass(frozen=True)
|
|
26
|
+
class EC2NetworkAclToVpcRelProperties(CartographyRelProperties):
|
|
27
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass(frozen=True)
|
|
31
|
+
class EC2NetworkAclToVpc(CartographyRelSchema):
|
|
32
|
+
target_node_label: str = 'AWSVpc'
|
|
33
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
34
|
+
{'vpcid': PropertyRef('VpcId')},
|
|
35
|
+
)
|
|
36
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
37
|
+
rel_label: str = "MEMBER_OF_AWS_VPC"
|
|
38
|
+
properties: EC2NetworkAclToVpcRelProperties = EC2NetworkAclToVpcRelProperties()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True)
|
|
42
|
+
class EC2NetworkAclToSubnetRelProperties(CartographyRelProperties):
|
|
43
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True)
|
|
47
|
+
class EC2NetworkAclToSubnet(CartographyRelSchema):
|
|
48
|
+
target_node_label: str = 'EC2Subnet'
|
|
49
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
50
|
+
{'subnetid': PropertyRef('SubnetId')},
|
|
51
|
+
)
|
|
52
|
+
direction: LinkDirection = LinkDirection.OUTWARD
|
|
53
|
+
rel_label: str = "PART_OF_SUBNET"
|
|
54
|
+
properties: EC2NetworkAclToSubnetRelProperties = EC2NetworkAclToSubnetRelProperties()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True)
|
|
58
|
+
class EC2NetworkAclToAwsAccountRelProperties(CartographyRelProperties):
|
|
59
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(frozen=True)
|
|
63
|
+
class EC2NetworkAclToAWSAccount(CartographyRelSchema):
|
|
64
|
+
target_node_label: str = 'AWSAccount'
|
|
65
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
66
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
67
|
+
)
|
|
68
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
69
|
+
rel_label: str = "RESOURCE"
|
|
70
|
+
properties: EC2NetworkAclToAwsAccountRelProperties = EC2NetworkAclToAwsAccountRelProperties()
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True)
|
|
74
|
+
class EC2NetworkAclSchema(CartographyNodeSchema):
|
|
75
|
+
"""
|
|
76
|
+
Network interface as known by describe-network-interfaces.
|
|
77
|
+
"""
|
|
78
|
+
label: str = 'EC2NetworkAcl'
|
|
79
|
+
properties: EC2NetworkAclNodeProperties = EC2NetworkAclNodeProperties()
|
|
80
|
+
sub_resource_relationship: EC2NetworkAclToAWSAccount = EC2NetworkAclToAWSAccount()
|
|
81
|
+
other_relationships: OtherRelationships = OtherRelationships(
|
|
82
|
+
[
|
|
83
|
+
EC2NetworkAclToVpc(),
|
|
84
|
+
EC2NetworkAclToSubnet(),
|
|
85
|
+
],
|
|
86
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from cartography.models.core.common import PropertyRef
|
|
4
|
+
from cartography.models.core.nodes import CartographyNodeProperties
|
|
5
|
+
from cartography.models.core.nodes import CartographyNodeSchema
|
|
6
|
+
from cartography.models.core.relationships import CartographyRelProperties
|
|
7
|
+
from cartography.models.core.relationships import CartographyRelSchema
|
|
8
|
+
from cartography.models.core.relationships import LinkDirection
|
|
9
|
+
from cartography.models.core.relationships import make_target_node_matcher
|
|
10
|
+
from cartography.models.core.relationships import TargetNodeMatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True)
|
|
14
|
+
class IdentityCenterInstanceProperties(CartographyNodeProperties):
|
|
15
|
+
identity_store_id: PropertyRef = PropertyRef('IdentityStoreId')
|
|
16
|
+
arn: PropertyRef = PropertyRef('InstanceArn')
|
|
17
|
+
created_date: PropertyRef = PropertyRef('CreatedDate')
|
|
18
|
+
id: PropertyRef = PropertyRef('InstanceArn')
|
|
19
|
+
status: PropertyRef = PropertyRef('Status')
|
|
20
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class IdentityCenterToAwsAccountRelProperties(CartographyRelProperties):
|
|
25
|
+
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
# (:IdentityCenter)<-[:RESOURCE]-(:AWSAccount)
|
|
30
|
+
class IdentityCenterToAWSAccount(CartographyRelSchema):
|
|
31
|
+
target_node_label: str = 'AWSAccount'
|
|
32
|
+
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
|
|
33
|
+
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
|
|
34
|
+
)
|
|
35
|
+
direction: LinkDirection = LinkDirection.INWARD
|
|
36
|
+
rel_label: str = "RESOURCE"
|
|
37
|
+
properties: IdentityCenterToAwsAccountRelProperties = IdentityCenterToAwsAccountRelProperties()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass(frozen=True)
|
|
41
|
+
class AWSIdentityCenterInstanceSchema(CartographyNodeSchema):
|
|
42
|
+
label: str = 'AWSIdentityCenter'
|
|
43
|
+
properties: IdentityCenterInstanceProperties = IdentityCenterInstanceProperties()
|
|
44
|
+
sub_resource_relationship: IdentityCenterToAWSAccount = IdentityCenterToAWSAccount()
|