def get_tags_for_copied_snapshot(): snapshot_tags = ( self.copied_volume_tagfiter.pairs_matching_any_filter( self.snapshot.get("Tags", {}))) snapshot_tags[actions.marker_snapshot_tag_source_source_volume_id( )] = self.source_volume_id snapshot_tags.update( self.build_tags_from_template( parameter_name=PARAM_SNAPSHOT_TAGS, region=self.source_region, tag_variables={ TAG_PLACEHOLDER_SOURCE_SNAPSHOT_ID: self.source_snapshot_id, TAG_PLACEHOLDER_SOURCE_REGION: self.source_region, TAG_PLACEHOLDER_OWNER_ACCOUNT: self.owner, TAG_PLACEHOLDER_SOURCE_VOLUME: self.source_volume_id })) snapshot_tags[Ec2CopySnapshotAction.marker_tag_source_snapshot_id( )] = self.source_snapshot_id snapshot_tags[actions.marker_snapshot_tag_source_source_volume_id( )] = self.source_volume_id return snapshot_tags
def check_copy_snapshot(self, snapshot_id, source_snapshot, destination): ec2_destination = Ec2(region=destination) self.logger.test("Checking copied snapshot") snapshot_copy = ec2_destination.get_snapshot(snapshot_id) self.assertIsNotNone(snapshot_copy, "Snapshot copy does exist") snapshot_tags = snapshot_copy.get("Tags", {}) self.assertTrue( TagFilterExpression("copied-tag=copied-value").is_match( snapshot_tags), "Source snapshot tag copied") self.assertFalse( TagFilterExpression("not-copied-tag=*").is_match(snapshot_tags), "Source snapshot tag not copied") self.logger.test("[X] Expected source snapshot tag copied") snapshot_placeholders = { copy_snapshot.TAG_PLACEHOLDER_SOURCE_REGION: source_snapshot["Region"], copy_snapshot.TAG_PLACEHOLDER_SOURCE_SNAPSHOT_ID: source_snapshot["SnapshotId"], copy_snapshot.TAG_PLACEHOLDER_SOURCE_VOLUME: source_snapshot["VolumeId"], copy_snapshot.TAG_PLACEHOLDER_OWNER_ACCOUNT: source_snapshot["AwsAccount"] } self.assertTrue( testing.tags.verify_placeholder_tags(snapshot_tags, snapshot_placeholders), "All placeholder tags set on snapshot {}".format(snapshot_id)) self.logger.test("[X] Placeholder tags created") self.assertTrue( TagFilterExpression("{}={}".format( actions.marker_snapshot_tag_source_source_volume_id(), source_snapshot["VolumeId"])).is_match(snapshot_tags), "Source volume tag set") self.logger.test("[X] Source volume tag created") self.assertTrue( TagFilterExpression("{}={}".format( copy_snapshot.Ec2CopySnapshotAction. marker_tag_source_snapshot_id(), source_snapshot["SnapshotId"])).is_match(snapshot_tags), "Source snapshot tag set") self.logger.test("[X] Source snapshot tag created") self.assertEqual( ec2_destination.get_snapshot_create_volume_permission_users( snapshot_id), ["123456789012"], "Create volume permissions set") self.logger.test("[X] Volume create permission set") self.assertEqual(snapshot_copy["Description"], source_snapshot["Description"], "Description is copied") self.logger.test("[X] Description is copied")
def set_snapshot_sources_tags(snapshot_id, source_volume_id=None, source_snapshot_id=None, region_name=None): tags = {} if source_volume_id is not None: tags[actions.marker_snapshot_tag_source_source_volume_id()] = source_volume_id if source_snapshot_id is not None: tags[Ec2CopySnapshotAction.marker_tag_source_snapshot_id()] = source_snapshot_id if len(tags) > 0: ec2 = Ec2(region_name) ec2.create_tags([snapshot_id], tags)
def __init__(self, action_args, action_parameters): self._destination_region_ = None ActionBase.__init__(self, action_args, action_parameters) # debug and dryrun self.snapshot = self._resources_ # snapshot source and destination information self.source_snapshot_id = self.snapshot["SnapshotId"] self.source_region = self.snapshot["Region"] self.owner = self.snapshot.get("OwnerId", "") self.encrypted = self.get(PARAM_ENCRYPTED, False) self.kms_key_id = self.get(PARAM_KMS_KEY_ID, None) self.accounts_with_create_permissions = self.get( PARAM_ACCOUNTS_VOLUME_CREATE_PERMISSIONS, []) self.delete_after_copy = self.get(PARAM_DELETE_AFTER_COPY, False) # filter for copied tags from source snapshot self.copied_volume_tagfiter = TagFilterSet( self.get(PARAM_COPIED_SNAPSHOT_TAGS, "")) self.tag_snapshots_in_shared_accounts = self.get( PARAM_TAG_IN_DESTINATION_ACCOUNT, False) self.tag_snapshots_in_source_account = self.get( PARAM_TAG_IN_SOURCE_ACCOUNT, False) # tagging roles self.dest_account_snapshot_tagging_rolename = self.get( PARAM_DESTINATION_ACCOUNT_TAG_ROLENAME, "") self.source_account_tagging_role_name = self.get( PARAM_SOURCE_ACCOUNT_TAG_ROLE_NAME, "") volume_id = self.snapshot["VolumeId"] if volume_id == DUMMY_VOLUME_IF_FOR_COPIED_SNAPSHOT: volume_from_tag = self.snapshot.get("Tags", {}).get( actions.marker_snapshot_tag_source_source_volume_id(), None) if volume_from_tag is not None: volume_id = volume_from_tag self.source_volume_id = volume_id self._ec2_destination_client = None self._ec2_source_client = None # setup result with known values self.result = { "account": self._account_, "task": self._task_, "destination-region": self._destination_region_, "source-region": self.source_region, "source-snapshot-id": self.source_snapshot_id, "encrypted": self.encrypted, "kms-id": self.kms_key_id if self.kms_key_id is not None else "" }
def process_and_select_resource(service, logger, resource_name, resource, context, task, task_assumed_role): volume_id = resource["VolumeId"] if volume_id == actions.DUMMY_VOLUME_IF_FOR_COPIED_SNAPSHOT: volume_from_tag = resource.get("Tags", {}).get( actions.marker_snapshot_tag_source_source_volume_id(), None) if volume_from_tag is not None: resource["VolumeId"] = volume_from_tag resource["IsCopied"] = True else: if task.get("parameters", {}).get(PARAM_RETENTION_COUNT, 0) > 0: logger.warning(WARN_NO_SOURCE_VOLUME_WITH_RETENTION, resource["SnapshotId"]) return None return resource
def get_tags_for_volume_snapshot(vol, dev): vol_tags = self.copied_instance_tagfilter.pairs_matching_any_filter(self.tags_on_instance) tags_on_volume = self.all_volume_tags.get(vol, {}) vol_tags.update(self.copied_volume_tagfilter.pairs_matching_any_filter(tags_on_volume)) vol_tags.update( self.build_tags_from_template(parameter_name=PARAM_SNAPSHOT_TAGS, tag_variables={ TAG_PLACEHOLDER_INSTANCE_ID: self.instance_id, TAG_PLACEHOLDER_VOLUME_ID: volume, TAG_PLACEHOLDER_DEVICE: dev })) vol_tags[actions.marker_snapshot_tag_source_source_volume_id()] = volume return vol_tags
def check_snapshot(snap_id, source_volume_id): checked_snapshot = self.ec2.get_snapshot(snap_id) self.assertIsNotNone(checked_snapshot, "Snapshot does exist") self.logger.test("[X] Snapshot was created") snapshot_tags = checked_snapshot.get("Tags", {}) self.assertTrue(TagFilterExpression("InstanceTag=Instance0").is_match(snapshot_tags), "Instance tag copied") self.logger.test("[X] Instance tags copied") source_volume = self.ec2.get_volume(source_volume_id) assert (source_volume is not None) device = source_volume.get("Attachments", [{}])[0].get("Device", "") if source_volume_id in self.data_volumes: volume_tags = source_volume.get("Tags", {}) self.assertTrue( TagFilterExpression("VolumeTag={}".format(volume_tags.get("VolumeTag", ""))).is_match(snapshot_tags), "Volume tag copied") self.logger.test("[X] Volume tags copied") snapshot_placeholders = { create_snapshot_action.TAG_PLACEHOLDER_VOLUME_ID: source_volume_id, create_snapshot_action.TAG_PLACEHOLDER_INSTANCE_ID: self.instance_id, create_snapshot_action.TAG_PLACEHOLDER_DEVICE: device } self.assertTrue(testing.tags.verify_placeholder_tags(snapshot_tags, snapshot_placeholders), "All placeholder tags set on snapshot {}".format(snap_id)) self.logger.test("[X] Placeholder tags created") self.assertTrue(TagFilterExpression( "{}={}".format(actions.marker_snapshot_tag_source_source_volume_id(), source_volume_id)).is_match( snapshot_tags), "Source volume tag set") self.logger.test("[X] Source volume tags created") self.assertTrue(self.ec2.get_snapshot_create_volume_permission_users(snap_id) == ["123456789012"], "Create volume permissions set") self.logger.test("[X] Volume create permissions set") expected_name = "snapshot-{}-{}-{}".format(self.task_runner.action_stack_name, self.instance_id, source_volume_id) self.assertEqual(expected_name, snapshot_tags["Name"], "Name has been set") self.logger.test("[X] Snapshot name set") description = checked_snapshot.get("Description", "") self.assertTrue( all([p in description for p in [source_volume_id, self.instance_id, region(), self.task_runner.task_name]]), "Description is set") self.logger.test("[X] Snapshot description set")
def _select_parameters(self, event_name, task): if self._event_name() == EBS_SNAPSHOT_FOR_VOLUME_CREATED: return { "Filters": [{ "Name": "volume-id", "Values": [self._source] }], "_expected_boto3_exceptions_": ["InvalidVolume.NotFound"] } if self._event_name() == EBS_SNAPSHOT_FOR_VOLUME_COPIED: ec2 = services.create_service( "ec2", role_arn=self._role_executing_triggered_task, service_retry_strategy=get_default_retry_strategy( "ec2", context=self._context)) try: source_volume = None copied_snapshot_id = self._event["detail"][ "snapshot_id"].split("/")[-1] # get the copied snapshot with tags copied_snapshot = ec2.get( services.ec2_service.SNAPSHOTS, SnapshotIds=[copied_snapshot_id], OwnerIds=["self"], region=self._event_region(), tags=True, _expected_boto3_exceptions_=["InvalidSnapshot.NotFound"]) if copied_snapshot is not None: # get the source volume from the tags source_volume = copied_snapshot.get("Tags", {}).get( marker_snapshot_tag_source_source_volume_id(), None) if source_volume is None: self._logger.warning(WARN_SOURCE_VOLUME_NOT_FOUND, copied_snapshot_id) return None snapshots = list( ec2.describe(services.ec2_service.SNAPSHOTS, region=self._event_region(), OwnerIds=["self"], Filters=[{ "Name": "volume-id", "Values": [source_volume] }], _expected_boto3_exceptions_=[ "InvalidVolume.NotFound" ])) snapshots += list( ec2.describe( services.ec2_service.SNAPSHOTS, region=self._event_region(), OwnerIds=["self"], tags=True, Filters=[{ "Name": "tag:" + actions. marker_snapshot_tag_source_source_volume_id(), "Values": [source_volume] }], _expected_boto3_exceptions_=["InvalidVolume.NotFound" ])) if len(snapshots) == 0: return None snapshots = list(set([s["SnapshotId"] for s in snapshots])) return { handlers.HANDLER_EVENT_RESOURCE_NAME: services.ec2_service.SNAPSHOTS, handlers.HANDLER_EVENT_REGIONS: [self._event_region()], "SnapshotIds": snapshots, "_expected_boto3_exceptions_": ["InvalidSnapshot.NotFound"] } except Exception as ex: self._logger.error( ERR_GETTING_SOURCE_VOLUME, self._event.get("detail", {}).get("source", ""), ex) return None return { "SnapshotIds": [r.split("/")[-1] for r in self._event.get("resources")], "_expected_boto3_exceptions_": ["InvalidSnapshot.NotFound"] }