Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/c7n/resources/sagemaker.py: 62%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

658 statements  

1# Copyright The Cloud Custodian Authors. 

2# SPDX-License-Identifier: Apache-2.0 

3 

4from c7n.actions import BaseAction 

5from c7n.exceptions import PolicyValidationError 

6from c7n.manager import resources 

7from c7n.query import QueryResourceManager, TypeInfo, DescribeSource, ConfigSource 

8from c7n.utils import local_session, type_schema 

9from c7n.tags import RemoveTag, Tag, TagActionFilter, TagDelayedAction, universal_augment 

10from c7n.filters.vpc import SubnetFilter, SecurityGroupFilter, NetworkLocation 

11from c7n.filters.kms import KmsRelatedFilter 

12from c7n.filters.offhours import OffHour, OnHour 

13 

14 

15class NotebookDescribe(DescribeSource): 

16 

17 def augment(self, resources): 

18 client = local_session(self.manager.session_factory).client('sagemaker') 

19 

20 def _augment(r): 

21 # List tags for the Notebook-Instance & set as attribute 

22 tags = self.manager.retry(client.list_tags, 

23 ResourceArn=r['NotebookInstanceArn'])['Tags'] 

24 r['Tags'] = tags 

25 return r 

26 

27 # Describe notebook-instance & then list tags 

28 resources = super().augment(resources) 

29 return list(map(_augment, resources)) 

30 

31 

32@resources.register('sagemaker-notebook') 

33class NotebookInstance(QueryResourceManager): 

34 

35 class resource_type(TypeInfo): 

36 service = 'sagemaker' 

37 enum_spec = ('list_notebook_instances', 'NotebookInstances', None) 

38 detail_spec = ( 

39 'describe_notebook_instance', 'NotebookInstanceName', 

40 'NotebookInstanceName', None) 

41 arn = id = 'NotebookInstanceArn' 

42 name = 'NotebookInstanceName' 

43 date = 'CreationTime' 

44 config_type = cfn_type = 'AWS::SageMaker::NotebookInstance' 

45 permissions_augment = ("sagemaker:ListTags",) 

46 

47 source_mapping = {'describe': NotebookDescribe, 'config': ConfigSource} 

48 

49 

50NotebookInstance.filter_registry.register('marked-for-op', TagActionFilter) 

51NotebookInstance.filter_registry.register('offhour', OffHour) 

52NotebookInstance.filter_registry.register('onhour', OnHour) 

53 

54 

55@resources.register('sagemaker-job') 

56class SagemakerJob(QueryResourceManager): 

57 

58 class resource_type(TypeInfo): 

59 service = 'sagemaker' 

60 enum_spec = ('list_training_jobs', 'TrainingJobSummaries', None) 

61 detail_spec = ( 

62 'describe_training_job', 'TrainingJobName', 'TrainingJobName', None) 

63 arn = id = 'TrainingJobArn' 

64 name = 'TrainingJobName' 

65 date = 'CreationTime' 

66 permission_augment = ( 

67 'sagemaker:DescribeTrainingJob', 'sagemaker:ListTags') 

68 

69 def __init__(self, ctx, data): 

70 super(SagemakerJob, self).__init__(ctx, data) 

71 self.queries = QueryFilter.parse( 

72 self.data.get('query', [ 

73 {'StatusEquals': 'InProgress'}])) 

74 

75 def resources(self, query=None): 

76 for q in self.queries: 

77 if q is None: 

78 continue 

79 query = query or {} 

80 for k, v in q.items(): 

81 query[k] = v 

82 return super(SagemakerJob, self).resources(query=query) 

83 

84 def augment(self, jobs): 

85 client = local_session(self.session_factory).client('sagemaker') 

86 

87 def _augment(j): 

88 tags = self.retry(client.list_tags, 

89 ResourceArn=j['TrainingJobArn'])['Tags'] 

90 j['Tags'] = tags 

91 return j 

92 

93 jobs = super(SagemakerJob, self).augment(jobs) 

94 return list(map(_augment, jobs)) 

95 

96 

97@resources.register('sagemaker-transform-job') 

98class SagemakerTransformJob(QueryResourceManager): 

99 

100 class resource_type(TypeInfo): 

101 arn_type = "transform-job" 

102 service = 'sagemaker' 

103 enum_spec = ('list_transform_jobs', 'TransformJobSummaries', None) 

104 detail_spec = ( 

105 'describe_transform_job', 'TransformJobName', 'TransformJobName', None) 

106 arn = id = 'TransformJobArn' 

107 name = 'TransformJobName' 

108 date = 'CreationTime' 

109 filter_name = 'NameContains' 

110 filter_type = 'scalar' 

111 permission_augment = ('sagemaker:DescribeTransformJob', 'sagemaker:ListTags') 

112 

113 def __init__(self, ctx, data): 

114 super(SagemakerTransformJob, self).__init__(ctx, data) 

115 self.queries = QueryFilter.parse( 

116 self.data.get('query', [ 

117 {'StatusEquals': 'InProgress'}])) 

118 

119 def resources(self, query=None): 

120 for q in self.queries: 

121 if q is None: 

122 continue 

123 query = query or {} 

124 for k, v in q.items(): 

125 query[k] = v 

126 return super(SagemakerTransformJob, self).resources(query=query) 

127 

128 def augment(self, jobs): 

129 client = local_session(self.session_factory).client('sagemaker') 

130 

131 def _augment(j): 

132 tags = self.retry(client.list_tags, 

133 ResourceArn=j['TransformJobArn'])['Tags'] 

134 j['Tags'] = tags 

135 return j 

136 

137 return list(map(_augment, super(SagemakerTransformJob, self).augment(jobs))) 

138 

139 

140class SagemakerHyperParameterTuningJobDescribe(DescribeSource): 

141 

142 def augment(self, resources): 

143 return universal_augment(self.manager, super().augment(resources)) 

144 

145 

146@resources.register('sagemaker-hyperparameter-tuning-job') 

147class SagemakerHyperParameterTuningJob(QueryResourceManager): 

148 class resource_type(TypeInfo): 

149 service = 'sagemaker' 

150 enum_spec = ('list_hyper_parameter_tuning_jobs', 'HyperParameterTuningJobSummaries', None) 

151 detail_spec = ( 

152 'describe_hyper_parameter_tuning_job', 'HyperParameterTuningJobName', 

153 'HyperParameterTuningJobName', None) 

154 arn = id = 'HyperParameterTuningJobArn' 

155 name = 'HyperParameterTuningJobName' 

156 date = 'CreationTime' 

157 permission_prefix = 'sagemaker' 

158 universal_taggable = object() 

159 

160 source_mapping = {'describe': SagemakerHyperParameterTuningJobDescribe} 

161 

162 def __init__(self, ctx, data): 

163 super(SagemakerHyperParameterTuningJob, self).__init__(ctx, data) 

164 self.queries = QueryFilter.parse( 

165 self.data.get('query', [ 

166 {'StatusEquals': 'InProgress'}])) 

167 

168 def resources(self, query=None): 

169 for q in self.queries: 

170 if q is None: 

171 continue 

172 query = query or {} 

173 for k, v in q.items(): 

174 query[k] = v 

175 return super(SagemakerHyperParameterTuningJob, self).resources(query=query) 

176 

177 

178class SagemakerAutoMLDescribeV2(DescribeSource): 

179 

180 def get_permissions(self): 

181 perms = super().get_permissions() 

182 perms.remove('sagemaker:DescribeAutoMlJobV2') 

183 return perms 

184 

185 def augment(self, resources): 

186 return universal_augment(self.manager, super().augment(resources)) 

187 

188 

189@resources.register('sagemaker-auto-ml-job') 

190class SagemakerAutoMLJob(QueryResourceManager): 

191 

192 class resource_type(TypeInfo): 

193 service = 'sagemaker' 

194 enum_spec = ('list_auto_ml_jobs', 'AutoMLJobSummaries', None) 

195 detail_spec = ( 

196 'describe_auto_ml_job_v2', 'AutoMLJobName', 'AutoMLJobName', None) 

197 arn = id = 'AutoMLJobArn' 

198 name = 'AutoMLJobName' 

199 date = 'CreationTime' 

200 # override defaults to casing issues 

201 permissions_augment = ('sagemaker:DescribeAutoMLJobV2',) 

202 permissions_enum = ('sagemaker:ListAutoMLJobs',) 

203 universal_taggable = object() 

204 

205 source_mapping = {'describe': SagemakerAutoMLDescribeV2} 

206 

207 def __init__(self, ctx, data): 

208 super(SagemakerAutoMLJob, self).__init__(ctx, data) 

209 self.queries = QueryFilter.parse( 

210 self.data.get('query', [ 

211 {'StatusEquals': 'InProgress'}])) 

212 

213 def resources(self, query=None): 

214 for q in self.queries: 

215 if q is None: 

216 continue 

217 query = query or {} 

218 for k, v in q.items(): 

219 query[k] = v 

220 return super(SagemakerAutoMLJob, self).resources(query=query) 

221 

222 

223class SagemakerCompilationJobDescribe(DescribeSource): 

224 

225 def augment(self, resources): 

226 return universal_augment(self.manager, super().augment(resources)) 

227 

228 

229@resources.register('sagemaker-compilation-job') 

230class SagemakerCompilationJob(QueryResourceManager): 

231 

232 class resource_type(TypeInfo): 

233 service = 'sagemaker' 

234 enum_spec = ('list_compilation_jobs', 'CompilationJobSummaries', None) 

235 detail_spec = ( 

236 'describe_compilation_job', 'CompilationJobName', 'CompilationJobName', None) 

237 arn = id = 'CompilationJobArn' 

238 name = 'CompilationJobName' 

239 date = 'CreationTime' 

240 permission_prefix = 'sagemaker' 

241 universal_taggable = object() 

242 

243 source_mapping = {'describe': SagemakerCompilationJobDescribe} 

244 

245 def __init__(self, ctx, data): 

246 super(SagemakerCompilationJob, self).__init__(ctx, data) 

247 self.queries = QueryFilter.parse( 

248 self.data.get('query', [ 

249 {'StatusEquals': 'INPROGRESS'}])) 

250 

251 def resources(self, query=None): 

252 for q in self.queries: 

253 if q is None: 

254 continue 

255 query = query or {} 

256 for k, v in q.items(): 

257 query[k] = v 

258 return super(SagemakerCompilationJob, self).resources(query=query) 

259 

260 

261class SagemakerProcessingJobDescribe(DescribeSource): 

262 

263 def augment(self, resources): 

264 return universal_augment(self.manager, super().augment(resources)) 

265 

266 

267@resources.register('sagemaker-processing-job') 

268class SagemakerProcessingJob(QueryResourceManager): 

269 

270 class resource_type(TypeInfo): 

271 service = 'sagemaker' 

272 enum_spec = ('list_processing_jobs', 'ProcessingJobSummaries', None) 

273 detail_spec = ( 

274 'describe_processing_job', 'ProcessingJobName', 'ProcessingJobName', None) 

275 arn = id = 'ProcessingJobArn' 

276 name = 'ProcessingJobName' 

277 date = 'CreationTime' 

278 permission_prefix = 'sagemaker' 

279 universal_taggable = object() 

280 

281 source_mapping = {'describe': SagemakerProcessingJobDescribe} 

282 

283 def __init__(self, ctx, data): 

284 super(SagemakerProcessingJob, self).__init__(ctx, data) 

285 self.queries = QueryFilter.parse( 

286 self.data.get('query', [ 

287 {'StatusEquals': 'InProgress'}])) 

288 

289 def resources(self, query=None): 

290 for q in self.queries: 

291 if q is None: 

292 continue 

293 query = query or {} 

294 for k, v in q.items(): 

295 query[k] = v 

296 return super(SagemakerProcessingJob, self).resources(query=query) 

297 

298 

299class SagemakerModelBiasJobDefinitionDescribe(DescribeSource): 

300 

301 def augment(self, resources): 

302 return universal_augment(self.manager, super().augment(resources)) 

303 

304 

305@resources.register('sagemaker-model-bias-job-definition') 

306class SagemakerModelBiasJobDefinition(QueryResourceManager): 

307 

308 class resource_type(TypeInfo): 

309 service = 'sagemaker' 

310 enum_spec = ('list_model_bias_job_definitions', 'JobDefinitionSummaries', None) 

311 detail_spec = ( 

312 'describe_model_bias_job_definition', 'JobDefinitionName', 

313 'MonitoringJobDefinitionName', None) 

314 arn = id = 'JobDefinitionArn' 

315 name = 'JobDefinitionName' 

316 date = 'CreationTime' 

317 permissions_prefix = 'sagemaker' 

318 universal_taggable = object() 

319 

320 source_mapping = {'describe': SagemakerModelBiasJobDefinitionDescribe} 

321 

322 

323class QueryFilter: 

324 

325 JOB_FILTERS = ('StatusEquals', 'NameContains',) 

326 

327 @classmethod 

328 def parse(cls, data): 

329 results = [] 

330 names = set() 

331 for d in data: 

332 if not isinstance(d, dict): 

333 raise PolicyValidationError( 

334 "Job Query Filter Invalid structure %s" % d) 

335 for k, v in d.items(): 

336 if isinstance(v, list): 

337 raise ValueError( 

338 'Job query filter invalid structure %s' % v) 

339 query = cls(d).validate().query() 

340 if query['Name'] in names: 

341 # Cannot filter multiple times on the same key 

342 continue 

343 names.add(query['Name']) 

344 if isinstance(query['Value'], list): 

345 results.append({query['Name']: query['Value'][0]}) 

346 continue 

347 results.append({query['Name']: query['Value']}) 

348 if 'StatusEquals' not in names: 

349 # add default StatusEquals if not included 

350 results.append({'Name': 'StatusEquals', 'Value': 'InProgress'}) 

351 return results 

352 

353 def __init__(self, data): 

354 self.data = data 

355 self.key = None 

356 self.value = None 

357 

358 def validate(self): 

359 if not len(list(self.data.keys())) == 1: 

360 raise PolicyValidationError( 

361 "Job Query Filter Invalid %s" % self.data) 

362 self.key = list(self.data.keys())[0] 

363 self.value = list(self.data.values())[0] 

364 

365 if self.key not in self.JOB_FILTERS and not self.key.startswith('tag:'): 

366 raise PolicyValidationError( 

367 "Job Query Filter invalid filter name %s" % ( 

368 self.data)) 

369 

370 if self.value is None: 

371 raise PolicyValidationError( 

372 "Job Query Filters must have a value, use tag-key" 

373 " w/ tag name as value for tag present checks" 

374 " %s" % self.data) 

375 return self 

376 

377 def query(self): 

378 value = self.value 

379 if isinstance(self.value, str): 

380 value = [self.value] 

381 return {'Name': self.key, 'Value': value} 

382 

383 

384class EndpointDescribe(DescribeSource): 

385 

386 def augment(self, resources): 

387 client = local_session(self.manager.session_factory).client('sagemaker') 

388 

389 def _augment(e): 

390 tags = self.manager.retry(client.list_tags, 

391 ResourceArn=e['EndpointArn'])['Tags'] 

392 e['Tags'] = tags 

393 return e 

394 

395 # Describe endpoints & then list tags 

396 endpoints = super().augment(resources) 

397 return list(map(_augment, endpoints)) 

398 

399 

400@resources.register('sagemaker-endpoint') 

401class SagemakerEndpoint(QueryResourceManager): 

402 

403 class resource_type(TypeInfo): 

404 service = 'sagemaker' 

405 enum_spec = ('list_endpoints', 'Endpoints', None) 

406 detail_spec = ( 

407 'describe_endpoint', 'EndpointName', 

408 'EndpointName', None) 

409 arn = id = 'EndpointArn' 

410 name = 'EndpointName' 

411 date = 'CreationTime' 

412 cfn_type = 'AWS::SageMaker::Endpoint' 

413 

414 permissions = ('sagemaker:ListTags',) 

415 

416 source_mapping = {'describe': EndpointDescribe} 

417 

418 

419SagemakerEndpoint.filter_registry.register('marked-for-op', TagActionFilter) 

420 

421 

422class EndpointConfigDescribe(DescribeSource): 

423 

424 def augment(self, resources): 

425 client = local_session(self.manager.session_factory).client('sagemaker') 

426 

427 def _augment(e): 

428 tags = self.manager.retry(client.list_tags, 

429 ResourceArn=e['EndpointConfigArn'])['Tags'] 

430 e['Tags'] = tags 

431 return e 

432 

433 endpoints = super().augment(resources) 

434 return list(map(_augment, endpoints)) 

435 

436 

437@resources.register('sagemaker-endpoint-config') 

438class SagemakerEndpointConfig(QueryResourceManager): 

439 

440 class resource_type(TypeInfo): 

441 service = 'sagemaker' 

442 enum_spec = ('list_endpoint_configs', 'EndpointConfigs', None) 

443 detail_spec = ( 

444 'describe_endpoint_config', 'EndpointConfigName', 

445 'EndpointConfigName', None) 

446 arn = id = 'EndpointConfigArn' 

447 name = 'EndpointConfigName' 

448 date = 'CreationTime' 

449 config_type = cfn_type = 'AWS::SageMaker::EndpointConfig' 

450 permissions_augment = ('sagemaker:ListTags',) 

451 

452 source_mapping = {'describe': EndpointConfigDescribe, 'config': ConfigSource} 

453 

454 

455SagemakerEndpointConfig.filter_registry.register('marked-for-op', TagActionFilter) 

456 

457 

458class DescribeModel(DescribeSource): 

459 

460 def augment(self, resources): 

461 client = local_session(self.manager.session_factory).client('sagemaker') 

462 

463 def _augment(r): 

464 tags = self.manager.retry(client.list_tags, 

465 ResourceArn=r['ModelArn'])['Tags'] 

466 r.setdefault('Tags', []).extend(tags) 

467 return r 

468 

469 resources = super(DescribeModel, self).augment(resources) 

470 return list(map(_augment, resources)) 

471 

472 

473@resources.register('sagemaker-model') 

474class Model(QueryResourceManager): 

475 

476 class resource_type(TypeInfo): 

477 service = 'sagemaker' 

478 enum_spec = ('list_models', 'Models', None) 

479 detail_spec = ( 

480 'describe_model', 'ModelName', 

481 'ModelName', None) 

482 arn = id = 'ModelArn' 

483 name = 'ModelName' 

484 date = 'CreationTime' 

485 cfn_type = config_type = 'AWS::SageMaker::Model' 

486 

487 source_mapping = { 

488 'describe': DescribeModel, 

489 'config': ConfigSource 

490 } 

491 

492 permissions = ('sagemaker:ListTags',) 

493 

494 

495Model.filter_registry.register('marked-for-op', TagActionFilter) 

496 

497 

498class SagemakerClusterDescribe(DescribeSource): 

499 

500 def augment(self, resources): 

501 return universal_augment(self.manager, super().augment(resources)) 

502 

503 

504@resources.register('sagemaker-cluster') 

505class Cluster(QueryResourceManager): 

506 

507 class resource_type(TypeInfo): 

508 service = 'sagemaker' 

509 enum_spec = ('list_clusters', 'ClusterSummaries', None) 

510 detail_spec = ( 

511 'describe_cluster', 'ClusterName', 

512 'ClusterName', None) 

513 arn = id = 'ClusterArn' 

514 name = 'ClusterName' 

515 date = 'CreationTime' 

516 cfn_type = None 

517 permission_prefix = 'sagemaker' 

518 universal_taggable = object() 

519 

520 source_mapping = {'describe': SagemakerClusterDescribe} 

521 

522 

523class SagemakerDataQualityJobDefinitionDescribe(DescribeSource): 

524 

525 def augment(self, resources): 

526 return universal_augment(self.manager, super().augment(resources)) 

527 

528 

529@resources.register('sagemaker-data-quality-job-definition') 

530class SagemakerDataQualityJobDefinition(QueryResourceManager): 

531 class resource_type(TypeInfo): 

532 service = 'sagemaker' 

533 enum_spec = ('list_data_quality_job_definitions', 'JobDefinitionSummaries', None) 

534 detail_spec = ('describe_data_quality_job_definition', 'JobDefinitionName', 

535 'MonitoringJobDefinitionName', None) 

536 arn = id = 'JobDefinitionArn' 

537 name = 'JobDefinitionName' 

538 date = 'CreationTime' 

539 cfn_type = 'AWS::SageMaker::DataQualityJobDefinition' 

540 permission_prefix = 'sagemaker' 

541 filter_name = 'EndpointName' 

542 filter_type = 'scalar' 

543 universal_taggable = object() 

544 

545 source_mapping = {'describe': SagemakerDataQualityJobDefinitionDescribe} 

546 

547 

548class SagemakerModelExplainabilityJobDefinitionDescribe(DescribeSource): 

549 

550 def augment(self, resources): 

551 return universal_augment(self.manager, super().augment(resources)) 

552 

553 

554@resources.register('sagemaker-model-explainability-job-definition') 

555class SagemakerModelExplainabilityJobDefinition(QueryResourceManager): 

556 class resource_type(TypeInfo): 

557 service = 'sagemaker' 

558 enum_spec = ('list_model_explainability_job_definitions', 'JobDefinitionSummaries', None) 

559 detail_spec = ('describe_model_explainability_job_definition', 'JobDefinitionName', 

560 'MonitoringJobDefinitionName', None) 

561 arn = id = 'JobDefinitionArn' 

562 name = 'JobDefinitionName' 

563 date = 'CreationTime' 

564 cfn_type = 'AWS::SageMaker::ModelExplainabilityJobDefinition' 

565 permission_prefix = 'sagemaker' 

566 filter_name = 'EndpointName' 

567 filter_type = 'scalar' 

568 universal_taggable = object() 

569 

570 source_mapping = {'describe': SagemakerModelExplainabilityJobDefinitionDescribe} 

571 

572 

573class SagemakerModelQualityJobDefinitionDescribe(DescribeSource): 

574 

575 def augment(self, resources): 

576 return universal_augment(self.manager, super().augment(resources)) 

577 

578 

579@resources.register('sagemaker-model-quality-job-definition') 

580class SagemakerModelQualityJobDefinition(QueryResourceManager): 

581 class resource_type(TypeInfo): 

582 service = 'sagemaker' 

583 enum_spec = ('list_model_quality_job_definitions', 'JobDefinitionSummaries', None) 

584 detail_spec = ('describe_model_quality_job_definition', 'JobDefinitionName', 

585 'MonitoringJobDefinitionName', None) 

586 arn = id = 'JobDefinitionArn' 

587 name = 'JobDefinitionName' 

588 date = 'CreationTime' 

589 cfn_type = 'AWS::SageMaker::ModelQualityJobDefinition' 

590 permission_prefix = 'sagemaker' 

591 filter_name = 'EndpointName' 

592 filter_type = 'scalar' 

593 universal_taggable = object() 

594 

595 source_mapping = {'describe': SagemakerModelQualityJobDefinitionDescribe} 

596 

597 

598@SagemakerEndpoint.action_registry.register('tag') 

599@SagemakerEndpointConfig.action_registry.register('tag') 

600@NotebookInstance.action_registry.register('tag') 

601@SagemakerJob.action_registry.register('tag') 

602@SagemakerTransformJob.action_registry.register('tag') 

603@Model.action_registry.register('tag') 

604class TagNotebookInstance(Tag): 

605 """Action to create tag(s) on a SageMaker resource 

606 (notebook-instance, endpoint, endpoint-config) 

607 

608 :example: 

609 

610 .. code-block:: yaml 

611 

612 policies: 

613 - name: tag-sagemaker-notebook 

614 resource: sagemaker-notebook 

615 filters: 

616 - "tag:target-tag": absent 

617 actions: 

618 - type: tag 

619 key: target-tag 

620 value: target-value 

621 

622 - name: tag-sagemaker-endpoint 

623 resource: sagemaker-endpoint 

624 filters: 

625 - "tag:required-tag": absent 

626 actions: 

627 - type: tag 

628 key: required-tag 

629 value: required-value 

630 

631 - name: tag-sagemaker-endpoint-config 

632 resource: sagemaker-endpoint-config 

633 filters: 

634 - "tag:required-tag": absent 

635 actions: 

636 - type: tag 

637 key: required-tag 

638 value: required-value 

639 

640 - name: tag-sagemaker-job 

641 resource: sagemaker-job 

642 filters: 

643 - "tag:required-tag": absent 

644 actions: 

645 - type: tag 

646 key: required-tag 

647 value: required-value 

648 """ 

649 permissions = ('sagemaker:AddTags',) 

650 

651 def process_resource_set(self, client, resources, tags): 

652 mid = self.manager.resource_type.id 

653 for r in resources: 

654 client.add_tags(ResourceArn=r[mid], Tags=tags) 

655 

656 

657@SagemakerEndpoint.action_registry.register('remove-tag') 

658@SagemakerEndpointConfig.action_registry.register('remove-tag') 

659@NotebookInstance.action_registry.register('remove-tag') 

660@SagemakerJob.action_registry.register('remove-tag') 

661@SagemakerTransformJob.action_registry.register('remove-tag') 

662@Model.action_registry.register('remove-tag') 

663class RemoveTagNotebookInstance(RemoveTag): 

664 """Remove tag(s) from SageMaker resources 

665 (notebook-instance, endpoint, endpoint-config) 

666 

667 :example: 

668 

669 .. code-block:: yaml 

670 

671 policies: 

672 - name: sagemaker-notebook-remove-tag 

673 resource: sagemaker-notebook 

674 filters: 

675 - "tag:BadTag": present 

676 actions: 

677 - type: remove-tag 

678 tags: ["BadTag"] 

679 

680 - name: sagemaker-endpoint-remove-tag 

681 resource: sagemaker-endpoint 

682 filters: 

683 - "tag:expired-tag": present 

684 actions: 

685 - type: remove-tag 

686 tags: ["expired-tag"] 

687 

688 - name: sagemaker-endpoint-config-remove-tag 

689 resource: sagemaker-endpoint-config 

690 filters: 

691 - "tag:expired-tag": present 

692 actions: 

693 - type: remove-tag 

694 tags: ["expired-tag"] 

695 

696 - name: sagemaker-job-remove-tag 

697 resource: sagemaker-job 

698 filters: 

699 - "tag:expired-tag": present 

700 actions: 

701 - type: remove-tag 

702 tags: ["expired-tag"] 

703 """ 

704 permissions = ('sagemaker:DeleteTags',) 

705 

706 def process_resource_set(self, client, resources, keys): 

707 for r in resources: 

708 client.delete_tags(ResourceArn=r[self.id_key], TagKeys=keys) 

709 

710 

711@SagemakerEndpoint.action_registry.register('mark-for-op') 

712@SagemakerEndpointConfig.action_registry.register('mark-for-op') 

713@NotebookInstance.action_registry.register('mark-for-op') 

714@Model.action_registry.register('mark-for-op') 

715class MarkNotebookInstanceForOp(TagDelayedAction): 

716 """Mark SageMaker resources for deferred action 

717 (notebook-instance, endpoint, endpoint-config) 

718 

719 :example: 

720 

721 .. code-block:: yaml 

722 

723 policies: 

724 - name: sagemaker-notebook-invalid-tag-stop 

725 resource: sagemaker-notebook 

726 filters: 

727 - "tag:InvalidTag": present 

728 actions: 

729 - type: mark-for-op 

730 op: stop 

731 days: 1 

732 

733 - name: sagemaker-endpoint-failure-delete 

734 resource: sagemaker-endpoint 

735 filters: 

736 - 'EndpointStatus': 'Failed' 

737 actions: 

738 - type: mark-for-op 

739 op: delete 

740 days: 1 

741 

742 - name: sagemaker-endpoint-config-invalid-size-delete 

743 resource: sagemaker-notebook 

744 filters: 

745 - type: value 

746 - key: ProductionVariants[].InstanceType 

747 - value: 'ml.m4.10xlarge' 

748 - op: contains 

749 actions: 

750 - type: mark-for-op 

751 op: delete 

752 days: 1 

753 """ 

754 

755 

756@NotebookInstance.action_registry.register('start') 

757class StartNotebookInstance(BaseAction): 

758 """Start sagemaker-notebook(s) 

759 

760 :example: 

761 

762 .. code-block:: yaml 

763 

764 policies: 

765 - name: start-sagemaker-notebook 

766 resource: sagemaker-notebook 

767 actions: 

768 - start 

769 """ 

770 schema = type_schema('start') 

771 permissions = ('sagemaker:StartNotebookInstance',) 

772 valid_origin_states = ('Stopped',) 

773 

774 def process(self, resources): 

775 resources = self.filter_resources(resources, 'NotebookInstanceStatus', 

776 self.valid_origin_states) 

777 if not len(resources): 

778 return 

779 

780 client = local_session(self.manager.session_factory).client('sagemaker') 

781 

782 for n in resources: 

783 try: 

784 client.start_notebook_instance( 

785 NotebookInstanceName=n['NotebookInstanceName']) 

786 except client.exceptions.ResourceNotFound: 

787 pass 

788 

789 

790@NotebookInstance.action_registry.register('stop') 

791class StopNotebookInstance(BaseAction): 

792 """Stop sagemaker-notebook(s) 

793 

794 :example: 

795 

796 .. code-block:: yaml 

797 

798 policies: 

799 - name: stop-sagemaker-notebook 

800 resource: sagemaker-notebook 

801 filters: 

802 - "tag:DeleteMe": present 

803 actions: 

804 - stop 

805 """ 

806 schema = type_schema('stop') 

807 permissions = ('sagemaker:StopNotebookInstance',) 

808 valid_origin_states = ('InService',) 

809 

810 def process(self, resources): 

811 resources = self.filter_resources(resources, 'NotebookInstanceStatus', 

812 self.valid_origin_states) 

813 if not len(resources): 

814 return 

815 

816 client = local_session(self.manager.session_factory).client('sagemaker') 

817 

818 for n in resources: 

819 try: 

820 client.stop_notebook_instance( 

821 NotebookInstanceName=n['NotebookInstanceName']) 

822 except client.exceptions.ResourceNotFound: 

823 pass 

824 

825 

826@NotebookInstance.action_registry.register('delete') 

827class DeleteNotebookInstance(BaseAction): 

828 """Deletes sagemaker-notebook(s) 

829 

830 :example: 

831 

832 .. code-block:: yaml 

833 

834 policies: 

835 - name: delete-sagemaker-notebook 

836 resource: sagemaker-notebook 

837 filters: 

838 - "tag:DeleteMe": present 

839 actions: 

840 - delete 

841 """ 

842 schema = type_schema('delete') 

843 permissions = ('sagemaker:DeleteNotebookInstance',) 

844 valid_origin_states = ('Stopped', 'Failed',) 

845 

846 def process(self, resources): 

847 resources = self.filter_resources(resources, 'NotebookInstanceStatus', 

848 self.valid_origin_states) 

849 if not len(resources): 

850 return 

851 

852 client = local_session(self.manager.session_factory).client('sagemaker') 

853 

854 for n in resources: 

855 try: 

856 client.delete_notebook_instance( 

857 NotebookInstanceName=n['NotebookInstanceName']) 

858 except client.exceptions.ResourceNotFound: 

859 pass 

860 

861 

862@NotebookInstance.filter_registry.register('security-group') 

863class NotebookSecurityGroupFilter(SecurityGroupFilter): 

864 

865 RelatedIdsExpression = "SecurityGroups[]" 

866 

867 

868@NotebookInstance.filter_registry.register('subnet') 

869class NotebookSubnetFilter(SubnetFilter): 

870 

871 RelatedIdsExpression = "SubnetId" 

872 

873 

874@Cluster.filter_registry.register('security-group') 

875class ClusterSecurityGroupFilter(SecurityGroupFilter): 

876 

877 RelatedIdsExpression = "VpcConfig.SecurityGroupIds[]" 

878 

879 

880@Cluster.filter_registry.register('subnet') 

881class ClusterSubnetFilter(SubnetFilter): 

882 

883 RelatedIdsExpression = "VpcConfig.Subnets[]" 

884 

885 

886@Cluster.filter_registry.register('network-location', NetworkLocation) 

887@NotebookInstance.filter_registry.register('kms-key') 

888@SagemakerEndpointConfig.filter_registry.register('kms-key') 

889class NotebookKmsFilter(KmsRelatedFilter): 

890 

891 RelatedIdsExpression = "KmsKeyId" 

892 

893 

894@Model.action_registry.register('delete') 

895class DeleteModel(BaseAction): 

896 """Deletes sagemaker-model(s) 

897 

898 :example: 

899 

900 .. code-block:: yaml 

901 

902 policies: 

903 - name: delete-sagemaker-model 

904 resource: sagemaker-model 

905 filters: 

906 - "tag:DeleteMe": present 

907 actions: 

908 - delete 

909 """ 

910 schema = type_schema('delete') 

911 permissions = ('sagemaker:DeleteModel',) 

912 

913 def process(self, resources): 

914 client = local_session(self.manager.session_factory).client('sagemaker') 

915 

916 for m in resources: 

917 try: 

918 client.delete_model(ModelName=m['ModelName']) 

919 except client.exceptions.ResourceNotFound: 

920 pass 

921 

922 

923@SagemakerJob.action_registry.register('stop') 

924class SagemakerJobStop(BaseAction): 

925 """Stops a SageMaker job 

926 

927 :example: 

928 

929 .. code-block:: yaml 

930 

931 policies: 

932 - name: stop-ml-job 

933 resource: sagemaker-job 

934 filters: 

935 - TrainingJobName: ml-job-10 

936 actions: 

937 - stop 

938 """ 

939 schema = type_schema('stop') 

940 permissions = ('sagemaker:StopTrainingJob',) 

941 

942 def process(self, jobs): 

943 client = local_session(self.manager.session_factory).client('sagemaker') 

944 

945 for j in jobs: 

946 try: 

947 client.stop_training_job(TrainingJobName=j['TrainingJobName']) 

948 except client.exceptions.ResourceNotFound: 

949 pass 

950 

951 

952@SagemakerEndpoint.action_registry.register('delete') 

953class SagemakerEndpointDelete(BaseAction): 

954 """Delete a SageMaker endpoint 

955 

956 :example: 

957 

958 .. code-block:: yaml 

959 

960 policies: 

961 - name: delete-sagemaker-endpoint 

962 resource: sagemaker-endpoint 

963 filters: 

964 - EndpointName: sagemaker-ep--2018-01-01-00-00-00 

965 actions: 

966 - type: delete 

967 """ 

968 permissions = ( 

969 'sagemaker:DeleteEndpoint', 

970 'sagemaker:DeleteEndpointConfig') 

971 schema = type_schema('delete') 

972 

973 def process(self, endpoints): 

974 client = local_session(self.manager.session_factory).client('sagemaker') 

975 for e in endpoints: 

976 try: 

977 client.delete_endpoint(EndpointName=e['EndpointName']) 

978 except client.exceptions.ResourceNotFound: 

979 pass 

980 

981 

982@SagemakerModelBiasJobDefinition.action_registry.register('delete') 

983class SagemakerModelBiasJobDefinitionDelete(BaseAction): 

984 """ Deletes sagemaker-model-bias-job-definition """ 

985 schema = type_schema('delete') 

986 permissions = ('sagemaker:DeleteModelBiasJobDefinition',) 

987 

988 def process(self, definitions): 

989 client = local_session(self.manager.session_factory).client('sagemaker') 

990 

991 for d in definitions: 

992 try: 

993 client.delete_model_bias_job_definition( 

994 JobDefinitionName=d['JobDefinitionName']) 

995 except client.exceptions.ResourceNotFound: 

996 pass 

997 

998 

999@SagemakerEndpointConfig.action_registry.register('delete') 

1000class SagemakerEndpointConfigDelete(BaseAction): 

1001 """Delete a SageMaker endpoint 

1002 

1003 :example: 

1004 

1005 .. code-block:: yaml 

1006 

1007 policies: 

1008 - name: delete-sagemaker-endpoint-config 

1009 resource: sagemaker-endpoint-config 

1010 filters: 

1011 - EndpointConfigName: sagemaker-2018-01-01-00-00-00-T00 

1012 actions: 

1013 - delete 

1014 """ 

1015 schema = type_schema('delete') 

1016 permissions = ('sagemaker:DeleteEndpointConfig',) 

1017 

1018 def process(self, endpoints): 

1019 client = local_session(self.manager.session_factory).client('sagemaker') 

1020 for e in endpoints: 

1021 try: 

1022 client.delete_endpoint_config( 

1023 EndpointConfigName=e['EndpointConfigName']) 

1024 except client.exceptions.ResourceNotFound: 

1025 pass 

1026 

1027 

1028@SagemakerDataQualityJobDefinition.action_registry.register('delete') 

1029class SagemakerDataQualityJobDefinitionDelete(BaseAction): 

1030 """Delete a SageMaker Data Quality Job Definition 

1031 

1032 :example: 

1033 

1034 .. code-block:: yaml 

1035 

1036 policies: 

1037 - name: delete-sagemaker-data-quality-job-definition 

1038 resource: sagemaker-data-quality-job-definition 

1039 filters: 

1040 - JobDefinitionName: job-def-1 

1041 actions: 

1042 - delete 

1043 """ 

1044 schema = type_schema('delete') 

1045 permissions = ('sagemaker:DeleteDataQualityJobDefinition',) 

1046 

1047 def process(self, job_definitions): 

1048 client = local_session(self.manager.session_factory).client('sagemaker') 

1049 for j in job_definitions: 

1050 try: 

1051 client.delete_data_quality_job_definition( 

1052 JobDefinitionName=j['JobDefinitionName']) 

1053 except client.exceptions.ResourceNotFound: 

1054 pass 

1055 

1056 

1057@SagemakerModelExplainabilityJobDefinition.action_registry.register('delete') 

1058class SagemakerModelExplainabilityJobDefinitionDelete(BaseAction): 

1059 """Delete a SageMaker Model Explainability Job Definition 

1060 

1061 :example: 

1062 

1063 .. code-block:: yaml 

1064 

1065 policies: 

1066 - name: delete-sagemaker-model-explainability-job-definition 

1067 resource: sagemaker-model-explainability-job-definition 

1068 filters: 

1069 - JobDefinitionName: job-def-1 

1070 actions: 

1071 - delete 

1072 """ 

1073 schema = type_schema('delete') 

1074 permissions = ('sagemaker:DeleteModelExplainabilityJobDefinition',) 

1075 

1076 def process(self, job_definitions): 

1077 client = local_session(self.manager.session_factory).client('sagemaker') 

1078 for j in job_definitions: 

1079 try: 

1080 client.delete_model_explainability_job_definition( 

1081 JobDefinitionName=j['JobDefinitionName']) 

1082 except client.exceptions.ResourceNotFound: 

1083 pass 

1084 

1085 

1086@SagemakerModelQualityJobDefinition.action_registry.register('delete') 

1087class SagemakerModelQualityJobDefinitionDelete(BaseAction): 

1088 """Delete a SageMaker Model Quality Job Definition 

1089 

1090 :example: 

1091 

1092 .. code-block:: yaml 

1093 

1094 policies: 

1095 - name: delete-sagemaker-model-quality-job-definition 

1096 resource: sagemaker-model-quality-job-definition 

1097 filters: 

1098 - JobDefinitionName: job-def-1 

1099 actions: 

1100 - delete 

1101 """ 

1102 schema = type_schema('delete') 

1103 permissions = ('sagemaker:DeleteModelQualityJobDefinition',) 

1104 

1105 def process(self, job_definitions): 

1106 client = local_session(self.manager.session_factory).client('sagemaker') 

1107 for j in job_definitions: 

1108 try: 

1109 client.delete_model_quality_job_definition( 

1110 JobDefinitionName=j['JobDefinitionName']) 

1111 except client.exceptions.ResourceNotFound: 

1112 pass 

1113 

1114 

1115@SagemakerTransformJob.action_registry.register('stop') 

1116class SagemakerTransformJobStop(BaseAction): 

1117 """Stops a SageMaker Transform job 

1118 

1119 :example: 

1120 

1121 .. code-block:: yaml 

1122 

1123 policies: 

1124 - name: stop-tranform-job 

1125 resource: sagemaker-transform-job 

1126 filters: 

1127 - TransformJobName: ml-job-10 

1128 actions: 

1129 - stop 

1130 """ 

1131 schema = type_schema('stop') 

1132 permissions = ('sagemaker:StopTransformJob',) 

1133 

1134 def process(self, jobs): 

1135 client = local_session(self.manager.session_factory).client('sagemaker') 

1136 

1137 for j in jobs: 

1138 try: 

1139 client.stop_transform_job(TransformJobName=j['TransformJobName']) 

1140 except client.exceptions.ResourceNotFound: 

1141 pass 

1142 

1143 

1144@SagemakerHyperParameterTuningJob.action_registry.register('stop') 

1145class SagemakerHyperParameterTuningJobStop(BaseAction): 

1146 """Stops a SageMaker Hyperparameter Tuning job 

1147 

1148 :example: 

1149 

1150 .. code-block:: yaml 

1151 

1152 policies: 

1153 - name: stop-hyperparameter-tuning-job 

1154 resource: sagemaker-hyperparameter-tuning-job 

1155 filters: 

1156 - HyperParameterTuningJobName: ml-job-10 

1157 actions: 

1158 - stop 

1159 """ 

1160 schema = type_schema('stop') 

1161 permissions = ('sagemaker:StopHyperParameterTuningJob',) 

1162 

1163 def process(self, jobs): 

1164 client = local_session(self.manager.session_factory).client('sagemaker') 

1165 

1166 for j in jobs: 

1167 try: 

1168 client.stop_hyper_parameter_tuning_job(HyperParameterTuningJobName=j['HyperParameterTuningJobName']) 

1169 except client.exceptions.ResourceNotFound: 

1170 pass 

1171 

1172 

1173@SagemakerAutoMLJob.action_registry.register('stop') 

1174class SagemakerAutoMLJobStop(BaseAction): 

1175 """Stops a SageMaker AutoML job 

1176 

1177 :example: 

1178 

1179 .. code-block:: yaml 

1180 

1181 policies: 

1182 - name: stop-automl-job 

1183 resource: sagemaker-auto-ml-job 

1184 filters: 

1185 - AutoMLJobName: ml-job-01 

1186 actions: 

1187 - stop 

1188 """ 

1189 schema = type_schema('stop') 

1190 permissions = ('sagemaker:StopAutoMLJob',) 

1191 

1192 def process(self, jobs): 

1193 client = local_session(self.manager.session_factory).client('sagemaker') 

1194 

1195 for j in jobs: 

1196 try: 

1197 client.stop_auto_ml_job(AutoMLJobName=j['AutoMLJobName']) 

1198 except client.exceptions.ResourceNotFound: 

1199 pass 

1200 

1201 

1202@SagemakerCompilationJob.action_registry.register('stop') 

1203class SagemakerCompilationJobStop(BaseAction): 

1204 """Stops a SageMaker Compilation job 

1205 

1206 :example: 

1207 

1208 .. code-block:: yaml 

1209 

1210 policies: 

1211 - name: stop-compilation-job 

1212 resource: sagemaker-compilation-job 

1213 filters: 

1214 - CompilationJobName: ml-job-10 

1215 actions: 

1216 - stop 

1217 """ 

1218 schema = type_schema('stop') 

1219 permissions = ('sagemaker:StopCompilationJob',) 

1220 

1221 def process(self, jobs): 

1222 client = local_session(self.manager.session_factory).client('sagemaker') 

1223 

1224 for j in jobs: 

1225 try: 

1226 client.stop_compilation_job(CompilationJobName=j['CompilationJobName']) 

1227 except client.exceptions.ResourceNotFound: 

1228 pass 

1229 

1230 

1231@SagemakerProcessingJob.action_registry.register('stop') 

1232class SagemakerProcessingJobStop(BaseAction): 

1233 """Stops a Sagemaker Processing job 

1234 

1235 :example: 

1236 

1237 .. code-block:: yaml 

1238 

1239 policies: 

1240 - name: stop-processing-job 

1241 resource: sagemaker-processing-job 

1242 filters: 

1243 - ProcessingJobName: ml-job-10 

1244 actions: 

1245 - stop 

1246 """ 

1247 schema = type_schema('stop') 

1248 permissions = ('sagemaker:StopProcessingJob',) 

1249 

1250 def process(self, jobs): 

1251 client = local_session(self.manager.session_factory).client('sagemaker') 

1252 

1253 for j in jobs: 

1254 try: 

1255 client.stop_processing_job(ProcessingJobName=j['ProcessingJobName']) 

1256 except client.exceptions.ResourceNotFound: 

1257 pass 

1258 

1259 

1260@Cluster.action_registry.register('delete') 

1261class ClusterDelete(BaseAction): 

1262 """Deletes sagemaker-cluster(s) 

1263 

1264 :example: 

1265 

1266 .. code-block:: yaml 

1267 

1268 policies: 

1269 - name: delete-sagemaker-cluster 

1270 resource: sagemaker-cluster 

1271 filters: 

1272 - "tag:DeleteMe": present 

1273 actions: 

1274 - delete 

1275 """ 

1276 schema = type_schema('delete') 

1277 permissions = ('sagemaker:DeleteCluster',) 

1278 

1279 def process(self, resources): 

1280 client = local_session(self.manager.session_factory).client('sagemaker') 

1281 

1282 for c in resources: 

1283 try: 

1284 client.delete_cluster(ClusterName=c['ClusterName']) 

1285 except client.exceptions.ResourceNotFound: 

1286 pass 

1287 

1288 

1289class SagemakerDomainDescribe(DescribeSource): 

1290 

1291 def augment(self, resources): 

1292 return universal_augment(self.manager, super().augment(resources)) 

1293 

1294 

1295@resources.register('sagemaker-domain') 

1296class SagemakerDomain(QueryResourceManager): 

1297 

1298 class resource_type(TypeInfo): 

1299 service = 'sagemaker' 

1300 enum_spec = ('list_domains', 'Domains', None) 

1301 detail_spec = ('describe_domain', 'DomainId', 'DomainId', None) 

1302 id = 'DomainId' 

1303 arn = 'DomainArn' 

1304 name = 'DomainName' 

1305 cfn_type = 'AWS::SageMaker::Domain' 

1306 permission_prefix = 'sagemaker' 

1307 universal_taggable = object() 

1308 

1309 source_mapping = {'describe': SagemakerDomainDescribe} 

1310 

1311 

1312@SagemakerDomain.filter_registry.register('kms-key') 

1313class SagemakerDomainKmsFilter(KmsRelatedFilter): 

1314 RelatedIdsExpression = 'KmsKeyId'