11package com .datapipe .jenkins .vault .credentials ;
22
33import com .bettercloud .vault .Vault ;
4- import com .bettercloud .vault .VaultConfig ;
5- import com .bettercloud .vault .VaultException ;
6- import com .datapipe .jenkins .vault .exception .VaultPluginException ;
4+ import com .cloudbees .plugins .credentials .CredentialsProvider ;
5+ import com .cloudbees .plugins .credentials .common .IdCredentials ;
6+ import com .datapipe .jenkins .vault .VaultAccessor ;
7+ import com .datapipe .jenkins .vault .configuration .VaultConfiguration ;
78import edu .umd .cs .findbugs .annotations .NonNull ;
89import edu .umd .cs .findbugs .annotations .Nullable ;
910import hudson .Extension ;
1011import hudson .FilePath ;
1112import hudson .Launcher ;
13+ import hudson .model .Descriptor ;
1214import hudson .model .Run ;
1315import hudson .model .TaskListener ;
1416import java .io .IOException ;
1719import java .util .HashSet ;
1820import java .util .Map ;
1921import java .util .Set ;
22+ import javax .annotation .Nonnull ;
23+ import jenkins .model .Jenkins ;
2024import org .apache .commons .lang .StringUtils ;
2125import org .jenkinsci .plugins .credentialsbinding .BindingDescriptor ;
2226import org .jenkinsci .plugins .credentialsbinding .MultiBinding ;
27+ import org .jenkinsci .plugins .credentialsbinding .impl .CredentialNotFoundException ;
2328import org .kohsuke .stapler .DataBoundConstructor ;
2429import org .kohsuke .stapler .DataBoundSetter ;
2530
@@ -29,7 +34,7 @@ public class VaultTokenCredentialBinding extends MultiBinding<AbstractVaultToken
2934 private final static String DEFAULT_VAULT_TOKEN_VARIABLE_NAME = "VAULT_TOKEN" ;
3035 private final static String DEFAULT_VAULT_NAMESPACE_VARIABLE_NAME = "VAULT_NAMESPACE" ;
3136
32- @ NonNull
37+ private final String credentialsId ;
3338 private final String addrVariable ;
3439 private final String tokenVariable ;
3540 private final String vaultAddr ;
@@ -47,6 +52,8 @@ public class VaultTokenCredentialBinding extends MultiBinding<AbstractVaultToken
4752 public VaultTokenCredentialBinding (@ Nullable String addrVariable ,
4853 @ Nullable String tokenVariable , String credentialsId , String vaultAddr ) {
4954 super (credentialsId );
55+ // The superclass field is private, so we need to store our own version
56+ this .credentialsId = credentialsId ;
5057 this .vaultAddr = vaultAddr ;
5158 this .addrVariable = StringUtils
5259 .defaultIfBlank (addrVariable , DEFAULT_VAULT_ADDR_VARIABLE_NAME );
@@ -94,32 +101,60 @@ protected Class<AbstractVaultTokenCredential> type() {
94101 return AbstractVaultTokenCredential .class ;
95102 }
96103
104+ private @ Nonnull AbstractVaultTokenCredential getCredentials (@ Nonnull Run <?,?> build ,
105+ VaultConfiguration config ) throws CredentialNotFoundException {
106+ // Copied and modified to pull the credentials ID from the Vault configuration
107+ IdCredentials cred = CredentialsProvider .findCredentialById (config .getVaultCredentialId (),
108+ IdCredentials .class , build );
109+ if (cred ==null )
110+ throw new CredentialNotFoundException ("Could not find credentials entry with ID '" +
111+ config .getVaultCredentialId () + "'" );
112+
113+ if (type ().isInstance (cred )) {
114+ CredentialsProvider .track (build , cred );
115+ return type ().cast (cred );
116+ }
117+
118+ Descriptor expected = Jenkins .getActiveInstance ().getDescriptor (type ());
119+ throw new CredentialNotFoundException ("Credentials '" +config .getVaultCredentialId ()+"' is of type '" +
120+ cred .getDescriptor ().getDisplayName ()+"' where '" +
121+ (expected !=null ? expected .getDisplayName () : type ().getName ())+
122+ "' was expected" );
123+ }
124+
97125 @ Override
98126 public MultiEnvironment bind (@ NonNull Run <?, ?> build , FilePath workspace , Launcher launcher ,
99- @ NonNull TaskListener listener ) throws IOException , InterruptedException {
100- AbstractVaultTokenCredential credentials = getCredentials (build );
127+ @ NonNull TaskListener listener ) throws IOException {
128+ VaultConfiguration config = getVaultConfiguration (build );
129+ AbstractVaultTokenCredential credentials = getCredentials (build , config );
101130 Map <String , String > m = new HashMap <>();
102- m .put (addrVariable , vaultAddr );
103- m .put (namespaceVariable , vaultNamespace );
104- String token = getToken (credentials );
131+ m .put (addrVariable , config . getVaultUrl () );
132+ m .put (namespaceVariable , StringUtils . defaultString ( config . getVaultNamespace ()) );
133+ String token = getToken (build , credentials , config );
105134 // don't add null token variable, can cause NPE in places where credential bindings impls
106135 // are not expecting null env var values.
107136 m .put (tokenVariable , StringUtils .defaultString (token ));
108137 return new MultiEnvironment (m );
109138 }
110139
111- private String getToken (AbstractVaultTokenCredential credentials ) {
112- try {
113- VaultConfig config = new VaultConfig ().address (vaultAddr );
114- if (StringUtils .isNotEmpty (vaultNamespace )) {
115- config .nameSpace (vaultNamespace );
116- }
117- config .build ();
118-
119- return credentials .getToken (new Vault (config ));
120- } catch (VaultException e ) {
121- throw new VaultPluginException ("could not log in into vault" , e );
140+ private VaultConfiguration getVaultConfiguration (Run <?, ?> build ) {
141+ VaultConfiguration initialConfig = new VaultConfiguration ();
142+ initialConfig .setVaultCredentialId (credentialsId );
143+ initialConfig .setVaultUrl (vaultAddr );
144+ initialConfig .setVaultNamespace (vaultNamespace );
145+ return VaultAccessor .pullAndMergeConfiguration (build , initialConfig );
146+ }
147+
148+ private String getToken (Run <?, ?> build , AbstractVaultTokenCredential credentials ,
149+ VaultConfiguration config ) {
150+ if (StringUtils .isBlank (config .getPolicies ())) {
151+ // Use simpler method to get token if no policies are set
152+ return credentials .getToken (new Vault (config .getVaultConfig ()));
122153 }
154+ return credentials .authorizeWithVault (
155+ config .getVaultConfig (),
156+ VaultAccessor .generatePolicies (config .getPolicies (), build .getCharacteristicEnvVars ())
157+ ).getToken ();
123158 }
124159
125160 @ Override
0 commit comments