From 7f85238ebd9362e401c88991e0d2aad569fde98b Mon Sep 17 00:00:00 2001 From: Chris Phillips Date: Fri, 13 Oct 2023 16:49:26 -0700 Subject: [PATCH] Adds support for AWS Credentials As suggested here: https://github.com/jenkinsci/aws-secrets-manager-credentials-provider-plugin/issues/237 --- docs/README.md | 50 ++++ pom.xml | 5 + .../factory/CredentialsFactory.java | 8 + .../secretsmanager/factory/Tags.java | 6 +- .../secretsmanager/factory/Type.java | 2 +- .../factory/aws/AwsAccessKeysCredentials.java | 110 +++++++ .../aws/AwsAccessKeysSnapshotTaker.java | 27 ++ .../secretsmanager/Messages.properties | 1 + .../AWSAccessKeysCredentialsIT.java | 270 ++++++++++++++++++ .../secretsmanager/util/AwsTags.java | 16 ++ .../AmazonWebServicesCredentialsAssert.java | 87 ++++++ .../util/assertions/CustomAssertions.java | 5 + 12 files changed, 585 insertions(+), 2 deletions(-) create mode 100644 src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysCredentials.java create mode 100644 src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysSnapshotTaker.java create mode 100644 src/test/java/io/jenkins/plugins/credentials/secretsmanager/AWSAccessKeysCredentialsIT.java create mode 100644 src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/AmazonWebServicesCredentialsAssert.java diff --git a/docs/README.md b/docs/README.md index 9ca22243..0d1d6712 100644 --- a/docs/README.md +++ b/docs/README.md @@ -297,6 +297,56 @@ node { } ``` +### AWS Credentials + +AWS access keys credentials compatible with the [aws-credentials-plugin](https://github.com/jenkinsci/aws-credentials-plugin). + +- Value: *awsSecretKey* +- Tags: + - `jenkins:credentials:type` = `awsAccessKeys` + - `jenkins:credentials:accesskeyid` = *accesskeyid* + - `jenkins:credentials:iamrolearn` = *iamrolearn* (optional) + - `jenkins:credentials:iamexternalid` = *iamexternalid* (optional) + - `jenkins:credentials:iammfaserialnumberid` = *iammfaserialnumberid* (optional) + - `jenkins:credentials:ststokenduration` = *ststokenduration* (optional) + +#### Example + +AWS CLI: + +```bash +aws secretsmanager create-secret --name 'aws-keys' --secret-string 'supersecret' --tags 'Key=jenkins:credentials:type,Value=awsAccessKeys' 'Key=jenkins:credentials:accesskeyid,Value=youraccesskeyid' --description 'Some AWS access keys' +``` + +Declarative Pipeline: + +```groovy +pipeline { + agent any + environment { + // Creates variables AWS_ACCESS_KEY_ID=accesskeyid, AWS_SECRET_ACCESS_KEY=superseccret + ARTIFACTORY = credentials('aws-keys') + } + stages { + stage('Foo') { + steps { + echo 'Hello world' + } + } + } +} +``` + +Scripted Pipeline: + +```groovy +node { + withCredentials([aws(credentialsId: 'aws')]) { + echo 'Hello world' + } +} +``` + ## Advanced Usage You may need to deal with multi-field credentials or vendor-specific credential types that the plugin does not (yet) support. diff --git a/pom.xml b/pom.xml index dd4e9d41..e0a82d2d 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,11 @@ org.jenkins-ci.plugins.aws-java-sdk aws-java-sdk-secretsmanager + + org.jenkins-ci.plugins + aws-credentials + 218.v1b_e9466ec5da_ + io.jenkins configuration-as-code diff --git a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/CredentialsFactory.java b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/CredentialsFactory.java index 7dd01198..d9e6bc7b 100644 --- a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/CredentialsFactory.java +++ b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/CredentialsFactory.java @@ -10,6 +10,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; import hudson.util.Secret; import io.jenkins.plugins.credentials.secretsmanager.Messages; +import io.jenkins.plugins.credentials.secretsmanager.factory.aws.AwsAccessKeysCredentials; import io.jenkins.plugins.credentials.secretsmanager.factory.certificate.AwsCertificateCredentials; import io.jenkins.plugins.credentials.secretsmanager.factory.file.AwsFileCredentials; import io.jenkins.plugins.credentials.secretsmanager.factory.ssh_user_private_key.AwsSshUserPrivateKey; @@ -52,6 +53,13 @@ public static Optional create(String arn, String name, Stri return Optional.of(new AwsCertificateCredentials(name, description, new SecretBytesSupplier(client, arn))); case Type.file: return Optional.of(new AwsFileCredentials(name, description, filename, new SecretBytesSupplier(client, arn))); + case Type.awsAccessKeys: + final String accesskeyid = tags.getOrDefault(Tags.accesskeyid, ""); + final String iamrolearn = tags.getOrDefault(Tags.iamrolearn, ""); + final String iamexternalid = tags.getOrDefault(Tags.iamexternalid, ""); + final String iammfaserialnumberid = tags.getOrDefault(Tags.iammfaserialnumberid, ""); + final String ststokenduration = tags.get(Tags.ststokenduration); + return Optional.of(new AwsAccessKeysCredentials(name, description, new SecretSupplier(client, arn), accesskeyid, iamrolearn, iamexternalid, iammfaserialnumberid, ststokenduration != null ? Integer.parseInt(ststokenduration) : null)); default: return Optional.empty(); } diff --git a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Tags.java b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Tags.java index 202e739a..ea857114 100644 --- a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Tags.java +++ b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Tags.java @@ -9,7 +9,11 @@ public abstract class Tags { public static final String filename = namespace + "filename"; public static final String type = namespace + "type"; public static final String username = namespace + "username"; - + public static final String accesskeyid = namespace + "accesskeyid"; + public static final String iamrolearn = namespace + "iamrolearn"; + public static final String iamexternalid = namespace + "iamexternalid"; + public static final String iammfaserialnumberid = namespace + "iammfaserialnumberid"; + public static final String ststokenduration = namespace + "ststokenduration"; private Tags() { } diff --git a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Type.java b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Type.java index 75322c32..c1777fa8 100644 --- a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Type.java +++ b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/Type.java @@ -9,7 +9,7 @@ public abstract class Type { public static final String usernamePassword = "usernamePassword"; public static final String sshUserPrivateKey = "sshUserPrivateKey"; public static final String string = "string"; - + public static final String awsAccessKeys = "awsAccessKeys"; private Type() { } diff --git a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysCredentials.java b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysCredentials.java new file mode 100644 index 00000000..155eca2e --- /dev/null +++ b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysCredentials.java @@ -0,0 +1,110 @@ +package io.jenkins.plugins.credentials.secretsmanager.factory.aws; + +import com.amazonaws.auth.AWSCredentials; +import com.amazonaws.auth.AWSCredentialsProvider; +import com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsImpl; +import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials; +import com.cloudbees.plugins.credentials.CredentialsProvider; +import com.cloudbees.plugins.credentials.CredentialsScope; +import com.cloudbees.plugins.credentials.impl.BaseStandardCredentials; +import hudson.Extension; +import hudson.util.Secret; +import io.jenkins.plugins.credentials.secretsmanager.AwsCredentialsProvider; +import io.jenkins.plugins.credentials.secretsmanager.Messages; +import org.apache.commons.lang3.NotImplementedException; + +import javax.annotation.Nonnull; +import java.util.function.Supplier; + +public class AwsAccessKeysCredentials extends BaseStandardCredentials implements AmazonWebServicesCredentials, AWSCredentialsProvider { + + private final Supplier awsSecretKeySupplier; + + private final String awsAccessKeyId; + private final String iamRoleArn; + private final String iamExternalId; + private final String iamMfaSerialNumber; + private final Integer stsTokenDuration; + + public AwsAccessKeysCredentials(String id, String description, Supplier awsSecretKeySupplier, String awsAccessKeyId, String iamRoleArn, String iamExternalId, String iamMfaSerialNumber, Integer stsTokenDuration) { + super(id, description); + this.awsAccessKeyId = awsAccessKeyId; + this.awsSecretKeySupplier = awsSecretKeySupplier; + this.iamRoleArn = iamRoleArn; + this.iamExternalId = iamExternalId; + this.iamMfaSerialNumber = iamMfaSerialNumber; + this.stsTokenDuration = stsTokenDuration; + } + + @Override + public String getDisplayName() { + return getId(); + } + + @Override + public AWSCredentials getCredentials(String mfaToken) { + return getCredentialsImpl().getCredentials(mfaToken); + } + + @Override + public AWSCredentials getCredentials() { + return getCredentialsImpl().getCredentials(); + } + + public AWSCredentialsImpl getCredentialsImpl() { + AWSCredentialsImpl credentials = new AWSCredentialsImpl(CredentialsScope.GLOBAL, getId(), this.awsAccessKeyId, this.awsSecretKeySupplier.get().getPlainText(), getDescription(),this.iamRoleArn, this.iamMfaSerialNumber, this.iamExternalId); + if(stsTokenDuration != null) { + credentials.setStsTokenDuration(this.stsTokenDuration); + } + return credentials; + } + + @Override + public void refresh() { + throw new NotImplementedException(); + } + + @Extension + @SuppressWarnings("unused") + public static class DescriptorImpl extends BaseStandardCredentialsDescriptor { + @Override + @Nonnull + public String getDisplayName() { + return Messages.awsAccessKeys(); + } + + @Override + public String getIconClassName() { + return "symbol-credentials plugin-credentials"; + } + + @Override + public boolean isApplicable(CredentialsProvider provider) { + return provider instanceof AwsCredentialsProvider; + } + } + + public Secret getAwsSecretKey() { + return awsSecretKeySupplier.get(); + } + + public String getAwsAccessKeyId() { + return awsAccessKeyId; + } + + public String getIamRoleArn() { + return iamRoleArn; + } + + public String getIamExternalId() { + return iamExternalId; + } + + public String getIamMfaSerialNumber() { + return iamMfaSerialNumber; + } + + public Integer getStsTokenDuration() { + return stsTokenDuration; + } +} diff --git a/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysSnapshotTaker.java b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysSnapshotTaker.java new file mode 100644 index 00000000..80040320 --- /dev/null +++ b/src/main/java/io/jenkins/plugins/credentials/secretsmanager/factory/aws/AwsAccessKeysSnapshotTaker.java @@ -0,0 +1,27 @@ +package io.jenkins.plugins.credentials.secretsmanager.factory.aws; + +import com.cloudbees.plugins.credentials.CredentialsSnapshotTaker; +import hudson.Extension; +import hudson.util.Secret; +import io.jenkins.plugins.credentials.secretsmanager.factory.Snapshot; + +@Extension +@SuppressWarnings("unused") +public class AwsAccessKeysSnapshotTaker extends CredentialsSnapshotTaker { + @Override + public Class type() { + return AwsAccessKeysCredentials.class; + } + + @Override + public AwsAccessKeysCredentials snapshot(AwsAccessKeysCredentials credential) { + return new AwsAccessKeysCredentials(credential.getId(), credential.getDescription(), new SecretSnapshot(Secret.fromString(credential.getCredentials().getAWSSecretKey())), credential.getAwsAccessKeyId(), credential.getIamRoleArn(), credential.getIamExternalId(), credential.getIamMfaSerialNumber(), credential.getStsTokenDuration()); + } + + private static class SecretSnapshot extends Snapshot { + SecretSnapshot(Secret value) { + super(value); + } + } +} + diff --git a/src/main/resources/io/jenkins/plugins/credentials/secretsmanager/Messages.properties b/src/main/resources/io/jenkins/plugins/credentials/secretsmanager/Messages.properties index 24e4e05f..9c93823b 100644 --- a/src/main/resources/io/jenkins/plugins/credentials/secretsmanager/Messages.properties +++ b/src/main/resources/io/jenkins/plugins/credentials/secretsmanager/Messages.properties @@ -4,6 +4,7 @@ secretText = Secret Text usernamePassword = Username With Password sshUserPrivateKey = SSH User Private Key certificate = Certificate +awsAccessKeys = AWS Credentials file = Secret File filter = Filter filters = Filters diff --git a/src/test/java/io/jenkins/plugins/credentials/secretsmanager/AWSAccessKeysCredentialsIT.java b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/AWSAccessKeysCredentialsIT.java new file mode 100644 index 00000000..edef088b --- /dev/null +++ b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/AWSAccessKeysCredentialsIT.java @@ -0,0 +1,270 @@ +package io.jenkins.plugins.credentials.secretsmanager; + +import com.amazonaws.services.secretsmanager.model.CreateSecretRequest; +import com.amazonaws.services.secretsmanager.model.CreateSecretResult; +import com.amazonaws.services.secretsmanager.model.Tag; +import com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsImpl; +import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials; +import io.jenkins.plugins.casc.misc.ConfiguredWithCode; +import io.jenkins.plugins.credentials.secretsmanager.factory.Type; +import io.jenkins.plugins.credentials.secretsmanager.util.*; +import org.jenkinsci.plugins.structs.describable.DescribableModel; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.jvnet.hudson.test.FlagRule; + +import java.util.ArrayList; +import java.util.Optional; + +import static io.jenkins.plugins.credentials.secretsmanager.util.assertions.CustomAssertions.assertThat; + + +/** + * The plugin should support AmazonWebServicesCredentials. + */ +public class AWSAccessKeysCredentialsIT implements CredentialsTests { + + private static final String ACCESSKEYID = "somekeyid"; + private static final String SECRETKEY = "supersecretkey"; + private static final String IAMROLEARN = "somearn"; + private static final String IAMEXTERNALID = "someexternalid"; + private static final String MFASERIALNUMBER = "somemfaserialnumber"; + private static final Integer STSTOKENDURATION = 77777; + + public final MyJenkinsConfiguredWithCodeRule jenkins = new MyJenkinsConfiguredWithCodeRule(); + public final AWSSecretsManagerRule secretsManager = new AWSSecretsManagerRule(); + + @Rule + public final TestRule chain = Rules.jenkinsWithSecretsManager(jenkins, secretsManager); + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldSupportListView() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + + // When + final var credentialList = jenkins.getCredentials().list(AmazonWebServicesCredentials.class); + // Then + assertThat(credentialList) + .containsOption(secret.getName(), secret.getName()); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveSecretKey() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasSecretKey(SECRETKEY); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveIamExternalId() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY, Optional.of(AwsTags.iamexternalid(IAMEXTERNALID))); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasIamExternalId(IAMEXTERNALID); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveIamRoleArn() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY, Optional.of(AwsTags.iamrolearn(IAMROLEARN))); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasIamRoleArn(IAMROLEARN); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveIamMfaSerialNumberId() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY, Optional.of(AwsTags.iammfaserialnumberid(MFASERIALNUMBER))); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasIamMfaSerialNumber(MFASERIALNUMBER); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveStsTokenDuration() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY, Optional.of(AwsTags.ststokenduration(STSTOKENDURATION.toString()))); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasStsTokenDuration(STSTOKENDURATION); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveAccessKeyId() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasAccessKeyId(ACCESSKEYID); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveId() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + + // When + final var credential = + jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + // Then + assertThat(credential) + .hasId(secret.getName()); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldSupportWithCredentialsBinding() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + + // When + final var run = runPipeline("", + "withCredentials([aws(credentialsId: '" + secret.getName() + "')]) {", + " echo \"Credential: {accesskeyid: $AWS_ACCESS_KEY_ID, secretkey: $AWS_SECRET_ACCESS_KEY}\"", + "}"); + + // Then + assertThat(run) + .hasResult(hudson.model.Result.SUCCESS) + .hasLogContaining("Credential: {accesskeyid: ****, secretkey: ****}"); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldSupportEnvironmentBinding() { + // Given + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + // Workaround for test failures due to this https://github.com/jenkinsci/aws-credentials-plugin/issues/68 + // Without setting this flag to false, the test would fail with an illegal argument exception. + // See https://github.com/jenkinsci/structs-plugin/blob/master/src/main/java/org/jenkinsci/plugins/structs/describable/DescribableModel.java#L321 + // However in a live jenkins instance the flag is set to false so a warning + // is logged and the build happily proceeds. Didn't dig any farther into why this field gets set to true in + // the test harness but this will work until that issue in the aws-credentials-plugin is fixed. + DescribableModel.STRICT_PARAMETER_CHECKING = false; + // When + final var run = runPipeline("", + "pipeline {", + " agent none", + " stages {", + " stage('Example') {", + " environment {", + " FOO = credentials('" + secret.getName() + "')", + " }", + " steps {", + " echo \"{accessKey: $AWS_ACCESS_KEY_ID, secretKey: $AWS_SECRET_ACCESS_KEY}\"", + " }", + " }", + " }", + "}"); + + // Then + assertThat(run) + .hasLogContaining("{accessKey: ****, secretKey: ****}") + .hasResult(hudson.model.Result.SUCCESS); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldSupportSnapshots() { + // Given + final CreateSecretResult foo = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + final AmazonWebServicesCredentials before = jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, foo.getName()); + + // When + final AmazonWebServicesCredentials after = CredentialSnapshots.snapshot(before); + + // Then + assertThat(after) + .hasSecretKey(before.getCredentials().getAWSSecretKey()) + .hasAccessKeyId(before.getCredentials().getAWSAccessKeyId()) + .hasId(before.getId()); + } + + @Test + @ConfiguredWithCode(value = "/integration.yml") + public void shouldHaveDescriptorIcon() { + final var secret = createAwsAccessKeysSecret(ACCESSKEYID, SECRETKEY); + + final var ours = jenkins.getCredentials().lookup(AmazonWebServicesCredentials.class, secret.getName()); + + final var theirs = new AWSCredentialsImpl(null, "id", "accesskey", "secretkey", "description"); + + assertThat(ours) + .hasSameDescriptorIconAs(theirs); + } + + private CreateSecretResult createAwsAccessKeysSecret(String accessKeyId, String secretKey) { + return createAwsAccessKeysSecret(accessKeyId, secretKey, Optional.empty()); + } + private CreateSecretResult createAwsAccessKeysSecret(String accessKeyId, String secretKey, Optional extraTag) { + + final var tags = new ArrayList(); + tags.add(AwsTags.type(Type.awsAccessKeys)); + tags.add(AwsTags.accesskeyid(accessKeyId)); + if(extraTag.isPresent()) { + tags.add(extraTag.get()); + } + + final var request = new CreateSecretRequest() + .withName(CredentialNames.random()) + .withSecretString(secretKey) + .withTags(tags); + + return secretsManager.getClient().createSecret(request); + } + + private WorkflowRun runPipeline(String... pipeline) { + return jenkins.getPipelines().run(Strings.m(pipeline)); + } + + @ClassRule + public static TestRule noStrictParameterChecking = FlagRule.systemProperty("org.jenkinsci.plugins.structs.describable.DescribableModel.STRICT_PARAMETER_CHECKING", "false"); +} + diff --git a/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/AwsTags.java b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/AwsTags.java index 7f5e1db7..b5418c80 100644 --- a/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/AwsTags.java +++ b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/AwsTags.java @@ -19,6 +19,22 @@ public static Tag username(String username) { return AwsTags.tag(Tags.username, username); } + public static Tag accesskeyid(String accessKeyId) { + return AwsTags.tag(Tags.accesskeyid, accessKeyId); + } + public static Tag iamrolearn(String iamrolearn) { + return AwsTags.tag(Tags.iamrolearn, iamrolearn); + } + public static Tag iamexternalid(String iamexternalid) { + return AwsTags.tag(Tags.iamexternalid, iamexternalid); + } + public static Tag iammfaserialnumberid(String iammfaserialnumberid) { + return AwsTags.tag(Tags.iammfaserialnumberid, iammfaserialnumberid); + } + public static Tag ststokenduration(String ststokenduration) { + return AwsTags.tag(Tags.ststokenduration, ststokenduration); + } + public static Tag type(String type) { return tag(Tags.type, type); } diff --git a/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/AmazonWebServicesCredentialsAssert.java b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/AmazonWebServicesCredentialsAssert.java new file mode 100644 index 00000000..17803133 --- /dev/null +++ b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/AmazonWebServicesCredentialsAssert.java @@ -0,0 +1,87 @@ +package io.jenkins.plugins.credentials.secretsmanager.util.assertions; + +import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials; +import io.jenkins.plugins.credentials.secretsmanager.factory.aws.AwsAccessKeysCredentials; +import org.assertj.core.api.AbstractAssert; + +import java.util.Objects; + +public class AmazonWebServicesCredentialsAssert extends AbstractAssert { + + public AmazonWebServicesCredentialsAssert(AmazonWebServicesCredentials actual) { + super(actual, AmazonWebServicesCredentialsAssert.class); + } + + public AmazonWebServicesCredentialsAssert hasAccessKeyId(String accessKeyId) { + isNotNull(); + + String actualAccessKeyId = actual.getCredentials().getAWSAccessKeyId(); + if (!Objects.equals(actualAccessKeyId, accessKeyId)) { + failWithMessage("Expected accessKeyId to be <%s> but was <%s>", accessKeyId, actualAccessKeyId); + } + + return this; + } + + public AmazonWebServicesCredentialsAssert hasSecretKey(String secretKey) { + isNotNull(); + String actualSecretKey = actual.getCredentials().getAWSSecretKey(); + if (!Objects.equals(actualSecretKey, secretKey)) { + failWithMessage("Expected secretkey to be <%s> but was <%s>", secretKey, actualSecretKey); + } + + return this; + } + + public AmazonWebServicesCredentialsAssert hasIamRoleArn(String iamRoleArn) { + isNotNull(); + String actualIamRoleArn = ((AwsAccessKeysCredentials)actual).getIamRoleArn(); + if (!Objects.equals(actualIamRoleArn, iamRoleArn)) { + failWithMessage("Expected iamRoleArn to be <%s> but was <%s>", iamRoleArn, actualIamRoleArn); + } + + return this; + } + + public AmazonWebServicesCredentialsAssert hasIamExternalId(String iamExternalId) { + isNotNull(); + String actualIamExternalId = ((AwsAccessKeysCredentials)actual).getIamExternalId(); + if (!Objects.equals(actualIamExternalId, iamExternalId)) { + failWithMessage("Expected iamExternalId to be <%s> but was <%s>", iamExternalId, actualIamExternalId); + } + + return this; + } + + public AmazonWebServicesCredentialsAssert hasIamMfaSerialNumber(String iamMfaSerialNumber) { + isNotNull(); + String actualIamMfaSerialNumber = ((AwsAccessKeysCredentials)actual).getIamMfaSerialNumber(); + if (!Objects.equals(actualIamMfaSerialNumber, iamMfaSerialNumber)) { + failWithMessage("Expected iamMfaSerialNumber to be <%s> but was <%s>", iamMfaSerialNumber, actualIamMfaSerialNumber); + } + + return this; + } + + public AmazonWebServicesCredentialsAssert hasStsTokenDuration(Integer stsTokenDuration) { + isNotNull(); + Integer actualStsTokenDuration = ((AwsAccessKeysCredentials)actual).getStsTokenDuration(); + if (!Objects.equals(actualStsTokenDuration, stsTokenDuration)) { + failWithMessage("Expected stsTokenDuration to be <%s> but was <%s>", stsTokenDuration, actualStsTokenDuration); + } + + return this; + } + + public AmazonWebServicesCredentialsAssert hasId(String id) { + new StandardCredentialsAssert(actual).hasId(id); + + return this; + } + + public AmazonWebServicesCredentialsAssert hasSameDescriptorIconAs(AmazonWebServicesCredentials theirs) { + new StandardCredentialsAssert(actual).hasSameDescriptorIconAs(theirs); + + return this; + } +} diff --git a/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/CustomAssertions.java b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/CustomAssertions.java index 63a92396..b6a79117 100644 --- a/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/CustomAssertions.java +++ b/src/test/java/io/jenkins/plugins/credentials/secretsmanager/util/assertions/CustomAssertions.java @@ -1,5 +1,6 @@ package io.jenkins.plugins.credentials.secretsmanager.util.assertions; +import com.cloudbees.jenkins.plugins.awscredentials.AmazonWebServicesCredentials; import com.cloudbees.jenkins.plugins.sshcredentials.SSHUserPrivateKey; import com.cloudbees.plugins.credentials.common.StandardCertificateCredentials; import com.cloudbees.plugins.credentials.common.StandardCredentials; @@ -42,6 +43,10 @@ public static SSHUserPrivateKeyAssert assertThat(SSHUserPrivateKey actual) { return new SSHUserPrivateKeyAssert(actual); } + public static AmazonWebServicesCredentialsAssert assertThat(AmazonWebServicesCredentials actual) { + return new AmazonWebServicesCredentialsAssert(actual); + } + public static WorkflowRunAssert assertThat(WorkflowRun actual) { return new WorkflowRunAssert(actual); }