Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws - sagemaker-cluster #9390

Merged
merged 13 commits into from Apr 3, 2024
1 change: 1 addition & 0 deletions c7n/resources/resource_map.py
Expand Up @@ -220,6 +220,7 @@
"aws.s3-access-point": "c7n.resources.s3control.AccessPoint",
"aws.s3-access-point-multi": "c7n.resources.s3control.MultiRegionAccessPoint",
"aws.s3-storage-lens": "c7n.resources.s3control.StorageLens",
"aws.sagemaker-cluster": "c7n.resources.sagemaker.Cluster",
"aws.sagemaker-domain": "c7n.resources.sagemaker.SagemakerDomain",
"aws.sagemaker-endpoint": "c7n.resources.sagemaker.SagemakerEndpoint",
"aws.sagemaker-endpoint-config": "c7n.resources.sagemaker.SagemakerEndpointConfig",
Expand Down
69 changes: 68 additions & 1 deletion c7n/resources/sagemaker.py
Expand Up @@ -7,7 +7,7 @@
from c7n.query import QueryResourceManager, TypeInfo, DescribeSource, ConfigSource
from c7n.utils import local_session, type_schema
from c7n.tags import RemoveTag, Tag, TagActionFilter, TagDelayedAction, universal_augment
from c7n.filters.vpc import SubnetFilter, SecurityGroupFilter
from c7n.filters.vpc import SubnetFilter, SecurityGroupFilter, NetworkLocation
from c7n.filters.kms import KmsRelatedFilter
from c7n.filters.offhours import OffHour, OnHour

Expand Down Expand Up @@ -312,6 +312,31 @@
Model.filter_registry.register('marked-for-op', TagActionFilter)


class SagemakerClusterDescribe(DescribeSource):

def augment(self, resources):
return universal_augment(self.manager, super().augment(resources))


@resources.register('sagemaker-cluster')
class Cluster(QueryResourceManager):

class resource_type(TypeInfo):
service = 'sagemaker'
enum_spec = ('list_clusters', 'ClusterSummaries', None)
detail_spec = (
'describe_cluster', 'ClusterName',
'ClusterName', None)
arn = id = 'ClusterArn'
name = 'ClusterName'
date = 'CreationTime'
cfn_type = None
permission_prefix = 'sagemaker'
universal_taggable = object()

source_mapping = {'describe': SagemakerClusterDescribe}


@SagemakerEndpoint.action_registry.register('tag')
@SagemakerEndpointConfig.action_registry.register('tag')
@NotebookInstance.action_registry.register('tag')
Expand Down Expand Up @@ -588,6 +613,19 @@
RelatedIdsExpression = "SubnetId"


@Cluster.filter_registry.register('security-group')
class ClusterSecurityGroupFilter(SecurityGroupFilter):

RelatedIdsExpression = "VpcConfig.SecurityGroupIds[]"


@Cluster.filter_registry.register('subnet')
class ClusterSubnetFilter(SubnetFilter):

RelatedIdsExpression = "VpcConfig.Subnets[]"


@Cluster.filter_registry.register('network-location', NetworkLocation)
@NotebookInstance.filter_registry.register('kms-key')
@SagemakerEndpointConfig.filter_registry.register('kms-key')
class NotebookKmsFilter(KmsRelatedFilter):
Expand Down Expand Up @@ -741,6 +779,35 @@
pass


@Cluster.action_registry.register('delete')
class ClusterDelete(BaseAction):
"""Deletes sagemaker-cluster(s)

:example:

.. code-block:: yaml

policies:
- name: delete-sagemaker-cluster
resource: sagemaker-cluster
filters:
- "tag:DeleteMe": present
actions:
- delete
"""
schema = type_schema('delete')
permissions = ('sagemaker:DeleteCluster',)

def process(self, resources):
client = local_session(self.manager.session_factory).client('sagemaker')

for c in resources:
try:
client.delete_cluster(ClusterName=c['ClusterName'])
except client.exceptions.ResourceNotFound:
pass

Check warning on line 808 in c7n/resources/sagemaker.py

View check run for this annotation

Codecov / codecov/patch

c7n/resources/sagemaker.py#L807-L808

Added lines #L807 - L808 were not covered by tests


class SagemakerDomainDescribe(DescribeSource):

def augment(self, resources):
Expand Down
@@ -0,0 +1,41 @@
{
"status_code": 200,
"data": {
"ClusterArn": "arn:aws:sagemaker:us-east-1:644160558196:cluster/f5t2ouux778p",
"ClusterName": "c7n-test-cluster",
"ClusterStatus": "Creating",
"CreationTime": {
"__class__": "datetime",
"year": 2024,
"month": 3,
"day": 28,
"hour": 10,
"minute": 55,
"second": 5,
"microsecond": 376000
},
"InstanceGroups": [
{
"CurrentCount": 0,
"TargetCount": 1,
"InstanceGroupName": "c7n-test-ig",
"InstanceType": "ml.t3.medium",
"LifeCycleConfig": {
"SourceS3Uri": "s3://hyperpod-lifecycle-scripts-test/src/",
"OnCreate": "on_create.sh"
},
"ExecutionRole": "arn:aws:iam::644160558196:role/service-role/AmazonSageMaker-ExecutionRole-20240319T150889",
"ThreadsPerCore": 1
}
],
"VpcConfig": {
"SecurityGroupIds": [
"sg-03c0b84cdad91744f"
],
"Subnets": [
"subnet-0bd18cd4df2d0d3b9"
]
},
"ResponseMetadata": {}
}
}
@@ -0,0 +1,24 @@
{
"status_code": 200,
"data": {
"NextToken": "",
"ClusterSummaries": [
{
"ClusterArn": "arn:aws:sagemaker:us-east-1:644160558196:cluster/f5t2ouux778p",
"ClusterName": "c7n-test-cluster",
"CreationTime": {
"__class__": "datetime",
"year": 2024,
"month": 3,
"day": 28,
"hour": 10,
"minute": 55,
"second": 5,
"microsecond": 376000
},
"ClusterStatus": "Creating"
}
],
"ResponseMetadata": {}
}
}
@@ -0,0 +1,51 @@
{
"status_code": 200,
"data": {
"SecurityGroups": [
{
"Description": "default VPC security group",
"GroupName": "default",
"IpPermissions": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"OwnerId": "644160558196",
"GroupId": "sg-03c0b84cdad91744f",
"IpPermissionsEgress": [
{
"IpProtocol": "-1",
"IpRanges": [
{
"CidrIp": "0.0.0.0/0"
}
],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": []
}
],
"Tags": [
{
"Key": "ASV",
"Value": "PolicyTest"
},
{
"Key": "Owner",
"Value": "c7n"
}
],
"VpcId": "vpc-0d4f819d13b730139"
}
],
"ResponseMetadata": {}
}
}
@@ -0,0 +1,8 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [],
"ResponseMetadata": {}
}
}
@@ -0,0 +1,41 @@
{
"status_code": 200,
"data": {
"ClusterArn": "arn:aws:sagemaker:us-east-1:644160558196:cluster/f5t2ouux778p",
"ClusterName": "c7n-test-cluster",
"ClusterStatus": "Creating",
"CreationTime": {
"__class__": "datetime",
"year": 2024,
"month": 3,
"day": 28,
"hour": 10,
"minute": 55,
"second": 5,
"microsecond": 376000
},
"InstanceGroups": [
{
"CurrentCount": 0,
"TargetCount": 1,
"InstanceGroupName": "c7n-test-ig",
"InstanceType": "ml.t3.medium",
"LifeCycleConfig": {
"SourceS3Uri": "s3://hyperpod-lifecycle-scripts-test/src/",
"OnCreate": "on_create.sh"
},
"ExecutionRole": "arn:aws:iam::644160558196:role/service-role/AmazonSageMaker-ExecutionRole-20240319T150889",
"ThreadsPerCore": 1
}
],
"VpcConfig": {
"SecurityGroupIds": [
"sg-03c0b84cdad91744f"
],
"Subnets": [
"subnet-0bd18cd4df2d0d3b9"
]
},
"ResponseMetadata": {}
}
}
@@ -0,0 +1,24 @@
{
"status_code": 200,
"data": {
"NextToken": "",
"ClusterSummaries": [
{
"ClusterArn": "arn:aws:sagemaker:us-east-1:644160558196:cluster/f5t2ouux778p",
"ClusterName": "c7n-test-cluster",
"CreationTime": {
"__class__": "datetime",
"year": 2024,
"month": 3,
"day": 28,
"hour": 10,
"minute": 55,
"second": 5,
"microsecond": 376000
},
"ClusterStatus": "Creating"
}
],
"ResponseMetadata": {}
}
}
@@ -0,0 +1,37 @@
{
"status_code": 200,
"data": {
"Subnets": [
{
"AvailabilityZone": "us-east-1a",
"AvailabilityZoneId": "use1-az4",
"AvailableIpAddressCount": 4090,
"CidrBlock": "10.0.16.0/20",
"DefaultForAz": false,
"MapPublicIpOnLaunch": false,
"MapCustomerOwnedIpOnLaunch": false,
"State": "available",
"SubnetId": "subnet-0bd18cd4df2d0d3b9",
"VpcId": "vpc-0d4f819d13b730139",
"OwnerId": "644160558196",
"AssignIpv6AddressOnCreation": false,
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Name",
"Value": "PrivateSubnetA"
}
],
"SubnetArn": "arn:aws:ec2:us-east-1:644160558196:subnet/subnet-0bd18cd4df2d0d3b9",
"EnableDns64": false,
"Ipv6Native": false,
"PrivateDnsNameOptionsOnLaunch": {
"HostnameType": "ip-name",
"EnableResourceNameDnsARecord": false,
"EnableResourceNameDnsAAAARecord": false
}
}
],
"ResponseMetadata": {}
}
}
@@ -0,0 +1,8 @@
{
"status_code": 200,
"data": {
"PaginationToken": "",
"ResourceTagMappingList": [],
"ResponseMetadata": {}
}
}
@@ -0,0 +1,7 @@
{
"status_code": 200,
"data": {
"ClusterArn": "arn:aws:sagemaker:us-east-1:644160558196:cluster/u72dzcdx4scy",
"ResponseMetadata": {}
}
}
@@ -0,0 +1,33 @@
{
"status_code": 200,
"data": {
"ClusterArn": "arn:aws:sagemaker:us-east-1:644160558196:cluster/u72dzcdx4scy",
"ClusterName": "test-c7n-cluster",
"ClusterStatus": "InService",
"CreationTime": {
"__class__": "datetime",
"year": 2024,
"month": 3,
"day": 28,
"hour": 11,
"minute": 15,
"second": 18,
"microsecond": 328000
},
"InstanceGroups": [
{
"CurrentCount": 1,
"TargetCount": 1,
"InstanceGroupName": "test-c7n-ig",
"InstanceType": "ml.t3.medium",
"LifeCycleConfig": {
"SourceS3Uri": "s3://hyperpod-lifecycle-scripts-test/src/",
"OnCreate": "on_create.sh"
},
"ExecutionRole": "arn:aws:iam::644160558196:role/service-role/AmazonSageMaker-ExecutionRole-20240319T150889",
"ThreadsPerCore": 1
}
],
"ResponseMetadata": {}
}
}