Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce locks when writing to infra repo #34

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@
All notable changes to this project will be documented in this file. See
[Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.3.3](https://github.com/stenic/jpipe/compare/v1.3.2...v1.3.3) (2023-03-24)


### Bug Fixes

* github host-key entry https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/ ([b9a435b](https://github.com/stenic/jpipe/commit/b9a435bcdb4e42fe15f6d0f025e0b9bdf014536b))

## [1.3.2](https://github.com/stenic/jpipe/compare/v1.3.1...v1.3.2) (2023-03-24)


### Bug Fixes

* Format and rebuild image ([068d8ab](https://github.com/stenic/jpipe/commit/068d8ab0b96172ad87a0c0ac781270a43ec21c03))

## [1.3.1](https://github.com/stenic/jpipe/compare/v1.3.0...v1.3.1) (2023-03-24)


### Bug Fixes

* Format and rebuild image ([0bb9752](https://github.com/stenic/jpipe/commit/0bb9752a4ef14556b3fd87526ac7ffea702739ba))

# [1.3.0](https://github.com/stenic/jpipe/compare/v1.2.2...v1.3.0) (2023-03-16)


Expand Down
7 changes: 5 additions & 2 deletions images/release/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ RUN npm install -g \
WORKDIR /app

RUN mkdir -p /home/node/.ssh/ \
&& ssh-keyscan -t rsa github.com >> /home/node/.ssh/known_hosts \
&& ssh-keyscan -t rsa gitlab.com >> /home/node/.ssh/known_hosts \
&& ssh-keyscan -t rsa bitbucket.org >> /home/node/.ssh/known_hosts
&& ssh-keyscan -t rsa bitbucket.org >> /home/node/.ssh/known_hosts \
&& ssh-keyscan -t rsa github.com >> /home/node/.ssh/known_hosts \
&& apk add --no-cache --virtual tooling jq curl \
&& curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | sed -e 's/^/github.com /' >> /home/node/.ssh/known_hosts \
&& apk del tooling

ENTRYPOINT [""]
69 changes: 43 additions & 26 deletions src/io/stenic/jpipe/plugin/CDInfraAsCodePlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ import org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException

class CDInfraAsCodePlugin extends Plugin {

private String yqDockerImage;
private String credentialId;
private String repository;
private String branch;
private String filePath;
private String yamlPath;
private String cdBranch;
private String gitUser;
private String gitEmail;
private String yqDockerImage
private String credentialId
private String repository
private String branch
private String filePath
private String yamlPath
private String cdBranch
private String gitUser
private String gitEmail

CDInfraAsCodePlugin(Map opts = [:]) {
this.repository = opts.get('repository', '');
this.credentialId = opts.get('credentialId', '');
this.cdBranch = opts.get('cdBranch', 'main');
this.branch = opts.get('branch', 'master');
this.yamlPath = opts.get('yamlPath', '.image.tag');
this.filePath = opts.get('filePath', 'values.yaml');
this.gitUser = opts.get('gitUser', 'jpipe-ci');
this.gitEmail = opts.get('gitEmail', '[email protected]');
this.yqDockerImage = opts.get('dockerImage', 'mikefarah/yq:4');
this.repository = opts.get('repository', '')
this.credentialId = opts.get('credentialId', '')
this.cdBranch = opts.get('cdBranch', 'main')
this.branch = opts.get('branch', 'master')
this.yamlPath = opts.get('yamlPath', '.image.tag')
this.filePath = opts.get('filePath', 'values.yaml')
this.gitUser = opts.get('gitUser', 'jpipe-ci')
this.gitEmail = opts.get('gitEmail', '[email protected]')
this.yqDockerImage = opts.get('dockerImage', 'mikefarah/yq:4')
}

public Map getSubscribedEvents() {
Expand All @@ -36,25 +36,35 @@ class CDInfraAsCodePlugin extends Plugin {
}

public Boolean doYamlUpdate(Event event) {
if (this.cdBranch == "" || event.env.BRANCH_NAME != this.cdBranch) {
event.script.println("Skipping CDInfraAsCodePlugin")
return true;
if (this.cdBranch == '' || event.env.BRANCH_NAME != this.cdBranch) {
event.script.println('Skipping CDInfraAsCodePlugin')
return true
}

if (this.credentialId == '') {
this.credentialId = event.script.scm.getUserRemoteConfigs()[0].getCredentialsId();
this.credentialId = event.script.scm.getUserRemoteConfigs()[0].getCredentialsId()
}

event.script.dir( "${System.currentTimeMillis()}" ) {
if (this.hasPlugin('lockable-resources')) {
event.script.lock("infrarepo-${this.repository}") {
return this.doCommit(event)
}
}

return this.doCommit(event)
}

private Boolean doCommit(Event event) {
event.script.dir("${System.currentTimeMillis()}") {
event.script.git(
url: this.repository,
branch: this.branch,
credentialsId: this.credentialId,
changelog: false
);
)

event.script.docker.image(this.yqDockerImage).inside("--entrypoint=''") {
event.script.sh "yq eval --inplace '${this.yamlPath} = \"${event.version}\"' ${this.filePath}";
event.script.sh "yq eval --inplace '${this.yamlPath} = \"${event.version}\"' ${this.filePath}"
}

event.script.sshagent(credentials: [this.credentialId]) {
Expand All @@ -66,7 +76,14 @@ class CDInfraAsCodePlugin extends Plugin {
event.script.sh "git push origin ${this.branch}"
}
}
}

return true
private Boolean hasPlugin(String pluginName) {
try {
return jenkins.model.Jenkins.instance.getPluginManager().getPlugin(pluginName) != null
} catch (RejectedAccessException e) {
return false
}
}

}
4 changes: 2 additions & 2 deletions src/io/stenic/jpipe/plugin/ConventionalCommitPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import io.stenic.jpipe.event.Event

class ConventionalCommitPlugin extends Plugin {

protected String dockerImage = 'ghcr.io/stenic/jpipe-release:1.2'
protected String dockerImage = 'ghcr.io/stenic/jpipe-release:1.3'
private Boolean useSemanticRelease = false

private String releaseBranches
Expand Down Expand Up @@ -81,7 +81,7 @@ class ConventionalCommitPlugin extends Plugin {

private runRelease(script, cmdArgs) {
Boolean configCreated = false
String configFile = 'release.config.js'
String configFile = 'release.config.cjs'
if (!script.fileExists("./${configFile}")) {
def releasercCfg = script.libraryResource "io/stenic/jpipe/release/${configFile}"
script.writeFile file: configFile, text: releasercCfg
Expand Down
69 changes: 35 additions & 34 deletions src/io/stenic/jpipe/plugin/DockerPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,34 @@ import io.stenic.jpipe.event.Event

class DockerPlugin extends Plugin {

private String credentialId;
private String server;
private String repository;
private String buildArgs;
private String target;
private Boolean push;
private String filePath;
private String testScript;
private List extraTargets;
private List extraTags;
private Boolean useCache;
private Boolean doCleanup;
private String buildArgVersionKey;
private String credentialId
private String server
private String repository
private String buildArgs
private String target
private Boolean push
private String filePath
private String testScript
private List extraTargets
private List extraTags
private Boolean useCache
private Boolean doCleanup
private String buildArgVersionKey

DockerPlugin(Map opts = [:]) {
this.repository = opts.get('repository', '');
this.credentialId = opts.get('credentialId', '');
this.server = opts.get('server', 'http://index.docker.io');
this.buildArgs = opts.get('buildArgs', '');
this.push = opts.get('push', this.credentialId != '');
this.filePath = opts.get('filePath', '.');
this.target = opts.get('target', '');
this.extraTargets = opts.get('extraTargets', []);
this.extraTags = opts.get('extraTags', []);
this.testScript = opts.get('testScript', '');
this.useCache = opts.get('useCache', true);
this.doCleanup = opts.get('doCleanup', false);
this.buildArgVersionKey = opts.get('buildArgVersionKey', 'VERSION');
this.repository = opts.get('repository', '')
this.credentialId = opts.get('credentialId', '')
this.server = opts.get('server', 'http://index.docker.io')
this.buildArgs = opts.get('buildArgs', '')
this.push = opts.get('push', this.credentialId != '')
this.filePath = opts.get('filePath', '.')
this.target = opts.get('target', '')
this.extraTargets = opts.get('extraTargets', [])
this.extraTags = opts.get('extraTags', [])
this.testScript = opts.get('testScript', '')
this.useCache = opts.get('useCache', true)
this.doCleanup = opts.get('doCleanup', false)
this.buildArgVersionKey = opts.get('buildArgVersionKey', 'VERSION')
}

public Map getSubscribedEvents() {
Expand All @@ -57,8 +57,8 @@ class DockerPlugin extends Plugin {
this.extraTargets.each { target ->
event.script.docker.image("${this.repository}:cache-${target}").pull()
}
} catch(Exception e) {}
}
} catch (Exception e) { }
}

def buildArgs = this.buildArgs
if (this.target != '') {
Expand All @@ -71,7 +71,7 @@ class DockerPlugin extends Plugin {
event.script.sshagent(credentials: [event.script.scm.getUserRemoteConfigs()[0].getCredentialsId()]) {
event.script.docker.build(
"${this.repository}:${event.version}",
"${buildArgs} ${this.filePath}"
"${buildArgs} --build-arg ${this.buildArgVersionKey}=${event.version} ${this.filePath}"
)
this.extraTags.each { tag ->
event.script.sh "docker tag ${this.repository}:${event.version} ${this.repository}:${tag}"
Expand All @@ -84,8 +84,8 @@ class DockerPlugin extends Plugin {
}
}
}
}
}
}

public void doTest(Event event) {
if (this.testScript != '') {
Expand All @@ -108,11 +108,11 @@ class DockerPlugin extends Plugin {
this.extraTargets.each { target ->
event.script.docker.image("${this.repository}:${target}").push("cache-${target}")
}
} catch(Exception e) {}
} catch (Exception e) { }
}
}
}
}
}

public void doDockerCleanup(Event event) {
if (!this.doCleanup) {
Expand All @@ -133,6 +133,7 @@ class DockerPlugin extends Plugin {
}
}
event.script.sh 'docker rmi -f $(docker images -f "dangling=true" -q)'
} catch(Exception e) {}
} catch (Exception e) { }
}

}
}
15 changes: 8 additions & 7 deletions src/io/stenic/jpipe/plugin/EcrPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import io.stenic.jpipe.event.Event

class EcrPlugin extends Plugin {

protected String dockerImage = 'amazon/aws-cli';
private String credentialsId;
private String repository;
private String region;
protected String dockerImage = 'amazon/aws-cli'
private String credentialsId
private String repository
private String region

EcrPlugin(Map opts = [:]) {
this.repository = opts.get('repository', '');
this.credentialsId = opts.get('credentialsId', '');
this.region = opts.get('region', '');
this.repository = opts.get('repository', '')
this.credentialsId = opts.get('credentialsId', '')
this.region = opts.get('region', '')
}

public Map getSubscribedEvents() {
Expand Down Expand Up @@ -41,4 +41,5 @@ class EcrPlugin extends Plugin {
}
}
}

}
6 changes: 3 additions & 3 deletions src/io/stenic/jpipe/plugin/SecretFinderPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import java.lang.Exception

class SecretFinderPlugin extends Plugin {

public static final String TURTLEHOG = "TURTLEHOG";
public static final String TRUFFELHOG = "TRUFFELHOG";

private Boolean allowFailure;
private String trufflehogImage;
Expand All @@ -14,7 +14,7 @@ class SecretFinderPlugin extends Plugin {
SecretFinderPlugin(Map opts = [:]) {
this.allowFailure = opts.get('allowFailure', false);
this.trufflehogImage = opts.get('trufflehogImage', 'trufflesecurity/trufflehog:latest');
this.scanners = opts.get('scanners', [this.TURTLEHOG]);
this.scanners = opts.get('scanners', [this.TRUFFELHOG]);
}

public Map getSubscribedEvents() {
Expand All @@ -27,7 +27,7 @@ class SecretFinderPlugin extends Plugin {

public void doScan(Event event) {
try {
if (this.scanners.contains(this.TURTLEHOG)) {
if (this.scanners.contains(this.TRUFFELHOG)) {
doTrufflehogScan(event)
}
} catch (Exception e) {
Expand Down
9 changes: 8 additions & 1 deletion src/io/stenic/jpipe/plugin/TrivyPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TrivyPlugin extends Plugin {
private List severity;
private String trivyVersion;
private String report;

TrivyPlugin(Map opts = [:]) {
this.report = opts.get('report', 'table');
this.allowFailure = opts.get('allowFailure', false);
Expand Down Expand Up @@ -45,6 +45,8 @@ class TrivyPlugin extends Plugin {
]
if (this.report == 'html') {
args.add('--format template --template "@contrib/html.tpl" -o /report/report.html')
} else if (this.report == 'json') {
args.add('--format json -o /report/report.json')
}
if (this.ignoreUnfixed == true) {
args.add('--ignore-unfixed')
Expand Down Expand Up @@ -80,6 +82,11 @@ class TrivyPlugin extends Plugin {
reportFiles: 'report.html',
reportName: "Trivy - ${imgName}",
])
} else if (this.report == 'json') {
event.script.recordIssues tool: event.script.trivy(
pattern: ".trivy-report-${imgName}/report.json",
reportEncoding: 'UTF-8'
)
}
}
}
Expand Down