package com.sequenceiq.cloudbreak.cloud.aws;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import com.amazonaws.services.autoscaling.AmazonAutoScalingClient;
import com.amazonaws.services.cloudformation.AmazonCloudFormationClient;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.Tag;
import com.sequenceiq.cloudbreak.cloud.aws.task.AwsPollTaskFactory;
import com.sequenceiq.cloudbreak.cloud.aws.view.AwsCredentialView;
import com.sequenceiq.cloudbreak.cloud.context.AuthenticatedContext;
import com.sequenceiq.cloudbreak.cloud.context.CloudContext;
import com.sequenceiq.cloudbreak.cloud.model.AvailabilityZone;
import com.sequenceiq.cloudbreak.cloud.model.CloudCredential;
import com.sequenceiq.cloudbreak.cloud.model.CloudInstance;
import com.sequenceiq.cloudbreak.cloud.model.CloudVmMetaDataStatus;
import com.sequenceiq.cloudbreak.cloud.model.InstanceStatus;
import com.sequenceiq.cloudbreak.cloud.model.InstanceTemplate;
import com.sequenceiq.cloudbreak.cloud.model.Location;
import com.sequenceiq.cloudbreak.cloud.model.Region;
import com.sequenceiq.cloudbreak.cloud.model.Volume;
import com.sequenceiq.cloudbreak.cloud.scheduler.SyncPollingScheduler;
@RunWith(MockitoJUnitRunner.class)
public class AwsMetaDataCollectorTest {
@Mock
private AwsClient awsClient;
@Mock
private CloudFormationStackUtil cloudFormationStackUtil;
@Mock
private SyncPollingScheduler<Boolean> syncPollingScheduler;
@Mock
private AwsPollTaskFactory awsPollTaskFactory;
@Mock
private AmazonCloudFormationClient amazonCFClient;
@Mock
private AmazonAutoScalingClient amazonASClient;
@Mock
private AmazonEC2Client amazonEC2Client;
@Mock
private DescribeInstancesRequest describeInstancesRequestGw;
@Mock
private DescribeInstancesRequest describeInstancesRequestMaster;
@Mock
private DescribeInstancesRequest describeInstancesRequestSlave;
@Mock
private DescribeInstancesResult describeInstancesResultGw;
@Mock
private DescribeInstancesResult describeInstancesResultMaster;
@Mock
private DescribeInstancesResult describeInstancesResultSlave;
@InjectMocks
private AwsMetadataCollector awsMetadataCollector;
@Before
public void setUp() {
Mockito.reset(amazonEC2Client);
}
@Test
public void collectMigratedExistingOneGroup() {
List<CloudInstance> vms = new ArrayList<>();
List<Volume> volumes = new ArrayList<>();
vms.add(new CloudInstance("i-1", new InstanceTemplate("fla", "cbgateway", 5L, volumes, InstanceStatus.CREATED, null)));
when(awsClient.createCloudFormationClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonCFClient);
when(awsClient.createAutoScalingClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonASClient);
when(awsClient.createAccess(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonEC2Client);
when(cloudFormationStackUtil.getAutoscalingGroupName(any(AuthenticatedContext.class), any(AmazonCloudFormationClient.class), eq("cbgateway")))
.thenReturn("cbgateway-AAA");
List<String> gatewayIds = Collections.singletonList("i-1");
when(cloudFormationStackUtil.getInstanceIds(any(AmazonAutoScalingClient.class), eq("cbgateway-AAA")))
.thenReturn(gatewayIds);
when(cloudFormationStackUtil.createDescribeInstancesRequest(eq(gatewayIds))).thenReturn(describeInstancesRequestGw);
when(amazonEC2Client.describeInstances(describeInstancesRequestGw)).thenReturn(describeInstancesResultGw);
Instance instance = Mockito.mock(Instance.class);
when(instance.getInstanceId()).thenReturn("i-1");
when(instance.getPrivateIpAddress()).thenReturn("privateIp");
when(instance.getPublicIpAddress()).thenReturn("publicIp");
List<Reservation> gatewayReservations = Collections.singletonList(getReservation(instance));
when(describeInstancesResultGw.getReservations()).thenReturn(gatewayReservations);
AuthenticatedContext ac = authenticatedContext();
List<CloudVmMetaDataStatus> statuses = awsMetadataCollector.collect(ac, null, vms);
verify(amazonEC2Client).createTags(any(CreateTagsRequest.class));
Assert.assertEquals(1, statuses.size());
Assert.assertEquals("i-1", statuses.get(0).getCloudVmInstanceStatus().getCloudInstance().getInstanceId());
Assert.assertEquals("privateIp", statuses.get(0).getMetaData().getPrivateIp());
Assert.assertEquals("publicIp", statuses.get(0).getMetaData().getPublicIp());
}
@Test
public void collectAlreadyTaggedOneGroup() {
List<CloudInstance> vms = new ArrayList<>();
List<Volume> volumes = new ArrayList<>();
vms.add(new CloudInstance("i-1", new InstanceTemplate("fla", "cbgateway", 5L, volumes, InstanceStatus.CREATED, null)));
when(awsClient.createCloudFormationClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonCFClient);
when(awsClient.createAutoScalingClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonASClient);
when(awsClient.createAccess(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonEC2Client);
when(cloudFormationStackUtil.getAutoscalingGroupName(any(AuthenticatedContext.class), any(AmazonCloudFormationClient.class), eq("cbgateway")))
.thenReturn("cbgateway-AAA");
List<String> gatewayIds = Collections.singletonList("i-1");
when(cloudFormationStackUtil.getInstanceIds(any(AmazonAutoScalingClient.class), eq("cbgateway-AAA")))
.thenReturn(gatewayIds);
when(cloudFormationStackUtil.createDescribeInstancesRequest(eq(gatewayIds))).thenReturn(describeInstancesRequestGw);
when(amazonEC2Client.describeInstances(describeInstancesRequestGw)).thenReturn(describeInstancesResultGw);
Instance instance = Mockito.mock(Instance.class);
when(instance.getInstanceId()).thenReturn("i-1");
when(instance.getPrivateIpAddress()).thenReturn("privateIp");
when(instance.getPublicIpAddress()).thenReturn("publicIp");
Tag tag = new Tag();
tag.setKey("cbname");
tag.setValue("somevalue");
when(instance.getTags()).thenReturn(Collections.singletonList(tag));
List<Reservation> gatewayReservations = Collections.singletonList(getReservation(instance));
when(describeInstancesResultGw.getReservations()).thenReturn(gatewayReservations);
AuthenticatedContext ac = authenticatedContext();
List<CloudVmMetaDataStatus> statuses = awsMetadataCollector.collect(ac, null, vms);
verify(amazonEC2Client, never()).createTags(any(CreateTagsRequest.class));
Assert.assertEquals(1, statuses.size());
Assert.assertEquals("i-1", statuses.get(0).getCloudVmInstanceStatus().getCloudInstance().getInstanceId());
Assert.assertEquals("privateIp", statuses.get(0).getMetaData().getPrivateIp());
Assert.assertEquals("publicIp", statuses.get(0).getMetaData().getPublicIp());
}
@Test
public void collectNewOneGroup() {
List<CloudInstance> vms = new ArrayList<>();
List<Volume> volumes = new ArrayList<>();
vms.add(new CloudInstance(null, new InstanceTemplate("fla", "cbgateway", 5L, volumes, InstanceStatus.CREATED, null)));
when(awsClient.createCloudFormationClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonCFClient);
when(awsClient.createAutoScalingClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonASClient);
when(awsClient.createAccess(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonEC2Client);
when(cloudFormationStackUtil.getAutoscalingGroupName(any(AuthenticatedContext.class), any(AmazonCloudFormationClient.class), eq("cbgateway")))
.thenReturn("cbgateway-AAA");
List<String> gatewayIds = Collections.singletonList("i-1");
when(cloudFormationStackUtil.getInstanceIds(any(AmazonAutoScalingClient.class), eq("cbgateway-AAA")))
.thenReturn(gatewayIds);
when(cloudFormationStackUtil.createDescribeInstancesRequest(eq(gatewayIds))).thenReturn(describeInstancesRequestGw);
when(amazonEC2Client.describeInstances(describeInstancesRequestGw)).thenReturn(describeInstancesResultGw);
Instance instance = Mockito.mock(Instance.class);
when(instance.getInstanceId()).thenReturn("i-1");
when(instance.getPrivateIpAddress()).thenReturn("privateIp");
when(instance.getPublicIpAddress()).thenReturn("publicIp");
List<Reservation> gatewayReservations = Collections.singletonList(getReservation(instance));
when(describeInstancesResultGw.getReservations()).thenReturn(gatewayReservations);
AuthenticatedContext ac = authenticatedContext();
List<CloudVmMetaDataStatus> statuses = awsMetadataCollector.collect(ac, null, vms);
verify(amazonEC2Client).createTags(any(CreateTagsRequest.class));
Assert.assertEquals(1, statuses.size());
Assert.assertEquals("i-1", statuses.get(0).getCloudVmInstanceStatus().getCloudInstance().getInstanceId());
Assert.assertEquals("privateIp", statuses.get(0).getMetaData().getPrivateIp());
Assert.assertEquals("publicIp", statuses.get(0).getMetaData().getPublicIp());
}
@Test
public void collectNewAndExistingOneGroup() {
List<CloudInstance> vms = new ArrayList<>();
List<Volume> volumes = new ArrayList<>();
vms.add(new CloudInstance(null, new InstanceTemplate("fla", "cbgateway", 5L, volumes, InstanceStatus.CREATED, null)));
vms.add(new CloudInstance("i-1", new InstanceTemplate("fla", "cbgateway", 5L, volumes, InstanceStatus.CREATED, null)));
when(awsClient.createCloudFormationClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonCFClient);
when(awsClient.createAutoScalingClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonASClient);
when(awsClient.createAccess(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonEC2Client);
when(cloudFormationStackUtil.getAutoscalingGroupName(any(AuthenticatedContext.class), any(AmazonCloudFormationClient.class), eq("cbgateway")))
.thenReturn("cbgateway-AAA");
List<String> gatewayIds = Arrays.asList("i-1", "i-2");
when(cloudFormationStackUtil.getInstanceIds(any(AmazonAutoScalingClient.class), eq("cbgateway-AAA")))
.thenReturn(gatewayIds);
when(cloudFormationStackUtil.createDescribeInstancesRequest(eq(gatewayIds))).thenReturn(describeInstancesRequestGw);
when(amazonEC2Client.describeInstances(describeInstancesRequestGw)).thenReturn(describeInstancesResultGw);
Instance instance1 = Mockito.mock(Instance.class);
when(instance1.getInstanceId()).thenReturn("i-1");
when(instance1.getPrivateIpAddress()).thenReturn("privateIp1");
when(instance1.getPublicIpAddress()).thenReturn("publicIp1");
Instance instance2 = Mockito.mock(Instance.class);
when(instance2.getInstanceId()).thenReturn("i-2");
when(instance2.getPrivateIpAddress()).thenReturn("privateIp2");
when(instance2.getPublicIpAddress()).thenReturn("publicIp2");
List<Reservation> gatewayReservations = Collections.singletonList(getReservation(instance1, instance2));
when(describeInstancesResultGw.getReservations()).thenReturn(gatewayReservations);
AuthenticatedContext ac = authenticatedContext();
List<CloudVmMetaDataStatus> statuses = awsMetadataCollector.collect(ac, null, vms);
verify(amazonEC2Client, times(2)).createTags(any(CreateTagsRequest.class));
Assert.assertEquals(2, statuses.size());
Assert.assertEquals("i-1", statuses.get(0).getCloudVmInstanceStatus().getCloudInstance().getInstanceId());
Assert.assertEquals("privateIp1", statuses.get(0).getMetaData().getPrivateIp());
Assert.assertEquals("publicIp1", statuses.get(0).getMetaData().getPublicIp());
Assert.assertEquals("i-2", statuses.get(1).getCloudVmInstanceStatus().getCloudInstance().getInstanceId());
Assert.assertEquals("privateIp2", statuses.get(1).getMetaData().getPrivateIp());
Assert.assertEquals("publicIp2", statuses.get(1).getMetaData().getPublicIp());
}
@Test
public void collectNewOldIsTagged() {
List<CloudInstance> vms = new ArrayList<>();
List<Volume> volumes = new ArrayList<>();
vms.add(new CloudInstance(null, new InstanceTemplate("fla", "cbgateway", 5L, volumes, InstanceStatus.CREATED, null)));
when(awsClient.createCloudFormationClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonCFClient);
when(awsClient.createAutoScalingClient(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonASClient);
when(awsClient.createAccess(any(AwsCredentialView.class), eq("region"))).thenReturn(amazonEC2Client);
when(cloudFormationStackUtil.getAutoscalingGroupName(any(AuthenticatedContext.class), any(AmazonCloudFormationClient.class), eq("cbgateway")))
.thenReturn("cbgateway-AAA");
List<String> gatewayIds = Arrays.asList("i-1", "i-new");
when(cloudFormationStackUtil.getInstanceIds(any(AmazonAutoScalingClient.class), eq("cbgateway-AAA")))
.thenReturn(gatewayIds);
when(cloudFormationStackUtil.createDescribeInstancesRequest(eq(gatewayIds))).thenReturn(describeInstancesRequestGw);
when(amazonEC2Client.describeInstances(describeInstancesRequestGw)).thenReturn(describeInstancesResultGw);
Instance instance1 = Mockito.mock(Instance.class);
when(instance1.getInstanceId()).thenReturn("i-1");
when(instance1.getPrivateIpAddress()).thenReturn("privateIp1");
when(instance1.getPublicIpAddress()).thenReturn("publicIp1");
Tag tag = new Tag();
tag.setKey("cbname");
tag.setValue("somevalue");
when(instance1.getTags()).thenReturn(Collections.singletonList(tag));
Instance instance2 = Mockito.mock(Instance.class);
when(instance2.getInstanceId()).thenReturn("i-new");
when(instance2.getPrivateIpAddress()).thenReturn("privateIp2");
when(instance2.getPublicIpAddress()).thenReturn("publicIp2");
List<Reservation> gatewayReservations = Collections.singletonList(getReservation(instance1, instance2));
when(describeInstancesResultGw.getReservations()).thenReturn(gatewayReservations);
AuthenticatedContext ac = authenticatedContext();
List<CloudVmMetaDataStatus> statuses = awsMetadataCollector.collect(ac, null, vms);
verify(amazonEC2Client, times(1)).createTags(any(CreateTagsRequest.class));
Assert.assertEquals(1, statuses.size());
Assert.assertEquals("i-new", statuses.get(0).getCloudVmInstanceStatus().getCloudInstance().getInstanceId());
Assert.assertEquals("privateIp2", statuses.get(0).getMetaData().getPrivateIp());
Assert.assertEquals("publicIp2", statuses.get(0).getMetaData().getPublicIp());
}
private Reservation getReservation(Instance... instance) {
List<Instance> instances = Arrays.asList(instance);
Reservation r = new Reservation();
r.setInstances(instances);
return r;
}
private AuthenticatedContext authenticatedContext() {
Location location = Location.location(Region.region("region"), AvailabilityZone.availabilityZone("az"));
CloudContext cloudContext = new CloudContext(5L, "name", "platform", "owner", "variant", location);
CloudCredential cc = new CloudCredential(1L, null, null, null);
return new AuthenticatedContext(cloudContext, cc);
}
}