package com.sequenceiq.it.cloudbreak.tags; import java.io.ByteArrayInputStream; import java.security.PrivateKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Assert; import org.openstack4j.api.OSClient; import org.openstack4j.openstack.OSFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import com.amazonaws.regions.Region; import com.amazonaws.regions.Regions; import com.amazonaws.services.ec2.AmazonEC2Client; 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.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.client.util.Base64; import com.google.api.client.util.SecurityUtils; import com.google.api.services.compute.Compute; import com.google.api.services.compute.ComputeScopes; import com.google.api.services.compute.model.Tags; import com.microsoft.azure.Azure; import com.microsoft.azure.PagedList; import com.microsoft.azure.credentials.ApplicationTokenCredentials; import com.microsoft.azure.management.compute.VirtualMachine; import com.microsoft.rest.credentials.ServiceClientCredentials; import com.sequenceiq.cloudbreak.api.model.InstanceGroupResponse; import com.sequenceiq.cloudbreak.api.model.InstanceMetaDataJson; import com.sequenceiq.cloudbreak.api.model.StackResponse; import com.sequenceiq.it.util.ResourceUtil; public class TagsUtil { private static final Logger LOGGER = LoggerFactory.getLogger(TagsUtil.class); private TagsUtil() { } public static Map<String, String> getTagsToCheck(String tags) { List<String> tagsToCheckList = Arrays.asList(tags.split(";")); Map<String, String> tagsToCheckMap = new HashMap<>(); for (String elem : tagsToCheckList) { String[] tmpList = elem.split(":"); Assert.assertTrue(tmpList.length > 1); tagsToCheckMap.put(tmpList[0], tmpList[1]); } return tagsToCheckMap; } protected static List<String> getInstancesList(StackResponse stackResponse) { List<InstanceGroupResponse> instanceGroups = stackResponse.getInstanceGroups(); List<String> instanceIdList = new ArrayList<>(); for (InstanceGroupResponse instanceGroup : instanceGroups) { Set<InstanceMetaDataJson> instanceMetaData = instanceGroup.getMetadata(); for (InstanceMetaDataJson metaData : instanceMetaData) { instanceIdList.add(metaData.getInstanceId()); } } return instanceIdList; } protected static void checkTags(Map<String, String> tagsToCheck, Map<String, String> extractedTagsToCheck) { for (Map.Entry entry : tagsToCheck.entrySet()) { Assert.assertTrue(extractedTagsToCheck.keySet().contains(entry.getKey())); Assert.assertEquals(extractedTagsToCheck.get(entry.getKey()), entry.getValue()); } } protected static Map<String, String> checkTagsStack(StackResponse stackResponse) { Map<String, Object> tagsList = stackResponse.getTags(); Map<String, String> userDefinedTagsList = (Map<String, String>) tagsList.get("userDefined"); Assert.assertNotNull(userDefinedTagsList); return userDefinedTagsList; } protected static void checkTagsWithProvider(String stackName, Map<String, String> cloudProviderParams, ApplicationContext applicationcontext, List<String> instanceIds, Map<String, String> tagsToCheckMap) throws Exception { switch (cloudProviderParams.get("cloudProvider")) { case "AWS": checkTagsAws(Regions.fromName(cloudProviderParams.get("region")), instanceIds, tagsToCheckMap); break; case "AZURE": checkTagsAzure(cloudProviderParams.get("accesKey"), cloudProviderParams.get("tenantId"), cloudProviderParams.get("secretKey"), cloudProviderParams.get("subscriptionId"), stackName, tagsToCheckMap); break; case "GCP": checkTagsGcp(applicationcontext, cloudProviderParams.get("applicationName"), cloudProviderParams.get("projectId"), cloudProviderParams.get("serviceAccountId"), cloudProviderParams.get("p12File"), cloudProviderParams.get("availabilityZone"), instanceIds, tagsToCheckMap); break; case "OPENSTACK": checkTagsOpenstack(cloudProviderParams.get("endpoint"), cloudProviderParams.get("userName"), cloudProviderParams.get("password"), cloudProviderParams.get("tenantName"), instanceIds, tagsToCheckMap); break; default: LOGGER.info("CloudProvider {} is not supported!", cloudProviderParams.get("cloudProvider")); break; } } protected static void checkTagsAws(Regions region, List<String> instanceIdList, Map<String, String> tagsToCheckMap) { Map<String, String> extractedTagsToCheck = new HashMap<>(); List<Tag> extractedTags; AmazonEC2Client ec2 = new AmazonEC2Client(); ec2.setRegion(Region.getRegion(region)); DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest(); describeInstancesRequest.withInstanceIds(instanceIdList); DescribeInstancesResult describeInstancesResultAll = ec2.describeInstances(describeInstancesRequest); List<Reservation> reservationsAll = describeInstancesResultAll.getReservations(); for (Reservation reservation : reservationsAll) { for (Instance instance : reservation.getInstances()) { extractedTags = instance.getTags(); Assert.assertNotNull(extractedTags); for (Tag tag : extractedTags) { extractedTagsToCheck.put(tag.getKey(), tag.getValue()); } TagsUtil.checkTags(tagsToCheckMap, extractedTagsToCheck); extractedTags.clear(); } } } protected static void checkTagsAzure(String accesKey, String tenantId, String secretKey, String subscriptionId, String stackName, Map<String, String> tagsToCheckMap) throws Exception { ServiceClientCredentials serviceClientCredentials = new ApplicationTokenCredentials(accesKey, tenantId, secretKey, null); Azure azure = Azure.authenticate(serviceClientCredentials).withSubscription(subscriptionId); PagedList<VirtualMachine> virtualMachinesList = azure.virtualMachines().list(); for (VirtualMachine vm : virtualMachinesList) { if (vm.name().contains(stackName)) { Map<String, String> extractedTags = vm.tags(); TagsUtil.checkTags(tagsToCheckMap, extractedTags); } } } protected static void checkTagsGcp(ApplicationContext applicationContext, String applicationName, String projectId, String serviceAccountId, String p12File, String availabilityZone, List<String> instanceIdList, Map<String, String> tagsToCheckMap) throws Exception { String serviceAccountPrivateKey = ResourceUtil.readBase64EncodedContentFromResource(applicationContext, p12File); HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); PrivateKey privateKey = SecurityUtils.loadPrivateKeyFromKeyStore(SecurityUtils.getPkcs12KeyStore(), new ByteArrayInputStream(Base64.decodeBase64(serviceAccountPrivateKey)), "notasecret", "privatekey", "notasecret"); JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance(); GoogleCredential googleCredential = new GoogleCredential.Builder().setTransport(httpTransport) .setJsonFactory(jsonFactory) .setServiceAccountId(serviceAccountId) .setServiceAccountScopes(Collections.singletonList(ComputeScopes.COMPUTE)) .setServiceAccountPrivateKey(privateKey) .build(); Compute compute = new Compute.Builder(httpTransport, jsonFactory, null) .setApplicationName(applicationName) .setHttpRequestInitializer(googleCredential) .build(); Compute.Instances instances = compute.instances(); for (String id : instanceIdList) { Compute.Instances.Get response = instances.get(projectId, availabilityZone, id); com.google.api.services.compute.model.Instance instance = response.execute(); Tags gcpTags = instance.getTags(); Map<String, String> extractedTags = new HashMap<>(); List<String> tagList = gcpTags.getItems(); for (String i : tagList) { String[] tmpTagList = i.split("-"); if (tmpTagList.length > 1) { extractedTags.put(tmpTagList[0], tmpTagList[1]); } } TagsUtil.checkTags(tagsToCheckMap, extractedTags); extractedTags.clear(); } } protected static void checkTagsOpenstack(String endpoint, String userName, String password, String tenantName, List<String> instanceIdList, Map<String, String> tagsToCheckMap) { OSClient os = OSFactory.builder() .endpoint(endpoint) .credentials(userName, password) .tenantName(tenantName) .authenticate(); for (String instanceId : instanceIdList) { Map<String, String> serverMetadata = os.compute().servers().getMetadata(instanceId); TagsUtil.checkTags(tagsToCheckMap, serverMetadata); } } }