package com.clouck.comparator; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.amazonaws.services.ec2.model.CreateVolumePermission; import com.amazonaws.services.ec2.model.Snapshot; import com.clouck.model.Event; import com.clouck.model.EventType; import com.clouck.model.aws.ec2.Ec2Snapshot; import com.clouck.util.ResourceUtil; @Component public class Ec2SnapshotComparator extends AbstractEc2Comparator<Ec2Snapshot> { private static final Logger log = LoggerFactory.getLogger(Ec2SnapshotComparator.class); @Autowired private ResourceUtil resourceUtil; @Override public Event firstScan() { return createFirstScanEvent(EventType.Ec2_Snapshot_First_Scan); } @Override public Event initialise(Ec2Snapshot newResource) { return createEvent(null, newResource, EventType.Ec2_Snapshot_Found); } @Override public Event add(Ec2Snapshot newResource) { Snapshot newSnapshot = newResource.getResource(); String state = newSnapshot.getState(); switch (state) { case "pending": return createEvent(null, newResource, EventType.Ec2_Snapshot_Pending); case "completed": return createEvent(null, newResource, EventType.Ec2_Snapshot_Created); default: log.error("not handled instance state:{}", state); return createEvent(null, newResource, EventType.Unknown); } } @Override protected void update(List<Event> result, Ec2Snapshot oldResource, Ec2Snapshot newResource) { Snapshot oldSnapshot = oldResource.getResource(); Snapshot newSnapshot = newResource.getResource(); compareSnapshotState(result, oldResource, newResource); compareCreateVolumePermission(result, oldResource.getCreateVolumePermissions(), newResource.getCreateVolumePermissions(), oldResource, newResource); compareTags(result, oldSnapshot.getTags(), newSnapshot.getTags(), oldResource, newResource); } @Override public Event delete(Ec2Snapshot oldResource) { return createEvent(oldResource, null, EventType.Ec2_Snapshot_Deleted); } private void compareSnapshotState(Collection<Event> result, Ec2Snapshot oldResource, Ec2Snapshot newResource) { Snapshot newInstance = newResource.getResource(); Snapshot oldInstance = oldResource.getResource(); String newState = newInstance.getState(); String oldState = oldInstance.getState(); if (notEqual(newState, oldState)) { switch (newState) { case "pending": result.add(createEvent(oldResource, newResource, EventType.Ec2_Snapshot_Pending)); break; case "completed": result.add(createEvent(oldResource, newResource, EventType.Ec2_Snapshot_Created)); break; default: log.error("not handled instance state:" + newState); result.add(createEvent(oldResource, newResource, EventType.Unknown)); } } } private void compareCreateVolumePermission(Collection<Event> result, List<CreateVolumePermission> oldPermissions, List<CreateVolumePermission> newPermissions, Ec2Snapshot oldResource, Ec2Snapshot newResource) { Boolean oldIsPublic = isPublic(result, oldResource, newResource, oldPermissions); Boolean newIsPublic = isPublic(result, oldResource, newResource, newPermissions); if (notEqual(oldIsPublic, newIsPublic)) { if (oldIsPublic != null && newIsPublic != null) { if (newIsPublic) { result.add(createEvent(oldResource, newResource, EventType.Ec2_Snapshot_Permission_Visibility_Public)); } else { result.add(createEvent(oldResource, newResource, EventType.Ec2_Snapshot_Permission_Visibility_Private)); } } } CompareResult<CreateVolumePermission> compareResult = resourceUtil.compare(removeGroup(oldPermissions), removeGroup(newPermissions)); for (CreateVolumePermission cvp : compareResult.getAdd()) { result.add(createEvent(oldResource, newResource, EventType.Ec2_Snapshot_Permission_Account_Added, cvp.getUserId())); } for (CreateVolumePermission cvp : compareResult.getDelete()) { result.add(createEvent(oldResource, newResource, EventType.Ec2_Snapshot_Permission_Account_Removed, cvp.getUserId())); } for (Pair<CreateVolumePermission, CreateVolumePermission> pair : compareResult.getUpdate()) { log.error("not handled case"); result.add(createEvent(oldResource, newResource, EventType.Unknown)); } } private Boolean isPublic(Collection<Event> result, Ec2Snapshot oldResource, Ec2Snapshot newResource, List<CreateVolumePermission> permissions) { Validate.notNull(permissions); for (CreateVolumePermission cvp : permissions) { if (cvp.getGroup() != null) { if (cvp.getGroup().equals("all")) { return true; } else { log.error("not handled group:{}", cvp.getGroup()); result.add(createEvent(oldResource, newResource, EventType.Unknown)); return null; } } } return false; } private List<CreateVolumePermission> removeGroup(List<CreateVolumePermission> permissions) { List<CreateVolumePermission> result = new ArrayList<>(); for (CreateVolumePermission cvp : permissions) { if (cvp.getGroup() == null) { result.add(cvp); } } return result; } }