Skip to content

Commit

Permalink
feat: add merge support for casc defined system credentials
Browse files Browse the repository at this point in the history
Enables support for merging casc defined credentials with existing credentials
(i.e. manually created).

fixes JENKINS-64079
  • Loading branch information
cronik committed Jan 24, 2023
1 parent 839a635 commit c3e8d85
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,24 @@ public synchronized void setDomainCredentialsMap(Map<Domain, List<Credentials>>
this.domainCredentialsMap = DomainCredentials.toCopyOnWriteMap(domainCredentialsMap);
}

/**
* Merge the given credentials with the current set. Replace existing domain credentials or add new credentials.
* Existing credentials not in the given set will not be removed.
*
* @param domainCredentialsMap credentials to add or update
*/
public synchronized void mergeDomainCredentialsMap(Map<Domain, List<Credentials>> domainCredentialsMap) {
for (Map.Entry<Domain, List<Credentials>> entry : DomainCredentials.toCopyOnWriteMap(domainCredentialsMap).entrySet()) {
List<Credentials> target = this.domainCredentialsMap.get(entry.getKey());
if (target == null) {
this.domainCredentialsMap.put(entry.getKey(), entry.getValue());
} else {
target.removeAll(entry.getValue());
target.addAll(entry.getValue());
}
}
}

/**
* Short-cut method for {@link Jenkins#checkPermission(hudson.security.Permission)}
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.Util;
import io.jenkins.plugins.casc.Attribute;
import io.jenkins.plugins.casc.BaseConfigurator;
import io.jenkins.plugins.casc.ConfigurationContext;
Expand All @@ -39,7 +40,9 @@
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

/**
Expand All @@ -62,10 +65,19 @@ protected SystemCredentialsProvider instance(Mapping mapping, ConfigurationConte
@NonNull
@Override
public Set<Attribute<SystemCredentialsProvider, ?>> describe() {
return Collections.singleton(
new MultivaluedAttribute<SystemCredentialsProvider, DomainCredentials>("domainCredentials", DomainCredentials.class)
.setter( (target, value) -> target.setDomainCredentialsMap(DomainCredentials.asMap(value)))
);
return new HashSet<>(Arrays.asList(
new MultivaluedAttribute<SystemCredentialsProvider, DomainCredentials>("domainCredentials", DomainCredentials.class)
.setter((target, value) -> {
String strategy = getPropertyOrEnv("CASC_CREDENTIALS_MERGE_STRATEGY", "casc.credentials.merge.strategy");
if ("merge".equalsIgnoreCase(strategy)) {
target.mergeDomainCredentialsMap(DomainCredentials.asMap(value));
} else {
target.setDomainCredentialsMap(DomainCredentials.asMap(value));
}
}),
new MultivaluedAttribute<SystemCredentialsProvider, DomainCredentials>("mergeDomainCredentials", DomainCredentials.class)
.setter((target, value) -> target.mergeDomainCredentialsMap(DomainCredentials.asMap(value)))
));
}

@CheckForNull
Expand All @@ -77,4 +89,11 @@ public CNode describe(SystemCredentialsProvider instance, ConfigurationContext c
}
return mapping;
}

private static String getPropertyOrEnv(String envKey, String proKey) {
return Util.fixEmptyAndTrim(System.getProperty(
proKey,
System.getenv(envKey)
));
}
}

0 comments on commit c3e8d85

Please sign in to comment.