Skip to content

Commit

Permalink
Add ability to configure trivy dbs (#720)
Browse files Browse the repository at this point in the history
Signed-off-by: Paolo Di Tommaso <[email protected]>
  • Loading branch information
pditommaso committed Oct 25, 2024
1 parent 0e2e9f5 commit 0f60030
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 19 deletions.
27 changes: 20 additions & 7 deletions src/main/groovy/io/seqera/wave/configuration/ScanConfig.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@ package io.seqera.wave.configuration
import java.nio.file.Files
import java.nio.file.Path
import java.time.Duration

import io.micronaut.context.annotation.Requires
import io.micronaut.core.annotation.Nullable
import javax.annotation.PostConstruct

import groovy.transform.CompileStatic
import groovy.transform.Memoized
import groovy.util.logging.Slf4j
import io.micronaut.context.annotation.Requires
import io.micronaut.context.annotation.Value
import io.seqera.wave.util.StringUtils
import io.micronaut.core.annotation.Nullable
import jakarta.inject.Singleton
/**
* Container Scan service settings
Expand Down Expand Up @@ -83,8 +81,8 @@ class ScanConfig {
Duration scanIdDuration

@Nullable
@Value('${wave.scan.github-token}')
String githubToken
@Value('${wave.scan.environment}')
List<String> environment

String getScanImage() {
return scanImage
Expand Down Expand Up @@ -118,8 +116,23 @@ class ScanConfig {
return severity
}

List<Tuple2<String,String>> getEnvironmentAsTuples() {
if( !environment )
return List.of()
final result = new ArrayList<Tuple2<String,String>>()
for( String entry : environment ) {
final p=entry.indexOf('=')
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'"
result.add(new Tuple2(name,value))
}
return result
}

@PostConstruct
private void init() {
log.info("Scanner config: docker image name: ${scanImage}; cache directory: ${cacheDirectory}; timeout=${timeout}; cpus: ${requestsCpu}; mem: ${requestsMemory}; severity: $severity; retry-attempts: $retryAttempts; github-token=${StringUtils.redact(githubToken)}")
log.info("Scan config: docker image name: ${scanImage}; cache directory: ${cacheDirectory}; timeout=${timeout}; cpus: ${requestsCpu}; mem: ${requestsMemory}; severity: $severity; retry-attempts: $retryAttempts; env=${environment}")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -784,8 +784,11 @@ class K8sServiceImpl implements K8sService {
.withVolumeMounts(mounts)
.withResources(requests)

if( scanConfig.githubToken ) {
container.withEnv(new V1EnvVar().name('GITHUB_TOKEN').value(scanConfig.githubToken))
final env = scanConfig.environmentAsTuples
for( Tuple2 entry : env ) {
final String k = entry.v1
final String v = entry.v2
container.withEnv(new V1EnvVar().name(k).value(v))
}

// spec section
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class DockerScanStrategy extends ScanStrategy {
// outfile file name
final reportFile = req.workDir.resolve(Trivy.OUTPUT_FILE_NAME)
// create the launch command
final dockerCommand = dockerWrapper(jobName, req.workDir, configFile, scanConfig.githubToken)
final dockerCommand = dockerWrapper(jobName, req.workDir, configFile, scanConfig.environment)
final trivyCommand = List.of(scanConfig.scanImage) + scanCommand(req.targetImage, reportFile, req.platform, scanConfig)
final command = dockerCommand + trivyCommand

Expand All @@ -89,7 +89,7 @@ class DockerScanStrategy extends ScanStrategy {
}
}

protected List<String> dockerWrapper(String jobName, Path scanDir, Path credsFile, String githubToken) {
protected List<String> dockerWrapper(String jobName, Path scanDir, Path credsFile, List<String> env) {

final wrapper = ['docker','run']
wrapper.add('--detach')
Expand All @@ -112,9 +112,11 @@ class DockerScanStrategy extends ScanStrategy {
wrapper.add("${credsFile}:${Trivy.CONFIG_MOUNT_PATH}:ro".toString())
}

if( githubToken ) {
wrapper.add('-e')
wrapper.add("GITHUB_TOKEN="+githubToken)
if( env ) {
for( String it : env ) {
wrapper.add('-e')
wrapper.add(it)
}
}

return wrapper
Expand Down
1 change: 0 additions & 1 deletion src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ wave:
enabled: true
failure:
duration: '30s'
github-token: "${GITHUB_TOKEN:}"
build:
workspace: 'build-workspace'
metrics:
Expand Down
6 changes: 5 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,11 @@ wave:
multiplier: '1.75'
scan:
image:
name: aquasec/trivy:0.55.0
name: aquasec/trivy:0.56.2
environment:
# see https://github.com/aquasecurity/trivy/discussions/7668#discussioncomment-11028887
- "TRIVY_DB_REPOSITORY=public.ecr.aws/aquasecurity/trivy-db"
- "TRIVY_JAVA_DB_REPOSITORY=public.ecr.aws/aquasecurity/trivy-java-db"
blobCache:
s5cmdImage: public.cr.seqera.io/wave/s5cmd:v2.2.2
---
Expand Down
41 changes: 41 additions & 0 deletions src/test/groovy/io/seqera/wave/configuration/ScanConfigTest.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Wave, containers provisioning service
* Copyright (c) 2023-2024, Seqera Labs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package io.seqera.wave.configuration

import spock.lang.Specification

/**
*
* @author Paolo Di Tommaso <[email protected]>
*/
class ScanConfigTest extends Specification {

def 'should convert env to tuples' () {
given:
def config1 = new ScanConfig()
def config2 = new ScanConfig(environment: ['FOO=one','BAR=two'])
def config3 = new ScanConfig(environment: ['FOO','BAR='])

expect:
config1.environmentAsTuples == []
config2.environmentAsTuples == [new Tuple2('FOO','one'), new Tuple2('BAR','two')]
config3.environmentAsTuples == [new Tuple2('FOO',''), new Tuple2('BAR','')]

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ class K8sServiceImplTest extends Specification {
getCacheDirectory() >> Path.of('/build/cache/dir')
getRequestsCpu() >> '2'
getRequestsMemory() >> '4Gi'
getGithubToken() >> '123abc'
getEnvironmentAsTuples() >> [new Tuple2<String, String>('GITHUB_TOKEN', '123abc')]
}

when:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class DockerScanStrategyTest extends Specification {
when:
def scanDir = Path.of('/some/scan/dir')
def config = Path.of("/user/test/build-workspace/config.json")
def command = dockerContainerStrategy.dockerWrapper('foo-123', scanDir, config, 'xyz')
def command = dockerContainerStrategy.dockerWrapper('foo-123', scanDir, config, ['FOO=1', 'BAR=2'])

then:
command == [
Expand All @@ -60,7 +60,9 @@ class DockerScanStrategyTest extends Specification {
'-v',
'/user/test/build-workspace/config.json:/root/.docker/config.json:ro',
'-e',
'GITHUB_TOKEN=xyz'
'FOO=1',
'-e',
'BAR=2'
]

cleanup:
Expand Down

0 comments on commit 0f60030

Please sign in to comment.