Skip to content

Commit

Permalink
Merge branch 'master' into 713-enhancement-redis-support-encryption-i…
Browse files Browse the repository at this point in the history
…n-transit
  • Loading branch information
munishchouhan authored Nov 18, 2024
2 parents d961bc9 + 080d5cc commit 71c7107
Show file tree
Hide file tree
Showing 48 changed files with 228 additions and 346 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
strategy:
fail-fast: false
matrix:
java_version: [19]
java_version: [21]

steps:
- name: Environment
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ images.
* Push and cache built containers to a user-provided container repository;
* Build Singularity native containers both using a Singularity spec file, Conda package(s);
* Push Singularity native container images to OCI-compliant registries;

* Scan container images for security vulnerabilities

### How it works

Expand All @@ -34,7 +34,7 @@ container registry where the image is stored, while the instrumented layers are

### Requirements

* Java 19 or later
* Java 21 or later
* Linux or macOS
* Redis 6.2 (or later)
* Docker engine (for development)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.13.11
1.15.0
87 changes: 44 additions & 43 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,79 +29,81 @@ repositories {
}

dependencies {
annotationProcessor("io.micronaut.validation:micronaut-validation-processor")
annotationProcessor("io.micronaut:micronaut-http-validation")
compileOnly("io.micronaut.data:micronaut-data-processor")
compileOnly("io.micronaut:micronaut-inject-groovy")
compileOnly("io.micronaut:micronaut-http-validation")
implementation("jakarta.persistence:jakarta.persistence-api:3.0.0")
api 'io.seqera:lib-mail:1.1.0'
api 'io.seqera:wave-api:0.13.3'
api 'io.seqera:wave-utils:0.14.1'
implementation("io.micronaut:micronaut-http-client")
implementation("io.micronaut:micronaut-jackson-databind")
implementation("io.micronaut.groovy:micronaut-runtime-groovy")
implementation("io.micronaut.reactor:micronaut-reactor")
implementation("io.micronaut.reactor:micronaut-reactor-http-client")
implementation("jakarta.annotation:jakarta.annotation-api")
implementation("io.micronaut.validation:micronaut-validation")
annotationProcessor 'io.micronaut.validation:micronaut-validation-processor'
annotationProcessor 'io.micronaut:micronaut-http-validation'
compileOnly 'io.micronaut.data:micronaut-data-processor'
compileOnly 'io.micronaut:micronaut-inject-groovy'
compileOnly 'io.micronaut:micronaut-http-validation'
implementation 'jakarta.persistence:jakarta.persistence-api:3.0.0'
api 'io.seqera:lib-mail:1.2.0'
api 'io.seqera:wave-api:0.14.0'
api 'io.seqera:wave-utils:0.15.0'
implementation 'io.micronaut:micronaut-http-client'
implementation 'io.micronaut:micronaut-jackson-databind'
implementation 'io.micronaut.groovy:micronaut-runtime-groovy'
implementation 'io.micronaut.reactor:micronaut-reactor'
implementation 'io.micronaut.reactor:micronaut-reactor-http-client'
implementation 'jakarta.annotation:jakarta.annotation-api'
implementation 'io.micronaut.validation:micronaut-validation'
implementation 'io.micronaut.security:micronaut-security'
implementation "org.apache.groovy:groovy-json"
implementation "org.apache.groovy:groovy-nio"
implementation 'com.google.guava:guava:32.1.2-jre'
implementation 'io.micronaut:micronaut-websocket'
implementation 'org.apache.groovy:groovy-json'
implementation 'org.apache.groovy:groovy-nio'
implementation 'com.google.guava:guava:33.3.1-jre'
implementation 'dev.failsafe:failsafe:3.1.0'
implementation 'io.micronaut.reactor:micronaut-reactor'
implementation 'io.micronaut.reactor:micronaut-reactor-http-client'
implementation("io.seqera:tower-crypto:22.4.0-watson") { transitive = false } // to be replaced with 22.4.0 once released
implementation('io.seqera:tower-crypto:22.4.0-watson') { transitive = false } // to be replaced with 22.4.0 once released
implementation 'org.apache.commons:commons-compress:1.27.1'
implementation 'org.apache.commons:commons-lang3:3.12.0'
implementation 'org.apache.commons:commons-lang3:3.17.0'
implementation 'io.kubernetes:client-java:19.0.0'
implementation 'io.kubernetes:client-java-api-fluent:18.0.1'
implementation 'com.google.code.gson:gson:2.9.0'
implementation "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml'
implementation 'com.squareup.moshi:moshi:1.14.0'
implementation 'com.squareup.moshi:moshi-adapters:1.14.0'
implementation 'com.squareup.moshi:moshi:1.15.1'
implementation 'com.squareup.moshi:moshi-adapters:1.15.1'
implementation 'redis.clients:jedis:5.1.3'
implementation "io.github.resilience4j:resilience4j-ratelimiter:0.17.0"
implementation("io.micronaut:micronaut-retry")
implementation 'io.github.resilience4j:resilience4j-ratelimiter:0.17.0'
implementation 'io.micronaut:micronaut-retry'
// caching deps
implementation("io.micronaut.cache:micronaut-cache-core")
implementation("io.micronaut.cache:micronaut-cache-caffeine")
implementation("io.micronaut.aws:micronaut-aws-parameter-store")
implementation "software.amazon.awssdk:ecr"
implementation "software.amazon.awssdk:ecrpublic"
implementation 'io.micronaut.cache:micronaut-cache-core'
implementation 'io.micronaut.cache:micronaut-cache-caffeine'
implementation 'io.micronaut.aws:micronaut-aws-parameter-store'
implementation 'software.amazon.awssdk:ecr'
implementation 'software.amazon.awssdk:ecrpublic'
implementation 'software.amazon.awssdk:ses'
implementation 'org.yaml:snakeyaml:2.2'
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
implementation 'org.luaj:luaj-jse:3.0.1'
//object storage dependency
implementation("io.micronaut.objectstorage:micronaut-object-storage-aws")
implementation 'io.micronaut.objectstorage:micronaut-object-storage-aws'
// include sts to allow the use of service account role - https://stackoverflow.com/a/73306570
// this sts dependency is require by micronaut-aws-parameter-store,
// not directly used by the app, for this reason keeping `runtimeOnly`
runtimeOnly "software.amazon.awssdk:sts"
runtimeOnly("io.netty:netty-tcnative-boringssl-static:2.0.0.Final")
runtimeOnly("javax.xml.bind:jaxb-api:2.3.1")
testImplementation("org.testcontainers:testcontainers")
testImplementation("org.testcontainers:mysql:1.17.3")
runtimeOnly 'software.amazon.awssdk:sts'
runtimeOnly 'io.netty:netty-tcnative-boringssl-static:2.0.0.Final'
runtimeOnly 'javax.xml.bind:jaxb-api:2.3.1'
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:mysql:1.17.3'

// --
implementation("ch.qos.logback:logback-classic:1.5.12")
implementation 'ch.qos.logback:logback-classic:1.5.12'

// rate limit
implementation 'com.coveo:spillway:3.0.0'

// monitoring
implementation "io.micronaut.micrometer:micronaut-micrometer-registry-prometheus"
implementation 'io.micronaut.micrometer:micronaut-micrometer-registry-prometheus'
// Also required to enable endpoint
implementation "io.micronaut:micronaut-management"
implementation 'io.micronaut:micronaut-management'
//views
implementation("io.micronaut.views:micronaut-views-handlebars")
implementation 'io.micronaut.views:micronaut-views-handlebars'

// upgrade indirect dependencies
runtimeOnly 'org.bouncycastle:bcpkix-jdk18on:1.78'
runtimeOnly 'org.bitbucket.b_c:jose4j:0.9.4'
runtimeOnly 'io.netty:netty-bom:4.1.115.Final'
}

application {
Expand Down Expand Up @@ -154,8 +156,7 @@ jib {

run{
def envs = findProperty('micronautEnvs')
// note: "--enable-preview" is required to use virtual threads on Java 19 and 20
def args = ["-Dmicronaut.environments=$envs","--enable-preview"]
def args = ["-Dmicronaut.environments=$envs","-Djdk.tracePinnedThreads=short"]
if( environment['JVM_OPTS'] ) args.add(environment['JVM_OPTS'])
jvmArgs args
systemProperties 'DOCKER_USER': project.findProperty('DOCKER_USER') ?: environment['DOCKER_USER'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,3 @@ plugins {
}

group = 'io.seqera'

tasks.withType(Test).configureEach {
// note: "--enable-preview" is required to use virtual thread on Java 19 and 20
jvmArgs(["--enable-preview"])
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ repositories {

java {
toolchain {
languageVersion = JavaLanguageVersion.of(19)
languageVersion = JavaLanguageVersion.of(21)
}
}

compileJava {
options.release.set(11)
options.release.set(17)
}

tasks.withType(GroovyCompile).configureEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ repositories {

java {
toolchain {
languageVersion = JavaLanguageVersion.of(19)
languageVersion = JavaLanguageVersion.of(21)
}
}

compileJava {
options.release.set(11)
options.release.set(17)
}

tasks.withType(GroovyCompile).configureEach {
Expand All @@ -40,7 +40,7 @@ java {
}

dependencies {
implementation 'org.slf4j:slf4j-api:2.0.13'
implementation 'org.slf4j:slf4j-api:2.0.16'

testImplementation 'ch.qos.logback:logback-core:1.5.12'
testImplementation 'ch.qos.logback:logback-classic:1.5.12'
Expand All @@ -55,7 +55,6 @@ dependencies {

tasks.withType(Test).configureEach {
jvmArgs([
'--enable-preview',
'--add-opens=java.base/java.lang=ALL-UNNAMED',
'--add-opens=java.base/java.io=ALL-UNNAMED',
'--add-opens=java.base/java.nio=ALL-UNNAMED',
Expand Down
28 changes: 28 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
# Wave changelog
1.15.0 - 18 Nov 2024
- Migration to virtual threads - phase 1 (#746) [aaf0420c]
- Use runAsync instead supplyAsync [ffd0dacd]
- Remove deprecated ThreadPoolBuilder [7af3046f]
- Replace Guava cache with Caffeine (#745) [cf813e0a]
- Update project deps [f24b684d]
- Bump guava to version 33.3.1-jre [328e9ea3]
- Bump Netty version 4.1.115.Final [9ba433ce]
- Bump gradle 8.10.2 [52272fe1]

1.14.1 - 14 Nov 2024
- Fix creds validation endpoint (#740) [8c0f3a4c]

1.14.0 - 10 Nov 2024
- Fix K8s env propagation [76f0a456]
- Remove deprecated K8s methods (#734) [481298bf]
- Bump to Micronaut 4.6 (#318) [f67e8556]
- Bump Java 21 as build requirement (#519) [132f9491]
- Bump bitbucket.b_c:jose4j:0.9.4 [2e10416a]
- Bump bouncycastle:bcpkix-jdk18on:1.78 [ede22ce5]
- Bump jedis 5.1.3 (#732) [2ee0854e]
- Bump logback 1.5.12 [f5fe3fa4]
- Bump make deps runtimeclasspath [2a342b18]
- Bump snakeyaml 2.2 [6aeb3c33]
- Bump spillway 3.0.0 (#731) [1502696d]
- Bump explicit dep to websocket module [2e413ac2]
- Enables EKS Pod identity via AWS SDK 2.27.8

1.13.11 - 2 Nov 2024
- Rename async methods for semantic consistency [38114d75]
- Save scan record async (#730) [3ad82a3a]
Expand Down
4 changes: 2 additions & 2 deletions docs/cli/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ The following CLI arguments are available for Seqera Platform integration:

The following environment variables are available for Seqera Platform integration:

- `TOWER_API_ENDPOINT`: A Seqera Platform auth token so that Wave can access your private registry credentials.
- `TOWER_ACCESS_TOKEN`: For Enterprise customers, the URL endpoint for your instance, such as `https://api.cloud.seqera.io`.
- `TOWER_ACCESS_TOKEN`: A Seqera Platform auth token so that Wave can access your private registry credentials.
- `TOWER_API_ENDPOINT`: For Enterprise customers, the URL endpoint for your instance, such as `https://api.cloud.seqera.io`.
- `TOWER_WORKSPACE_ID`: A Seqera Platform workspace ID, such as `1234567890`, where credentials may be stored.

## Usage limits
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
7 changes: 7 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
plugins {
// required to download the toolchain (jdk) from a remote repository
// https://github.com/gradle/foojay-toolchains
// https://docs.gradle.org/current/userguide/toolchains.html#sub:download_repositories
id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
}

rootProject.name="wave"

// only for development
Expand Down
22 changes: 12 additions & 10 deletions src/main/groovy/io/seqera/wave/auth/RegistryAuthServiceImpl.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,12 @@ package io.seqera.wave.auth
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.time.Duration
import java.util.concurrent.ExecutionException
import java.util.concurrent.CompletionException
import java.util.concurrent.TimeUnit

import com.google.common.cache.CacheBuilder
import com.google.common.cache.CacheLoader
import com.google.common.cache.LoadingCache
import com.google.common.util.concurrent.UncheckedExecutionException
import com.github.benmanes.caffeine.cache.AsyncLoadingCache
import com.github.benmanes.caffeine.cache.CacheLoader
import com.github.benmanes.caffeine.cache.Caffeine
import groovy.json.JsonSlurper
import groovy.transform.Canonical
import groovy.transform.CompileStatic
Expand Down Expand Up @@ -101,11 +100,12 @@ class RegistryAuthServiceImpl implements RegistryAuthService {
return result
}

private LoadingCache<CacheKey, String> cacheTokens = CacheBuilder<CacheKey, String>
// FIXME https://github.com/seqeralabs/wave/issues/747
private AsyncLoadingCache<CacheKey, String> cacheTokens = Caffeine.newBuilder()
.newBuilder()
.maximumSize(10_000)
.expireAfterAccess(_1_HOUR.toMillis(), TimeUnit.MILLISECONDS)
.build(loader)
.buildAsync(loader)

@Inject
private RegistryLookupService lookupService
Expand Down Expand Up @@ -269,9 +269,10 @@ class RegistryAuthServiceImpl implements RegistryAuthService {
protected String getAuthToken(String image, RegistryAuth auth, RegistryCredentials creds) {
final key = new CacheKey(image, auth, creds)
try {
return cacheTokens.get(key)
// FIXME https://github.com/seqeralabs/wave/issues/747
return cacheTokens.synchronous().get(key)
}
catch (UncheckedExecutionException | ExecutionException e) {
catch (CompletionException e) {
// this catches the exception thrown in the cache loader lookup
// and throws the causing exception that should be `RegistryUnauthorizedAccessException`
throw e.cause
Expand All @@ -287,7 +288,8 @@ class RegistryAuthServiceImpl implements RegistryAuthService {
*/
void invalidateAuthorization(String image, RegistryAuth auth, RegistryCredentials creds) {
final key = new CacheKey(image, auth, creds)
cacheTokens.invalidate(key)
// FIXME https://github.com/seqeralabs/wave/issues/747
cacheTokens.synchronous().invalidate(key)
tokenStore.remove(getStableKey(key))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ package io.seqera.wave.auth

import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.util.concurrent.ExecutionException
import java.util.concurrent.CompletionException
import java.util.concurrent.TimeUnit

import com.google.common.cache.CacheBuilder
import com.google.common.cache.CacheLoader
import com.google.common.cache.LoadingCache
import com.google.common.util.concurrent.UncheckedExecutionException
import com.github.benmanes.caffeine.cache.AsyncLoadingCache
import com.github.benmanes.caffeine.cache.CacheLoader
import com.github.benmanes.caffeine.cache.Caffeine
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
import io.seqera.wave.configuration.HttpClientConfig
Expand Down Expand Up @@ -74,11 +73,12 @@ class RegistryLookupServiceImpl implements RegistryLookupService {
}
}

private LoadingCache<URI, RegistryAuth> cache = CacheBuilder<URI, RegistryAuth>
// FIXME https://github.com/seqeralabs/wave/issues/747
private AsyncLoadingCache<URI, RegistryAuth> cache = Caffeine.newBuilder()
.newBuilder()
.maximumSize(10_000)
.expireAfterAccess(1, TimeUnit.HOURS)
.build(loader)
.buildAsync(loader)

protected RegistryAuth lookup0(URI endpoint) {
final httpClient = HttpClientFactory.followRedirectsHttpClient()
Expand Down Expand Up @@ -117,10 +117,11 @@ class RegistryLookupServiceImpl implements RegistryLookupService {
RegistryInfo lookup(String registry) {
try {
final endpoint = registryEndpoint(registry)
final auth = cache.get(endpoint)
// FIXME https://github.com/seqeralabs/wave/issues/747
final auth = cache.synchronous().get(endpoint)
return new RegistryInfo(registry, endpoint, auth)
}
catch (UncheckedExecutionException | ExecutionException e) {
catch (CompletionException e) {
// this catches the exception thrown in the cache loader lookup
// and throws the causing exception that should be `RegistryUnauthorizedAccessException`
throw e.cause
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class ScanConfig {
final name = p!=-1 ? entry.substring(0,p) : entry
final value = p!=-1 ? entry.substring(p+1) : ''
if( !value )
log.warn "Invalid 'wave.scan.environment value' -- offending entry: '$entry'"
log.warn "Invalid 'wave.scan.environment' value -- offending entry: '$entry'"
result.add(new Tuple2(name,value))
}
return result
Expand Down
Loading

0 comments on commit 71c7107

Please sign in to comment.