diff --git a/k8s/stage/osh-client-tekton/pipline/osh-client-from-source-pipeline.yaml b/k8s/stage/osh-client-tekton/pipline/osh-client-from-source-pipeline.yaml index f806c12..613023a 100644 --- a/k8s/stage/osh-client-tekton/pipline/osh-client-from-source-pipeline.yaml +++ b/k8s/stage/osh-client-tekton/pipline/osh-client-from-source-pipeline.yaml @@ -15,6 +15,10 @@ spec: description: The revision or tag type: string + - name: mock-build-params + description: The parameters to pass to covscan mock-build + type: string + - name: archive-name description: The name of the git archive file type: string @@ -77,6 +81,8 @@ spec: params: - name: targz-file value: $(params.archive-name) + - name: mock-build-params + value: $(params.mock-build-params) runAfter: - archive taskRef: diff --git a/k8s/stage/osh-client-tekton/task/osh-client-from-source.yaml b/k8s/stage/osh-client-tekton/task/osh-client-from-source.yaml index aba0eb1..fe8b38d 100644 --- a/k8s/stage/osh-client-tekton/task/osh-client-from-source.yaml +++ b/k8s/stage/osh-client-tekton/task/osh-client-from-source.yaml @@ -13,15 +13,10 @@ spec: default: "source.tar.gz" description: The filename of the tar.gz we'll be uploading to covscan - - name: scan-profile + - name: mock-build-params type: string - description: The scan profile we will use - default: "snyk-only-unstable" - - - name: tarball-build-script - type: string - description: Parameters to be passed to tarball-build-script - default: ":" + description: Parameters pushed to mock build + default: "-p snyk-only-unstable --tarball-build-script=:" volumes: - name: osh-client-kerb-vol @@ -72,7 +67,6 @@ spec: script: | #!/bin/bash - echo $(params.scan-profile) - echo $(params.tarball-build-script) + echo $(params.mock-build-params) echo $(params.targz-file) - covscan mock-build -p $(params.scan-profile) --tarball-build-script=$(params.tarball-build-script) /workspace/source-tars/$(params.targz-file) + covscan mock-build $(params.mock-build-params) /workspace/source-tars/$(params.targz-file) diff --git a/src/main/java/com/redhat/pctsec/model/Git.java b/src/main/java/com/redhat/pctsec/model/Git.java index f91eac1..26e649f 100644 --- a/src/main/java/com/redhat/pctsec/model/Git.java +++ b/src/main/java/com/redhat/pctsec/model/Git.java @@ -12,7 +12,7 @@ import java.util.UUID; @Entity public class Git { public Git() { - super(); + } @Id diff --git a/src/main/java/com/redhat/pctsec/model/PNCBuild.java b/src/main/java/com/redhat/pctsec/model/PNCBuild.java index a6f2f88..ef54558 100644 --- a/src/main/java/com/redhat/pctsec/model/PNCBuild.java +++ b/src/main/java/com/redhat/pctsec/model/PNCBuild.java @@ -1,5 +1,6 @@ package com.redhat.pctsec.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.redhat.pctsec.model.api.service.AltPncService; //import com.redhat.pctsec.model.api.service.PncService; import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder; @@ -19,8 +20,10 @@ public class PNCBuild extends BuildType{ @Transient + @JsonIgnore public static final String apiUrl = ConfigProvider.getConfig().getValue("pnc.api-url",String.class); @Transient + @JsonIgnore private static final AltPncService pnc = QuarkusRestClientBuilder.newBuilder().baseUri(URI.create(apiUrl)).build(AltPncService.class); @@ -29,8 +32,10 @@ public class PNCBuild extends BuildType{ PncService pnc; */ + @Transient - Build build; + @JsonIgnore + private Build build; private URI SCMURL; private String revision; @@ -38,6 +43,8 @@ public class PNCBuild extends BuildType{ public PNCBuild() { super(); } + @Transient + @JsonIgnore public Build getBuild() { if(build == null) build = pnc.getBuild(this.buildRef); diff --git a/src/main/java/com/redhat/pctsec/model/Scan.java b/src/main/java/com/redhat/pctsec/model/Scan.java index a1e3daa..95fd891 100644 --- a/src/main/java/com/redhat/pctsec/model/Scan.java +++ b/src/main/java/com/redhat/pctsec/model/Scan.java @@ -1,6 +1,7 @@ package com.redhat.pctsec.model; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.persistence.*; import jakarta.transaction.Transactional; import jakarta.validation.constraints.Email; @@ -17,6 +18,50 @@ enum ScanState { @Entity public class Scan { + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public UUID id; + + + /* + @OneToOne + @NotNull + @JoinColumn(name = "product_id", referencedColumnName = "id") + private String productName; + */ + @Column(name="product_name") + private String productName; + + //@Temporal(TemporalType.TIMESTAMP) + + @CreationTimestamp + @JsonIgnore + @Column(name="creation_timestamp") + //@NotNull + private Instant creationTimestamp; + + @UpdateTimestamp + @JsonIgnore + @Column(name="update_timestamp") + //@NotNull + private Instant updateTimestamp; + + @Column(name="state") + @Enumerated(EnumType.STRING) + private ScanState state; + + @Column(name="requestor") + @NotNull + private String requestor; + + @Column(name="email") + @Email + private String email; + + @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.EAGER) + @JoinColumn(name = "scan_requests_id", referencedColumnName = "id") + public ScanRequests scanRequests = new ScanRequests(); + public Scan() { this.scanRequests = new ScanRequests(); } @@ -53,8 +98,14 @@ public class Scan { this.requestor = requestor; } + @JsonProperty("email") + @Access(AccessType.PROPERTY) + @Email public String getEmail() { - return email; + if(email != null) { + return email; + } + return getRequestor() + "@redhat.com"; } public void setEmail(String email) { @@ -70,47 +121,12 @@ public class Scan { this.scanRequests = scanRequests; } - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public UUID id; - - - /* - @OneToOne - @NotNull - @JoinColumn(name = "product_id", referencedColumnName = "id") - private String productName; - */ - @Column(name="proudct_name") - private String productName; - - //@Temporal(TemporalType.TIMESTAMP) - - @CreationTimestamp - @JsonIgnore - @Column(name="creation_timestamp") - //@NotNull - private Instant creationTimestamp; - - @UpdateTimestamp @JsonIgnore - @Column(name="update_timestamp") - //@NotNull - private Instant updateTimestamp; - - @Column(name="state") - @Enumerated(EnumType.STRING) - private ScanState state; - - @Column(name="requestor") - @NotNull - private String requestor; - - @Column(name="report_email") - @Email - private String email; - - @OneToOne(cascade = CascadeType.ALL, fetch=FetchType.LAZY) - @JoinColumn(name = "scan_requests_id", referencedColumnName = "id") - public ScanRequests scanRequests; + @Transient + public void propagateOptions(){ + //In future lets export this scan object as YAML + getScanRequests().propagateOptions(); + String covscanArgs = " --email-to " + this.getEmail() + " --comment \"" + this.productName + "\""; + getScanRequests().scanRequests.forEach(sr -> sr.setScanProperties(sr.getScanProperties() + covscanArgs)); + } } diff --git a/src/main/java/com/redhat/pctsec/model/ScanRequest.java b/src/main/java/com/redhat/pctsec/model/ScanRequest.java index 2955d87..8bc16d3 100644 --- a/src/main/java/com/redhat/pctsec/model/ScanRequest.java +++ b/src/main/java/com/redhat/pctsec/model/ScanRequest.java @@ -22,7 +22,7 @@ public class ScanRequest { @GeneratedValue protected UUID id; private String metadata; - private String oshScanOptions; + //private String oshScanOptions; public EventBus getBus() { return bus; @@ -43,28 +43,21 @@ public class ScanRequest { private RequestType type; - @OneToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL) + @OneToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "brew_build_id", referencedColumnName = "id") @JsonInclude(JsonInclude.Include.NON_NULL) public BrewBuild brewBuild; - @OneToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL) + @OneToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "pnc_build_id", referencedColumnName = "id") @JsonInclude(JsonInclude.Include.NON_NULL) public PNCBuild pncBuild; - @OneToOne(fetch=FetchType.LAZY, cascade = CascadeType.ALL) + @OneToOne(fetch=FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "git_id", referencedColumnName = "id") @JsonInclude(JsonInclude.Include.NON_NULL) public Git git; - public String getOshScanOptions() { - return oshScanOptions; - } - - public void setOshScanOptions(String oshScanOptions) { - this.oshScanOptions = oshScanOptions; - } public String getScanProperties() { return scanProperties; @@ -77,6 +70,7 @@ public class ScanRequest { @Column(name="scan_properties") public String scanProperties; public ScanRequest() { + } public ScanRequest(BrewBuild brewBuild) diff --git a/src/main/java/com/redhat/pctsec/model/ScanRequests.java b/src/main/java/com/redhat/pctsec/model/ScanRequests.java index cc510e2..9d2199f 100644 --- a/src/main/java/com/redhat/pctsec/model/ScanRequests.java +++ b/src/main/java/com/redhat/pctsec/model/ScanRequests.java @@ -1,5 +1,7 @@ package com.redhat.pctsec.model; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import com.redhat.pctsec.model.api.request.pssaas; import com.redhat.pctsec.model.api.request.scanChain; import io.vertx.mutiny.core.eventbus.EventBus; @@ -9,6 +11,8 @@ import java.util.*; import java.util.stream.Collectors; import jakarta.persistence.*; +import jakarta.transaction.Transactional; +import org.jboss.logging.annotations.Property; @ApplicationScoped @Entity @@ -19,15 +23,19 @@ public class ScanRequests { @GeneratedValue protected UUID id; + + @OneToMany(fetch=FetchType.EAGER, cascade = CascadeType.ALL) @JoinColumn(name = "scan_request_id", referencedColumnName = "id") - private Set scanRequests;// = new HashSet<>(); + public Set scanRequests = new HashSet<>(); @Column(name="scan_properties") + @JsonIgnore private String globalScanProperties; @Column(name="scan_metadata") + @JsonIgnore private String scanMetadata; @@ -88,14 +96,14 @@ public class ScanRequests { */ } - public Set getScanRequests() { - return scanRequests; - } + public void setScanRequests(Set scanRequests) { this.scanRequests = scanRequests; } + @JsonProperty("globalScanProperties") + @Transient public String getGlobalScanProperties() { return globalScanProperties; } @@ -104,6 +112,9 @@ public class ScanRequests { this.globalScanProperties = globalScanProperties; } + + @JsonProperty("scanMetadata") + @Transient public String getScanMetadata() { return scanMetadata; } @@ -111,4 +122,18 @@ public class ScanRequests { public void setScanMetadata(String scanMetadata) { this.scanMetadata = scanMetadata; } + + @JsonProperty("scanRequests") + @Transient + public Set getScanRequests() { + return this.scanRequests; + } + + @JsonIgnore + @Transient + public void propagateOptions(){ + //In future lets export this scan object as YAML + //If its empy overwrite with the global options + getScanRequests().stream().filter(eso -> eso.getScanProperties() == null).forEach(sr -> sr.setScanProperties(getGlobalScanProperties())); + } } diff --git a/src/main/java/com/redhat/pctsec/model/jpa/UriConverter.java b/src/main/java/com/redhat/pctsec/model/jpa/UriConverter.java index c96d21f..45eb7a7 100644 --- a/src/main/java/com/redhat/pctsec/model/jpa/UriConverter.java +++ b/src/main/java/com/redhat/pctsec/model/jpa/UriConverter.java @@ -17,6 +17,8 @@ public class UriConverter implements AttributeConverter @Override public URI convertToEntityAttribute(String s) { - return ((s.length() > 0) ? URI.create(s.trim()) : null); + if(s != null) + return ((s.length() > 0) ? URI.create(s.trim()) : null); + return null; } } diff --git a/src/main/java/com/redhat/pctsec/model/osh/paramMapper.java b/src/main/java/com/redhat/pctsec/model/osh/paramMapper.java index dc0ed64..32322e6 100644 --- a/src/main/java/com/redhat/pctsec/model/osh/paramMapper.java +++ b/src/main/java/com/redhat/pctsec/model/osh/paramMapper.java @@ -32,6 +32,12 @@ public class paramMapper { " of a local file") private String brewBuild; + @Option(names = {"--email-to"}, description = "Email address for email repots") + private String emailTo; + + @Option(names = {"--comment"}, description = "Comments to add to scan request") + private String comment; + public paramMapper(){} public paramMapper(String params){ diff --git a/src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanResource.java b/src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanResource.java index 610c328..046970d 100644 --- a/src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanResource.java +++ b/src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanResource.java @@ -5,11 +5,13 @@ import com.redhat.pctsec.model.api.request.pssaas; import com.redhat.pctsec.model.api.request.scanChain; import com.redhat.pctsec.model.jpa.ScanRepository; import io.quarkus.security.Authenticated; +import io.quarkus.security.identity.SecurityIdentity; import io.vertx.mutiny.core.eventbus.EventBus; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import jakarta.transaction.Transactional; import jakarta.validation.Valid; +import jakarta.validation.constraints.Email; import jakarta.ws.rs.*; import org.jboss.resteasy.reactive.RestQuery; @@ -29,6 +31,10 @@ public class ScanResource { @Inject EventBus bus; + @Inject + SecurityIdentity identity; + + @POST @Path("PSSaaS") @Consumes({ "application/json" }) @@ -38,9 +44,12 @@ public class ScanResource { { ScanRequests scanRequests = new ScanRequests(scanRequest); Scan s = new Scan(); - s.setRequestor("cpaas"); s.setProductName(scanRequest.productId); s.setScanRequests(scanRequests); + if(!identity.getPrincipal().getName().isEmpty()) + s.setRequestor(identity.getPrincipal().getName()); + else + s.setRequestor("CPaaS"); sr.persist(s); return s; } @@ -52,6 +61,7 @@ public class ScanResource { public List createRunPSSAAS(@Valid pssaas scanRequest) { Scan s = this.createPSSAAS(scanRequest); + s.propagateOptions(); return s.scanRequests.execute(bus); } @@ -64,6 +74,12 @@ public class ScanResource { { ScanRequests scanRequests = new ScanRequests(scanRequest); Scan s = new Scan(); + //Set the requestor to kerberos uid first + if(!identity.getPrincipal().getName().isEmpty()) + s.setRequestor(identity.getPrincipal().getName()); + //Set the email to be our kerberos id + @redhat.com + s.setEmail(s.getEmail()); + //Now set the actual payload requestor s.setRequestor(scanRequest.requestor); s.setProductName(scanRequest.productName); s.setScanRequests(scanRequests); @@ -78,6 +94,7 @@ public class ScanResource { public List createRunScanChain(@Valid scanChain scanRequest) { Scan s = this.createScanChain(scanRequest); + s.propagateOptions(); return s.scanRequests.execute(bus); } @GET @@ -103,9 +120,23 @@ public class ScanResource { public List scanRequestExe(String id) { Scan s = sr.findById(UUID.fromString(id)); + s.propagateOptions(); return s.scanRequests.execute(bus); } + @PATCH + @Path("{id}/{email}") + @Consumes({"application/octet-stream"}) + @Produces({"application/json"}) + @Authenticated + @Transactional + public Scan patchScanEmail(String id, @Email String email) + { + Scan s = sr.findById(UUID.fromString(id)); + s.setEmail(email); + sr.persist(s); + return s; + } @GET @Path("single/git") @@ -115,7 +146,8 @@ public class ScanResource { public Scan singleGit(@RestQuery String repo, @RestQuery String ref) { Scan s = new Scan(); - s.setRequestor("jochrist"); + if(!identity.getPrincipal().getName().isEmpty()) + s.setRequestor(identity.getPrincipal().getName()); s.getScanRequests().addGit(repo,ref); sr.persist(s); return s; @@ -129,7 +161,8 @@ public class ScanResource { public Scan singleGit(@RestQuery String brewId) { Scan s = new Scan(); - s.setRequestor("jochrist"); + if(!identity.getPrincipal().getName().isEmpty()) + s.setRequestor(identity.getPrincipal().getName()); s.getScanRequests().addBrewBuild(brewId); sr.persist(s); return s; @@ -142,7 +175,8 @@ public class ScanResource { public Scan singlePNC(@RestQuery String pncId) { Scan s = new Scan(); - s.setRequestor("jochrist"); + if(!identity.getPrincipal().getName().isEmpty()) + s.setRequestor(identity.getPrincipal().getName()); s.getScanRequests().addPNCBuild(pncId); sr.persist(s); return s; diff --git a/src/main/java/com/redhat/pctsec/tekton/TaskHandler.java b/src/main/java/com/redhat/pctsec/tekton/TaskHandler.java index b240716..8a26960 100644 --- a/src/main/java/com/redhat/pctsec/tekton/TaskHandler.java +++ b/src/main/java/com/redhat/pctsec/tekton/TaskHandler.java @@ -46,19 +46,19 @@ public class TaskHandler { switch(scanTask.getScanRequest().getType()) { case BREW: - scanTask.setTektonRunId(invokeScanTask(scanTask.getScanRequest().brewBuild.buildRef)); + scanTask.setTektonRunId(invokeScanTask(scanTask.getScanRequest().brewBuild.buildRef, "")); scanTask.setState(ScanTaskState.RUNNING); break; case PNC: String repo = scanTask.getScanRequest().pncBuild.SCMURL().toString(); String ref = scanTask.getScanRequest().pncBuild.revision(); - scanTask.setTektonRunId(invokeOshScmScanPipeline(repo, ref)); + scanTask.setTektonRunId(invokeOshScmScanPipeline(repo, ref, scanTask.getScanRequest().getScanProperties())); scanTask.setState(ScanTaskState.RUNNING); break; case GIT: - scanTask.setTektonRunId(invokeOshScmScanPipeline(scanTask.getScanRequest().git.repo.toString(), scanTask.getScanRequest().git.ref)); + scanTask.setTektonRunId(invokeOshScmScanPipeline(scanTask.getScanRequest().git.repo.toString(), scanTask.getScanRequest().git.ref, scanTask.getScanRequest().getScanProperties())); scanTask.setState(ScanTaskState.RUNNING); break; } @@ -66,7 +66,7 @@ public class TaskHandler { return scanTask; } - public String invokeScanTask(String buildId) { + public String invokeScanTask(String buildId, String mockbuildArgs) { // String buildId = "xterm-366-8.el9"; String scanProfile = "snyk-only-unstable"; @@ -89,7 +89,7 @@ public class TaskHandler { return taskRun.getMetadata().getName(); } - public String invokeOshScmScanPipeline(String repo, String ref) { + public String invokeOshScmScanPipeline(String repo, String ref, String mockBuildArgs) { PodSecurityContext securityContext = new PodSecurityContextBuilder() .withRunAsNonRoot(true) @@ -126,6 +126,7 @@ public class TaskHandler { .withNewPipelineRef().withName(PIPELINE_REFERENCE).endPipelineRef() .addNewParam().withName("repo-url").withNewValue(repo).endParam() .addNewParam().withName("revision").withNewValue(ref).endParam() + .addNewParam().withName("mock-build-params").withNewValue(mockBuildArgs).endParam() .withWorkspaces(workspaceBindings) .endSpec() .build();