Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
259d2d9
Fix elb arn namespace : "elasticloadbalancing" instead of "elb"
Sep 4, 2018
0e8521b
Add support for 8 resources
Sep 4, 2018
828768e
Return specific ARN
Sep 13, 2018
95dd06f
Sort a list to get consistent outputs
Sep 13, 2018
02af227
Add set tag feature for ACM, ASG and CloudFront
Oct 1, 2018
1b893fb
Set the Name from the instance ID, because PrivateDnsName count be un…
Oct 3, 2018
4dc7c61
Merge branch 'more-resources' of github.com:lbncmorio/skew into more-…
Oct 3, 2018
fb89799
Define asset name from short Id/Name instead of fqdn
Oct 3, 2018
97b5c25
Prefer short name
Oct 15, 2018
48831a5
Fix tags read
Oct 15, 2018
f67c108
Class method for tag writing
Oct 15, 2018
83ca012
Fix the ARN with specific convention
Oct 15, 2018
b7ee364
Rename tags_support to resourcegroups_tagging
Oct 15, 2018
489a2b3
Enable Resource Groups Tagging (write) when possible
Oct 15, 2018
29de51d
Sleek datas frequently varied
Oct 22, 2018
297f404
Add set tag feature for EFS
Oct 22, 2018
72a7f83
Add OpsWorks stack
Oct 23, 2018
0856ccc
Fix the ARN with specific convention
Oct 23, 2018
08296e9
Adjust logging
Oct 23, 2018
67901bb
Tags using OpsWorks API instead of ResourceGroupsTaggingAPI
Oct 23, 2018
0e3feaa
Fix bucket Name
Oct 23, 2018
bcc0ad7
Set EC2 Instance name from its tag Name (or InstanceId)
Nov 16, 2018
ddfb456
Fix sleek, set at DBInstance instead of DBSecurityGroup
Nov 21, 2018
b503c7a
Implement in sleek method the lists consitant ordering
Nov 29, 2018
8ba2041
Compatibility fix for ECS, that use lowercase 'key' and 'value' as di…
Dec 26, 2018
94298a2
Add tagging support for ECS
Dec 26, 2018
6c03255
New method unset_tags()
Dec 26, 2018
8aace79
Typo in TagKeys
Dec 26, 2018
e4f0c49
Fix elb arn namespace : "elasticloadbalancing" instead of "elb"
Sep 4, 2018
ff4acba
Add support for 8 resources
Sep 4, 2018
a4046ba
Return specific ARN
Sep 13, 2018
4871e90
Sort a list to get consistent outputs
Sep 13, 2018
c79d849
Add set tag feature for ACM, ASG and CloudFront
Oct 1, 2018
a9701ca
Set the Name from the instance ID, because PrivateDnsName count be un…
Oct 3, 2018
74b43a2
Define asset name from short Id/Name instead of fqdn
Oct 3, 2018
a2019fa
Prefer short name
Oct 15, 2018
b4ec71f
Fix tags read
Oct 15, 2018
7d23256
Class method for tag writing
Oct 15, 2018
b9ee73e
Fix the ARN with specific convention
Oct 15, 2018
e60c818
Rename tags_support to resourcegroups_tagging
Oct 15, 2018
458bd79
Enable Resource Groups Tagging (write) when possible
Oct 15, 2018
cada9c0
Sleek datas frequently varied
Oct 22, 2018
fae1e0e
Add set tag feature for EFS
Oct 22, 2018
b0595ec
Add OpsWorks stack
Oct 23, 2018
a850f73
Fix the ARN with specific convention
Oct 23, 2018
944df83
Adjust logging
Oct 23, 2018
97d3814
Tags using OpsWorks API instead of ResourceGroupsTaggingAPI
Oct 23, 2018
9a55a06
Fix bucket Name
Oct 23, 2018
6f5207b
Set EC2 Instance name from its tag Name (or InstanceId)
Nov 16, 2018
b586450
Fix sleek, set at DBInstance instead of DBSecurityGroup
Nov 21, 2018
8a75751
Implement in sleek method the lists consitant ordering
Nov 29, 2018
57606de
Compatibility fix for ECS, that use lowercase 'key' and 'value' as di…
Dec 26, 2018
bdc5b0f
Add tagging support for ECS
Dec 26, 2018
3ef8b1a
New method unset_tags()
Dec 26, 2018
982a961
Typo in TagKeys
Dec 26, 2018
d622d47
Merge changes from develop branch
Dec 28, 2018
17a31d3
Cosmetic change, replace 'tags_keys' by 'tag_keys' for wording consis…
Dec 28, 2018
4f0ec5d
Improve acm resource
Dec 28, 2018
4e57e79
Disable tag support while Lambda boto3 version not yet support ecs/li…
Jan 8, 2019
bbd55ac
Asset name is get by tags if defined, or is FileSystemId
Jan 15, 2019
9dda937
Attribute DisplayName is not relevant, set Id as name instead
Jan 15, 2019
b2e6672
Add Cloudsearch Domain
Jan 17, 2019
abecda8
Fix bucket no detected when LocationConstraint == 'EU'
Jan 22, 2019
817f34c
Use native SQS tagging action
Jan 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion skew/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
# Maps resources names as they appear in ARN's to the path name
# of the Python class representing that resource.
ResourceTypes = {
'aws.acm.certificate': 'aws.acm.Certificate',
'aws.apigateway.restapis': 'aws.apigateway.RestAPI',
'aws.autoscaling.autoScalingGroup': 'aws.autoscaling.AutoScalingGroup',
'aws.autoscaling.launchConfigurationName': 'aws.autoscaling.LaunchConfiguration',
'aws.cloudfront.distribution': 'aws.cloudfront.Distribution',
'aws.cloudformation.stack': 'aws.cloudformation.Stack',
'aws.cloudsearch.domain': 'aws.cloudsearch.Domain',
'aws.cloudwatch.alarm': 'aws.cloudwatch.Alarm',
'aws.dynamodb.table': 'aws.dynamodb.Table',
'aws.ec2.address': 'aws.ec2.Address',
Expand All @@ -40,12 +42,17 @@
'aws.ec2.vpc-peering-connection': 'aws.ec2.VpcPeeringConnection',
'aws.ec2.subnet': 'aws.ec2.Subnet',
'aws.ec2.launch-template': 'aws.ec2.LaunchTemplate',
'aws.ecs.cluster': 'aws.ecs.Cluster',
'aws.ecs.task-definition': 'aws.ecs.TaskDefinition',
'aws.efs.filesystem': 'aws.efs.Filesystem',
'aws.elasticache.cluster': 'aws.elasticache.Cluster',
'aws.elasticache.subnet-group': 'aws.elasticache.SubnetGroup',
'aws.elasticache.snapshot': 'aws.elasticache.Snapshot',
'aws.elasticbeanstalk.application': 'aws.elasticbeanstalk.Application',
'aws.elasticbeanstalk.environment': 'aws.elasticbeanstalk.Environment',
'aws.elb.loadbalancer': 'aws.elb.LoadBalancer',
'aws.elbv2.loadbalancer': 'aws.elbv2.LoadBalancer',
'aws.elbv2.targetgroup': 'aws.elbv2.TargetGroup',
'aws.es.domain': 'aws.es.ElasticsearchDomain',
'aws.firehose.deliverystream': 'aws.firehose.DeliveryStream',
'aws.iam.group': 'aws.iam.Group',
Expand All @@ -56,15 +63,18 @@
'aws.iam.server-certificate': 'aws.iam.ServerCertificate',
'aws.kinesis.stream': 'aws.kinesis.Stream',
'aws.lambda.function': 'aws.lambda.Function',
'aws.opsworks.stack': 'aws.opsworks.Stack',
'aws.rds.db': 'aws.rds.DBInstance',
'aws.rds.secgrp': 'aws.rds.DBSecurityGroup',
'aws.redshift.cluster': 'aws.redshift.Cluster',
'aws.route53.hostedzone': 'aws.route53.HostedZone',
'aws.route53.healthcheck': 'aws.route53.HealthCheck',
'aws.s3.bucket': 'aws.s3.Bucket',
'aws.sqs.queue': 'aws.sqs.Queue',
'aws.ses.identity': 'aws.ses.Identity',
'aws.sns.subscription': 'aws.sns.Subscription',
'aws.sns.topic': 'aws.sns.Topic'
'aws.sns.topic': 'aws.sns.Topic',
'aws.support.check': 'aws.support.Check'
}


Expand Down
15 changes: 10 additions & 5 deletions skew/resources/aws/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class AWSResource(Resource):
Each entry in the dictionary we define:

* service - The AWS service in which this resource is defined.
* resourcegroups_tagging - Precise if the resource supports tags.
* enum_spec - The enumeration configuration. This is a tuple consisting
of the name of the operation to call to enumerate the resources,
a jmespath query that will be run against the result of the operation
Expand Down Expand Up @@ -169,12 +170,16 @@ def tags(self):
_tags = self.data['Tags']
if isinstance(_tags, list):
for kvpair in _tags:
if kvpair['Key'] in self._tags:
if not isinstance(self._tags[kvpair['Key']], list):
self._tags[kvpair['Key']] = [self._tags[kvpair['Key']]]
self._tags[kvpair['Key']].append(kvpair['Value'])
# Compatibility fix for ECS, that use lowercase 'key' and 'value' as dict keys
# https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.list_tags_for_resource
tags_key = kvpair.get('Key', kvpair.get('key'))
tags_value = kvpair.get('Value', kvpair.get('value'))
if tags_key in self._tags:
if not isinstance(self._tags[tags_key], list):
self._tags[tags_key] = [self._tags[tags_key]]
self._tags[tags_key].append(tags_value)
else:
self._tags[kvpair['Key']] = kvpair['Value']
self._tags[tags_key] = tags_value
elif isinstance(_tags, dict):
self._tags = _tags
return self._tags
Expand Down
60 changes: 60 additions & 0 deletions skew/resources/aws/acm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright (c) 2014 Scopely, Inc.
# Copyright (c) 2015 Mitch Garnaat
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

import logging

import jmespath

from skew.resources.aws import AWSResource


LOG = logging.getLogger(__name__)


class Certificate(AWSResource):

class Meta(object):
service = 'acm'
type = 'certificate'
resourcegroups_tagging = True
enum_spec = ('list_certificates', 'CertificateSummaryList', None)
detail_spec = ('describe_certificate', 'CertificateArn', 'Certificate')
id = 'CertificateArn'
tags_spec = ('list_tags_for_certificate', 'Tags[]',
'CertificateArn', 'id')
filter_name = None
name = 'DomainName'
date = 'CreatedAt'
dimension = None

@classmethod
def filter(cls, arn, resource_id, data):
certificate_id = data.get(cls.Meta.id).split('/')[-1]
LOG.debug('%s == %s', resource_id, certificate_id)
return resource_id == certificate_id

@property
def arn(self):
return self.data['CertificateArn']

def __init__(self, client, data, query=None):
super(Certificate, self).__init__(client, data, query)

self._id = data['CertificateArn']

detail_op, param_name, detail_path = self.Meta.detail_spec
params = {param_name: data['CertificateArn']}
data = client.call(detail_op, **params)

self.data = jmespath.search(detail_path, data)
8 changes: 8 additions & 0 deletions skew/resources/aws/apigateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class RestAPI(AWSResource):
class Meta(object):
service = 'apigateway'
type = 'restapis'
resourcegroups_tagging = False
enum_spec = ('get_rest_apis', 'items', None)
id = 'id'
filter_name = None
Expand All @@ -35,3 +36,10 @@ def filter(cls, arn, resource_id, data):
api_id = data.get(cls.Meta.id)
LOG.debug('%s == %s', resource_id, api_id)
return resource_id == api_id

@property
def arn(self):
# arn:aws:apigateway:us-east-1::/restapis/vwxyz12345
return 'arn:aws:apigateway:%s::/restapis/%s' % (
self._client.region_name,
self.id)
29 changes: 29 additions & 0 deletions skew/resources/aws/autoscaling.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
import jmespath

from skew.resources.aws import AWSResource
from skew.awsclient import get_awsclient


class AutoScalingGroup(AWSResource):

class Meta(object):
service = 'autoscaling'
type = 'autoScalingGroup'
resourcegroups_tagging = False
name = 'AutoScalingGroupName'
date = 'CreatedTime'
dimension = 'AutoScalingGroupName'
Expand All @@ -39,6 +41,33 @@ def __init__(self, client, data, query=None):
def arn(self):
return self._arn_query.search(self.data)

def sleek(self):
# Always render lists in the same order to avoid false changes detection
self.data['EnabledMetrics'].sort(key=lambda item: item['Metric'])
self.data['SuspendedProcesses'].sort(key=str)

@classmethod
def set_tags(cls, arn, region, account, tags, resource_id=None, **kwargs):
client = get_awsclient(
cls.Meta.service, region, account, **kwargs)
asg_name = arn.split(':')[7].split('/')[1]
addon = dict(ResourceId=asg_name,
ResourceType='auto-scaling-group',
PropagateAtLaunch=False)
tags_list = [dict(Key=k, Value=str(v), **addon) for k, v in tags.items()]
return client.call('create_or_update_tags', Tags=tags_list)

@classmethod
def unset_tags(cls, arn, region, account, tag_keys, resource_id=None, **kwargs):
client = get_awsclient(
cls.Meta.service, region, account, **kwargs)
asg_name = arn.split(':')[7].split('/')[1]
addon = dict(ResourceId=asg_name,
ResourceType='auto-scaling-group',
PropagateAtLaunch=False)
tags_list = [dict(Key=k, **addon) for k in tag_keys]
return client.call('delete_tags', Tags=tags_list)


class LaunchConfiguration(AWSResource):

Expand Down
1 change: 1 addition & 0 deletions skew/resources/aws/cloudformation.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def enumerate(cls, arn, region, account, resource_id=None, **kwargs):
class Meta(object):
service = 'cloudformation'
type = 'stack'
resourcegroups_tagging = False
enum_spec = ('describe_stacks', 'Stacks[]', None)
detail_spec = ('describe_stack_resources', 'StackName',
'StackResources[]')
Expand Down
17 changes: 16 additions & 1 deletion skew/resources/aws/cloudfront.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging

from skew.resources.aws import AWSResource
from skew.awsclient import get_awsclient


LOG = logging.getLogger(__name__)
Expand All @@ -20,12 +21,13 @@ class Distribution(CloudfrontResource):
class Meta(object):
service = 'cloudfront'
type = 'distribution'
resourcegroups_tagging = False
enum_spec = ('list_distributions', 'DistributionList.Items[]', None)
detail_spec = None
id = 'Id'
tags_spec = ('list_tags_for_resource', 'Tags.Items[]',
'Resource', 'arn')
name = 'DomainName'
name = 'Id'
filter_name = None
date = 'LastModifiedTime'
dimension = None
Expand All @@ -34,3 +36,16 @@ class Meta(object):
def filter(cls, arn, resource_id, data):
LOG.debug('%s == %s', resource_id, data)
return resource_id == data['Id']

@classmethod
def set_tags(cls, arn, region, account, tags, resource_id=None, **kwargs):
client = get_awsclient(
cls.Meta.service, region, account, **kwargs)
tags_list = [dict(Key=k, Value=str(v)) for k, v in tags.items()]
return client.call('tag_resource', Resource=arn, Tags=dict(Items=tags_list))

@classmethod
def unset_tags(cls, arn, region, account, tag_keys, resource_id=None, **kwargs):
client = get_awsclient(
cls.Meta.service, region, account, **kwargs)
return client.call('untag_resource', Resource=arn, TagKeys=dict(Items=tag_keys))
42 changes: 42 additions & 0 deletions skew/resources/aws/cloudsearch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2014 Scopely, Inc.
# Copyright (c) 2015 Mitch Garnaat
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

import logging

import jmespath

from skew.resources.aws import AWSResource


LOG = logging.getLogger(__name__)


class Domain(AWSResource):

class Meta(object):
service = 'cloudsearch'
type = 'domain'
resourcegroups_tagging = False
enum_spec = ('describe_domains', 'DomainStatusList', None)
detail_spec = None
id = 'ARN'
tags_spec = None
filter_name = None
name = 'DomainName'
date = 'Created'
dimension = None

@property
def arn(self):
return self.data['ARN']
1 change: 1 addition & 0 deletions skew/resources/aws/cloudwatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class Alarm(AWSResource):
class Meta(object):
service = 'cloudwatch'
type = 'alarm'
resourcegroups_tagging = False
enum_spec = ('describe_alarms', 'MetricAlarms', None)
id = 'AlarmArn'
filter_name = 'AlarmNames'
Expand Down
1 change: 1 addition & 0 deletions skew/resources/aws/dynamodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Table(AWSResource):
class Meta(object):
service = 'dynamodb'
type = 'table'
resourcegroups_tagging = True
enum_spec = ('list_tables', 'TableNames', None)
detail_spec = ('describe_table', 'TableName', 'Table')
id = 'Table'
Expand Down
Loading