- edited description
Migrate to AWS SDK v2
Issue #27
new
While v1 is working fine, other gradle plugins (S3 build cache for example) have moved to AWS SDK v2, and it would be nice to reduce the number of AWS SDK versions required to be downloaded by the build system.
com.amazonaws:aws-java-sdk-ecr:xxx → software.amazon.awssdk:ecr:xxx
Comments (3)
-
reporter -
reporter Something like:
diff --git a/build.gradle b/build.gradle index 763f162..6fe0ea4 100644 --- a/build.gradle +++ b/build.gradle @@ -52,7 +52,7 @@ dependencies { implementation gradleApi() implementation localGroovy() implementation 'com.bmuschko:gradle-docker-plugin:6.4.0' - implementation 'com.amazonaws:aws-java-sdk-ecr:1.11.759' + implementation 'software.amazon.awssdk:ecr:2.16.60' testImplementation('org.spockframework:spock-core:1.1-groovy-2.4') { exclude module: 'groovy-all' } diff --git a/src/main/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentials.groovy b/src/main/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentials.groovy index 3ac165d..b8c89ac 100644 --- a/src/main/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentials.groovy +++ b/src/main/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentials.groovy @@ -1,10 +1,5 @@ package com.patdouble.gradle.awsecr -import com.amazonaws.auth.AWSStaticCredentialsProvider -import com.amazonaws.auth.BasicAWSCredentials -import com.amazonaws.services.ecr.AmazonECRClientBuilder -import com.amazonaws.services.ecr.model.GetAuthorizationTokenRequest -import com.amazonaws.services.ecr.model.GetAuthorizationTokenResult import com.bmuschko.gradle.docker.DockerRegistryCredentials import com.bmuschko.gradle.docker.tasks.RegistryCredentialsAware import groovy.transform.Canonical @@ -16,6 +11,12 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Optional import org.gradle.api.tasks.TaskAction +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider +import software.amazon.awssdk.regions.Region +import software.amazon.awssdk.services.ecr.EcrClient +import software.amazon.awssdk.services.ecr.EcrClientBuilder +import software.amazon.awssdk.services.ecr.model.GetAuthorizationTokenResponse import java.security.MessageDigest @@ -132,27 +133,30 @@ class PopulateECRCredentials extends DefaultTask implements RegistryCredentialsA //Get the region from the registry URL String region = registryUrl.replaceAll(/^.*ecr\.(.*)\.amazonaws.*$/, '$1') - AmazonECRClientBuilder ecrClientBuilder = AmazonECRClientBuilder.standard().withRegion(region) + EcrClientBuilder ecrClientBuilder = EcrClient.builder().region(Region.of(region)) if (awsAccessKeyId && awsSecretAccessKey) { - ecrClientBuilder.credentials = new AWSStaticCredentialsProvider( - new BasicAWSCredentials(awsAccessKeyId, awsSecretAccessKey)) + ecrClientBuilder.credentials = StaticCredentialsProvider.create( + AwsBasicCredentials.create(awsAccessKeyId, awsSecretAccessKey) + ) } - GetAuthorizationTokenResult tokens = ecrClientBuilder.build() - .getAuthorizationToken(new GetAuthorizationTokenRequest().withRegistryIds(registryId)) + GetAuthorizationTokenResponse tokens = ecrClientBuilder.build() + .getAuthorizationToken({ request -> + request.registryIds(registryId) + }) - if (!tokens.authorizationData) { - throw new GradleException("Could not get ECR token: ${tokens.sdkHttpMetadata.httpStatusCode}") + if (!tokens.authorizationData()) { + throw new GradleException("Could not get ECR token: ${tokens.sdkHttpResponse().statusCode()}") } - String[] ecrCreds = new String(tokens.authorizationData.first().authorizationToken.decodeBase64(), + String[] ecrCreds = new String(tokens.authorizationData().first().authorizationToken().decodeBase64(), 'US-ASCII').split(COLON_SEPARATOR) new CachedCredentials( username: ecrCreds[0], password: ecrCreds[1], - expiresAt: tokens.authorizationData.first().expiresAt.time, + expiresAt: tokens.authorizationData().first().expiresAt().epochSecond, ) }
But as the EcrClient is no longer a concrete class, but rather an interface, I didn’t get the tests working. Tried using DefaultEcrClient, which is concrete, but it needs an argument for creation. Maybe trivial to… dunno.. I’m not native to Groovy.
diff --git a/src/test/groovy/com/patdouble/gradle/awsecr/CredentialsFileSpec.groovy b/src/test/groovy/com/patdouble/gradle/awsecr/CredentialsFileSpec.groovy index 1f30886..ff9d30b 100644 --- a/src/test/groovy/com/patdouble/gradle/awsecr/CredentialsFileSpec.groovy +++ b/src/test/groovy/com/patdouble/gradle/awsecr/CredentialsFileSpec.groovy @@ -1,18 +1,20 @@ package com.patdouble.gradle.awsecr -import com.amazonaws.auth.DefaultAWSCredentialsProviderChain -import com.amazonaws.services.ecr.AmazonECRClient -import com.amazonaws.services.ecr.model.AuthorizationData -import com.amazonaws.services.ecr.model.GetAuthorizationTokenRequest -import com.amazonaws.services.ecr.model.GetAuthorizationTokenResult import org.gradle.testfixtures.ProjectBuilder import org.junit.Rule import org.junit.rules.TemporaryFolder +import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain +import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider +import software.amazon.awssdk.services.ecr.DefaultEcrClient +import software.amazon.awssdk.services.ecr.EcrClient +import software.amazon.awssdk.services.ecr.model.GetAuthorizationTokenRequest +import software.amazon.awssdk.services.ecr.model.GetAuthorizationTokenResponse import spock.lang.Specification import spock.lang.Unroll import java.lang.reflect.Field import java.lang.reflect.Modifier +import java.time.Instant /** * Tests usage of the AWS credentials file that is handled automatically by the default AWS client. @@ -50,14 +52,15 @@ class CredentialsFileSpec extends Specification { task.credentialFile.delete() // Set the DefaultAWSCredentialsProviderChain.INSTANCE field to get the new profile - def providerChainInstance = DefaultAWSCredentialsProviderChain.getDeclaredField('INSTANCE') + def providerChainInstance = DefaultCredentialsProvider.getDeclaredField('DEFAULT_CREDENTIALS_PROVIDER') providerChainInstance.accessible = true Field modifiersField = Field.class.getDeclaredField("modifiers") modifiersField.accessible = true modifiersField.setInt(providerChainInstance, providerChainInstance.getModifiers() & ~Modifier.FINAL) - providerChainInstance.set(null, new DefaultAWSCredentialsProviderChain()) + providerChainInstance.set(null, AwsCredentialsProviderChain.builder().build()) - def amazonECRClient = GroovySpy(AmazonECRClient, global: true) + // TODO: Doesn't work as it needs ClientConfiguration + def amazonECRClient = GroovySpy(DefaultEcrClient, global: true) when: task.populateCredentials() @@ -65,12 +68,16 @@ class CredentialsFileSpec extends Specification { then: 1 * amazonECRClient.getAuthorizationToken(_) >> { GetAuthorizationTokenRequest request -> // we're changing the getAuthorizationToken(...) method to return the AWS credentials so we can verify it later - AmazonECRClient thisClient = delegate.mockObject.instance - Field awsCredentialsProviderField = AmazonECRClient.getDeclaredField('awsCredentialsProvider') + EcrClient thisClient = delegate.mockObject.instance + // TODO: This has to be something else as that method doesn't exist there. + Field awsCredentialsProviderField = EcrClient.getDeclaredField('awsCredentialsProvider') awsCredentialsProviderField.accessible = true def awsCredentialsProvider = awsCredentialsProviderField.get(thisClient) def credentials = awsCredentialsProvider.getCredentials() - new GetAuthorizationTokenResult().withAuthorizationData(new AuthorizationData(authorizationToken: "${credentials.AWSAccessKeyId}:${credentials.AWSSecretKey}".bytes.encodeBase64().toString(), expiresAt: new Date() + 7)) + GetAuthorizationTokenResponse.builder().authorizationData({ data -> + data.authorizationToken("${credentials.AWSAccessKeyId}:${credentials.AWSSecretKey}".bytes.encodeBase64().toString()) + data.expiresAt(Instant.now() + 7) + }) } and: diff --git a/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsNoECRSpec.groovy b/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsNoECRSpec.groovy index 803a351..a557f9f 100644 --- a/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsNoECRSpec.groovy +++ b/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsNoECRSpec.groovy @@ -1,9 +1,10 @@ package com.patdouble.gradle.awsecr -import com.amazonaws.services.ecr.AmazonECRClient import org.gradle.testfixtures.ProjectBuilder import org.junit.Rule import org.junit.rules.TemporaryFolder +import software.amazon.awssdk.services.ecr.DefaultEcrClient +import software.amazon.awssdk.services.ecr.EcrClient import spock.lang.Specification /** @@ -11,12 +12,13 @@ import spock.lang.Specification */ class PopulateECRCredentialsNoECRSpec extends Specification { PopulateECRCredentials task - AmazonECRClient amazonECRClient + EcrClient amazonECRClient @Rule TemporaryFolder tmp def setup() { - amazonECRClient = GroovySpy(AmazonECRClient, global: true) + // TODO: Doesn't work as it needs ClientConfiguration + amazonECRClient = GroovySpy(DefaultEcrClient, global: true) def project = ProjectBuilder.builder().withProjectDir(tmp.newFolder('project')).build() project.with { diff --git a/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsSpec.groovy b/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsSpec.groovy index f1c20e2..2158fab 100644 --- a/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsSpec.groovy +++ b/src/test/groovy/com/patdouble/gradle/awsecr/PopulateECRCredentialsSpec.groovy @@ -1,27 +1,31 @@ package com.patdouble.gradle.awsecr -import com.amazonaws.auth.AWSStaticCredentialsProvider -import com.amazonaws.auth.BasicAWSCredentials -import com.amazonaws.services.ecr.AmazonECRClient -import com.amazonaws.services.ecr.model.AuthorizationData -import com.amazonaws.services.ecr.model.GetAuthorizationTokenRequest -import com.amazonaws.services.ecr.model.GetAuthorizationTokenResult import org.gradle.testfixtures.ProjectBuilder import org.junit.Rule import org.junit.rules.TemporaryFolder +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider +import software.amazon.awssdk.services.ecr.DefaultEcrClient +import software.amazon.awssdk.services.ecr.EcrClient +import software.amazon.awssdk.services.ecr.model.AuthorizationData +import software.amazon.awssdk.services.ecr.model.GetAuthorizationTokenRequest +import software.amazon.awssdk.services.ecr.model.GetAuthorizationTokenResponse import spock.lang.Specification import com.patdouble.gradle.awsecr.PopulateECRCredentials.CachedCredentials +import java.time.Instant import java.util.concurrent.TimeUnit class PopulateECRCredentialsSpec extends Specification { PopulateECRCredentials task - AmazonECRClient amazonECRClient + EcrClient amazonECRClient @Rule TemporaryFolder tmp + @SuppressWarnings('GroovyAccessibility') def setup() { - amazonECRClient = GroovySpy(AmazonECRClient, global: true) + // TODO: Doesn't work as it needs ClientConfiguration + amazonECRClient = GroovySpy(DefaultEcrClient, global: true) def project = ProjectBuilder.builder().withProjectDir(tmp.newFolder('project')).build() project.with { @@ -98,11 +102,16 @@ class PopulateECRCredentialsSpec extends Specification { void "should request credentials from AWS"() { given: - def tokens = new GetAuthorizationTokenResult().withAuthorizationData(new AuthorizationData(authorizationToken: 'user1:pw'.bytes.encodeBase64().toString(), expiresAt: new Date() + 7)) + def tokens = GetAuthorizationTokenResponse.builder().authorizationData({ data -> + data.authorizationToken('user1:pw'.bytes.encodeBase64().toString()) + data.expiresAt(Instant.now() + 7) + }).build() when: task.populateCredentials() then: - 1 * amazonECRClient.getAuthorizationToken(new GetAuthorizationTokenRequest().withRegistryIds('123456789')) >> tokens + 1 * amazonECRClient.getAuthorizationToken({ request -> + request.registryIds('123456789') + }) >> tokens and: task.registryCredentials.username.get() == 'user1' task.registryCredentials.password.get() == 'pw' @@ -110,16 +119,23 @@ class PopulateECRCredentialsSpec extends Specification { void "should request credentials with AWS keys"() { given: - def tokens = new GetAuthorizationTokenResult().withAuthorizationData(new AuthorizationData(authorizationToken: 'user1:pw'.bytes.encodeBase64().toString(), expiresAt: new Date() + 7)) - def request = new GetAuthorizationTokenRequest().withRegistryIds('123456789') + def tokens = GetAuthorizationTokenResponse.builder().authorizationData({ data -> + data.authorizationToken('user1:pw'.bytes.encodeBase64().toString()) + data.expiresAt(Instant.now() + 7) + }) task.awsAccessKeyId = 'aws_access_key' task.awsSecretAccessKey = 'aws_secret_key' - request.setRequestCredentialsProvider(new AWSStaticCredentialsProvider( - new BasicAWSCredentials('aws_access_key', 'aws_secret_key'))) when: task.populateCredentials() then: - 1 * amazonECRClient.getAuthorizationToken(request) >> tokens + 1 * amazonECRClient.getAuthorizationToken({ request -> + request.registryIds('123456789') + request.overrideConfiguration( { config -> + config.credentialsProvider(StaticCredentialsProvider.create( + AwsBasicCredentials.create('aws_access_key', 'aws_secret_key') + )) + }) + }) >> tokens and: task.registryCredentials.username.get() == 'user1' task.registryCredentials.password.get() == 'pw' @@ -140,7 +156,10 @@ class PopulateECRCredentialsSpec extends Specification { void "should configure refreshed credentials"() { given: - def tokens = new GetAuthorizationTokenResult().withAuthorizationData(new AuthorizationData(authorizationToken: 'user1:pw'.bytes.encodeBase64().toString(), expiresAt: new Date() + 7)) + def tokens = GetAuthorizationTokenResponse.builder().authorizationData({ data -> + data.authorizationToken('user1:pw'.bytes.encodeBase64().toString()) + data.expiresAt(Instant.now() + 7) + }).build() def creds = new CachedCredentials(username: 'cacheduser', password: 'cachedpw', expiresAt: (new Date()-7).time) task.setCachedCredentials(task.getCredentialFile(), creds) when:
-
reporter This idea from gradle s3 build cache plugin is also a bit interesting, and slightly related, after moving to 2.x, https://github.com/burrunan/gradle-s3-build-cache/issues/5
- Log in to comment