Add Keystone V3 Support
update JEL with explicit getVariable call
set project object into scope object
add camunda properties as defaults in application.yaml
added exception handling to keystone v3 case
added in password method to identity object
initial commit of keystone v3 auth support
updated json property values with "_name"
added new columns to cloud identity
Change-Id: Ie08e9893c34d7199197efdb21fe4dd5413b25f44
Issue-ID: SO-1225
Signed-off-by: Benjamin, Max (mb388a) <mb388a@us.att.com>
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java
index 1912cd8..49c80b4 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/AuthenticationMethodFactory.java
@@ -20,14 +20,22 @@
package org.onap.so.cloud.authentication;
+import java.util.Collections;
+
+import org.onap.so.cloud.authentication.models.RackspaceAuthentication;
import org.onap.so.db.catalog.beans.AuthenticationType;
import org.onap.so.db.catalog.beans.CloudIdentity;
-import org.onap.so.cloud.authentication.models.RackspaceAuthentication;
import org.onap.so.utils.CryptoUtils;
import org.springframework.stereotype.Component;
import com.woorea.openstack.keystone.model.Authentication;
import com.woorea.openstack.keystone.model.authentication.UsernamePassword;
+import com.woorea.openstack.keystone.v3.model.Authentication.Identity;
+import com.woorea.openstack.keystone.v3.model.Authentication.Identity.Password;
+import com.woorea.openstack.keystone.v3.model.Authentication.Identity.Password.User;
+import com.woorea.openstack.keystone.v3.model.Authentication.Identity.Password.User.Domain;
+import com.woorea.openstack.keystone.v3.model.Authentication.Scope;
+import com.woorea.openstack.keystone.v3.model.Authentication.Scope.Project;
/**
* This factory manages all the wrappers associated to authentication types.
@@ -50,4 +58,30 @@
return new UsernamePassword (cloudIdentity.getMsoId (), CryptoUtils.decryptCloudConfigPassword(cloudIdentity.getMsoPass ()));
}
}
+
+
+ public final com.woorea.openstack.keystone.v3.model.Authentication getAuthenticationForV3(CloudIdentity cloudIdentity, String tenantId) {
+ Identity identity = new Identity();
+ Password password = new Password();
+ User user = new User();
+ Domain userDomain = new Domain();
+ Scope scope = new Scope();
+ Project project = new Project();
+ Project.Domain projectDomain = new Project.Domain();
+ userDomain.setName(cloudIdentity.getUserDomainName());
+ projectDomain.setName(cloudIdentity.getProjectDomainName());
+ user.setName(cloudIdentity.getMsoId());
+ user.setPassword(CryptoUtils.decryptCloudConfigPassword(cloudIdentity.getMsoPass()));
+ user.setDomain(userDomain);
+ password.setUser(user);
+ project.setDomain(projectDomain);
+ project.setId(tenantId);
+ scope.setProject(project);
+ identity.setPassword(password);
+ identity.setMethods(Collections.singletonList("password"));
+ com.woorea.openstack.keystone.v3.model.Authentication v3Auth = new com.woorea.openstack.keystone.v3.model.Authentication();
+ v3Auth.setIdentity(identity);
+ v3Auth.setScope(scope);
+ return v3Auth;
+ }
}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneAuthHolder.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneAuthHolder.java
new file mode 100644
index 0000000..1a221a8
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneAuthHolder.java
@@ -0,0 +1,32 @@
+package org.onap.so.cloud.authentication;
+
+import java.io.Serializable;
+import java.util.Calendar;
+
+public class KeystoneAuthHolder implements Serializable {
+
+ private static final long serialVersionUID = -9073252905181739224L;
+
+ private String id;
+ private Calendar expiration;
+ private String serviceUrl;
+
+ public String getId() {
+ return id;
+ }
+ public void setId(String id) {
+ this.id = id;
+ }
+ public Calendar getexpiration() {
+ return expiration;
+ }
+ public void setexpiration(Calendar expiration) {
+ this.expiration = expiration;
+ }
+ public String getServiceUrl() {
+ return serviceUrl;
+ }
+ public void setHeatUrl(String serviceUrl) {
+ this.serviceUrl = serviceUrl;
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java
new file mode 100644
index 0000000..05364d0
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/KeystoneV3Authentication.java
@@ -0,0 +1,113 @@
+package org.onap.so.cloud.authentication;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Predicate;
+
+import org.onap.so.config.beans.PoConfig;
+import org.onap.so.db.catalog.beans.CloudIdentity;
+import org.onap.so.db.catalog.beans.CloudSite;
+import org.onap.so.openstack.exceptions.MsoException;
+import org.onap.so.openstack.utils.MsoTenantUtils;
+import org.onap.so.openstack.utils.MsoTenantUtilsFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.woorea.openstack.base.client.OpenStackConnectException;
+import com.woorea.openstack.base.client.OpenStackRequest;
+import com.woorea.openstack.base.client.OpenStackResponse;
+import com.woorea.openstack.base.client.OpenStackResponseException;
+import com.woorea.openstack.keystone.v3.Keystone;
+import com.woorea.openstack.keystone.v3.model.Authentication;
+import com.woorea.openstack.keystone.v3.model.Token;
+import com.woorea.openstack.keystone.v3.model.Token.Service;
+
+import net.jodah.failsafe.Failsafe;
+import net.jodah.failsafe.RetryPolicy;
+
+
+@Component
+public class KeystoneV3Authentication {
+
+ @Autowired
+ private AuthenticationMethodFactory authenticationMethodFactory;
+
+ @Autowired
+ private MsoTenantUtilsFactory tenantUtilsFactory;
+
+ @Autowired
+ private PoConfig poConfig;
+
+ public KeystoneAuthHolder getToken(CloudSite cloudSite, String tenantId, String type) throws MsoException {
+
+ String cloudId = cloudSite.getId();
+ String region = cloudSite.getRegionId();
+
+ CloudIdentity cloudIdentity = cloudSite.getIdentityService();
+ MsoTenantUtils tenantUtils = tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType());
+ String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity);
+ Keystone keystoneTenantClient = new Keystone (keystoneUrl);
+ Authentication v3Credentials = authenticationMethodFactory.getAuthenticationForV3(cloudIdentity, tenantId);
+
+
+ OpenStackRequest<Token> v3Request = keystoneTenantClient.tokens ()
+ .authenticate(v3Credentials);
+
+ KeystoneAuthHolder holder = makeRequest(v3Request, type, region);
+
+ return holder;
+ }
+
+ protected KeystoneAuthHolder makeRequest(OpenStackRequest<Token> v3Request, String type, String region) {
+
+ OpenStackResponse response = Failsafe.with(createRetryPolicy()).get(() -> {
+ return v3Request.request();
+ });
+ String id = response.header("X-Subject-Token");
+ Token token = response.getEntity(Token.class);
+ KeystoneAuthHolder result = new KeystoneAuthHolder();
+ result.setId(id);
+ result.setexpiration(token.getExpiresAt());
+ result.setHeatUrl(findEndpointURL(token.getCatalog(), type, region, "public"));
+ return result;
+ }
+
+ protected RetryPolicy createRetryPolicy() {
+ RetryPolicy policy = new RetryPolicy();
+ List<Predicate<Throwable>> result = new ArrayList<>();
+ result.add(e -> {
+ return e.getCause() instanceof OpenStackResponseException
+ && Arrays.asList(poConfig.getRetryCodes().split(","))
+ .contains(Integer.toString(((OpenStackResponseException)e).getStatus()));
+ });
+ result.add(e -> {
+ return e.getCause() instanceof OpenStackConnectException;
+ });
+
+ Predicate<Throwable> pred = result.stream().reduce(Predicate::or).orElse(x -> false);
+
+ policy.retryOn(error -> pred.test(error));
+
+ policy.withDelay(poConfig.getRetryDelay(), TimeUnit.SECONDS)
+ .withMaxRetries(poConfig.getRetryCount());
+
+ return policy;
+ }
+
+ protected String findEndpointURL(List<Service> serviceCatalog, String type, String region, String facing) {
+ for(Service service : serviceCatalog) {
+ if(type.equals(service.getType())) {
+ for(Service.Endpoint endpoint : service.getEndpoints()) {
+ if(region == null || region.equals(endpoint.getRegion())) {
+ if(facing.equals(endpoint.getInterface())) {
+ return endpoint.getUrl();
+ }
+ }
+ }
+ }
+ }
+ throw new ServiceEndpointNotFoundException("endpoint url not found");
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/ServiceEndpointNotFoundException.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/ServiceEndpointNotFoundException.java
new file mode 100644
index 0000000..3bc57a8
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/cloud/authentication/ServiceEndpointNotFoundException.java
@@ -0,0 +1,10 @@
+package org.onap.so.cloud.authentication;
+
+public class ServiceEndpointNotFoundException extends RuntimeException {
+
+ private static final long serialVersionUID = -5347215451284361397L;
+
+ public ServiceEndpointNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
index e36d0ff..d87330b 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -41,11 +42,15 @@
import org.onap.so.adapters.vdu.VduStateType;
import org.onap.so.adapters.vdu.VduStatus;
import org.onap.so.cloud.CloudConfig;
+import org.onap.so.cloud.authentication.AuthenticationMethodFactory;
+import org.onap.so.cloud.authentication.KeystoneAuthHolder;
+import org.onap.so.cloud.authentication.KeystoneV3Authentication;
+import org.onap.so.cloud.authentication.ServiceEndpointNotFoundException;
import org.onap.so.db.catalog.beans.CloudIdentity;
import org.onap.so.db.catalog.beans.CloudSite;
-import org.onap.so.cloud.authentication.AuthenticationMethodFactory;
import org.onap.so.db.catalog.beans.HeatTemplate;
import org.onap.so.db.catalog.beans.HeatTemplateParam;
+import org.onap.so.db.catalog.beans.ServerType;
import org.onap.so.logger.MessageEnum;
import org.onap.so.logger.MsoAlarmLogger;
import org.onap.so.logger.MsoLogger;
@@ -115,7 +120,10 @@
@Autowired
private MsoTenantUtilsFactory tenantUtilsFactory;
-
+
+ @Autowired
+ private KeystoneV3Authentication keystoneV3Authentication;
+
private static final MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA, MsoHeatUtils.class);
// Properties names and variables (with default values)
@@ -875,7 +883,9 @@
*/
public Heat getHeatClient (CloudSite cloudSite, String tenantId) throws MsoException {
String cloudId = cloudSite.getId();
-
+ // For DCP/LCP, the region should be the cloudId.
+ String region = cloudSite.getRegionId ();
+
// Check first in the cache of previously authorized clients
String cacheKey = cloudId + ":" + tenantId;
if (heatClientCache.containsKey (cacheKey)) {
@@ -895,16 +905,58 @@
MsoTenantUtils tenantUtils = tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType());
String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity);
LOGGER.debug("keystoneUrl=" + keystoneUrl);
- Keystone keystoneTenantClient = new Keystone (keystoneUrl);
- Access access = null;
- try {
- Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
-
- OpenStackRequest <Access> request = keystoneTenantClient.tokens ()
- .authenticate (credentials).withTenantId (tenantId);
-
- access = executeAndRecordOpenstackRequest (request);
- } catch (OpenStackResponseException e) {
+ String heatUrl = null;
+ String tokenId = null;
+ Calendar expiration = null;
+ try {
+ if (ServerType.KEYSTONE.equals(cloudIdentity.getIdentityServerType())) {
+ Keystone keystoneTenantClient = new Keystone (keystoneUrl);
+ Access access = null;
+
+ Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
+
+ OpenStackRequest <Access> request = keystoneTenantClient.tokens ()
+ .authenticate (credentials).withTenantId (tenantId);
+
+ access = executeAndRecordOpenstackRequest (request);
+
+ try {
+ // Isolate trying to printout the region IDs
+ try {
+ LOGGER.debug("access=" + access.toString());
+ for (Access.Service service : access.getServiceCatalog()) {
+ List<Access.Service.Endpoint> endpoints = service.getEndpoints();
+ for (Access.Service.Endpoint endpoint : endpoints) {
+ LOGGER.debug("AIC returned region=" + endpoint.getRegion());
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.debug("Encountered an error trying to printout Access object returned from AIC. " + e.getMessage());
+ }
+ heatUrl = KeystoneUtils.findEndpointURL (access.getServiceCatalog (), "orchestration", region, "public");
+ LOGGER.debug("heatUrl=" + heatUrl + ", region=" + region);
+ } catch (RuntimeException e) {
+ // This comes back for not found (probably an incorrect region ID)
+ String error = "AIC did not match an orchestration service for: region=" + region + ",cloud=" + cloudIdentity.getIdentityUrl();
+ alarmLogger.sendAlarm ("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error);
+ throw new MsoAdapterException (error, e);
+ }
+ tokenId = access.getToken ().getId ();
+ expiration = access.getToken ().getExpires ();
+ } else if (ServerType.KEYSTONE_V3.equals(cloudIdentity.getIdentityServerType())) {
+ try {
+ KeystoneAuthHolder holder = keystoneV3Authentication.getToken(cloudSite, tenantId, "orchestration");
+ tokenId = holder.getId();
+ expiration = holder.getexpiration();
+ heatUrl = holder.getServiceUrl();
+ } catch (ServiceEndpointNotFoundException e) {
+ // This comes back for not found (probably an incorrect region ID)
+ String error = "cloud did not match an orchestration service for: region=" + region + ",cloud=" + cloudIdentity.getIdentityUrl();
+ alarmLogger.sendAlarm ("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error);
+ throw new MsoAdapterException (error, e);
+ }
+ }
+ } catch (OpenStackResponseException e) {
if (e.getStatus () == 401) {
// Authentication error.
String error = "Authentication Failure: tenant=" + tenantId + ",cloud=" + cloudIdentity.getId ();
@@ -922,39 +974,13 @@
// Catch-all
throw runtimeExceptionToMsoException (e, TOKEN_AUTH);
}
-
- // For DCP/LCP, the region should be the cloudId.
- String region = cloudSite.getRegionId ();
- String heatUrl = null;
- try {
- // Isolate trying to printout the region IDs
- try {
- LOGGER.debug("access=" + access.toString());
- for (Access.Service service : access.getServiceCatalog()) {
- List<Access.Service.Endpoint> endpoints = service.getEndpoints();
- for (Access.Service.Endpoint endpoint : endpoints) {
- LOGGER.debug("AIC returned region=" + endpoint.getRegion());
- }
- }
- } catch (Exception e) {
- LOGGER.debug("Encountered an error trying to printout Access object returned from AIC. " + e.getMessage());
- }
- heatUrl = KeystoneUtils.findEndpointURL (access.getServiceCatalog (), "orchestration", region, "public");
- LOGGER.debug("heatUrl=" + heatUrl + ", region=" + region);
- } catch (RuntimeException e) {
- // This comes back for not found (probably an incorrect region ID)
- String error = "AIC did not match an orchestration service for: region=" + region + ",cloud=" + cloudIdentity.getIdentityUrl();
- alarmLogger.sendAlarm ("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error);
- throw new MsoAdapterException (error, e);
- }
-
Heat heatClient = new Heat (heatUrl);
- heatClient.token (access.getToken ().getId ());
+ heatClient.token (tokenId);
heatClientCache.put (cacheKey,
new HeatCacheEntry (heatUrl,
- access.getToken ().getId (),
- access.getToken ().getExpires ()));
+ tokenId,
+ expiration));
LOGGER.debug ("Caching HEAT Client for " + cacheKey);
return heatClient;
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoKeystoneV3Utils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoKeystoneV3Utils.java
new file mode 100644
index 0000000..da1957f
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoKeystoneV3Utils.java
@@ -0,0 +1,41 @@
+package org.onap.so.openstack.utils;
+
+import java.util.Map;
+
+import org.onap.so.db.catalog.beans.CloudIdentity;
+import org.onap.so.openstack.beans.MsoTenant;
+import org.onap.so.openstack.exceptions.MsoCloudSiteNotFound;
+import org.onap.so.openstack.exceptions.MsoException;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MsoKeystoneV3Utils extends MsoTenantUtils {
+
+ @Override
+ public String createTenant(String tenantName, String cloudSiteId, Map<String, String> metadata, boolean backout)
+ throws MsoException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public MsoTenant queryTenant(String tenantId, String cloudSiteId) throws MsoException, MsoCloudSiteNotFound {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public MsoTenant queryTenantByName(String tenantName, String cloudSiteId)
+ throws MsoException, MsoCloudSiteNotFound {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean deleteTenant(String tenantId, String cloudSiteId) throws MsoException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getKeystoneUrl(String regionId, CloudIdentity cloudIdentity) throws MsoException {
+ return cloudIdentity.getIdentityUrl();
+ }
+
+}
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoNeutronUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoNeutronUtils.java
index a9f0a39..b7676e0 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoNeutronUtils.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoNeutronUtils.java
@@ -22,14 +22,19 @@
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.onap.so.cloud.CloudConfig;
+import org.onap.so.cloud.authentication.AuthenticationMethodFactory;
+import org.onap.so.cloud.authentication.KeystoneAuthHolder;
+import org.onap.so.cloud.authentication.KeystoneV3Authentication;
+import org.onap.so.cloud.authentication.ServiceEndpointNotFoundException;
import org.onap.so.db.catalog.beans.CloudIdentity;
import org.onap.so.db.catalog.beans.CloudSite;
-import org.onap.so.cloud.authentication.AuthenticationMethodFactory;
+import org.onap.so.db.catalog.beans.ServerType;
import org.onap.so.logger.MessageEnum;
import org.onap.so.logger.MsoAlarmLogger;
import org.onap.so.logger.MsoLogger;
@@ -78,6 +83,9 @@
@Autowired
private MsoTenantUtilsFactory tenantUtilsFactory;
+
+ @Autowired
+ private KeystoneV3Authentication keystoneV3Authentication;
private static MsoLogger LOGGER = MsoLogger.getMsoLogger (MsoLogger.Catalog.RA, MsoNeutronUtils.class);
@@ -356,7 +364,8 @@
private Quantum getNeutronClient(CloudSite cloudSite, String tenantId) throws MsoException
{
String cloudId = cloudSite.getId();
-
+ String region = cloudSite.getRegionId();
+
// Check first in the cache of previously authorized clients
String cacheKey = cloudId + ":" + tenantId;
if (neutronClientCache.containsKey(cacheKey)) {
@@ -378,12 +387,48 @@
CloudIdentity cloudIdentity = cloudSite.getIdentityService();
MsoTenantUtils tenantUtils = tenantUtilsFactory.getTenantUtilsByServerType(cloudIdentity.getIdentityServerType());
final String keystoneUrl = tenantUtils.getKeystoneUrl(cloudId, cloudIdentity);
- Keystone keystoneTenantClient = new Keystone(keystoneUrl);
- Access access = null;
+ String neutronUrl = null;
+ String tokenId = null;
+ Calendar expiration = null;
try {
- Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
- OpenStackRequest<Access> request = keystoneTenantClient.tokens().authenticate(credentials).withTenantId(tenantId);
- access = executeAndRecordOpenstackRequest(request);
+ if (ServerType.KEYSTONE.equals(cloudIdentity.getIdentityServerType())) {
+ Keystone keystoneTenantClient = new Keystone(keystoneUrl);
+ Access access = null;
+
+ Authentication credentials = authenticationMethodFactory.getAuthenticationFor(cloudIdentity);
+ OpenStackRequest<Access> request = keystoneTenantClient.tokens().authenticate(credentials).withTenantId(tenantId);
+ access = executeAndRecordOpenstackRequest(request);
+
+
+ try {
+ neutronUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "network", region, "public");
+ if (! neutronUrl.endsWith("/")) {
+ neutronUrl += "/v2.0/";
+ }
+ } catch (RuntimeException e) {
+ // This comes back for not found (probably an incorrect region ID)
+ String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
+ alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error);
+ throw new MsoAdapterException (error, e);
+ }
+ tokenId = access.getToken().getId();
+ expiration = access.getToken().getExpires();
+ } else if (ServerType.KEYSTONE_V3.equals(cloudIdentity.getIdentityServerType())) {
+ try {
+ KeystoneAuthHolder holder = keystoneV3Authentication.getToken(cloudSite, tenantId, "network");
+ tokenId = holder.getId();
+ expiration = holder.getexpiration();
+ neutronUrl = holder.getServiceUrl();
+ if (! neutronUrl.endsWith("/")) {
+ neutronUrl += "/v2.0/";
+ }
+ } catch (ServiceEndpointNotFoundException e) {
+ // This comes back for not found (probably an incorrect region ID)
+ String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
+ alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error);
+ throw new MsoAdapterException (error, e);
+ }
+ }
}
catch (OpenStackResponseException e) {
if (e.getStatus() == 401) {
@@ -408,25 +453,10 @@
MsoException me = runtimeExceptionToMsoException(e, "TokenAuth");
throw me;
}
-
- String region = cloudSite.getRegionId();
- String neutronUrl = null;
- try {
- neutronUrl = KeystoneUtils.findEndpointURL(access.getServiceCatalog(), "network", region, "public");
- if (! neutronUrl.endsWith("/")) {
- neutronUrl += "/v2.0/";
- }
- } catch (RuntimeException e) {
- // This comes back for not found (probably an incorrect region ID)
- String error = "Network service not found: region=" + region + ",cloud=" + cloudIdentity.getId();
- alarmLogger.sendAlarm("MsoConfigurationError", MsoAlarmLogger.CRITICAL, error);
- throw new MsoAdapterException (error, e);
- }
-
Quantum neutronClient = new Quantum(neutronUrl);
- neutronClient.token(access.getToken().getId());
+ neutronClient.token(tokenId);
- neutronClientCache.put(cacheKey, new NeutronCacheEntry(neutronUrl, access.getToken().getId(), access.getToken().getExpires()));
+ neutronClientCache.put(cacheKey, new NeutronCacheEntry(neutronUrl, tokenId, expiration));
LOGGER.debug ("Caching Neutron Client for " + cacheKey);
return neutronClient;
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoTenantUtilsFactory.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoTenantUtilsFactory.java
index 79934cc..08c98f3 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoTenantUtilsFactory.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoTenantUtilsFactory.java
@@ -36,6 +36,8 @@
protected CloudConfig cloudConfig;
@Autowired
protected MsoKeystoneUtils keystoneUtils;
+ @Autowired
+ protected MsoKeystoneV3Utils keystoneV3Utils;
// based on Cloud IdentityServerType returns ORM or KEYSTONE Utils
public MsoTenantUtils getTenantUtils(String cloudSiteId) throws MsoCloudSiteNotFound {
@@ -50,6 +52,8 @@
MsoTenantUtils tenantU = null;
if (ServerType.KEYSTONE.equals(serverType)) {
tenantU = keystoneUtils;
+ } else if (ServerType.KEYSTONE_V3.equals(serverType)) {
+ tenantU = keystoneV3Utils;
}
return tenantU;
}
diff --git a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloud/authentication/AuthenticationMethodTest.java b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloud/authentication/AuthenticationMethodTest.java
index 95e4352..a5abe75 100644
--- a/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloud/authentication/AuthenticationMethodTest.java
+++ b/adapters/mso-adapter-utils/src/test/java/org/onap/so/cloud/authentication/AuthenticationMethodTest.java
@@ -20,19 +20,23 @@
package org.onap.so.cloud.authentication;
+import static com.shazam.shazamcrest.matcher.Matchers.sameBeanAs;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.onap.so.BaseTest;
+import org.onap.so.cloud.authentication.models.RackspaceAuthentication;
import org.onap.so.db.catalog.beans.AuthenticationType;
import org.onap.so.db.catalog.beans.CloudIdentity;
-import org.onap.so.cloud.authentication.models.RackspaceAuthentication;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.ActiveProfiles;
-import org.springframework.test.context.junit4.SpringRunner;
+import org.onap.so.utils.CryptoUtils;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import com.woorea.openstack.keystone.model.Authentication;
import com.woorea.openstack.keystone.model.authentication.UsernamePassword;
@@ -42,10 +46,9 @@
* only are tested.
*
*/
-public class AuthenticationMethodTest extends BaseTest {
+public class AuthenticationMethodTest {
- @Autowired
- private AuthenticationMethodFactory authenticationMethodFactory;
+ private AuthenticationMethodFactory authenticationMethodFactory = new AuthenticationMethodFactory();
/**
*
*/
@@ -99,4 +102,20 @@
assertTrue(UsernamePassword.class.equals(auth.getClass()));
}
+
+ @Test
+ public void getAuthenticationForV3Test() throws JsonParseException, JsonMappingException, IOException {
+
+ CloudIdentity identity = new CloudIdentity();
+ identity.setMsoId("my-username");
+ identity.setMsoPass(CryptoUtils.encryptCloudConfigPassword("my-password"));
+ identity.setProjectDomainName("test-domain");
+ identity.setUserDomainName("user-domain");
+ ObjectMapper mapper = new ObjectMapper();
+ com.woorea.openstack.keystone.v3.model.Authentication expected =
+ mapper.readValue(new String(Files.readAllBytes(Paths.get("src/test/resources/__files/KeystoneV3Payload.json"))), com.woorea.openstack.keystone.v3.model.Authentication.class);
+ com.woorea.openstack.keystone.v3.model.Authentication actual = authenticationMethodFactory.getAuthenticationForV3(identity, "project-x");
+
+ assertThat(actual, sameBeanAs(expected));
+ }
}
diff --git a/adapters/mso-adapter-utils/src/test/resources/__files/KeystoneV3Payload.json b/adapters/mso-adapter-utils/src/test/resources/__files/KeystoneV3Payload.json
new file mode 100644
index 0000000..dc6588e
--- /dev/null
+++ b/adapters/mso-adapter-utils/src/test/resources/__files/KeystoneV3Payload.json
@@ -0,0 +1,24 @@
+{
+ "identity": {
+ "methods": [
+ "password"
+ ],
+ "password": {
+ "user": {
+ "domain": {
+ "name": "user-domain"
+ },
+ "name": "my-username",
+ "password": "my-password"
+ }
+ }
+ },
+ "scope": {
+ "project": {
+ "domain": {
+ "name": "test-domain"
+ },
+ "id": "project-x"
+ }
+ }
+}
diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.12.2__AddDomainColumnsCloudIdentity.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.12.2__AddDomainColumnsCloudIdentity.sql
new file mode 100644
index 0000000..e2c4dc8
--- /dev/null
+++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V4.12.2__AddDomainColumnsCloudIdentity.sql
@@ -0,0 +1,3 @@
+ALTER TABLE identity_services
+ADD PROJECT_DOMAIN_NAME VARCHAR(255) DEFAULT NULL,
+ADD USER_DOMAIN_NAME VARCHAR(255) DEFAULT NULL;
diff --git a/adapters/mso-catalog-db-adapter/src/test/resources/db/migration/afterMigrate.sql b/adapters/mso-catalog-db-adapter/src/test/resources/db/migration/afterMigrate.sql
index b4916bd..4d5105d 100644
--- a/adapters/mso-catalog-db-adapter/src/test/resources/db/migration/afterMigrate.sql
+++ b/adapters/mso-catalog-db-adapter/src/test/resources/db/migration/afterMigrate.sql
@@ -4,6 +4,8 @@
`IDENTITY_URL` varchar(200) DEFAULT NULL,
`MSO_ID` varchar(255) DEFAULT NULL,
`MSO_PASS` varchar(255) DEFAULT NULL,
+ `PROJECT_DOMAIN_NAME` varchar(255) DEFAULT NULL,
+ `USER_DOMAIN_NAME` varchar(255) DEFAULT NULL,
`ADMIN_TENANT` varchar(50) DEFAULT NULL,
`MEMBER_ROLE` varchar(50) DEFAULT NULL,
`TENANT_METADATA` tinyint(1) DEFAULT 0,
@@ -193,7 +195,7 @@
INSERT INTO `cloudify_managers` (`ID`, `CLOUDIFY_URL`, `USERNAME`, `PASSWORD`, `VERSION`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('mtn13', 'http://localhost:28090/v2.0', 'm93945', '93937EA01B94A10A49279D4572B48369', NULL, 'MSO_USER', '2018-07-17 14:05:08', '2018-07-17 14:05:08');
-INSERT INTO `identity_services` (`ID`, `IDENTITY_URL`, `MSO_ID`, `MSO_PASS`, `ADMIN_TENANT`, `MEMBER_ROLE`, `TENANT_METADATA`, `IDENTITY_SERVER_TYPE`, `IDENTITY_AUTHENTICATION_TYPE`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('MTN13', 'http://localhost:28090/v2.0', 'm93945', '93937EA01B94A10A49279D4572B48369', 'admin', 'admin', 1, 'KEYSTONE', 'USERNAME_PASSWORD', 'MSO_USER', '2018-07-17 14:02:33', '2018-07-17 14:02:33');
+INSERT INTO `identity_services` (`ID`, `IDENTITY_URL`, `MSO_ID`, `MSO_PASS`, `PROJECT_DOMAIN_NAME`, `USER_DOMAIN_NAME`, `ADMIN_TENANT`, `MEMBER_ROLE`, `TENANT_METADATA`, `IDENTITY_SERVER_TYPE`, `IDENTITY_AUTHENTICATION_TYPE`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('MTN13', 'http://localhost:28090/v2.0', 'm93945', '93937EA01B94A10A49279D4572B48369', NULL, NULL, 'admin', 'admin', 1, 'KEYSTONE', 'USERNAME_PASSWORD', 'MSO_USER', '2018-07-17 14:02:33', '2018-07-17 14:02:33');
INSERT INTO `cloud_sites` (`ID`, `REGION_ID`, `IDENTITY_SERVICE_ID`, `CLOUD_VERSION`, `CLLI`, `CLOUDIFY_ID`, `PLATFORM`, `ORCHESTRATOR`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('mtn13', 'mtn13', 'MTN13', '2.5', 'MDT13', 'mtn13', NULL, 'orchestrator', 'MSO_USER', '2018-07-17 14:06:28', '2018-07-17 14:06:28');
diff --git a/adapters/mso-openstack-adapters/src/test/resources/data.sql b/adapters/mso-openstack-adapters/src/test/resources/data.sql
index 0103564..77df06b 100644
--- a/adapters/mso-openstack-adapters/src/test/resources/data.sql
+++ b/adapters/mso-openstack-adapters/src/test/resources/data.sql
@@ -152,7 +152,7 @@
INSERT INTO `cloudify_managers` (`ID`, `CLOUDIFY_URL`, `USERNAME`, `PASSWORD`, `VERSION`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('mtn13', 'http://localhost:28090/v2.0', 'm93945', '93937EA01B94A10A49279D4572B48369', NULL, 'MSO_USER', '2018-07-17 14:05:08', '2018-07-17 14:05:08');
-INSERT INTO `identity_services` (`ID`, `IDENTITY_URL`, `MSO_ID`, `MSO_PASS`, `ADMIN_TENANT`, `MEMBER_ROLE`, `TENANT_METADATA`, `IDENTITY_SERVER_TYPE`, `IDENTITY_AUTHENTICATION_TYPE`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('MTN13', 'http://localhost:28090/v2.0', 'm939454', '93937EA01B94A10A49279D4572B48369', 'admin', 'admin', 1, 'KEYSTONE', 'USERNAME_PASSWORD', 'MSO_USER', '2018-07-17 14:02:33', '2018-07-17 14:02:33');
+INSERT INTO `identity_services` (`ID`, `IDENTITY_URL`, `MSO_ID`, `MSO_PASS`, `PROJECT_DOMAIN_NAME`, `USER_DOMAIN_NAME`, `ADMIN_TENANT`, `MEMBER_ROLE`, `TENANT_METADATA`, `IDENTITY_SERVER_TYPE`, `IDENTITY_AUTHENTICATION_TYPE`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('MTN13', 'http://localhost:28090/v2.0', 'm939454', '93937EA01B94A10A49279D4572B48369', null, null, 'admin', 'admin', 1, 'KEYSTONE', 'USERNAME_PASSWORD', 'MSO_USER', '2018-07-17 14:02:33', '2018-07-17 14:02:33');
INSERT INTO `cloud_sites` (`ID`, `region_id`, `identity_service_id`, `cloud_version`, `clli`, `cloudify_id`, `platform`, `orchestrator`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('MTN13', 'mtn13', 'MTN13', '3.0', 'MDT13', 'mtn13', null, 'orchestrator', '2018-07-17 14:06:28', '2018-07-17 14:06:28');
diff --git a/adapters/mso-openstack-adapters/src/test/resources/schema.sql b/adapters/mso-openstack-adapters/src/test/resources/schema.sql
index a051417..0c67123 100644
--- a/adapters/mso-openstack-adapters/src/test/resources/schema.sql
+++ b/adapters/mso-openstack-adapters/src/test/resources/schema.sql
@@ -788,6 +788,8 @@
`IDENTITY_URL` varchar(200) DEFAULT NULL,
`MSO_ID` varchar(255) DEFAULT NULL,
`MSO_PASS` varchar(255) DEFAULT NULL,
+ `PROJECT_DOMAIN_NAME` varchar(255) DEFAULT NULL,
+ `USER_DOMAIN_NAME` varchar(255) DEFAULT NULL,
`ADMIN_TENANT` varchar(50) DEFAULT NULL,
`MEMBER_ROLE` varchar(50) DEFAULT NULL,
`TENANT_METADATA` tinyint(1) DEFAULT 0,