Skip to content

Commit

Permalink
Add possibility to reload secrets from properties file with JCasC rel…
Browse files Browse the repository at this point in the history
…oad (#1556)
  • Loading branch information
tempora-mutantur committed Jan 20, 2021
1 parent 9a40a90 commit 161c501
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@
import com.cloudbees.plugins.credentials.common.UsernamePasswordCredentials;
import io.jenkins.plugins.casc.misc.ConfiguredWithCode;
import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithCodeRule;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStream;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import jenkins.model.Jenkins;
import org.junit.Rule;
import org.junit.Test;
Expand All @@ -16,14 +21,16 @@

public class PropertiesSecretSourceTest {

private static final String USERNAME_SECRET = "ken";

@Rule
public RuleChain chain = RuleChain.outerRule(new EnvironmentVariables()
.set("SECRETS_FILE", getClass().getResource("secrets.properties").getFile()))
.around(new JenkinsConfiguredWithCodeRule());

@Test
@ConfiguredWithCode("PropertiesSecretSourceTest.yaml")
public void test_reading_secrets_from_properties() throws Exception {
public void testReadingSecretsFromProperties() throws Exception {
List<UsernamePasswordCredentials> credentialList = CredentialsProvider
.lookupCredentials(UsernamePasswordCredentials.class,
Jenkins.getInstanceOrNull(), null, Collections.emptyList());
Expand All @@ -32,7 +39,39 @@ public void test_reading_secrets_from_properties() throws Exception {
UsernamePasswordCredentials credentials = credentialList.get(0);

// https://leahneukirchen.org/blog/archive/2019/10/ken-thompson-s-unix-password.html
assertEquals("ken", credentials.getUsername());
assertEquals(USERNAME_SECRET, credentials.getUsername());
assertEquals("p/q2-q4!", credentials.getPassword().getPlainText());
}

@Test
@ConfiguredWithCode("PropertiesSecretSourceTest.yaml")
public void testSecretsFromPropertiesAreUpdatedAfterReload() throws Exception {
File secretsFile = new File(getClass().getResource("secrets.properties").getFile());
Properties secrets = new Properties();
InputStream inputStream = new FileInputStream(secretsFile);
secrets.load(inputStream);

FileWriter fileWriter = new FileWriter(secretsFile);

String secretName = "testuser";
String updatedTestUserSecret = "charmander";
secrets.setProperty(secretName, updatedTestUserSecret);
try {
secrets.store(fileWriter, "store to properties file");

ConfigurationAsCode.get().configure(this.getClass().getResource("PropertiesSecretSourceTest.yaml").toString());

List<UsernamePasswordCredentials> credentialList = CredentialsProvider
.lookupCredentials(UsernamePasswordCredentials.class,
Jenkins.getInstanceOrNull(), null, Collections.emptyList());
assertEquals(1, credentialList.size());

UsernamePasswordCredentials credentials = credentialList.get(0);

assertEquals(updatedTestUserSecret, credentials.getUsername());
} finally {
secrets.setProperty(secretName, USERNAME_SECRET);
secrets.store(fileWriter, "store to properties file");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,26 @@ public class PropertiesSecretSource extends SecretSource {
*/
public static final String SECRETS_DEFAULT_PATH = "/run/secrets/secrets.properties";

private Properties secrets;
private final Properties secrets = new Properties();

@Override
public Optional<String> reveal(String secret) {
// lazy initialization
if (secrets == null) {
secrets = new Properties();
final String secretsEnv = System.getenv("SECRETS_FILE");
final String secretsPath = secretsEnv == null ? SECRETS_DEFAULT_PATH : secretsEnv;
final File secretsFile = new File(secretsPath);
if (secretsFile.exists() && secretsFile.isFile()) {
try (InputStream input = new FileInputStream(secretsFile)) {
secrets.load(input);
} catch (IOException ioe) {
LOGGER.log(Level.WARNING,
"Source properties file " + secretsPath + " could not be loaded", ioe);
}
}
}
return Optional.ofNullable(secrets.getProperty(secret));
}

if (secrets.getProperty(secret) == null) {
return Optional.empty();
} else {
return Optional.of(secrets.getProperty(secret));
@Override
public void init() {
final String secretsEnv = System.getenv("SECRETS_FILE");
final String secretsPath = secretsEnv == null ? SECRETS_DEFAULT_PATH : secretsEnv;
final File secretsFile = new File(secretsPath);
if (secretsFile.exists() && secretsFile.isFile()) {
try (InputStream input = new FileInputStream(secretsFile)) {
secrets.clear();
secrets.load(input);
} catch (IOException ioe) {
LOGGER.log(Level.WARNING,
"Source properties file " + secretsPath + " could not be loaded", ioe);
}
}
}
}

0 comments on commit 161c501

Please sign in to comment.