Repository: airavata Updated Branches: refs/heads/AIRAVATA-2500 c5452426b -> d2ac74936
AIRAVATA-2500 Implement doesUserHaveSSHAccount and setup SSH account methods in API Project: http://git-wip-us.apache.org/repos/asf/airavata/repo Commit: http://git-wip-us.apache.org/repos/asf/airavata/commit/d2ac7493 Tree: http://git-wip-us.apache.org/repos/asf/airavata/tree/d2ac7493 Diff: http://git-wip-us.apache.org/repos/asf/airavata/diff/d2ac7493 Branch: refs/heads/AIRAVATA-2500 Commit: d2ac74936762fc11d1a625b2d1d29bb5db8979e8 Parents: c545242 Author: Marcus Christie <[email protected]> Authored: Thu Aug 31 09:16:03 2017 -0400 Committer: Marcus Christie <[email protected]> Committed: Thu Aug 31 09:16:03 2017 -0400 ---------------------------------------------------------------------- airavata-api/airavata-api-server/pom.xml | 5 ++ .../server/handler/AiravataServerHandler.java | 55 ++++++++++++++++++++ .../accountprovisioning/SSHAccountManager.java | 42 ++++++++++++--- .../SSHAccountProvisionerProvider.java | 1 + .../airavata-apis/airavata_api.thrift | 24 ++++++++- .../account_provisioning_model.thrift | 2 + 6 files changed, 122 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/airavata/blob/d2ac7493/airavata-api/airavata-api-server/pom.xml ---------------------------------------------------------------------- diff --git a/airavata-api/airavata-api-server/pom.xml b/airavata-api/airavata-api-server/pom.xml index ada0b8f..a4d10af 100644 --- a/airavata-api/airavata-api-server/pom.xml +++ b/airavata-api/airavata-api-server/pom.xml @@ -93,6 +93,11 @@ <artifactId>services-security</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.airavata</groupId> + <artifactId>compute-account-provisioning</artifactId> + <version>${project.version}</version> + </dependency> <!--<dependency>--> <!--<groupId>org.apache.airavata</groupId>--> <!--<artifactId>group-manager</artifactId>--> http://git-wip-us.apache.org/repos/asf/airavata/blob/d2ac7493/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java ---------------------------------------------------------------------- diff --git a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java index 4ae91ea..bb3f2c0 100644 --- a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java +++ b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java @@ -19,6 +19,7 @@ */ package org.apache.airavata.api.server.handler; +import org.apache.airavata.accountprovisioning.SSHAccountManager; import org.apache.airavata.api.Airavata; import org.apache.airavata.api.airavata_apiConstants; import org.apache.airavata.api.server.util.ThriftClientPool; @@ -35,6 +36,8 @@ import org.apache.airavata.messaging.core.MessagingFactory; import org.apache.airavata.messaging.core.Publisher; import org.apache.airavata.messaging.core.Type; import org.apache.airavata.model.WorkflowModel; +import org.apache.airavata.model.appcatalog.accountprovisioning.SSHAccountProvisioner; +import org.apache.airavata.model.appcatalog.accountprovisioning.SSHAccountProvisionerConfigParam; import org.apache.airavata.model.appcatalog.appdeployment.ApplicationDeploymentDescription; import org.apache.airavata.model.appcatalog.appdeployment.ApplicationModule; import org.apache.airavata.model.appcatalog.appinterface.ApplicationInterfaceDescription; @@ -3964,6 +3967,58 @@ public class AiravataServerHandler implements Airavata.Iface { } } + @Override + @SecurityCheck + public List<SSHAccountProvisioner> getSSHAccountProvisionerNames(AuthzToken authzToken) throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException { + + // TODO: implement + return null; + } + + @Override + @SecurityCheck + public List<SSHAccountProvisionerConfigParam> getSSHAccountProvisionerConfigParams(AuthzToken authzToken, String provisionerName) throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException { + + // TODO: implement + return null; + } + + @Override + @SecurityCheck + public boolean doesUserHaveSSHAccount(AuthzToken authzToken, String computeResourceId, String username) throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException { + String gatewayId = authzToken.getClaimsMap().get(Constants.GATEWAY_ID); + return SSHAccountManager.doesUserHaveSSHAccount(gatewayId, computeResourceId, username); + } + + @Override + @SecurityCheck + public UserComputeResourcePreference setupUserComputeResourcePreferencesForSSH(AuthzToken authzToken, String computeResourceId, String username, String airavataCredStoreToken) throws InvalidRequestException, AiravataClientException, AiravataSystemException, AuthorizationException, TException { + String gatewayId = authzToken.getClaimsMap().get(Constants.GATEWAY_ID); + CredentialStoreService.Client csClient = csClientPool.getResource(); + SSHCredential sshCredential = null; + try { + sshCredential = csClient.getSSHCredential(airavataCredStoreToken, gatewayId); + }catch (Exception e){ + logger.error("Error occurred while retrieving SSH Credential", e); + AiravataSystemException exception = new AiravataSystemException(); + exception.setAiravataErrorType(AiravataErrorType.INTERNAL_ERROR); + exception.setMessage("Error occurred while retrieving SSH Credential. More info : " + e.getMessage()); + csClientPool.returnBrokenResource(csClient); + throw exception; + } + + try { + UserComputeResourcePreference userComputeResourcePreference = SSHAccountManager.setupSSHAccount(gatewayId, computeResourceId, username, sshCredential); + return userComputeResourcePreference; + }catch (Exception e){ + logger.error("Error occurred while automatically setting up SSH account for user [" + username + "]", e); + AiravataSystemException exception = new AiravataSystemException(); + exception.setAiravataErrorType(AiravataErrorType.INTERNAL_ERROR); + exception.setMessage("Error occurred while automatically setting up SSH account for user [" + username + "]. More info : " + e.getMessage()); + throw exception; + } + } + /** * Register a User Resource Profile. * http://git-wip-us.apache.org/repos/asf/airavata/blob/d2ac7493/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java ---------------------------------------------------------------------- diff --git a/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java b/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java index ec7cfc1..f9ed22a 100644 --- a/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java +++ b/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountManager.java @@ -51,6 +51,30 @@ public class SSHAccountManager { private final static Logger logger = LoggerFactory.getLogger(SSHAccountManager.class); + public static boolean doesUserHaveSSHAccount(String gatewayId, String computeResourceId, String username) { + + // get compute resource preferences for the gateway and hostname + RegistryService.Client registryServiceClient = getRegistryServiceClient(); + ComputeResourcePreference computeResourcePreference = null; + try { + computeResourcePreference = registryServiceClient.getGatewayComputeResourcePreference(gatewayId, computeResourceId); + } catch(TException e) { + throw new RuntimeException(e); + } finally { + if (registryServiceClient.getInputProtocol().getTransport().isOpen()) { + registryServiceClient.getInputProtocol().getTransport().close(); + } + } + + // get the account provisioner and config values for the preferences + if (!computeResourcePreference.isSetSshAccountProvisioner()) { + throw new RuntimeException("Compute resource [" + computeResourceId + "] does not have an SSH Account Provisioner configured for it."); + } + SSHAccountProvisioner sshAccountProvisioner = createSshAccountProvisioner(gatewayId, computeResourcePreference); + + return sshAccountProvisioner.hasAccount(username); + } + public static UserComputeResourcePreference setupSSHAccount(String gatewayId, String computeResourceId, String username, SSHCredential sshCredential) { // get compute resource preferences for the gateway and hostname @@ -84,19 +108,15 @@ public class SSHAccountManager { if (!computeResourcePreference.isSetSshAccountProvisioner()) { throw new RuntimeException("Compute resource [" + computeResourceId + "] does not have an SSH Account Provisioner configured for it."); } - String provisionerName = computeResourcePreference.getSshAccountProvisioner(); - Map<ConfigParam,String> provisionerConfig = convertConfigParams(provisionerName, computeResourcePreference.getSshAccountProvisionerConfig()); - - Map<ConfigParam, String> resolvedConfig = resolveProvisionerConfig(gatewayId, provisionerName, provisionerConfig); // instantiate and init the account provisioner - SSHAccountProvisioner sshAccountProvisioner = SSHAccountProvisionerFactory.createSSHAccountProvisioner(provisionerName, resolvedConfig); + SSHAccountProvisioner sshAccountProvisioner = createSshAccountProvisioner(gatewayId, computeResourcePreference); // First check if username has an account boolean hasAccount = sshAccountProvisioner.hasAccount(username); if (!hasAccount && !sshAccountProvisioner.canCreateAccount()) { - throw new RuntimeException("User [" + username + "] doesn't have account and [" + provisionerName + "] doesn't support creating account."); + throw new RuntimeException("User [" + username + "] doesn't have account and [" + computeResourceId + "] doesn't have a SSH Account Provisioner that supports creating accounts."); } // Install SSH key @@ -123,6 +143,16 @@ public class SSHAccountManager { return userComputeResourcePreference; } + private static SSHAccountProvisioner createSshAccountProvisioner(String gatewayId, ComputeResourcePreference computeResourcePreference) { + String provisionerName = computeResourcePreference.getSshAccountProvisioner(); + Map<ConfigParam,String> provisionerConfig = convertConfigParams(provisionerName, computeResourcePreference.getSshAccountProvisionerConfig()); + + Map<ConfigParam, String> resolvedConfig = resolveProvisionerConfig(gatewayId, provisionerName, provisionerConfig); + + // instantiate and init the account provisioner + return SSHAccountProvisionerFactory.createSSHAccountProvisioner(provisionerName, resolvedConfig); + } + private static Map<ConfigParam, String> resolveProvisionerConfig(String gatewayId, String provisionerName, Map<ConfigParam, String> provisionerConfig) { CredentialStoreService.Client credentialStoreServiceClient = null; try { http://git-wip-us.apache.org/repos/asf/airavata/blob/d2ac7493/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountProvisionerProvider.java ---------------------------------------------------------------------- diff --git a/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountProvisionerProvider.java b/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountProvisionerProvider.java index 42f2794..a43a022 100644 --- a/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountProvisionerProvider.java +++ b/modules/compute-account-provisioning/src/main/java/org/apache/airavata/accountprovisioning/SSHAccountProvisionerProvider.java @@ -34,4 +34,5 @@ public interface SSHAccountProvisionerProvider { } List<ConfigParam> getConfigParams(); SSHAccountProvisioner createSSHAccountProvisioner(Map<ConfigParam,String> config); + // TODO: should canCreateAccount and canInstallSSHKey move here? All metadata about provisioner could be on this class } http://git-wip-us.apache.org/repos/asf/airavata/blob/d2ac7493/thrift-interface-descriptions/airavata-apis/airavata_api.thrift ---------------------------------------------------------------------- diff --git a/thrift-interface-descriptions/airavata-apis/airavata_api.thrift b/thrift-interface-descriptions/airavata-apis/airavata_api.thrift index 471af41..e06c234 100644 --- a/thrift-interface-descriptions/airavata-apis/airavata_api.thrift +++ b/thrift-interface-descriptions/airavata-apis/airavata_api.thrift @@ -2950,7 +2950,7 @@ service Airavata { 3: airavata_errors.AiravataSystemException ase, 4: airavata_errors.AuthorizationException ae) - list<string> getSSHAccountProvisionerNames(1: required security_model.AuthzToken authzToken) + list<account_provisioning_model.SSHAccountProvisioner> getSSHAccountProvisionerNames(1: required security_model.AuthzToken authzToken) throws (1: airavata_errors.InvalidRequestException ire, 2: airavata_errors.AiravataClientException ace, 3: airavata_errors.AiravataSystemException ase, @@ -2962,6 +2962,28 @@ service Airavata { 3: airavata_errors.AiravataSystemException ase, 4: airavata_errors.AuthorizationException ae) + /** + * Check if user has an SSH account on the given compute resource. This + * method will only work if the compute resource has an SSHAccountProvisioner configured for it. + */ + bool doesUserHaveSSHAccount(1: required security_model.AuthzToken authzToken, 2: required string computeResourceId, 3: required string username) + throws (1: airavata_errors.InvalidRequestException ire, + 2: airavata_errors.AiravataClientException ace, + 3: airavata_errors.AiravataSystemException ase, + 4: airavata_errors.AuthorizationException ae) + + /** + * Setup and return a UserComputeResourcePreference object for this user to SSH into the given compute resource with + * the given SSH credential. This method will only work if the compute resource has an SSHAccountProvisioner + * configured for it. The returned UserComputeResourcePreference object is not saved; it is up to the client to + * call addUserComputeResourcePreference to persist it. + */ + user_resource_profile_model.UserComputeResourcePreference setupUserComputeResourcePreferencesForSSH(1: required security_model.AuthzToken authzToken, + 2: required string computeResourceId, 3: required string username, 4: required string airavataCredStoreToken) + throws (1: airavata_errors.InvalidRequestException ire, + 2: airavata_errors.AiravataClientException ace, + 3: airavata_errors.AiravataSystemException ase, + 4: airavata_errors.AuthorizationException ae) /* * User Resource Profile http://git-wip-us.apache.org/repos/asf/airavata/blob/d2ac7493/thrift-interface-descriptions/data-models/resource-catalog-models/account_provisioning_model.thrift ---------------------------------------------------------------------- diff --git a/thrift-interface-descriptions/data-models/resource-catalog-models/account_provisioning_model.thrift b/thrift-interface-descriptions/data-models/resource-catalog-models/account_provisioning_model.thrift index a6c6ab9..245d295 100644 --- a/thrift-interface-descriptions/data-models/resource-catalog-models/account_provisioning_model.thrift +++ b/thrift-interface-descriptions/data-models/resource-catalog-models/account_provisioning_model.thrift @@ -30,6 +30,8 @@ enum SSHAccountProvisionerConfigParamType { struct SSHAccountProvisioner { 1: required string name; + 2: required bool canCreateAccount; + 3: required bool canInstallSSHKey; } struct SSHAccountProvisionerConfigParam {
