# Copyright 2018 Capital One Services, LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License 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.
from c7n.manager import resources
from c7n.query import QueryResourceManager
from c7n.actions import ActionRegistry, BaseAction
from c7n.filters import FilterRegistry
from c7n.tags import Tag, TagDelayedAction, RemoveTag, coalesce_copy_user_tags, TagActionFilter
from c7n.utils import local_session, type_schema
from c7n.filters.kms import KmsRelatedFilter
[docs]@resources.register('fsx')
class FSx(QueryResourceManager):
filter_registry = FilterRegistry('fsx.filters')
action_registry = ActionRegistry('fsx.actions')
[docs] class resource_type(object):
service = 'fsx'
enum_spec = ('describe_file_systems', 'FileSystems', None)
name = id = 'FileSystemId'
arn = "ResourceARN"
date = 'CreationTime'
dimension = None
filter_name = None
[docs]@resources.register('fsx-backup')
class FSxBackup(QueryResourceManager):
filter_registry = FilterRegistry('fsx-baackup.filters')
action_registry = ActionRegistry('fsx-baackup.actions')
[docs] class resource_type(object):
service = 'fsx'
enum_spec = ('describe_backups', 'Backups', None)
name = id = 'BackupId'
arn = "ResourceARN"
date = 'CreationTime'
dimension = None
filter_name = None
[docs]@FSxBackup.action_registry.register('delete')
class DeleteBackup(BaseAction):
"""
Delete backups
:example:
.. code-block: yaml
policies:
- name: delete-backups
resource: fsx-backup
filters:
- type: value
value_type: age
key: CreationDate
value: 30
op: gt
actions:
- type: delete
"""
permissions = ('fsx:DeleteBackup',)
schema = type_schema('delete')
[docs] def process(self, resources):
client = local_session(self.manager.session_factory).client('fsx')
for r in resources:
try:
client.delete_backup(BackupId=r['BackupId'])
except client.exceptions.BackupRestoring as e:
self.log.warning(
'Unable to delete backup for: %s - %s - %s' % (
r['FileSystemId'], r['BackupId'], e))
FSxBackup.filter_registry.register('marked-for-op', TagActionFilter)
FSx.filter_registry.register('marked-for-op', TagActionFilter)
[docs]@FSxBackup.action_registry.register('mark-for-op')
@FSx.action_registry.register('mark-for-op')
class MarkForOpFileSystem(TagDelayedAction):
permissions = ('fsx:TagResource',)
[docs]@FSxBackup.action_registry.register('tag')
@FSx.action_registry.register('tag')
class TagFileSystem(Tag):
concurrency = 2
batch_size = 5
permissions = ('fsx:TagResource',)
[docs] def process_resource_set(self, client, resources, tags):
for r in resources:
client.tag_resource(ResourceARN=r['ResourceARN'], Tags=tags)
[docs]@FSxBackup.action_registry.register('remove-tag')
@FSx.action_registry.register('remove-tag')
class UnTagFileSystem(RemoveTag):
concurrency = 2
batch_size = 5
permissions = ('fsx:UntagResource',)
[docs] def process_resource_set(self, client, resources, tag_keys):
for r in resources:
client.untag_resource(ResourceARN=r['ResourceARN'], TagKeys=tag_keys)
[docs]@FSx.action_registry.register('update')
class UpdateFileSystem(BaseAction):
"""
Update FSx resource configurations
:example:
.. code-block: yaml
policies:
- name: update-fsx-resource
resource: fsx
actions:
- type: update
WindowsConfiguration:
AutomaticBackupRetentionDays: 1
DailyAutomaticBackupStartTime: '04:30'
WeeklyMaintenanceStartTime: '04:30'
LustreConfiguration:
WeeklyMaintenanceStartTime: '04:30'
Reference: https://docs.aws.amazon.com/fsx/latest/APIReference/API_UpdateFileSystem.html
"""
permissions = ('fsx:UpdateFileSystem',)
schema = type_schema(
'update',
WindowsConfiguration={'type': 'object'},
LustreConfiguration={'type': 'object'}
)
[docs] def process(self, resources):
client = local_session(self.manager.session_factory).client('fsx')
for r in resources:
client.update_file_system(
FileSystemId=r['FileSystemId'],
WindowsConfiguration=self.data.get('WindowsConfiguration', {}),
LustreConfiguration=self.data.get('LustreConfiguration', {})
)
[docs]@FSx.action_registry.register('backup')
class BackupFileSystem(BaseAction):
"""
Create Backups of File Systems
Tags are specified in key value pairs, e.g.: BackupSource: CloudCustodian
:example:
.. code-block: yaml
policies:
- name: backup-fsx-resource
comment: |
creates a backup of fsx resources and
copies tags from file system to the backup
resource: fsx
actions:
- type: backup
copy-tags: True
tags:
BackupSource: CloudCustodian
- name: backup-fsx-resource-copy-specific-tags
comment: |
creates a backup of fsx resources and
copies tags from file system to the backup
resource: fsx
actions:
- type: backup
copy-tags:
- Application
- Owner
# or use '*' to specify all tags
tags:
BackupSource: CloudCustodian
"""
permissions = ('fsx:CreateBackup',)
schema = type_schema(
'backup',
**{
'tags': {
'type': 'object'
},
'copy-tags': {
'oneOf': [
{
'type': 'boolean'
},
{
'type': 'array',
'items': {
'type': 'string'
}
}
]
}
}
)
[docs] def process(self, resources):
client = local_session(self.manager.session_factory).client('fsx')
user_tags = self.data.get('tags', {})
copy_tags = self.data.get('copy-tags', True)
for r in resources:
tags = coalesce_copy_user_tags(r, copy_tags, user_tags)
try:
if tags:
client.create_backup(
FileSystemId=r['FileSystemId'],
Tags=tags
)
else:
client.create_backup(
FileSystemId=r['FileSystemId']
)
except client.exceptions.BackupInProgress as e:
self.log.warning(
'Unable to create backup for: %s - %s' % (r['FileSystemId'], e))
[docs]@FSx.action_registry.register('delete')
class DeleteFileSystem(BaseAction):
"""
Delete Filesystems
:example:
.. code-block: yaml
policies:
- name: delete-fsx-instance-with-snapshot
resource: fsx
filters:
- FileSystemId: fs-1234567890123
actions:
- type: delete
copy-tags:
- Application
- Owner
tags:
DeletedBy: CloudCustodian
- name: delete-fsx-instance-skip-snapshot
resource: fsx
filters:
- FileSystemId: fs-1234567890123
actions:
- type: delete
skip-snapshot: True
"""
permissions = ('fsx:DeleteFileSystem',)
schema = type_schema(
'delete',
**{
'skip-snapshot': {'type': 'boolean'},
'tags': {'type': 'object'},
'copy-tags': {
'oneOf': [
{
'type': 'array',
'items': {
'type': 'string'
}
},
{
'type': 'boolean'
}
]
}
}
)
[docs] def process(self, resources):
client = local_session(self.manager.session_factory).client('fsx')
skip_snapshot = self.data.get('skip-snapshot', False)
copy_tags = self.data.get('copy-tags', True)
user_tags = self.data.get('tags', [])
for r in resources:
tags = coalesce_copy_user_tags(r, copy_tags, user_tags)
config = {'SkipFinalBackup': skip_snapshot}
if tags and not skip_snapshot:
config['FinalBackupTags'] = tags
try:
client.delete_file_system(
FileSystemId=r['FileSystemId'],
WindowsConfiguration=config
)
except client.exceptions.BadRequest as e:
self.log.warning('Unable to delete: %s - %s' % (r['FileSystemId'], e))
[docs]@FSx.filter_registry.register('kms-key')
class KmsFilter(KmsRelatedFilter):
"""
Filter a resource by its associcated kms key and optionally the aliasname
of the kms key by using 'c7n:AliasName'
:example:
.. code-block:: yaml
policies:
- name: fsx-kms-key-filters
resource: fsx
filters:
- type: kms-key
key: c7n:AliasName
value: "^(alias/aws/fsx)"
op: regex
"""
RelatedIdsExpression = 'KmsKeyId'
[docs]@FSxBackup.filter_registry.register('kms-key')
class KmsFilterFsxBackup(KmsRelatedFilter):
"""
Filter a resource by its associcated kms key and optionally the aliasname
of the kms key by using 'c7n:AliasName'
:example:
.. code-block:: yaml
policies:
- name: fsx-backup-kms-key-filters
resource: fsx-backup
filters:
- type: kms-key
key: c7n:AliasName
value: "^(alias/aws/fsx)"
op: regex
"""
RelatedIdsExpression = 'KmsKeyId'