From acbaa1049cb47806a1d90a1d39afde31fb910114 Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Tue, 12 Apr 2022 17:59:08 -0600 Subject: [PATCH 1/9] Move to using plugin properties. Configure properties in getVaultClient method as it is called on entry --- .../plugin/vault/VaultStoragePlugin.java | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java index 582dc8d..6678e28 100644 --- a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java +++ b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java @@ -18,6 +18,7 @@ import com.dtolabs.rundeck.core.plugins.configuration.Description; import com.dtolabs.rundeck.core.storage.ResourceMeta; import com.dtolabs.rundeck.plugins.ServiceNameConstants; +import com.dtolabs.rundeck.plugins.descriptions.PluginProperty; import com.dtolabs.rundeck.plugins.storage.StoragePlugin; import org.rundeck.storage.api.Path; import org.rundeck.storage.api.PathUtil; @@ -34,7 +35,7 @@ * @since 2017-09-18 */ @Plugin(name = "vault-storage", service = ServiceNameConstants.Storage) -public class VaultStoragePlugin implements StoragePlugin, Configurable, Describable { +public class VaultStoragePlugin implements StoragePlugin { java.util.logging.Logger log = java.util.logging.Logger.getLogger("vault-storage"); @@ -50,8 +51,6 @@ public VaultStoragePlugin() {} public static final int MAX_GUARANTEED_VALIDITY_SECONDS = 60; - private String vaultPrefix; - private String vaultSecretBackend; private Logical vault; private int guaranteedTokenValidity; //if is true, objects will be saved with rundeck default headers behaivour @@ -59,26 +58,35 @@ public VaultStoragePlugin() {} private VaultClientProvider clientProvider; private Vault vaultClient; + @PluginProperty(title = "vaultPrefix", description = "username for the account to authenticate to") + String vaultPrefix; - @Override - public Description getDescription() { - return DescriptionProvider.getDescription(); - } + @PluginProperty(title = "vaultSecretBackend", description = "password for the account to authenticate to") + String vaultSecretBackend; - @Override - public void configure(Properties configuration) throws ConfigurationException { - vaultPrefix = configuration.getProperty(VAULT_PREFIX); - vaultSecretBackend = configuration.getProperty(VAULT_SECRET_BACKEND); - clientProvider = getVaultClientProvider(configuration); - loginVault(clientProvider); - - //check storage behaivour - String storageBehaviour=configuration.getProperty(VAULT_STORAGE_BEHAVIOUR); - if(storageBehaviour!=null && storageBehaviour.equals("vault")){ - rundeckObject=false; + @PluginProperty(title = "storageBehaviour", description = "storageBehaviour for the account to authenticate to") + String storageBehaviour; + + private Vault getVaultClient() throws ConfigurationException { + //clone former properties configuration passes to configure method + if(vaultClient == null) { + Properties properties = new Properties(); + properties.setProperty(VAULT_PREFIX, vaultPrefix); + properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); + properties.setProperty(VAULT_STORAGE_BEHAVIOUR, storageBehaviour); + + //set member variables on object on entry, lookup -> getVaultClient() + if (storageBehaviour != null && storageBehaviour.equals("vault")) { + rundeckObject = false; + } + + guaranteedTokenValidity = calculateGuaranteedTokenValidity(properties); + + clientProvider = getVaultClientProvider(properties); + vaultClient = clientProvider.getVaultClient(); } + return vaultClient; - guaranteedTokenValidity = calculateGuaranteedTokenValidity(configuration); } protected VaultClientProvider getVaultClientProvider(Properties configuration) { @@ -106,7 +114,7 @@ private boolean isDir(String key) { protected void lookup(){ try { - if (vaultClient.auth().lookupSelf().getTTL() <= guaranteedTokenValidity) { + if (getVaultClient().auth().lookupSelf().getTTL() <= guaranteedTokenValidity) { loginVault(clientProvider); } } catch (VaultException e) { @@ -115,13 +123,14 @@ protected void lookup(){ } else { e.printStackTrace(); } + } catch (ConfigurationException e) { + e.printStackTrace(); } } private void loginVault(VaultClientProvider provider){ try { - vaultClient = provider.getVaultClient(); - vault = vaultClient.logical(); + vault = getVaultClient().logical(); } catch (ConfigurationException e) { e.printStackTrace(); } From d691bc85844eccefc82e3a7a3197a9fd79c4ea70 Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 09:03:52 -0600 Subject: [PATCH 2/9] fix tests --- .../rundeck/plugin/vault/VaultStoragePlugin.java | 4 ++-- .../plugin/vault/VaultStoragePluginTest.java | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java index 6678e28..5cb4e8a 100644 --- a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java +++ b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java @@ -57,6 +57,7 @@ public VaultStoragePlugin() {} private boolean rundeckObject=true; private VaultClientProvider clientProvider; private Vault vaultClient; + Properties properties = new Properties(); @PluginProperty(title = "vaultPrefix", description = "username for the account to authenticate to") String vaultPrefix; @@ -67,10 +68,9 @@ public VaultStoragePlugin() {} @PluginProperty(title = "storageBehaviour", description = "storageBehaviour for the account to authenticate to") String storageBehaviour; - private Vault getVaultClient() throws ConfigurationException { + protected Vault getVaultClient() throws ConfigurationException { //clone former properties configuration passes to configure method if(vaultClient == null) { - Properties properties = new Properties(); properties.setProperty(VAULT_PREFIX, vaultPrefix); properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); properties.setProperty(VAULT_STORAGE_BEHAVIOUR, storageBehaviour); diff --git a/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java b/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java index 72e4f3f..a7ff5a7 100644 --- a/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java +++ b/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java @@ -62,6 +62,7 @@ public void lookUp_passes_when_tokenIsValid() throws ConfigurationException, Vau doReturn(vaultClientProvider).when(vaultStoragePlugin).getVaultClientProvider(properties); doReturn(vault).when(vaultClientProvider).getVaultClient(); + doReturn(vault).when(vaultStoragePlugin).getVaultClient(); doReturn(logical).when(vault).logical(); doReturn(auth).when(vault).auth(); @@ -77,7 +78,6 @@ public void lookUp_passes_when_tokenIsValid() throws ConfigurationException, Vau doReturn("2").when(properties).getProperty(VAULT_OPEN_TIMEOUT); doReturn("1000").when(properties).getProperty(VAULT_RETRY_INTERVAL_MILLISECONDS); - vaultStoragePlugin.configure(properties); clearInvocations(vaultClientProvider); vaultStoragePlugin.lookup(); @@ -107,14 +107,19 @@ public void lookUp_refreshesToken_when_currentTokenIsAboutToExpire() throws Conf doReturn("approle").when(properties).getProperty(VAULT_SECRET_BACKEND); doReturn("vault").when(properties).getProperty(VAULT_STORAGE_BEHAVIOUR); + doReturn("rundeck").when(properties).setProperty(VAULT_PREFIX, "rundeck"); + doReturn("approle").when(properties).setProperty(VAULT_SECRET_BACKEND, "approle"); + doReturn("vault").when(properties).setProperty(VAULT_STORAGE_BEHAVIOUR, "vault"); + doReturn("5").when(properties).getProperty(VAULT_MAX_RETRIES); doReturn("2").when(properties).getProperty(VAULT_READ_TIMEOUT); doReturn("2").when(properties).getProperty(VAULT_OPEN_TIMEOUT); doReturn("1000").when(properties).getProperty(VAULT_RETRY_INTERVAL_MILLISECONDS); - vaultStoragePlugin.configure(properties); clearInvocations(vaultClientProvider); + vaultStoragePlugin.properties=properties; + vaultStoragePlugin.lookup(); verify(vaultClientProvider).getVaultClient(); @@ -140,14 +145,18 @@ public void lookUp_refreshesToken_when_tokenIsExpired() throws ConfigurationExce doReturn("approle").when(properties).getProperty(VAULT_SECRET_BACKEND); doReturn("vault").when(properties).getProperty(VAULT_STORAGE_BEHAVIOUR); + doReturn("rundeck").when(properties).setProperty(VAULT_PREFIX, "rundeck"); + doReturn("approle").when(properties).setProperty(VAULT_SECRET_BACKEND, "approle"); + doReturn("vault").when(properties).setProperty(VAULT_STORAGE_BEHAVIOUR, "vault"); + doReturn("5").when(properties).getProperty(VAULT_MAX_RETRIES); doReturn("2").when(properties).getProperty(VAULT_READ_TIMEOUT); doReturn("2").when(properties).getProperty(VAULT_OPEN_TIMEOUT); doReturn("1000").when(properties).getProperty(VAULT_RETRY_INTERVAL_MILLISECONDS); - vaultStoragePlugin.configure(properties); clearInvocations(vaultClientProvider); + vaultStoragePlugin.properties=properties; vaultStoragePlugin.lookup(); verify(vaultClientProvider).getVaultClient(); From dd612f17f037c847dd506fd55a2dd4f44df6444d Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 09:13:14 -0600 Subject: [PATCH 3/9] fix groovy test --- .../rundeck/plugin/vault/VaultStoragePluginSpec.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/groovy/id/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginSpec.groovy b/src/test/groovy/id/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginSpec.groovy index 50ee637..6a5006b 100644 --- a/src/test/groovy/id/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginSpec.groovy +++ b/src/test/groovy/id/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginSpec.groovy @@ -23,7 +23,7 @@ class VaultStoragePluginSpec extends Specification{ "authBackend":"token", "token":"123456"] def plugin = new VaultStoragePlugin() - plugin.configure(properties) + plugin.properties=properties; Logical vault = Mock(Logical){ list(_)>>Mock(LogicalResponse){ @@ -65,7 +65,7 @@ class VaultStoragePluginSpec extends Specification{ "authBackend":"token", "token":"123456"] def plugin = new VaultStoragePlugin() - plugin.configure(properties) + plugin.properties=properties; Logical vault = Mock(Logical){ list(_)>>Mock(LogicalResponse){ From 4a84da7c1a333935fc2ad98ccd5f7b485f35b84e Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 09:53:29 -0600 Subject: [PATCH 4/9] move description builder to plugin props --- .../plugin/vault/VaultStoragePlugin.java | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java index 5cb4e8a..eacb3a6 100644 --- a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java +++ b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java @@ -65,15 +65,115 @@ public VaultStoragePlugin() {} @PluginProperty(title = "vaultSecretBackend", description = "password for the account to authenticate to") String vaultSecretBackend; + @PluginProperty(title = "Vault address", description = "Address of the Vault server", defaultValue = "https://localhost:8200") + String address; + + @PluginProperty(title = "Vault token", description = "Vault authentication token. " + "Required, if authentication backend is 'token'") + String token; + + @PluginProperty(title = "Vault auth backend", description = "Authentication backend") + String authBackend; + + @PluginProperty(title = "Key store file", description = "A Java keystore, containing a client certificate " + "that's registered with Vault's TLS Certificate auth backend.") + String keyStoreFile; + + @PluginProperty(title = "Key store password", description = "The password needed to access the keystore", defaultValue = "") + String keyStoreFilePassword; + + @PluginProperty(title = "Truststore file", description = "A JKS truststore file, containing the Vault " + "server's X509 certificate") + String trustStoreFile; + + @PluginProperty(title = "PEM file", description = "The path of a file containing an X.509 certificate, " + "in unencrypted PEM format with UTF-8 encoding.") + String pemFile; + + @PluginProperty(title = "Client PEM file", description = "The path of a file containing an X.509 certificate, " + "in unencrypted PEM format with UTF-8 encoding.") + String clientPemFile; + + @PluginProperty(title = "Client Key PEM file", description = "The path of a file containing an RSA private key, " + "in unencrypted PEM format with UTF-8 encoding.") + String clientKeyPemFile; + + @PluginProperty(title = "Disable SSL validation", description = "Specifies whether SSL validation is to be performed", defaultValue = "true", required = true) + String validateSsl; + + @PluginProperty(title = "Userpass Mount name", description = "The mount name of the Userpass authentication back end", defaultValue = "userpass") + String userpassAuthMount; + + @PluginProperty(title = "User name", description = "Required for user/password and LDAP authentication backend") + String username; + + @PluginProperty(title = "Password", description = "Required for user/password and LDAP authentication backend") + String password; + + @PluginProperty(title = "AppRole role ID", description = "The role-id used for authentication") + String approleId; + + @PluginProperty(title = "AppRole secret ID", description = "The secret-id used for authentication") + String approleSecretId; + + @PluginProperty(title = "AppRole mount name", description = "The mount name of the AppRole authentication back end") + String approleAuthMount; + + @PluginProperty(title = "GitHub token", description = "The app-id used for authentication") + String githubToken; + + @PluginProperty(title = "Max retries", description = "Maximum number of connection " + "retries to Vault server", defaultValue = "5") + String maxRetries; + + @PluginProperty(title = "Retry interval", description = "Connection retry interval, in ms", defaultValue = "1000") + String retryIntervalMilliseconds; + + @PluginProperty(title = "Open timeout", description = "Connection opening timeout, in seconds", defaultValue = "5") + String openTimeout; + + @PluginProperty(title = "Read timeout", description = "Response read timeout, in seconds", defaultValue = "20") + String readTimeout; + + @PluginProperty(title = "Secret Backend", description = "The secret backend to use in vault", defaultValue = "secret") + String secretBackend; + + @PluginProperty(title = "Namespace", description = "The namespace to access and save the secrets") + String namespace; + @PluginProperty(title = "storageBehaviour", description = "storageBehaviour for the account to authenticate to") String storageBehaviour; + @PluginProperty(title = "Vault Engine Version", description = "Key/Value Secret Engine Config", defaultValue = "1") + String engineVersion; + + @PluginProperty(title = "Authentication Namespace", description = "The namespace for authentication") + String authNamespace; + protected Vault getVaultClient() throws ConfigurationException { //clone former properties configuration passes to configure method if(vaultClient == null) { properties.setProperty(VAULT_PREFIX, vaultPrefix); properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); + properties.setProperty(VAULT_ADDRESS, address); + properties.setProperty(VAULT_TOKEN, token); + properties.setProperty(VAULT_AUTH_BACKEND, authBackend); + properties.setProperty(VAULT_KEY_STORE_FILE, keyStoreFile); + properties.setProperty(VAULT_KEY_STORE_FILE_PASSWORD, keyStoreFilePassword); + properties.setProperty(VAULT_TRUST_STORE_FILE, trustStoreFile); + properties.setProperty(VAULT_PEM_FILE, pemFile); + properties.setProperty(VAULT_CLIENT_PEM_FILE, clientPemFile); + properties.setProperty(VAULT_CLIENT_KEY_PEM_FILE, clientKeyPemFile); + properties.setProperty(VAULT_VERIFY_SSL, validateSsl); + properties.setProperty(VAULT_USERPASS_AUTH_MOUNT, userpassAuthMount); + properties.setProperty(VAULT_USERNAME, username); + properties.setProperty(VAULT_PASSWORD, password); + properties.setProperty(VAULT_APPROLE_ID, approleId); + properties.setProperty(VAULT_APPROLE_SECRET_ID, approleSecretId); + properties.setProperty(VAULT_APPROLE_AUTH_MOUNT, approleAuthMount); + properties.setProperty(VAULT_GITHUB_TOKEN, githubToken); + properties.setProperty(VAULT_MAX_RETRIES, maxRetries); + properties.setProperty(VAULT_RETRY_INTERVAL_MILLISECONDS, retryIntervalMilliseconds); + properties.setProperty(VAULT_OPEN_TIMEOUT, openTimeout); + properties.setProperty(VAULT_READ_TIMEOUT, readTimeout); + properties.setProperty(VAULT_SECRET_BACKEND, secretBackend); + properties.setProperty(VAULT_NAMESPACE, namespace); properties.setProperty(VAULT_STORAGE_BEHAVIOUR, storageBehaviour); + properties.setProperty(VAULT_ENGINE_VERSION, engineVersion); + properties.setProperty(VAULT_AUTH_NAMESPACE, authNamespace); //set member variables on object on entry, lookup -> getVaultClient() if (storageBehaviour != null && storageBehaviour.equals("vault")) { From 4f6490492ec05813d81352e9b227e6ba2f46f573 Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 10:41:50 -0600 Subject: [PATCH 5/9] update check for client --- .../rundeck/plugin/vault/VaultStoragePlugin.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java index eacb3a6..15f02cb 100644 --- a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java +++ b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java @@ -145,7 +145,7 @@ public VaultStoragePlugin() {} protected Vault getVaultClient() throws ConfigurationException { //clone former properties configuration passes to configure method - if(vaultClient == null) { + if(this.vaultClient == null) { properties.setProperty(VAULT_PREFIX, vaultPrefix); properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); properties.setProperty(VAULT_ADDRESS, address); @@ -214,7 +214,8 @@ private boolean isDir(String key) { protected void lookup(){ try { - if (getVaultClient().auth().lookupSelf().getTTL() <= guaranteedTokenValidity) { + long ttl = getVaultClient().auth().lookupSelf().getTTL(); + if (ttl <= guaranteedTokenValidity) { loginVault(clientProvider); } } catch (VaultException e) { @@ -229,10 +230,11 @@ protected void lookup(){ } private void loginVault(VaultClientProvider provider){ - try { - vault = getVaultClient().logical(); - } catch (ConfigurationException e) { - e.printStackTrace(); + try{ + vault = vaultClient.logical(); + } + catch (Exception ignored){ + } } From 669e03b3f75bd960b1987c25fc8570cd7752be4c Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 11:49:25 -0600 Subject: [PATCH 6/9] check props before setting --- .../plugin/vault/VaultStoragePlugin.java | 114 +++++++++++++----- 1 file changed, 85 insertions(+), 29 deletions(-) diff --git a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java index 15f02cb..d9c3d7f 100644 --- a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java +++ b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java @@ -146,34 +146,90 @@ public VaultStoragePlugin() {} protected Vault getVaultClient() throws ConfigurationException { //clone former properties configuration passes to configure method if(this.vaultClient == null) { - properties.setProperty(VAULT_PREFIX, vaultPrefix); - properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); - properties.setProperty(VAULT_ADDRESS, address); - properties.setProperty(VAULT_TOKEN, token); - properties.setProperty(VAULT_AUTH_BACKEND, authBackend); - properties.setProperty(VAULT_KEY_STORE_FILE, keyStoreFile); - properties.setProperty(VAULT_KEY_STORE_FILE_PASSWORD, keyStoreFilePassword); - properties.setProperty(VAULT_TRUST_STORE_FILE, trustStoreFile); - properties.setProperty(VAULT_PEM_FILE, pemFile); - properties.setProperty(VAULT_CLIENT_PEM_FILE, clientPemFile); - properties.setProperty(VAULT_CLIENT_KEY_PEM_FILE, clientKeyPemFile); - properties.setProperty(VAULT_VERIFY_SSL, validateSsl); - properties.setProperty(VAULT_USERPASS_AUTH_MOUNT, userpassAuthMount); - properties.setProperty(VAULT_USERNAME, username); - properties.setProperty(VAULT_PASSWORD, password); - properties.setProperty(VAULT_APPROLE_ID, approleId); - properties.setProperty(VAULT_APPROLE_SECRET_ID, approleSecretId); - properties.setProperty(VAULT_APPROLE_AUTH_MOUNT, approleAuthMount); - properties.setProperty(VAULT_GITHUB_TOKEN, githubToken); - properties.setProperty(VAULT_MAX_RETRIES, maxRetries); - properties.setProperty(VAULT_RETRY_INTERVAL_MILLISECONDS, retryIntervalMilliseconds); - properties.setProperty(VAULT_OPEN_TIMEOUT, openTimeout); - properties.setProperty(VAULT_READ_TIMEOUT, readTimeout); - properties.setProperty(VAULT_SECRET_BACKEND, secretBackend); - properties.setProperty(VAULT_NAMESPACE, namespace); - properties.setProperty(VAULT_STORAGE_BEHAVIOUR, storageBehaviour); - properties.setProperty(VAULT_ENGINE_VERSION, engineVersion); - properties.setProperty(VAULT_AUTH_NAMESPACE, authNamespace); + if(vaultPrefix != null){ + properties.setProperty(VAULT_PREFIX, vaultPrefix); + } + if(vaultSecretBackend != null){ + properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); + } + if(address != null){ + properties.setProperty(VAULT_ADDRESS, address); + } + if(token != null){ + properties.setProperty(VAULT_TOKEN, token); + } + if(authBackend != null){ + properties.setProperty(VAULT_AUTH_BACKEND, authBackend); + } + if(keyStoreFile != null){ + properties.setProperty(VAULT_KEY_STORE_FILE, keyStoreFile); + } + if(keyStoreFilePassword != null){ + properties.setProperty(VAULT_KEY_STORE_FILE_PASSWORD, keyStoreFilePassword); + } + if(trustStoreFile != null){ + properties.setProperty(VAULT_TRUST_STORE_FILE, trustStoreFile); + } + if(pemFile != null){ + properties.setProperty(VAULT_PEM_FILE, pemFile); + } + if(clientPemFile != null){ + properties.setProperty(VAULT_CLIENT_PEM_FILE, clientPemFile); + } + if(clientKeyPemFile != null){ + properties.setProperty(VAULT_CLIENT_KEY_PEM_FILE, clientKeyPemFile); + } + if(validateSsl != null){ + properties.setProperty(VAULT_VERIFY_SSL, validateSsl); + } + if(userpassAuthMount != null){ + properties.setProperty(VAULT_USERPASS_AUTH_MOUNT, userpassAuthMount); + } + if(username != null){ + properties.setProperty(VAULT_USERNAME, username); + } + if(password != null){ + properties.setProperty(VAULT_PASSWORD, password); + } + if(approleId != null){ + properties.setProperty(VAULT_APPROLE_ID, approleId); + } + if(approleSecretId != null){ + properties.setProperty(VAULT_APPROLE_SECRET_ID, approleSecretId); + } + if(approleAuthMount != null){ + properties.setProperty(VAULT_APPROLE_AUTH_MOUNT, approleAuthMount); + } + if(githubToken != null){ + properties.setProperty(VAULT_GITHUB_TOKEN, githubToken); + } + if(maxRetries != null){ + properties.setProperty(VAULT_MAX_RETRIES, maxRetries); + } + if(retryIntervalMilliseconds != null){ + properties.setProperty(VAULT_RETRY_INTERVAL_MILLISECONDS, retryIntervalMilliseconds); + } + if(openTimeout != null){ + properties.setProperty(VAULT_OPEN_TIMEOUT, openTimeout); + } + if(readTimeout != null){ + properties.setProperty(VAULT_READ_TIMEOUT, readTimeout); + } + if(secretBackend != null){ + properties.setProperty(VAULT_SECRET_BACKEND, secretBackend); + } + if(namespace != null){ + properties.setProperty(VAULT_NAMESPACE, namespace); + } + if(storageBehaviour != null){ + properties.setProperty(VAULT_STORAGE_BEHAVIOUR, storageBehaviour); + } + if(engineVersion != null){ + properties.setProperty(VAULT_ENGINE_VERSION, engineVersion); + } + if(authNamespace != null){ + properties.setProperty(VAULT_AUTH_NAMESPACE, authNamespace); + } //set member variables on object on entry, lookup -> getVaultClient() if (storageBehaviour != null && storageBehaviour.equals("vault")) { @@ -214,7 +270,7 @@ private boolean isDir(String key) { protected void lookup(){ try { - long ttl = getVaultClient().auth().lookupSelf().getTTL(); + long ttl = this.getVaultClient().auth().lookupSelf().getTTL(); if (ttl <= guaranteedTokenValidity) { loginVault(clientProvider); } From cdcf90cfcffc18fe46f8c54b6038046b9160ebbe Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 19:31:22 -0600 Subject: [PATCH 7/9] fix plugin --- .../plugin/vault/VaultStoragePlugin.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java index d9c3d7f..18089bf 100644 --- a/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java +++ b/src/main/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePlugin.java @@ -60,10 +60,7 @@ public VaultStoragePlugin() {} Properties properties = new Properties(); @PluginProperty(title = "vaultPrefix", description = "username for the account to authenticate to") - String vaultPrefix; - - @PluginProperty(title = "vaultSecretBackend", description = "password for the account to authenticate to") - String vaultSecretBackend; + String prefix; @PluginProperty(title = "Vault address", description = "Address of the Vault server", defaultValue = "https://localhost:8200") String address; @@ -71,7 +68,7 @@ public VaultStoragePlugin() {} @PluginProperty(title = "Vault token", description = "Vault authentication token. " + "Required, if authentication backend is 'token'") String token; - @PluginProperty(title = "Vault auth backend", description = "Authentication backend") + @PluginProperty(title = "Vault auth backend", description = "Authentication backend", defaultValue = "token") String authBackend; @PluginProperty(title = "Key store file", description = "A Java keystore, containing a client certificate " + "that's registered with Vault's TLS Certificate auth backend.") @@ -145,12 +142,14 @@ public VaultStoragePlugin() {} protected Vault getVaultClient() throws ConfigurationException { //clone former properties configuration passes to configure method - if(this.vaultClient == null) { - if(vaultPrefix != null){ - properties.setProperty(VAULT_PREFIX, vaultPrefix); + if(vaultClient == null || properties.size()==0) { + + if(secretBackend != null){ + properties.setProperty(VAULT_SECRET_BACKEND, secretBackend); } - if(vaultSecretBackend != null){ - properties.setProperty(VAULT_SECRET_BACKEND, vaultSecretBackend); + + if(prefix != null){ + properties.setProperty(VAULT_PREFIX, prefix); } if(address != null){ properties.setProperty(VAULT_ADDRESS, address); @@ -239,7 +238,7 @@ protected Vault getVaultClient() throws ConfigurationException { guaranteedTokenValidity = calculateGuaranteedTokenValidity(properties); clientProvider = getVaultClientProvider(properties); - vaultClient = clientProvider.getVaultClient(); + loginVault(clientProvider); } return vaultClient; @@ -270,7 +269,7 @@ private boolean isDir(String key) { protected void lookup(){ try { - long ttl = this.getVaultClient().auth().lookupSelf().getTTL(); + long ttl = getVaultClient().auth().lookupSelf().getTTL(); if (ttl <= guaranteedTokenValidity) { loginVault(clientProvider); } @@ -287,6 +286,7 @@ protected void lookup(){ private void loginVault(VaultClientProvider provider){ try{ + vaultClient = provider.getVaultClient(); vault = vaultClient.logical(); } catch (Exception ignored){ @@ -354,7 +354,7 @@ private VaultResponse saveResource(Path path, ResourceMeta content, String event try { lookup(); - return vault.write(getVaultPath(object.getPath().getPath(),vaultSecretBackend,vaultPrefix), payload); + return vault.write(getVaultPath(object.getPath().getPath(),secretBackend,prefix), payload); } catch (VaultException e) { throw new StorageException( String.format("Encountered error while writing data to Vault %s", @@ -596,7 +596,7 @@ public Set> listDirectorySubdirs(String path) { @Override public boolean deleteResource(Path path) { KeyObject object = this.getVaultObject(path); - return object.delete(vault,vaultSecretBackend,vaultPrefix); + return object.delete(vault,secretBackend,prefix); } @Override @@ -631,8 +631,8 @@ public KeyObject getVaultObject(Path path){ KeyObject value= KeyObjectBuilder.builder() .path(path) .vault(vault) - .vaultPrefix(vaultPrefix) - .vaultSecretBackend(vaultSecretBackend) + .vaultPrefix(prefix) + .vaultSecretBackend(secretBackend) .build(); return value; @@ -645,7 +645,7 @@ private List getVaultList(Path path) throws VaultException { } private List getVaultList(String path) throws VaultException { - LogicalResponse response = vault.list(getVaultPath(path,vaultSecretBackend,vaultPrefix)); + LogicalResponse response = vault.list(getVaultPath(path,secretBackend,prefix)); if (response.getRestResponse().getStatus()==403){ String body = new String(response.getRestResponse().getBody()); throw StorageException.listException( From 80b76a98c5523ea41af1130f1fc9c86cea266324 Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 19:42:55 -0600 Subject: [PATCH 8/9] fix remco mappings --- .../remco/templates/rundeck-config-storage.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker/rundeck/remco/templates/rundeck-config-storage.properties b/docker/rundeck/remco/templates/rundeck-config-storage.properties index 14e1aaf..8376593 100644 --- a/docker/rundeck/remco/templates/rundeck-config-storage.properties +++ b/docker/rundeck/remco/templates/rundeck-config-storage.properties @@ -19,12 +19,12 @@ rundeck.storage.provider.{{index}}.config.readTimeout={% set readtimeout = print rundeck.storage.provider.{{index}}.config.engineVersion={% set engineversion = printf("%s/config/engineversion", provider) %}{{ getv(engineversion, "1")}} {%- set auth = getv(printf("%s/config/authbackend", provider), "token") %} -{%- set namespace = getv(printf("%s/config/namespace", provider)) %} -{%- set authnamespace = getv(printf("%s/config/authnamespace", provider)) %} +{%- set namespace = getv(printf("%s/config/namespace", provider), "rundeck/demo") %} +{%- set authnamespace = getv(printf("%s/config/authnamespace", provider), "rundeck") %} {% if namespace %} -rundeck.storage.provider.{{index}}.config.namespace={% set namespace = printf("%s/config/namespace", provider) %}{{ getv(namespace)}} +rundeck.storage.provider.{{index}}.config.namespace={% set namespace = printf("%s/config/namespace", provider) %}{{ getv(namespace, "rundeck/demo")}} {% endif %} {% if auth == 'token' %} @@ -42,7 +42,7 @@ rundeck.storage.provider.{{index}}.config.authBackend=approle {% endif %} {% if authnamespace %} -rundeck.storage.provider.{{index}}.config.authNamespace={% set authnamespace = printf("%s/config/authnamespace", provider) %}{{ getv(authnamespace)}} +rundeck.storage.provider.{{index}}.config.authNamespace={% set authnamespace = printf("%s/config/authnamespace", provider) %}{{ getv(authnamespace, "rundeck")}} {% endif %} {% endmacro %} From 6f865b0f7fb6d69bd83097fcec17edac109a5fb8 Mon Sep 17 00:00:00 2001 From: chrismcg14 Date: Wed, 13 Apr 2022 20:09:01 -0600 Subject: [PATCH 9/9] fix tests --- .../rundeck/plugin/vault/VaultStoragePluginTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java b/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java index a7ff5a7..510540b 100644 --- a/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java +++ b/src/test/java/io/github/valfadeev/rundeck/plugin/vault/VaultStoragePluginTest.java @@ -122,7 +122,7 @@ public void lookUp_refreshesToken_when_currentTokenIsAboutToExpire() throws Conf vaultStoragePlugin.lookup(); - verify(vaultClientProvider).getVaultClient(); + verify(vaultClientProvider, times(2)).getVaultClient(); } @Test @@ -159,6 +159,6 @@ public void lookUp_refreshesToken_when_tokenIsExpired() throws ConfigurationExce vaultStoragePlugin.properties=properties; vaultStoragePlugin.lookup(); - verify(vaultClientProvider).getVaultClient(); + verify(vaultClientProvider, times(2)).getVaultClient(); } }