Skip to content

Commit

Permalink
Auto scaling groups data model refactor (cartography-cncf#1394)
Browse files Browse the repository at this point in the history
### Summary

Migrating the ASG sync to use the data model. Nothing else was changed
in the sync aside from creating the model and using it during the sync.

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [ ] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [ ] Update the
[schema](https://github.com/lyft/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/lyft/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [ ] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).

---------

Signed-off-by: Sergio Franco <[email protected]>
Signed-off-by: cmm-lyft <[email protected]>
  • Loading branch information
serge-wq authored and cmm-lyft committed Dec 6, 2024
1 parent d2a4cbe commit 5309729
Show file tree
Hide file tree
Showing 9 changed files with 656 additions and 230 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.*.swp
.DS_Store
/venv*
.venv/
.cache/
build/
.idea/
Expand Down
332 changes: 147 additions & 185 deletions cartography/intel/aws/ec2/auto_scaling_groups.py

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions cartography/intel/aws/ec2/instances.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from cartography.client.core.tx import load
from cartography.graph.job import GraphJob
from cartography.intel.aws.ec2.util import get_botocore_config
from cartography.models.aws.ec2.auto_scaling_groups import EC2InstanceAutoScalingGroupSchema
from cartography.models.aws.ec2.instances import EC2InstanceSchema
from cartography.models.aws.ec2.keypairs import EC2KeyPairSchema
from cartography.models.aws.ec2.networkinterface_instance import EC2NetworkInterfaceInstanceSchema
Expand Down Expand Up @@ -308,6 +309,7 @@ def cleanup(neo4j_session: neo4j.Session, common_job_parameters: Dict[str, Any])
logger.debug("Running EC2 instance cleanup")
GraphJob.from_node_schema(EC2ReservationSchema(), common_job_parameters).run(neo4j_session)
GraphJob.from_node_schema(EC2InstanceSchema(), common_job_parameters).run(neo4j_session)
GraphJob.from_node_schema(EC2InstanceAutoScalingGroupSchema(), common_job_parameters).run(neo4j_session)


@timeit
Expand Down
2 changes: 2 additions & 0 deletions cartography/intel/aws/ec2/subnets.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from .util import get_botocore_config
from cartography.graph.job import GraphJob
from cartography.models.aws.ec2.auto_scaling_groups import EC2SubnetAutoScalingGroupSchema
from cartography.models.aws.ec2.subnet_instance import EC2SubnetInstanceSchema
from cartography.util import aws_handle_regions
from cartography.util import run_cleanup_job
Expand Down Expand Up @@ -79,6 +80,7 @@ def load_subnets(
def cleanup_subnets(neo4j_session: neo4j.Session, common_job_parameters: Dict) -> None:
run_cleanup_job('aws_ingest_subnets_cleanup.json', neo4j_session, common_job_parameters)
GraphJob.from_node_schema(EC2SubnetInstanceSchema(), common_job_parameters).run(neo4j_session)
GraphJob.from_node_schema(EC2SubnetAutoScalingGroupSchema(), common_job_parameters).run(neo4j_session)


@timeit
Expand Down
204 changes: 204 additions & 0 deletions cartography/models/aws/ec2/auto_scaling_groups.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
from dataclasses import dataclass

from cartography.models.core.common import PropertyRef
from cartography.models.core.nodes import CartographyNodeProperties
from cartography.models.core.nodes import CartographyNodeSchema
from cartography.models.core.relationships import CartographyRelProperties
from cartography.models.core.relationships import CartographyRelSchema
from cartography.models.core.relationships import LinkDirection
from cartography.models.core.relationships import make_target_node_matcher
from cartography.models.core.relationships import OtherRelationships
from cartography.models.core.relationships import TargetNodeMatcher


@dataclass(frozen=True)
class AutoScalingGroupNodeProperties(CartographyNodeProperties):
id: PropertyRef = PropertyRef('AutoScalingGroupARN')
arn: PropertyRef = PropertyRef('AutoScalingGroupARN')
capacityrebalance: PropertyRef = PropertyRef('CapacityRebalance')
createdtime: PropertyRef = PropertyRef('CreatedTime')
defaultcooldown: PropertyRef = PropertyRef('DefaultCooldown')
desiredcapacity: PropertyRef = PropertyRef('DesiredCapacity')
healthcheckgraceperiod: PropertyRef = PropertyRef('HealthCheckGracePeriod')
healthchecktype: PropertyRef = PropertyRef('HealthCheckType')
launchconfigurationname: PropertyRef = PropertyRef('LaunchConfigurationName')
launchtemplatename: PropertyRef = PropertyRef('LaunchTemplateName')
launchtemplateid: PropertyRef = PropertyRef('LaunchTemplateId')
launchtemplateversion: PropertyRef = PropertyRef('LaunchTemplateVersion')
maxinstancelifetime: PropertyRef = PropertyRef('MaxInstanceLifetime')
maxsize: PropertyRef = PropertyRef('MaxSize')
minsize: PropertyRef = PropertyRef('MinSize')
name: PropertyRef = PropertyRef('AutoScalingGroupName')
newinstancesprotectedfromscalein: PropertyRef = PropertyRef('NewInstancesProtectedFromScaleIn')
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)
status: PropertyRef = PropertyRef('Status')
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


# EC2 to AutoScalingGroup
@dataclass(frozen=True)
class EC2InstanceToAwsAccountRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class EC2InstanceToAWSAccount(CartographyRelSchema):
target_node_label: str = 'AWSAccount'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
)
direction: LinkDirection = LinkDirection.INWARD
rel_label: str = "RESOURCE"
properties: EC2InstanceToAwsAccountRelProperties = EC2InstanceToAwsAccountRelProperties()


@dataclass(frozen=True)
class EC2InstanceToAutoScalingGroupRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class EC2InstanceToAutoScalingGroup(CartographyRelSchema):
target_node_label: str = 'AutoScalingGroup'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('AutoScalingGroupARN')},
)
direction: LinkDirection = LinkDirection.OUTWARD
rel_label: str = "MEMBER_AUTO_SCALE_GROUP"
properties: EC2InstanceToAutoScalingGroupRelProperties = EC2InstanceToAutoScalingGroupRelProperties()


@dataclass(frozen=True)
class EC2InstanceAutoScalingGroupProperties(CartographyNodeProperties):
id: PropertyRef = PropertyRef('InstanceId')
instanceid: PropertyRef = PropertyRef('InstanceId', extra_index=True)
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)


@dataclass(frozen=True)
class EC2InstanceAutoScalingGroupSchema(CartographyNodeSchema):
label: str = 'EC2Instance'
properties: EC2InstanceAutoScalingGroupProperties = EC2InstanceAutoScalingGroupProperties()
sub_resource_relationship: EC2InstanceToAWSAccount = EC2InstanceToAWSAccount()
other_relationships: OtherRelationships = OtherRelationships(
[
EC2InstanceToAutoScalingGroup(),
],
)


# EC2Subnet to AutoScalingGroup
@dataclass(frozen=True)
class EC2SubnetToAwsAccountRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class EC2SubnetToAWSAccount(CartographyRelSchema):
target_node_label: str = 'AWSAccount'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
)
direction: LinkDirection = LinkDirection.INWARD
rel_label: str = "RESOURCE"
properties: EC2SubnetToAwsAccountRelProperties = EC2SubnetToAwsAccountRelProperties()


@dataclass(frozen=True)
class EC2SubnetToAutoScalingGroupRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class EC2SubnetToAutoScalingGroup(CartographyRelSchema):
target_node_label: str = 'AutoScalingGroup'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('AutoScalingGroupARN')},
)
direction: LinkDirection = LinkDirection.INWARD
rel_label: str = "VPC_IDENTIFIER"
properties: EC2SubnetToAutoScalingGroupRelProperties = EC2SubnetToAutoScalingGroupRelProperties()


@dataclass(frozen=True)
class EC2SubnetAutoScalingGroupNodeProperties(CartographyNodeProperties):
id: PropertyRef = PropertyRef('VPCZoneIdentifier')
subnetid: PropertyRef = PropertyRef('VPCZoneIdentifier', extra_index=True)
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class EC2SubnetAutoScalingGroupSchema(CartographyNodeSchema):
label: str = 'EC2Subnet'
properties: EC2SubnetAutoScalingGroupNodeProperties = EC2SubnetAutoScalingGroupNodeProperties()
sub_resource_relationship: EC2SubnetToAWSAccount = EC2SubnetToAWSAccount()
other_relationships: OtherRelationships = OtherRelationships(
[
EC2SubnetToAutoScalingGroup(),
],
)


# AutoScalingGroup
@dataclass(frozen=True)
class AutoScalingGroupToAwsAccountRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class AutoScalingGroupToAWSAccount(CartographyRelSchema):
target_node_label: str = 'AWSAccount'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
)
direction: LinkDirection = LinkDirection.INWARD
rel_label: str = "RESOURCE"
properties: AutoScalingGroupToAwsAccountRelProperties = AutoScalingGroupToAwsAccountRelProperties()


@dataclass(frozen=True)
class AutoScalingGroupToLaunchTemplateRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class AutoScalingGroupToLaunchTemplate(CartographyRelSchema):
target_node_label: str = 'LaunchTemplate'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('LaunchTemplateId')},
)
direction: LinkDirection = LinkDirection.OUTWARD
rel_label: str = "HAS_LAUNCH_TEMPLATE"
properties: AutoScalingGroupToLaunchTemplateRelProperties = AutoScalingGroupToLaunchTemplateRelProperties()


@dataclass(frozen=True)
class AutoScalingGroupToLaunchConfigurationRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class AutoScalingGroupToLaunchConfiguration(CartographyRelSchema):
target_node_label: str = 'LaunchConfiguration'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'name': PropertyRef('LaunchConfigurationName')},
)
direction: LinkDirection = LinkDirection.OUTWARD
rel_label: str = "HAS_LAUNCH_CONFIG"
properties: AutoScalingGroupToLaunchConfigurationRelProperties = (
AutoScalingGroupToLaunchConfigurationRelProperties()
)


@dataclass(frozen=True)
class AutoScalingGroupSchema(CartographyNodeSchema):
label: str = 'AutoScalingGroup'
properties: AutoScalingGroupNodeProperties = AutoScalingGroupNodeProperties()
sub_resource_relationship: AutoScalingGroupToAWSAccount = AutoScalingGroupToAWSAccount()
other_relationships: OtherRelationships = OtherRelationships(
[
AutoScalingGroupToLaunchTemplate(),
AutoScalingGroupToLaunchConfiguration(),
],
)
55 changes: 55 additions & 0 deletions cartography/models/aws/ec2/launch_configurations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from dataclasses import dataclass

from cartography.models.core.common import PropertyRef
from cartography.models.core.nodes import CartographyNodeProperties
from cartography.models.core.nodes import CartographyNodeSchema
from cartography.models.core.relationships import CartographyRelProperties
from cartography.models.core.relationships import CartographyRelSchema
from cartography.models.core.relationships import LinkDirection
from cartography.models.core.relationships import make_target_node_matcher
from cartography.models.core.relationships import TargetNodeMatcher


@dataclass(frozen=True)
class LaunchConfigurationNodeProperties(CartographyNodeProperties):
id: PropertyRef = PropertyRef('LaunchConfigurationARN')
arn: PropertyRef = PropertyRef('LaunchConfigurationARN')
created_time = PropertyRef('CreatedTime')
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)
image_id: PropertyRef = PropertyRef('ImageId')
key_name: PropertyRef = PropertyRef('KeyName')
name: PropertyRef = PropertyRef('LaunchConfigurationName')
security_groups: PropertyRef = PropertyRef('SecurityGroups')
instance_type: PropertyRef = PropertyRef('InstanceType')
kernel_id: PropertyRef = PropertyRef('KernelId')
ramdisk_id: PropertyRef = PropertyRef('RamdiskId')
instance_monitoring_enabled: PropertyRef = PropertyRef('InstanceMonitoringEnabled')
spot_price: PropertyRef = PropertyRef('SpotPrice')
iam_instance_profile: PropertyRef = PropertyRef('IamInstanceProfile')
ebs_optimized: PropertyRef = PropertyRef('EbsOptimized')
associate_public_ip_address: PropertyRef = PropertyRef('AssociatePublicIpAddress')
placement_tenancy: PropertyRef = PropertyRef('PlacementTenancy')
region: PropertyRef = PropertyRef('Region', set_in_kwargs=True)


@dataclass(frozen=True)
class LaunchConfigurationToAwsAccountRelProperties(CartographyRelProperties):
lastupdated: PropertyRef = PropertyRef('lastupdated', set_in_kwargs=True)


@dataclass(frozen=True)
class LaunchConfigurationToAwsAccount(CartographyRelSchema):
target_node_label: str = 'AWSAccount'
target_node_matcher: TargetNodeMatcher = make_target_node_matcher(
{'id': PropertyRef('AWS_ID', set_in_kwargs=True)},
)
direction: LinkDirection = LinkDirection.INWARD
rel_label: str = "RESOURCE"
properties: LaunchConfigurationToAwsAccountRelProperties = LaunchConfigurationToAwsAccountRelProperties()


@dataclass(frozen=True)
class LaunchConfigurationSchema(CartographyNodeSchema):
label: str = 'LaunchConfiguration'
properties: LaunchConfigurationNodeProperties = LaunchConfigurationNodeProperties()
sub_resource_relationship: LaunchConfigurationToAwsAccount = LaunchConfigurationToAwsAccount()
Loading

0 comments on commit 5309729

Please sign in to comment.