Skip to content

Commit

Permalink
Merge pull request #1 from cloud-custodian/master
Browse files Browse the repository at this point in the history
Sync with Original
  • Loading branch information
bc-jcarlson authored Aug 24, 2021
2 parents 27b2be3 + d3453d0 commit 845cd4e
Show file tree
Hide file tree
Showing 101 changed files with 4,713 additions and 1,109 deletions.
115 changes: 115 additions & 0 deletions c7n/resources/airflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Copyright The Cloud Custodian Authors.
# SPDX-License-Identifier: Apache-2.0
from c7n.manager import resources
from c7n.query import QueryResourceManager, TypeInfo
from c7n.filters.kms import KmsRelatedFilter
from c7n.tags import RemoveTag, Tag, TagDelayedAction, TagActionFilter


@resources.register('airflow')
class ApacheAirflow(QueryResourceManager):
class resource_type(TypeInfo):
service = 'mwaa'
id = name = 'Name'
enum_spec = ('list_environments', 'Environments', None)
detail_spec = ('get_environment', 'Name', None, 'Environment')
arn = 'Arn'
arn_type = 'environment'
cfn_type = 'AWS::MWAA::Environment'
permission_prefix = 'airflow'

permissions = (
'airflow:GetEnvironment',
'airflow:ListEnvironments',
)

def augment(self, resources):
resources = super(ApacheAirflow, self).augment(resources)
for r in resources:
r['Tags'] = [{'Key': k, 'Value': v} for k, v in r.get('Tags', {}).items()]
return resources


@ApacheAirflow.filter_registry.register('kms-key')
class ApacheAirflowKmsFilter(KmsRelatedFilter):
"""
Filter a Managed Workflow for Apache Airflow environment by its associcated kms key
and optionally the aliasname of the kms key by using 'c7n:AliasName'
:example:
.. code-block:: yaml
policies:
- name: airflow-kms-key-filter
resource: airflow
filters:
- type: kms-key
key: c7n:AliasName
value: alias/aws/mwaa
"""
RelatedIdsExpression = 'KmsKey'


@ApacheAirflow.action_registry.register('tag')
class TagApacheAirflow(Tag):
"""Action to create tag(s) on a Managed Workflow for Apache Airflow environment
:example:
.. code-block:: yaml
policies:
- name: tag-airflow
resource: airflow
filters:
- "tag:target-tag": absent
actions:
- type: tag
key: target-tag
value: target-tag-value
"""

permissions = ('airflow:TagResource',)

def process_resource_set(self, client, airflow, new_tags):
for r in airflow:
try:
client.tag_resource(
ResourceArn=r['Arn'],
Tags={t['Key']: t['Value'] for t in new_tags})
except client.exceptions.ResourceNotFound:
continue


@ApacheAirflow.action_registry.register('remove-tag')
class UntagApacheAirflow(RemoveTag):
"""Action to remove tag(s) on a Managed Workflow for Apache Airflow environment
:example:
.. code-block:: yaml
policies:
- name: airflow-remove-tag
resource: airflow
filters:
- "tag:OutdatedTag": present
actions:
- type: remove-tag
tags: ["OutdatedTag"]
"""

permissions = ('airflow:UntagResource',)

def process_resource_set(self, client, airflow, tags):
for r in airflow:
try:
client.untag_resource(ResourceArn=r['Arn'], tagKeys=tags)
except client.exceptions.ResourceNotFound:
continue


ApacheAirflow.filter_registry.register('marked-for-op', TagActionFilter)
ApacheAirflow.action_registry.register('mark-for-op', TagDelayedAction)
133 changes: 132 additions & 1 deletion c7n/resources/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
from c7n.actions import BaseAction
from c7n.filters.vpc import SubnetFilter, SecurityGroupFilter, VpcFilter
from c7n.manager import resources
from c7n.query import QueryResourceManager, DescribeSource, ConfigSource, TypeInfo
from c7n.query import (
QueryResourceManager, DescribeSource, ConfigSource, TypeInfo, ChildResourceManager)
from c7n.tags import universal_augment
from c7n.utils import local_session, type_schema
from c7n import query

from .securityhub import OtherResourcePostFinding

Expand Down Expand Up @@ -265,3 +267,132 @@ def process(self, resources):
self.manager.retry(client.delete_pipeline, name=r['name'])
except client.exceptions.PipelineNotFoundException:
continue


@resources.register('codedeploy-app')
class CodeDeployApplication(QueryResourceManager):

class resource_type(TypeInfo):
service = 'codedeploy'
enum_spec = ('list_applications', 'applications', None)
batch_detail_spec = (
'batch_get_applications', 'applicationNames',
None, 'applicationsInfo', None)
id = 'applicationId'
name = 'applicationName'
date = 'createTime'
arn_type = "application"
arn_separator = ":"
cfn_type = "AWS::CodeDeploy::Application"
universal_taggable = True

def augment(self, resources):
resources = super().augment(resources)
client = local_session(self.session_factory).client('codedeploy')
for r, arn in zip(resources, self.get_arns(resources)):
r['Tags'] = client.list_tags_for_resource(
ResourceArn=arn).get('Tags', [])
return resources

def get_arns(self, resources):
return [self.generate_arn(r['applicationName']) for r in resources]


@CodeDeployApplication.action_registry.register('delete')
class DeleteApplication(BaseAction):

schema = type_schema('delete')
permissions = ('codedeploy:DeleteApplication',)

def process(self, resources):
client = local_session(self.manager.session_factory).client('codedeploy')
for r in resources:
try:
self.manager.retry(client.delete_application, applicationName=r['applicationName'])
except (client.exceptions.InvalidApplicationNameException,
client.exceptions.ApplicationDoesNotExistException):
continue


@resources.register('codedeploy-deployment')
class CodeDeployDeployment(QueryResourceManager):

class resource_type(TypeInfo):
service = 'codedeploy'
enum_spec = ('list_deployments', 'deployments', {'includeOnlyStatuses': [
'Created', 'Queued', 'InProgress', 'Baking', 'Ready']})
batch_detail_spec = (
'batch_get_deployments', 'deploymentIds',
None, 'deploymentsInfo', None)
name = id = 'deploymentId'
# couldn't find a real cloudformation type
cfn_type = None
arn_type = "deploymentgroup"
date = 'createTime'


class DescribeDeploymentGroup(query.ChildDescribeSource):

def get_query(self):
query = super().get_query()
query.capture_parent_id = True
return query

def augment(self, resources):
client = local_session(self.manager.session_factory).client('codedeploy')
results = []
for parent_id, group_name in resources:
dg = self.manager.retry(
client.get_deployment_group, applicationName=parent_id,
deploymentGroupName=group_name).get('deploymentGroupInfo')
results.append(dg)
for r in results:
rarn = self.manager.generate_arn(r['applicationName'] + '/' + r['deploymentGroupName'])
r['Tags'] = self.manager.retry(
client.list_tags_for_resource, ResourceArn=rarn).get('Tags')
return results


@resources.register('codedeploy-group')
class CodeDeployDeploymentGroup(ChildResourceManager):

class resource_type(TypeInfo):
service = 'codedeploy'
parent_spec = ('codedeploy-app', 'applicationName', None)
enum_spec = ('list_deployment_groups', 'deploymentGroups', None)
id = 'deploymentGroupId'
name = 'deploymentGroupName'
arn_type = "deploymentgroup"
cfn_type = 'AWS::CodeDeploy::DeploymentGroup'
arn_separator = ':'
permission_prefix = 'codedeploy'
universal_taggable = True

source_mapping = {
'describe-child': DescribeDeploymentGroup
}

def get_arns(self, resources):
arns = []
for r in resources:
arns.append(self.generate_arn(r['applicationName'] + '/' + r['deploymentGroupName']))
return arns


@CodeDeployDeploymentGroup.action_registry.register('delete')
class DeleteDeploymentGroup(BaseAction):
"""Delete a deployment group tied to an application.
"""

schema = type_schema('delete')
permissions = ('codedeploy:DeleteDeploymentGroup',)

def process(self, resources):
client = local_session(self.manager.session_factory).client('codedeploy')
for r in resources:
try:
self.manager.retry(client.delete_deployment_group,
applicationName=r['applicationName'],
deploymentGroupName=r['deploymentGroupName'])
except client.exceptions.InvalidDeploymentGroupNameException:
continue
4 changes: 4 additions & 0 deletions c7n/resources/resource_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
ResourceMap = {
"aws.account": "c7n.resources.account.Account",
"aws.acm-certificate": "c7n.resources.acm.Certificate",
"aws.airflow": "c7n.resources.airflow.ApacheAirflow",
"aws.alarm": "c7n.resources.cw.Alarm",
"aws.ami": "c7n.resources.ami.AMI",
"aws.app-elb": "c7n.resources.appelb.AppELB",
Expand All @@ -27,6 +28,9 @@
"aws.artifact-repo": "c7n.resources.artifact.ArtifactRepo",
"aws.codebuild": "c7n.resources.code.CodeBuildProject",
"aws.codecommit": "c7n.resources.code.CodeRepository",
"aws.codedeploy-app": "c7n.resources.code.CodeDeployApplication",
"aws.codedeploy-deployment": "c7n.resources.code.CodeDeployDeployment",
"aws.codedeploy-group": "c7n.resources.code.CodeDeployDeploymentGroup",
"aws.codepipeline": "c7n.resources.code.CodeDeployPipeline",
"aws.config-recorder": "c7n.resources.config.ConfigRecorder",
"aws.config-rule": "c7n.resources.config.ConfigRule",
Expand Down
2 changes: 1 addition & 1 deletion c7n/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Generated via tools/dev/poetrypkg.py
version = "0.9.13"
version = "0.9.14"
4 changes: 2 additions & 2 deletions docs/source/aws/contribute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Run the following commands in the root directory after cloning Cloud Custodian:

.. code-block:: bash
$ make install
$ source bin/activate
make install
source bin/activate
This creates a virtual env in your enlistment and installs all packages as editable.

Expand Down
14 changes: 7 additions & 7 deletions docs/source/aws/gettingstarted.rst
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,14 @@ Given that, you can run Cloud Custodian with
.. code-block:: bash
# Validate the configuration (note this happens by default on run)
$ custodian validate policy.yml
custodian validate policy.yml
# Dryrun on the policies (no actions executed) to see what resources
# match each policy.
$ custodian run --dryrun -s out policy.yml
custodian run --dryrun -s out policy.yml
# Run the policy
$ custodian run -s out policy.yml
custodian run -s out policy.yml
.. _monitor-aws-cc:

Expand All @@ -173,15 +173,15 @@ Monitor AWS

You can generate CloudWatch metrics by specifying the ``--metrics`` flag and specifying ``aws``::

$ custodian run -s <output_directory> --metrics aws <policyfile>.yml
custodian run -s <output_directory> --metrics aws <policyfile>.yml

You can also upload Cloud Custodian logs to CloudWatch logs::

$ custodian run --log-group=/cloud-custodian/<dev-account>/<region> -s <output_directory> <policyfile>.yml
custodian run --log-group=/cloud-custodian/<dev-account>/<region> -s <output_directory> <policyfile>.yml

And you can output logs and resource records to S3::

$ custodian run -s s3://<my-bucket><my-prefix> <policyfile>.yml
custodian run -s s3://<my-bucket><my-prefix> <policyfile>.yml

If Custodian is being run without Assume Roles, all output will be put into the same account.
Custodian is built with the ability to be run from different accounts and leverage STS
Expand All @@ -200,4 +200,4 @@ as well, either on the command line or in an environment variable:
.. code-block:: bash
$ AWS_DEFAULT_REGION=us-west-1
AWS_DEFAULT_REGION=us-west-1
Loading

0 comments on commit 845cd4e

Please sign in to comment.