package com.clouck.comparator;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.amazonaws.services.ec2.model.Volume;
import com.amazonaws.services.ec2.model.VolumeAttachment;
import com.clouck.exception.ClouckUnexpectedConditionException;
import com.clouck.model.Event;
import com.clouck.model.EventType;
import com.clouck.model.aws.ec2.Ec2Volume;
@Component
public class Ec2VolumeComparator extends AbstractEc2Comparator<Ec2Volume> {
private static final Logger log = LoggerFactory.getLogger(Ec2VolumeComparator.class);
@Override
public Event firstScan() {
return createFirstScanEvent(EventType.Ec2_Volume_First_Scan);
}
@Override
public Event initialise(Ec2Volume newResource) {
return createEvent(null, newResource, EventType.Ec2_Volume_Found);
}
@Override
public Event add(Ec2Volume newResource) {
Volume volume = newResource.getResource();
String state = volume.getState();
switch (state) {
case "creating":
return createEvent(null, newResource, EventType.Ec2_Volume_Creating);
case "available":
case "in-use":
return createEvent(null, newResource, EventType.Ec2_Volume_Create);
case "deleting":
return createEvent(null, newResource, EventType.Ec2_Volume_Deleting);
case "error":
return createEvent(null, newResource, EventType.Ec2_Volume_Error);
default:
log.error("not handled instance state:{}", state);
return createEvent(null, newResource, EventType.Unknown);
}
}
@Override
public Event delete(Ec2Volume oldResource) {
return createEvent(oldResource, null, EventType.Ec2_Volume_Delete);
}
@Override
protected void update(List<Event> result, Ec2Volume oldResource, Ec2Volume newResource) {
Volume oldVolume = oldResource.getResource();
Volume newVolume = newResource.getResource();
Validate.isTrue(oldVolume.getAttachments().size() < 2);
Validate.isTrue(newVolume.getAttachments().size() < 2);
if (notEqual(oldResource.getAutoEnableIO(), newResource.getAutoEnableIO())) {
result.add(createEvent(oldResource, newResource, newResource.getAutoEnableIO() ?
EventType.Ec2_Volume_Auto_Enable_IO_Enabled : EventType.Ec2_Volume_Auto_Enable_IO_Disabled));
}
compareVolumeState(result, oldResource, newResource);
compareVolumeAttachment(result, oldResource, newResource);
compareTags(result, oldVolume.getTags(), newVolume.getTags(), oldResource, newResource);
}
private void compareVolumeState(Collection<Event> result, Ec2Volume oldResource, Ec2Volume newResource) {
Volume oldVolume = oldResource.getResource();
Volume newVolume = newResource.getResource();
String oldState = oldVolume.getState();
String newState = newVolume.getState();
if (equal(newState, oldState)) {
return;
}
switch (newState) {
case "deleting":
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Deleting));
break;
case "creating":
case "available":
case "in-use":
case "error":
break;
default:
log.error("not handled volume state:{}", newState);
result.add(createEvent(oldResource, newResource, EventType.Unknown));
}
}
private void compareVolumeAttachment(Collection<Event> result, Ec2Volume oldResource, Ec2Volume newResource) {
Volume oldVolume = oldResource.getResource();
Volume newVolume = newResource.getResource();
List<VolumeAttachment> oldVolumeAttachments = oldVolume.getAttachments();
List<VolumeAttachment> newVolumeAttachments = newVolume.getAttachments();
if (oldVolumeAttachments.size() == 0) {
if (newVolumeAttachments.size() != 0) {
VolumeAttachment newVolumeAttachment = newVolumeAttachments.get(0);
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Attached, newVolumeAttachment.getInstanceId()));
}
} else {
if (newVolumeAttachments.size() == 0) {
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Detached));
} else {
VolumeAttachment oldVolumeAttachment = oldVolumeAttachments.get(0);
VolumeAttachment newVolumeAttachment = newVolumeAttachments.get(0);
Validate.isTrue(oldVolumeAttachment.getVolumeId().equals(newVolumeAttachment.getVolumeId()));
if (notEqual(oldVolumeAttachment.getInstanceId(), newVolumeAttachment.getInstanceId())) {
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Detached, oldVolumeAttachment.getInstanceId()));
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Attached, newVolumeAttachment.getInstanceId()));
}
if (notEqual(oldVolumeAttachment.getDevice(), newVolumeAttachment.getDevice())) {
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Device, oldVolumeAttachment.getDevice(), newVolumeAttachment.getDevice()));
}
if (notEqual(oldVolumeAttachment.getState(), newVolumeAttachment.getState())) {
switch (newVolumeAttachment.getState()) {
case "attaching":
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Attaching, newVolumeAttachment.getInstanceId()));
break;
case "attached":
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Attached, newVolumeAttachment.getInstanceId()));
break;
case "detaching":
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Detaching));
break;
case "detached":
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Detached));
break;
default:
log.error("not handled volume attachment state:{}", newVolumeAttachment.getState());
result.add(createEvent(oldResource, newResource, EventType.Unknown));
}
}
//ignore attach time, as no one care
if (notEqual(oldVolumeAttachment.getDeleteOnTermination(), newVolumeAttachment.getDeleteOnTermination())) {
if (newVolumeAttachment.getDeleteOnTermination()) {
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Delete_On_Termination_Enabled));
} else {
result.add(createEvent(oldResource, newResource, EventType.Ec2_Volume_Delete_On_Termination_Disabled));
}
}
}
}
}
}