diff --git a/src/main/java/org/activeeon/morphemic/PAGateway.java b/src/main/java/org/activeeon/morphemic/PAGateway.java index 80056a4543c4b03005edbeab10fd51c6de6211b7..0fbf7b5b025ca321d5d166d12d54f03fb4b02935 100644 --- a/src/main/java/org/activeeon/morphemic/PAGateway.java +++ b/src/main/java/org/activeeon/morphemic/PAGateway.java @@ -157,9 +157,6 @@ public class PAGateway { em.getTransaction().begin(); - //TODO: Add docker job handling - //TODO: Add spark job handling (throw not handled yet exception) - Job newJob = new Job(); newJob.setJobId(job.optJSONObject("jobInformation").optString("id")); newJob.setName(job.optJSONObject("jobInformation").optString("name")); @@ -242,24 +239,47 @@ public class PAGateway { * @param deployment The deployment information object */ private void defineNSWithDeploymentInfo(String nodeSourceName, PACloud cloud, Deployment deployment) { - File fXmlFile = null; - try { - fXmlFile = new File(getClass().getResource("/Define_NS_AWS.xml").toURI()); - } catch (URISyntaxException e) { - LOGGER.error(e.getStackTrace()); - } + String filename; Map variables = new HashMap<>(); variables.put("NS_name", nodeSourceName); variables.put("NS_nVMs", "0"); - variables.put("aws_username", cloud.getCredentials().getUserName()); - variables.put("aws_secret", cloud.getCredentials().getPrivateKey()); variables.put("security_group", cloud.getSecurityGroup()); variables.put("image", deployment.getLocationName() + "/" + deployment.getImageProviderId()); try { - variables.put("rm_host_name", (new URL(this.paURL)).getHost()); + URL endpointPa = (new URL(this.paURL)); + variables.put("rm_host_name", endpointPa.getHost()); + variables.put("pa_port", "" + endpointPa.getPort()); } catch (MalformedURLException e) { LOGGER.error(e.getStackTrace()); } + switch (cloud.getCloudProviderName()) { + case "aws-ec2": + filename = "/Define_NS_AWS.xml"; + variables.put("aws_username", cloud.getCredentials().getUserName()); + variables.put("aws_secret", cloud.getCredentials().getPrivateKey()); + break; + case "openstack": + filename = "/Define_NS_OS.xml"; + variables.put("os_endpoint", cloud.getEndpoint()); + variables.put("os_scopePrefix", cloud.getScopePrefix()); + variables.put("os_scopeValue", cloud.getScopeValue()); + variables.put("os_identityVersion", cloud.getIdentityVersion()); + variables.put("os_username", cloud.getCredentials().getUserName()); + variables.put("os_password", cloud.getCredentials().getPrivateKey()); + variables.put("os_domain", cloud.getCredentials().getDomain()); + variables.put("os_region", deployment.getLocationName()); + variables.put("os_networkId",cloud.getDefaultNetwork()); + break; + default: + throw new IllegalArgumentException("Spark tasks are not handled yet."); + } + File fXmlFile = null; + try { + fXmlFile = new File(getClass().getResource(filename).toURI()); + } catch (URISyntaxException e) { + LOGGER.error(e.getStackTrace()); + } + assert fXmlFile != null; LOGGER.info("Submitting the file: " + fXmlFile.toString()); LOGGER.info("Trying to deploy the NS: " + nodeSourceName); schedulerGateway.submit(fXmlFile, variables); @@ -439,15 +459,22 @@ public class PAGateway { } else { newCloud.setSecurityGroup(cloud.optString("securityGroup")); } + newCloud.setEndpoint(cloud.optString("endpoint")); + newCloud.setScopePrefix(cloud.optJSONObject("scope").optString("prefix")); + newCloud.setScopeValue(cloud.optJSONObject("scope").optString("value")); + newCloud.setIdentityVersion(cloud.optString("identityVersion")); + newCloud.setDefaultNetwork(cloud.optString("defaultNetwork")); + newCloud.setBlacklist(cloud.optString("blacklist")); Credentials credentials = new Credentials(); credentials.setUserName(cloud.optJSONObject("credentials").optString("user")); credentials.setPrivateKey(cloud.optJSONObject("credentials").optString("secret")); + credentials.setDomain(cloud.optJSONObject("credentials").optString("domain")); em.persist(credentials); newCloud.setCredentials(credentials); String dummyInfraName = "iamadummy" + newCloud.getCloudProviderName(); - connectorIaasGateway.defineInfrastructure(dummyInfraName, newCloud.getCloudProviderName(), credentials, ""); + connectorIaasGateway.defineInfrastructure(dummyInfraName, newCloud, ""); newCloud.setDummyInfrastructureName(dummyInfraName); em.persist(newCloud); diff --git a/src/main/java/org/activeeon/morphemic/infrastructure/deployment/PAConnectorIaasGateway.java b/src/main/java/org/activeeon/morphemic/infrastructure/deployment/PAConnectorIaasGateway.java index 2d1dce9aba0ba9d0b651ee76590fcfc246046bb4..db93ef5d74ccbd78079926b6c541f957f46a6153 100644 --- a/src/main/java/org/activeeon/morphemic/infrastructure/deployment/PAConnectorIaasGateway.java +++ b/src/main/java/org/activeeon/morphemic/infrastructure/deployment/PAConnectorIaasGateway.java @@ -2,6 +2,7 @@ package org.activeeon.morphemic.infrastructure.deployment; import lombok.SneakyThrows; import org.activeeon.morphemic.model.Credentials; +import org.activeeon.morphemic.model.PACloud; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.Validate; import org.apache.http.client.utils.URIBuilder; @@ -128,9 +129,9 @@ public class PAConnectorIaasGateway { } @SneakyThrows - public void defineInfrastructure(String infrastructureName, String cloudProviderName, Credentials credentials, String region) { + public void defineInfrastructure(String infrastructureName, PACloud cloud, String region) { Validate.notNull(infrastructureName, "infrastructureName must not be null"); - Validate.notNull(cloudProviderName, "cloudProviderName must not be null"); + Validate.notNull(cloud.getCloudProviderName(), "cloudProviderName must not be null"); URIBuilder uriBuilder = new URIBuilder(new URL(paURL).toURI()); URI requestUri = uriBuilder.setPath(CONNECTOR_IAAS_PATH + "/infrastructures").build(); @@ -140,9 +141,26 @@ public class PAConnectorIaasGateway { connection.setRequestProperty("Content-Type", "application/json; utf-8"); connection.setDoOutput(true); - String jsonOutputString = "{\"id\": \"" + infrastructureName + "\"," + - "\"type\": \"" + cloudProviderName + "\"," + - "\"credentials\": {\"username\": \"" + credentials.getUserName() + "\", \"password\": \"" + credentials.getPrivateKey() + "\"}, \"region\": \"" + region + "\"}"; + String jsonOutputString; + switch (cloud.getCloudProviderName()) { + case "aws-ec2": + jsonOutputString = "{\"id\": \"" + infrastructureName + "\"," + + "\"type\": \"" + cloud.getCloudProviderName() + "\"," + + "\"credentials\": {\"username\": \"" + cloud.getCredentials().getUserName() + "\", \"password\": \"" + + cloud.getCredentials().getPrivateKey() + "\"}, \"region\": \"" + region + "\"}"; + break; + case "openstack": + jsonOutputString = "{\"id\": \"" + infrastructureName + "\"," + + "\"type\": \"openstack-nova\", \"endpoint\": \"" + cloud.getEndpoint() + + "\", \"scope\":{\"prefix\": \"" + cloud.getScopePrefix() + "\", \"value\":\"" + + cloud.getScopeValue() + "\"}, \"identityVersion\": \"" + cloud.getIdentityVersion() + "\", " + + "\"credentials\": {\"username\": \"" + cloud.getCredentials().getUserName() + + "\", \"password\": \"" + cloud.getCredentials().getPrivateKey() + "\", \"domain\": \"" + + cloud.getCredentials().getDomain() + "\"}, \"region\": \"" + region + "\"}"; + break; + default: + throw new IllegalArgumentException("The infrastructure " + cloud.getCloudProviderName() + " is not handled yet."); + } try(OutputStream os = connection.getOutputStream()) { byte[] input = jsonOutputString.getBytes("utf-8"); diff --git a/src/main/java/org/activeeon/morphemic/model/Credentials.java b/src/main/java/org/activeeon/morphemic/model/Credentials.java index 2ca1d4d50ea3efae7325acb6fd720c9bbe62d78f..a081ac4ddc0ad0ef90f63e33de897baf3f7cf049 100644 --- a/src/main/java/org/activeeon/morphemic/model/Credentials.java +++ b/src/main/java/org/activeeon/morphemic/model/Credentials.java @@ -29,4 +29,7 @@ public class Credentials implements Serializable { @Column(name = "PUBLIC_KEY") private String publicKey; + + @Column(name = "DOMAIN") + private String domain; } diff --git a/src/main/java/org/activeeon/morphemic/model/PACloud.java b/src/main/java/org/activeeon/morphemic/model/PACloud.java index e9824722a39a5980cbbad7448872f8ef0c2f33c5..93e86f76baaf9942d4215078df431879253fe0fa 100644 --- a/src/main/java/org/activeeon/morphemic/model/PACloud.java +++ b/src/main/java/org/activeeon/morphemic/model/PACloud.java @@ -36,9 +36,27 @@ public class PACloud implements Serializable { @Column(name = "SECURITY_GROUP") private String securityGroup; + @Column(name = "ENDPOINT") + private String endpoint; + + @Column(name = "SCOPE_PREFIX") + private String scopePrefix; + + @Column(name = "SCOPE_VALUE") + private String scopeValue; + + @Column(name = "IDENTITY_VERSION") + private String identityVersion; + @Column(name = "DUMMY_INFRASTRUCTURE_NAME") private String dummyInfrastructureName; + @Column(name = "DEFAULT_NETWORK") + private String defaultNetwork; + + @Column(name = "BLACKLIST") + private String blacklist; + @Column(name = "DEPLOYED_REGIONS") @ElementCollection(targetClass=String.class) private Map deployedRegions; diff --git a/src/main/java/org/activeeon/morphemic/service/GeoLocationUtils.java b/src/main/java/org/activeeon/morphemic/service/GeoLocationUtils.java index dd75248bb19225ffb5a71ffd62a338cf2ae40a60..36712f9d9be5df5905d66e14d85de2f853ae878b 100644 --- a/src/main/java/org/activeeon/morphemic/service/GeoLocationUtils.java +++ b/src/main/java/org/activeeon/morphemic/service/GeoLocationUtils.java @@ -52,6 +52,6 @@ public class GeoLocationUtils { return cloudsGeoLocationData.stream() .filter(cloudGL -> cloud.equals(cloudGL.getCloud()) && region.equals(cloudGL.getRegion())) .findAny() - .orElse(null); + .orElse(new GeoLocationData()); } } diff --git a/src/main/java/org/activeeon/morphemic/service/NodeCandidateUtils.java b/src/main/java/org/activeeon/morphemic/service/NodeCandidateUtils.java index af79dba670e139a9c778bf1581f818782ea3ce6f..9feb5d6f0390df342bae6d0c59b2ca6bee441d14 100644 --- a/src/main/java/org/activeeon/morphemic/service/NodeCandidateUtils.java +++ b/src/main/java/org/activeeon/morphemic/service/NodeCandidateUtils.java @@ -11,6 +11,8 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import java.math.BigDecimal; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class NodeCandidateUtils { @@ -115,7 +117,7 @@ public class NodeCandidateUtils { hardware.setId(hardwareId); hardware.setName(hardwareJSON.optString("type")); hardware.setProviderId(paCloud.getCloudID()); - hardware.setCores(Integer.valueOf(hardwareJSON.optString("minCores"))); + hardware.setCores(Math.round(Float.parseFloat(hardwareJSON.optString("minCores")))); hardware.setRam(Long.valueOf(hardwareJSON.optString("minRam"))); if ("aws-ec2".equals(nodeCandidateJSON.optString("cloud"))) { hardware.setDisk((double) 8); @@ -224,16 +226,28 @@ public class NodeCandidateUtils { newCloudIds.forEach(newCloudId -> { PACloud paCloud = em.find(PACloud.class, newCloudId); + List blacklistedRegions = Arrays.asList(paCloud.getBlacklist().split(",")); JSONArray images = connectorIaasGateway.getImages(paCloud.getDummyInfrastructureName()); + List consolidatedImages = images.toList().parallelStream().map(o -> (JSONObject) o).filter(record -> !blacklistedRegions.contains(record.get("location"))).collect(Collectors.toList()); //TODO: (Optimization) An images per region map structure could be the best here. // It can reduce the getNodeCandidates calls to PA. - images.forEach(img -> { - JSONObject image = (JSONObject) img; + consolidatedImages.forEach(image -> { String region = image.optString("location"); + String imageReq; + switch (paCloud.getCloudProviderName()) { + case "aws-ec2": + imageReq = "Linux"; + break; + case "openstack": + imageReq = "linux"; + break; + default: + throw new IllegalArgumentException("The infrastructure " + paCloud.getCloudProviderName() + " is not handled yet."); + } JSONArray nodeCandidates = connectorIaasGateway.getNodeCandidates(paCloud.getDummyInfrastructureName(), - region, "Linux"); + region, imageReq); nodeCandidates.forEach(nc -> { JSONObject nodeCandidate = (JSONObject) nc; em.persist(createLocation(nodeCandidate, paCloud)); diff --git a/src/main/resources/Define_NS_OS.xml b/src/main/resources/Define_NS_OS.xml new file mode 100644 index 0000000000000000000000000000000000000000..072fc5d8f56863e9e40ba6c19115245385f444cd --- /dev/null +++ b/src/main/resources/Define_NS_OS.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 142.13333129882812 + + + 351.5 + + + + + + + + + + + + + + + + ]]> + + + \ No newline at end of file