Compare commits

...

54 Commits

Author SHA1 Message Date
Jonathan Christison ec1528cef8 Try defining openapi defintion on app 2 years ago
Jonathan Christison a39b3f37cc Enable HTTP Basic AUTH 2 years ago
Mert Bugra Bicak ee54eeb57d Merge branch 'tekton-pod-optimization' into 'main' 2 years ago
Jonathan Christison 78b1995557 Dont apply global properties to brew builds 2 years ago
Jonathan Christison 22a3668a21 Echo to terminal what was executed 2 years ago
Mert Bugra Bicak 08afd70476 changeing invokeScanTask to point to mockBuildArgs instead of hardcoded example profile 2 years ago
Mert Bugra Bicak 47d6ab1588 made mock-build params consistent with brew scan tekton task, added -p flag 2 years ago
Mert Bugra Bicak ea5f1d6fb7 added change to get created taskrun id after creation 3 years ago
Jonathan Christison ba3cc5f726 Merge branch '31-tekton-pipelinerun-and-taskrun-pruning' into 'main' 3 years ago
Mert Bugra Bicak 6d99df5945 converted scm pipeline run to task run with 1 pod instead of 3, fixed generateName issue in brew scan, made config adjustments 3 years ago
Jonathan Christison 29889925d1 Seems slightly aggressive of a run time, change to every 50 mins 3 years ago
Jonathan Christison bdefadd090 Add big payload using builds from cpass test builds 3 years ago
Jonathan Christison 8548244a00 Change SA for tekton terminator 3 years ago
Jonathan Christison 3cf29f95b2 Create a SA with the correct tekton permissions 3 years ago
Jonathan Christison 97b0255c47 Just re-use the OSH service account 3 years ago
Jonathan Christison 798675466f Start adding cronjob to do the clearup for us 3 years ago
Jonathan Christison 6e13d06238 We dont have permissions to do this 3 years ago
Jonathan Christison 6e6f80fbc0 Merge branch '32-switch-stage-environment-pct-security-tooling-to-use-stage-osh' into 'main' 3 years ago
Jonathan Christison 0aded42dac OSH-134 Use stage env 3 years ago
Jonathan Christison 55f1a9bb1a Merge branch '17-prod-deployment' into 'main' 3 years ago
Jonathan Christison 8727bff831 We really need to set these to template values, every redeploy will 3 years ago
Jonathan Christison 82fbf480ec Set the correct namespace 3 years ago
Jonathan Christison 721c0ad374 Revert "Try setting the principle in the kt file" 3 years ago
Jonathan Christison ce845c9ade Try setting the principle in the kt file 3 years ago
Jonathan Christison f83d0a1b06 Specify its IPA we need to authenticate against 3 years ago
Jonathan Christison 26592328b9 Use openshift env settings as k8s are not carried across to openshift 3 years ago
Jonathan Christison 3f003048a6 Set postgresql as the default driver for all profiles 3 years ago
Jonathan Christison 29c73976f3 Set path to be osh-wrapper for prod system route 3 years ago
Jonathan Christison 161651f61e Create the schema initially for blank db 3 years ago
Jonathan Christison e8738d1cd1 Use an alternate DB in the postgres instance (alter 3 years ago
Jonathan Christison 6da7606ad7 Use an alternate DB in the postgres instance 3 years ago
Jonathan Christison b3feca922b Change to prod namespace 3 years ago
Jonathan Christison dc8de982f0 Minor alterations for prod deploy 3 years ago
Jonathan Christison 3dff549872 Change ID to public, we need this visible for subequent requests 3 years ago
Leonid Bossis 98ba0545e1 Merge branch '21-email-to-args-for-osh-client' into 'main' 3 years ago
Jonathan Christison 6069d11e1c Fix issues pointed out in https://gitlab.cee.redhat.com/pct-security/covscanrest/-/merge_requests/13 3 years ago
Jonathan Christison 353854b790 Merge branch 'prod-deployment' into 'main' 3 years ago
jperezde fcf47f8d50 Modified principal 3 years ago
Jonathan Christison 5566213fec Pass parameters though to OSH tekton run 3 years ago
Jonathan Christison b07123618d Fix `jakarta.persistence.PersistenceException: Error attempting to apply 3 years ago
jperezde 16acdd3061 Modified namespace 3 years ago
jperezde 9d18e6d9cb Added yaml files for prod 3 years ago
jperezde f0c0b91be2 Added production settings to application.properties 3 years ago
Jonathan Christison d2386ac83a Set scanRequests on scan, dont put pnc build in json 3 years ago
Jonathan Christison ca186cdd04 Set email based on requesting kerberos id for now 3 years ago
Jonathan Christison 0a7f11d6bf Not sure what I did but ORM is working again :-S 3 years ago
Jonathan Christison ccb33b4c64 Add email patch method 3 years ago
Nicholas Caughey 3392029b8c Merge branch '18-scanchain-endpoint' into 'main' 3 years ago
Jonathan Christison 2fb746abae Add scanchain endpoint 3 years ago
Nicholas Caughey 9e175ca403 Merge branch '12-add-pnc-build-support' into 'main' 3 years ago
Jonathan Christison bad8b847ec Remove PncService for now 3 years ago
Jonathan Christison 87f45b8329 Give up on using PNC rest client for now roll our own 3 years ago
Jonathan Christison c7bd13c3ac Attempt to add PNC Client (Currently Broken) 3 years ago
Jonathan Christison 421dce3b6c Merge branch 'refactor' into 'main' 3 years ago
  1. 45
      hack/sample-pssaas-big.json
  2. 8
      k8s/prod/app/database-envs.yaml
  3. 21
      k8s/prod/app/edge-route.yaml
  4. 44
      k8s/prod/app/kerberos-config.yaml
  5. 36
      k8s/prod/app/linux-krb5.conf
  6. 15
      k8s/prod/app/service-account.yaml
  7. 31
      k8s/prod/app/tekton-rbac.yaml
  8. 79
      k8s/prod/osh-client-tekton/osh-client-config.yaml
  9. 28
      k8s/prod/osh-client-tekton/osh-client-pvc.yaml
  10. 6
      k8s/prod/osh-client-tekton/pipeline/osh-client-from-source-pipeline.yaml
  11. 0
      k8s/prod/osh-client-tekton/task/osh-client-from-source-clearup-workspace.yaml
  12. 16
      k8s/prod/osh-client-tekton/task/osh-client-from-source.yaml
  13. 2
      k8s/prod/osh-client-tekton/task/osh-client-git-cli-modified.yaml
  14. 63
      k8s/prod/osh-client-tekton/task/osh-scan-task.yaml
  15. 7
      k8s/stage/osh-client-tekton/osh-client-config.yaml
  16. 104
      k8s/stage/osh-client-tekton/task/osh-scan-scm-task.yaml
  17. 3
      k8s/stage/osh-client-tekton/task/osh-scan-task.yaml
  18. 23
      k8s/stage/osh-client-tekton/tekton-cleanup-cronjob.yaml
  19. 43
      k8s/stage/osh-client-tekton/tekton-terminator-sa-rbac.yaml
  20. 24
      pom.xml
  21. 2
      src/main/java/com/redhat/pctsec/model/Git.java
  22. 49
      src/main/java/com/redhat/pctsec/model/PNCBuild.java
  23. 102
      src/main/java/com/redhat/pctsec/model/Scan.java
  24. 20
      src/main/java/com/redhat/pctsec/model/ScanRequest.java
  25. 38
      src/main/java/com/redhat/pctsec/model/ScanRequests.java
  26. 31
      src/main/java/com/redhat/pctsec/model/api/request/scanChain.java
  27. 34
      src/main/java/com/redhat/pctsec/model/api/request/scanChainGit.java
  28. 12
      src/main/java/com/redhat/pctsec/model/api/service/AltPncService.java
  29. 4
      src/main/java/com/redhat/pctsec/model/jpa/UriConverter.java
  30. 6
      src/main/java/com/redhat/pctsec/model/osh/paramMapper.java
  31. 49
      src/main/java/com/redhat/pctsec/rest/v1alpha1/OshWrapperApiApplication.java
  32. 4
      src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanRequestsResource.java
  33. 70
      src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanResource.java
  34. 104
      src/main/java/com/redhat/pctsec/tekton/TaskHandler.java
  35. 96
      src/main/resources/application.properties
  36. 19
      src/test/java/com/redhat/pctsec/model/test/PNCBuildTest.java
  37. 3
      src/test/java/com/redhat/pctsec/model/test/paramMapperTest.java

45
hack/sample-pssaas-big.json

@ -0,0 +1,45 @@
{
"product-id": "jochrist-dev-test-rhbq",
"is-managed-service": false,
"cpaas-version": "latest",
"component-list":[
{"build-id":"AZ2HRIN2S7AAC","type":"pnc"},
{"build-id":"AZ2JABY727AAA","type":"pnc"},
{"build-id":"AZ2JRSQZC7AAC","type":"pnc"},
{"build-id":"AZ2Z2WLAK7AAC","type":"pnc"},
{"build-id":"AZ4AMGCV27AAC","type":"pnc"},
{"build-id":"AZ4A5CSJC7AAC","type":"pnc"},
{"build-id":"AZ4B7LCNC7AAC","type":"pnc"},
{"build-id":"AZ4CLXF4K7AAC","type":"pnc"},
{"build-id":"AZ4CMZK6S7AAC","type":"pnc"},
{"build-id":"AZ4C62YEC7AAC","type":"pnc"},
{"build-id":"AZ4DGFNK27AAC","type":"pnc"},
{"build-id":"AZ4DIMTNS7AAC","type":"pnc"},
{"build-id":"AZ4KSFVIC7AAC","type":"pnc"},
{"build-id":"AZ4VFB7XK7AAC","type":"pnc"},
{"build-id":"AZ4WLXXFC7AAC","type":"pnc"},
{"build-id":"AZ5JPS7SK7AAC","type":"pnc"},
{"build-id":"AZ5LC7M327AAC","type":"pnc"},
{"build-id":"AZ5LQCKAC7AAC","type":"pnc"},
{"build-id":"AZ5LW6NGS7AAC","type":"pnc"},
{"build-id":"AZ5MHDELK7AAC","type":"pnc"},
{"build-id":"AZ5ONFXEC7AAC","type":"pnc"},
{"build-id":"AZ5P2MUBK7AAC","type":"pnc"},
{"build-id":"AZ5QJ7VPK7AAC","type":"pnc"},
{"build-id":"AZ5RPXHM27AAC","type":"pnc"},
{"build-id":"AZ5SRVAG27AAC","type":"pnc"},
{"build-id":"AZ56V4B4K7AAC","type":"pnc"},
{"build-id":"AZ5642PZS7AAC","type":"pnc"},
{"build-id":"AZ6ATGHXC7AAC","type":"pnc"},
{"build-id":"AZ6XRDLCS7AAC","type":"pnc"},
{"build-id":"AZ6YYPCZK7AAC","type":"pnc"},
{"build-id":"AZ62QFTQ27AAC","type":"pnc"},
{"build-id":"AZ65EUXBC7AAC","type":"pnc"},
{"build-id":"AZ65VXKKC7AAC","type":"pnc"},
{"build-id":"A2ARB7X3S7AAC","type":"pnc"},
{"build-id":"A2ARDJ7MS7AAC","type":"pnc"},
{"build-id":"A2ARENQ4S7AAC","type":"pnc"},
{"build-id":"A2ARFRPLC7AAC","type":"pnc"}
]
}

8
k8s/prod/app/database-envs.yaml

@ -0,0 +1,8 @@
apiVersion: v1
data:
POSTGRESQL_DATABASE: oshwrapper-db
POSTGRESQL_USER: scanner
kind: ConfigMap
metadata:
name: database-envs-osh
namespace: psse-scanchain-prod

21
k8s/prod/app/edge-route.yaml

@ -0,0 +1,21 @@
#oc create route edge --service=osh --dry-run=client -o yaml > edgeroute.yml
apiVersion: route.openshift.io/v1
kind: Route
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/name: osh
app.kubernetes.io/version: 1.0.0-SNAPSHOT
app.openshift.io/runtime: quarkus
env: prod
name: osh
spec:
port:
targetPort: http
tls:
termination: edge
to:
kind: ""
name: osh
weight: null
status: {}

44
k8s/prod/app/kerberos-config.yaml

@ -0,0 +1,44 @@
#oc create configmap kerberos-config --from-file=linux-krb5.conf --dry-run=client -o yaml > kerberos-config.yaml
apiVersion: v1
data:
linux-krb5.conf: |
includedir /etc/krb5.conf.d/
# depending on your config, you may wish to uncomment the following:
# includedir /var/lib/sss/pubconf/krb5.include.d/
[libdefaults]
default_realm = IPA.REDHAT.COM
dns_lookup_realm = true
dns_lookup_kdc = true
rdns = false
dns_canonicalize_hostname = false
ticket_lifetime = 24h
forwardable = true
udp_preference_limit = 1
default_ccache_name = KEYRING:persistent:%{uid}
max_retries = 1
kdc_timeout = 1500
[realms]
REDHAT.COM = {
default_domain = redhat.com
dns_lookup_kdc = true
master_kdc = kerberos.corp.redhat.com
admin_server = kerberos.corp.redhat.com
}
IPA.REDHAT.COM = {
default_domain = ipa.redhat.com
dns_lookup_kdc = true
# Trust tickets issued by legacy realm on this host
auth_to_local = RULE:[1:$1@$0](.*@REDHAT\.COM)s/@.*//
auth_to_local = DEFAULT
}
#DO NOT ADD A [domain_realms] section
#https://mojo.redhat.com/docs/DOC-1166841
kind: ConfigMap
metadata:
creationTimestamp: null
name: kerberos-config

36
k8s/prod/app/linux-krb5.conf

@ -0,0 +1,36 @@
includedir /etc/krb5.conf.d/
# depending on your config, you may wish to uncomment the following:
# includedir /var/lib/sss/pubconf/krb5.include.d/
[libdefaults]
default_realm = IPA.REDHAT.COM
dns_lookup_realm = true
dns_lookup_kdc = true
rdns = false
dns_canonicalize_hostname = false
ticket_lifetime = 24h
forwardable = true
udp_preference_limit = 1
default_ccache_name = KEYRING:persistent:%{uid}
max_retries = 1
kdc_timeout = 1500
[realms]
REDHAT.COM = {
default_domain = redhat.com
dns_lookup_kdc = true
master_kdc = kerberos.corp.redhat.com
admin_server = kerberos.corp.redhat.com
}
IPA.REDHAT.COM = {
default_domain = ipa.redhat.com
dns_lookup_kdc = true
# Trust tickets issued by legacy realm on this host
auth_to_local = RULE:[1:$1@$0](.*@REDHAT\.COM)s/@.*//
auth_to_local = DEFAULT
}
#DO NOT ADD A [domain_realms] section
#https://mojo.redhat.com/docs/DOC-1166841

15
k8s/prod/app/service-account.yaml

@ -0,0 +1,15 @@
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/name: osh
app.kubernetes.io/version: 1.0.0-SNAPSHOT
app.openshift.io/runtime: quarkus
env: prod
name: osh
namespace: psse-scanchain-prod
imagePullSecrets:
- name: pct-security-osh-wrapper-client-pull-secret
- name: osh-dockercfg-n2hr7
secrets:
- name: osh-dockercfg-n2hr7

31
k8s/prod/app/tekton-rbac.yaml

@ -0,0 +1,31 @@
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
app.kubernetes.io/component: tekton
name: osh-wrapper-tekton
namespace: psse-scanchain-prod
rules:
- apiGroups:
- tekton.dev
resources:
- taskruns
- pipelineruns
verbs:
- create
- get
- watch
- list
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: osh-wrapper-tekton-rolebinding
namespace: psse-scanchain-prod
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: osh-wrapper-tekton
subjects:
- kind: ServiceAccount
name: osh

79
k8s/prod/osh-client-tekton/osh-client-config.yaml

@ -0,0 +1,79 @@
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
name: kerberos-config-osh-client
namespace: psse-scanchain-prod
data:
linux-krb5.conf: |
includedir /etc/krb5.conf.d/
# depending on your config, you may wish to uncomment the following:
# includedir /var/lib/sss/pubconf/krb5.include.d/
[libdefaults]
default_realm = IPA.REDHAT.COM
dns_lookup_realm = true
dns_lookup_kdc = true
rdns = false
dns_canonicalize_hostname = false
ticket_lifetime = 24h
forwardable = true
udp_preference_limit = 1
default_ccache_name = FILE:/tmp/krb5cc_%{uid}
max_retries = 1
kdc_timeout = 1500
[realms]
REDHAT.COM = {
default_domain = redhat.com
dns_lookup_kdc = true
master_kdc = kerberos.corp.redhat.com
admin_server = kerberos.corp.redhat.com
}
IPA.REDHAT.COM = {
default_domain = ipa.redhat.com
dns_lookup_kdc = true
# Trust tickets issued by legacy realm on this host
auth_to_local = RULE:[1:$1@$0](.*@REDHAT\.COM)s/@.*//
auth_to_local = DEFAULT
}
#DO NOT ADD A [domain_realms] section
#https://mojo.redhat.com/docs/DOC-1166841
---
#oc create configmap osh-client-config --from-file=client.conf --dry-run=client -o yaml > osh-client-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: osh-client-config
namespace: psse-scanchain-prod
data:
client.conf: |+
# client config file for covscan
# Hub XML-RPC address.
HUB_URL = "https://cov01.lab.eng.brq2.redhat.com/covscanhub/xmlrpc"
BREW_URL = "https://brewhub.engineering.redhat.com/brewhub"
KOJI_URL = "https://koji.fedoraproject.org/kojihub"
KOJI_PROFILES = "brew,koji"
CIM_SERVER = "cov01.lab.eng.brq2.redhat.com"
CIM_PORT = "8080"
DEFAULT_MOCKCONFIG = "fedora-rawhide-x86_64"
# Hub authentication method: "krbv", "password", or "gssapi"
AUTH_METHOD = "krbv"
KRB_REALM = "IPA.REDHAT.COM"
# Kerberos principal. If commented, default principal obtained by kinit is used.
KRB_PRINCIPAL = "HTTP/prodsec-scanchain.apps.ocp-c1.prod.psi.redhat.com"
# Kerberos keytab file.
KRB_KEYTAB = "/kerberos/kerberos-keytab-osh"
# Enables XML-RPC verbose flag
DEBUG_XMLRPC = 0

28
k8s/prod/osh-client-tekton/osh-client-pvc.yaml

@ -0,0 +1,28 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: osh-client-sources
namespace: psse-scanchain-prod
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
storageClassName: dynamic-nfs
volumeMode: Filesystem
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: osh-client-source-tars
namespace: psse-scanchain-prod
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: dynamic-nfs
volumeMode: Filesystem

6
k8s/stage/osh-client-tekton/pipline/osh-client-from-source-pipeline.yaml → k8s/prod/osh-client-tekton/pipeline/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:

0
k8s/stage/osh-client-tekton/task/osh-client-from-source-clearup-workspace.yaml → k8s/prod/osh-client-tekton/task/osh-client-from-source-clearup-workspace.yaml

16
k8s/stage/osh-client-tekton/task/osh-client-from-source.yaml → k8s/prod/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)

2
k8s/stage/osh-client-tekton/task/osh-client-git-cli-modified.yaml → k8s/prod/osh-client-tekton/task/osh-client-git-cli-modified.yaml

@ -13,7 +13,7 @@ metadata:
app.kubernetes.io/version: "0.4"
hub.tekton.dev/catalog: tekton
name: git-cli
namespace: pct-security-tooling
namespace: psse-scanchain-prod
resourceVersion: "3453559180"
uid: 95fc93dd-8780-41ab-9477-b698762dc1de
spec:

63
k8s/prod/osh-client-tekton/task/osh-scan-task.yaml

@ -0,0 +1,63 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: osh-scan-task
spec:
stepTemplate:
env:
- name: "HOME"
value: "/tekton/home"
params:
- name: buildId
type: string
- name: scanProfile
type: string
volumes:
- name: osh-client-kerb-vol
secret:
defaultMode: 384
optional: false
secretName: kerberos-keytab-osh
- name: osh-client-kerb-config-vol
configMap:
name: kerberos-config-osh-client
items:
- key: linux-krb5.conf
path: linux-krb5.conf
defaultMode: 384
optional: false
- name: osh-client-config-vol
configMap:
name: osh-client-config
items:
- key: client.conf
path: client.conf
optional: false
steps:
- name: perform-buildid-scan
image: quay.io/pct-security/osh-wrapper-client:latest
workingDir: /home/covscan
volumeMounts:
- name: osh-client-kerb-vol
mountPath: /kerberos
readOnly: true
- name: osh-client-config-vol
mountPath: /etc/osh/client.conf
readOnly: true
subPath: client.conf
- name: osh-client-kerb-config-vol
mountPath: /etc/krb5.conf
readOnly: true
subPath: linux-krb5.conf
script: |
#!/bin/bash
echo $(params.buildId)
echo $(params.scanProfile)
covscan mock-build -p $(params.scanProfile) --brew-build $(params.buildId)

7
k8s/stage/osh-client-tekton/osh-client-config.yaml

@ -55,14 +55,11 @@ data:
# client config file for covscan
# Hub XML-RPC address.
HUB_URL = "https://cov01.lab.eng.brq2.redhat.com/covscanhub/xmlrpc"
HUB_URL = "https://covscan.lab.eng.brq2.redhat.com/osh/xmlrpc"
BREW_URL = "https://brewhub.engineering.redhat.com/brewhub"
KOJI_URL = "https://koji.fedoraproject.org/kojihub"
KOJI_PROFILES = "brew,koji"
CIM_SERVER = "cov01.lab.eng.brq2.redhat.com"
CIM_PORT = "8080"
DEFAULT_MOCKCONFIG = "fedora-rawhide-x86_64"
# Hub authentication method: "krbv", "password", or "gssapi"
@ -76,4 +73,4 @@ data:
KRB_KEYTAB = "/kerberos/kerberos-keytab-osh"
# Enables XML-RPC verbose flag
DEBUG_XMLRPC = 0
DEBUG_XMLRPC = 1

104
k8s/stage/osh-client-tekton/task/osh-scan-scm-task.yaml

@ -0,0 +1,104 @@
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: osh-scan-scm-task
spec:
stepTemplate:
env:
- name: "HOME"
value: "/tekton/home"
params:
- name: repo-url
type: string
description: The SCMURL
- name: revision
type: string
description: The revision or tag
- name: mock-build-params
type: string
description: Parameters pushed to mock build
default: "snyk-only-unstable --tarball-build-script=:"
- name: archive-name
type: string
description: The name of the git archive file
default: $(context.taskRun.uid).tar.gz
- name: tarball-storage-dir
type: string
description: What directory the scan tar gz will be put into
default: /workspace/source-tars/$(context.taskRun.name)
- name: working-dir
type: string
description: Working directory for the task
default: /home/covscan
workspaces:
- name: source-tars
description: This workspace contains our source tar gzips for covscan and is semi-persistant
- name: ssl-ca-directory
description: Location of CA bundle for ssl verification with internal services
volumes:
- name: osh-client-kerb-vol
secret:
defaultMode: 384
optional: false
secretName: kerberos-keytab-osh
- name: osh-client-kerb-config-vol
configMap:
name: kerberos-config-osh-client
items:
- key: linux-krb5.conf
path: linux-krb5.conf
defaultMode: 384
optional: false
- name: osh-client-config-vol
configMap:
name: osh-client-config
items:
- key: client.conf
path: client.conf
optional: false
steps:
- name: perform-osh-scm-scan
image: quay.io/pct-security/osh-wrapper-client:latest
workingDir: $(params.working-dir)
volumeMounts:
- name: osh-client-kerb-vol
mountPath: /kerberos
readOnly: true
- name: osh-client-config-vol
mountPath: /etc/osh/client.conf
readOnly: true
subPath: client.conf
- name: osh-client-kerb-config-vol
mountPath: /etc/krb5.conf
readOnly: true
subPath: linux-krb5.conf
script: |
#!/bin/bash
set -x
echo $(params.working-dir)
echo $(params.repo-url)
echo $(params.revision)
echo $(params.mock-build-params)
echo $(params.archive-name)
git clone -v $(params.repo-url) -b $(params.revision)
git --git-dir=$(basename $(params.repo-url) .git)/.git archive --format=tar.gz HEAD -o $(params.working-dir)/$(params.archive-name)
mkdir $(params.tarball-storage-dir)
cp $(params.working-dir)/$(params.archive-name) $(params.tarball-storage-dir)/
covscan mock-build $(params.mock-build-params) $(params.working-dir)/$(params.archive-name)

3
k8s/stage/osh-client-tekton/task/osh-scan-task.yaml

@ -58,6 +58,7 @@ spec:
script: |
#!/bin/bash
set -x
echo $(params.buildId)
echo $(params.scanProfile)
covscan mock-build -p $(params.scanProfile) --brew-build $(params.buildId)
covscan mock-build $(params.scanProfile) --brew-build $(params.buildId)

23
k8s/stage/osh-client-tekton/tekton-cleanup-cronjob.yaml

@ -0,0 +1,23 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: tekton-terminator
namespace: pct-security-tooling
spec:
schedule: "*/50 * * * *"
concurrencyPolicy: Forbid
backoffLimit: 2
jobTemplate:
spec:
template:
spec:
serviceAccountName: osh-wrapper-tekton-terminator-sa
containers:
- name: tekton-cleanup
image: quay.io/openshift-pipeline/openshift-pipelines-cli-tkn:1.11
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- tkn pipelinerun delete --keep 10 -f && tkn taskrun delete --keep 40 -f
restartPolicy: Never

43
k8s/stage/osh-client-tekton/tekton-terminator-sa-rbac.yaml

@ -0,0 +1,43 @@
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: pct-security-tooling
name: osh-wrapper-tekton-terminator-sa
labels:
app.kubernetes.io/name: osh-wrapper-tekton-terminator
env: stage
imagePullSecrets:
- name: pct-security-osh-wrapper-client-pull-secret
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: osh-wrapper-tekton-terminator
labels:
app.kubernetes.io/component: tekton
namespace: pct-security-tooling
rules:
- apiGroups:
- tekton.dev
resources:
- taskruns
- pipelineruns
verbs:
- get
- list
- delete
- update
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: osh-wrapper-tekton-terminator-rolebinding
namespace: pct-security-tooling
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: osh-wrapper-tekton-terminator
subjects:
- kind: ServiceAccount
name: osh-wrapper-tekton-terminator-sa

24
pom.xml

@ -12,7 +12,7 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>3.1.2.Final</quarkus.platform.version>
<quarkus.platform.version>3.1.3.Final</quarkus.platform.version>
<skipITs>true</skipITs>
<surefire-plugin.version>3.0.0</surefire-plugin.version>
</properties>
@ -87,6 +87,28 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-kubernetes-config</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.pnc</groupId>
<artifactId>common</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>org.jboss.pnc</groupId>
<artifactId>rest-client</artifactId>
<version>2.5.1</version>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-elytron-security-properties-file</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-reactive-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-rest-client-reactive</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>

2
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

49
src/main/java/com/redhat/pctsec/model/PNCBuild.java

@ -1,15 +1,55 @@
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;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.persistence.Entity;
import jakarta.persistence.Transient;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.jboss.pnc.dto.Build;
import java.net.URI;
import java.net.URL;
@Entity
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);
/*
@Transient
PncService pnc;
*/
@Transient
@JsonIgnore
private Build build;
private URI SCMURL;
private String revision;
public PNCBuild() {
super();
}
@Transient
@JsonIgnore
public Build getBuild() {
if(build == null)
build = pnc.getBuild(this.buildRef);
return build;
}
public PNCBuild(String buildRef) {
super(buildRef);
@ -17,7 +57,10 @@ public class PNCBuild extends BuildType{
@Override
public URI SCMURL() {
return null;
if(SCMURL == null)
SCMURL = URI.create(getBuild().getScmUrl());
return this.SCMURL;
}
@Override
@ -27,7 +70,9 @@ public class PNCBuild extends BuildType{
@Override
public String revision() {
return null;
if(revision == null)
revision = getBuild().getScmTag();
return revision;
}
public static boolean isValidRef(String ref){

102
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));
}
}

20
src/main/java/com/redhat/pctsec/model/ScanRequest.java

@ -20,9 +20,9 @@ public class ScanRequest {
@Id
@GeneratedValue
protected UUID id;
public 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;
@ -75,8 +68,9 @@ public class ScanRequest {
}
@Column(name="scan_properties")
public String scanProperties;
public String scanProperties = "";
public ScanRequest() {
}
public ScanRequest(BrewBuild brewBuild)

38
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<ScanRequest> scanRequests;// = new HashSet<>();
public Set<ScanRequest> scanRequests = new HashSet<>();
@Column(name="scan_properties")
@JsonIgnore
private String globalScanProperties;
@Column(name="scan_metadata")
@JsonIgnore
private String scanMetadata;
@ -44,8 +52,11 @@ public class ScanRequests {
pssaas.componentList.stream().filter(c -> c.getType().equals("pnc")).forEach(g -> this.addPNCBuild(g.getBuildId()));
}
public ScanRequests(scanChain scanchain){
public ScanRequests(scanChain scanChain){
this();
scanChain.urls.stream().forEach(g -> this.addGit(g.getRepo().toString(), g.getRef()));
}
//public ScanRequests(String repo, String rev){
@ -85,14 +96,14 @@ public class ScanRequests {
*/
}
public Set<ScanRequest> getScanRequests() {
return scanRequests;
}
public void setScanRequests(Set<ScanRequest> scanRequests) {
this.scanRequests = scanRequests;
}
@JsonProperty("globalScanProperties")
@Transient
public String getGlobalScanProperties() {
return globalScanProperties;
}
@ -101,6 +112,9 @@ public class ScanRequests {
this.globalScanProperties = globalScanProperties;
}
@JsonProperty("scanMetadata")
@Transient
public String getScanMetadata() {
return scanMetadata;
}
@ -108,4 +122,18 @@ public class ScanRequests {
public void setScanMetadata(String scanMetadata) {
this.scanMetadata = scanMetadata;
}
@JsonProperty("scanRequests")
@Transient
public Set<ScanRequest> 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().equals("")).filter(eso -> eso.getType() != RequestType.BREW).forEach(sr -> sr.setScanProperties(getGlobalScanProperties()));
}
}

31
src/main/java/com/redhat/pctsec/model/api/request/scanChain.java

@ -1,4 +1,35 @@
package com.redhat.pctsec.model.api.request;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.List;
import java.util.Set;
public class scanChain {
@JsonProperty("product_name")
@JsonPropertyDescription("The product name associated with the scan.")
@NotNull
public String productName;
@JsonProperty("urls")
@JsonDeserialize(as = java.util.LinkedHashSet.class)
@JsonPropertyDescription("List of source urls to be scanned")
@Size(min = 1)
@Valid
@NotNull
public Set<scanChainGit> urls;
@JsonProperty("requestor")
@JsonPropertyDescription("The requesting user")
@NotNull
public String requestor;
}

34
src/main/java/com/redhat/pctsec/model/api/request/scanChainGit.java

@ -0,0 +1,34 @@
package com.redhat.pctsec.model.api.request;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotNull;
import java.net.URI;
public class scanChainGit {
private URI repo;
private String ref;
public scanChainGit(@NotNull URI repo, @NotNull String ref) {
this.repo = repo;
this.ref = ref;
}
@NotNull
@JsonProperty("url")
public URI getRepo() {
return this.repo;
}
@NotNull
@JsonProperty("branch")
public String getRef() {
return this.ref;
}
}

12
src/main/java/com/redhat/pctsec/model/api/service/AltPncService.java

@ -0,0 +1,12 @@
package com.redhat.pctsec.model.api.service;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.pnc.dto.Build;
@Path("pnc-rest/v2/builds")
@RegisterRestClient
public interface AltPncService {
@GET
@Path("{id}")
Build getBuild(@PathParam("id") String id);
}

4
src/main/java/com/redhat/pctsec/model/jpa/UriConverter.java

@ -17,6 +17,8 @@ public class UriConverter implements AttributeConverter<URI, String>
@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;
}
}

6
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){

49
src/main/java/com/redhat/pctsec/rest/v1alpha1/OshWrapperApiApplication.java

@ -0,0 +1,49 @@
package com.redhat.pctsec.rest.v1alpha1;
import jakarta.ws.rs.core.Application;
import org.eclipse.microprofile.openapi.annotations.Components;
import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition;
import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType;
import org.eclipse.microprofile.openapi.annotations.info.Contact;
import org.eclipse.microprofile.openapi.annotations.info.Info;
import org.eclipse.microprofile.openapi.annotations.info.License;
import org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement;
import org.eclipse.microprofile.openapi.annotations.security.SecurityScheme;
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
@OpenAPIDefinition(
tags = {
//@Tag(name="widget", description="Widget operations."),
//@Tag(name="gasket", description="Operations related to gaskets")
},
info = @Info(
title="Example API",
version = "1.0.1",
contact = @Contact(
name = "Example API Support",
url = "http://exampleurl.com/contact",
email = "techsupport@example.com"),
license = @License(
name = "Apache 2.0",
url = "https://www.apache.org/licenses/LICENSE-2.0.html")),
components = @Components(
securitySchemes = {
@SecurityScheme(
securitySchemeName = "Kerberos",
type = SecuritySchemeType.HTTP,
scheme = "Negotiate"
//bearerFormat = "JWT"
),
@SecurityScheme(
securitySchemeName = "basic",
type = SecuritySchemeType.HTTP,
scheme = "basic"
)
}
),
security = {
@SecurityRequirement(name = "Kerberos"),
@SecurityRequirement(name = "basic")
}
)
public class OshWrapperApiApplication extends Application {
}

4
src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanRequestsResource.java

@ -9,7 +9,7 @@ import io.quarkus.security.Authenticated;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.*;
import org.jboss.resteasy.reactive.common.NotImplementedYet;
//import org.jboss.resteasy.reactive.common.NotImplementedYet;
import java.util.UUID;
@ -35,7 +35,7 @@ public class ScanRequestsResource {
@Authenticated
public ScanRequests addScanRequest(String id, ScanRequest scanRequest)
{
throw new NotImplementedYet();
throw new WebApplicationException("Not implemented");
}
}

70
src/main/java/com/redhat/pctsec/rest/v1alpha1/ScanResource.java

@ -2,16 +2,20 @@ package com.redhat.pctsec.rest.v1alpha1;
import com.redhat.pctsec.model.*;
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;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
@ -27,6 +31,10 @@ public class ScanResource {
@Inject
EventBus bus;
@Inject
SecurityIdentity identity;
@POST
@Path("PSSaaS")
@Consumes({ "application/json" })
@ -36,8 +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;
}
@ -49,9 +61,42 @@ public class ScanResource {
public List<ScanTask> createRunPSSAAS(@Valid pssaas scanRequest)
{
Scan s = this.createPSSAAS(scanRequest);
s.propagateOptions();
return s.scanRequests.execute(bus);
}
@POST
@Path("ScanChain")
@Consumes({ "application/json" })
@Transactional
@Authenticated
public Scan createScanChain(@Valid scanChain scanRequest)
{
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);
sr.persist(s);
return s;
}
@POST
@Path("ScanChain/run")
@Consumes({ "application/json" })
@Transactional
@Authenticated
public List<ScanTask> createRunScanChain(@Valid scanChain scanRequest)
{
Scan s = this.createScanChain(scanRequest);
s.propagateOptions();
return s.scanRequests.execute(bus);
}
@GET
@Path("All")
@Produces({"application/json"})
@ -75,9 +120,23 @@ public class ScanResource {
public List<ScanTask> 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")
@ -87,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;
@ -101,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;
@ -114,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;

104
src/main/java/com/redhat/pctsec/tekton/TaskHandler.java

@ -1,14 +1,8 @@
package com.redhat.pctsec.tekton;
import com.redhat.pctsec.model.RequestType;
import com.redhat.pctsec.model.ScanTask;
import com.redhat.pctsec.model.ScanTaskState;
import io.fabric8.kubernetes.api.model.ConfigMapVolumeSource;
import io.fabric8.kubernetes.api.model.PersistentVolumeClaimVolumeSource;
import io.fabric8.kubernetes.api.model.PodSecurityContext;
import io.fabric8.kubernetes.api.model.PodSecurityContextBuilder;
import io.fabric8.tekton.client.DefaultTektonClient;
import io.fabric8.tekton.client.TektonClient;
import io.fabric8.tekton.client.DefaultTektonClient;
import io.fabric8.tekton.client.TektonClient;
import io.fabric8.tekton.pipeline.v1beta1.*;
@ -17,9 +11,10 @@ import io.quarkus.vertx.ConsumeEvent;
import io.smallrye.common.annotation.Blocking;
import jakarta.inject.Inject;
import org.apache.commons.lang3.RandomStringUtils;
import org.eclipse.microprofile.config.inject.ConfigProperty;
import org.apache.commons.compress.utils.FileNameUtils;
import java.util.ArrayList;
import java.util.List;
@ -27,13 +22,13 @@ public class TaskHandler {
@ConfigProperty(name = "quarkus.openshift.namespace")
String NAMESPACE;
@ConfigProperty(name = "tekton.pipeline.ref")
String PIPELINE_REFERENCE;
@ConfigProperty(name = "tekton.scmscan.task.ref")
String SCM_SCAN_REFERENCE;
@ConfigProperty(name = "tekton.service-account")
String SERVICE_ACCOUNT;
@ConfigProperty(name = "tekton.task.ref")
String TASK_REFERENCE;
@ConfigProperty(name = "tekton.brewscan.task.ref")
String BREW_SCAN_TASK_REFERENCE;
@Inject
TektonClient tektonClient;
@ -46,19 +41,20 @@ public class TaskHandler {
switch(scanTask.getScanRequest().getType())
{
case BREW:
scanTask.setTektonRunId(invokeScanTask(scanTask.getScanRequest().brewBuild.buildRef));
scanTask.setTektonRunId(invokeScanTask(scanTask.getScanRequest().brewBuild.buildRef,
scanTask.getScanRequest().getScanProperties()));
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,73 +62,67 @@ 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";
// String scanProfile = "snyk-only-unstable";
// random taskrun name generating for now
TaskRun taskRun = new TaskRunBuilder().withNewMetadata().withName("osh-scan-taskrun-" + RandomStringUtils.randomAlphanumeric(8).toLowerCase())
TaskRun taskRun = new TaskRunBuilder()
.withNewMetadata()
.withGenerateName("osh-brew-scan-taskrun-")
.endMetadata()
.withNewSpec()
.withServiceAccountName(SERVICE_ACCOUNT)
.withNewTaskRef()
.withName(TASK_REFERENCE)
.withName(BREW_SCAN_TASK_REFERENCE)
.endTaskRef()
.withParams(
new Param("buildId", new ArrayOrString(buildId)),
new Param("scanProfile", new ArrayOrString(scanProfile)))
new Param("scanProfile", new ArrayOrString(mockbuildArgs)))
.endSpec()
.build();
tektonClient.v1beta1().taskRuns().inNamespace(NAMESPACE).resource(taskRun).create();
TaskRun createdTaskRun = tektonClient.v1beta1().taskRuns().inNamespace(NAMESPACE).resource(taskRun).create();
return taskRun.getMetadata().getName();
return createdTaskRun.getMetadata().getName();
}
public String invokeOshScmScanPipeline(String repo, String ref) {
PodSecurityContext securityContext = new PodSecurityContextBuilder()
.withRunAsNonRoot(true)
.withRunAsUser(65532L)
.build();
WorkspaceBinding sourcesWorkspaceBinding = new WorkspaceBindingBuilder()
.withName("sources")
.withPersistentVolumeClaim(new PersistentVolumeClaimVolumeSource("osh-client-sources", null))
.build();
public String invokeOshScmScanPipeline(String repo, String ref, String mockBuildArgs) {
WorkspaceBinding sourceTarsWorkspaceBinding = new WorkspaceBindingBuilder()
.withName("source-tars")
.withPersistentVolumeClaim(new PersistentVolumeClaimVolumeSource("osh-client-source-tars", null))
.build();
.withName("source-tars")
.withPersistentVolumeClaim(new PersistentVolumeClaimVolumeSource("osh-client-source-tars", null))
.build();
WorkspaceBinding sslCaDirectoryWorkspaceBinding = new WorkspaceBindingBuilder()
.withName("ssl-ca-directory")
.withConfigMap(new ConfigMapVolumeSource(null, null, "config-trusted-cabundle", null))
.build();
.withName("ssl-ca-directory")
.withConfigMap(new ConfigMapVolumeSource(null, null, "config-trusted-cabundle", null))
.build();
List<WorkspaceBinding> workspaceBindings = new ArrayList<>();
workspaceBindings.add(sourcesWorkspaceBinding);
workspaceBindings.add(sourceTarsWorkspaceBinding);
workspaceBindings.add(sslCaDirectoryWorkspaceBinding);
PipelineRun pipelineRun = new PipelineRunBuilder()
.withNewMetadata().withName("osh-scm-scan-" + RandomStringUtils.randomAlphanumeric(8).toLowerCase()).endMetadata()
.withNewSpec()
.withNewPodTemplate()
.withSecurityContext(securityContext)
.endPodTemplate()
.withServiceAccountName(SERVICE_ACCOUNT)
.withNewPipelineRef().withName(PIPELINE_REFERENCE).endPipelineRef()
.addNewParam().withName("repo-url").withNewValue(repo).endParam()
.addNewParam().withName("revision").withNewValue(ref).endParam()
.withWorkspaces(workspaceBindings)
.endSpec()
.build();
tektonClient.v1beta1().pipelineRuns().inNamespace(NAMESPACE).resource(pipelineRun).create();
return pipelineRun.getMetadata().getName();
TaskRun taskRun = new TaskRunBuilder()
.withNewMetadata()
.withGenerateName("osh-scm-scan-taskrun-")
.endMetadata()
.withNewSpec()
.withServiceAccountName(SERVICE_ACCOUNT)
.withNewTaskRef()
.withName(SCM_SCAN_REFERENCE)
.endTaskRef()
.addNewParam().withName("repo-url").withNewValue(repo).endParam()
.addNewParam().withName("revision").withNewValue(ref).endParam()
.addNewParam().withName("mock-build-params").withNewValue(mockBuildArgs).endParam()
.addNewParam().withName("archive-name").withNewValue(FileNameUtils.getBaseName(repo) + "-" + ref + ".tar.gz").endParam()
.withWorkspaces(workspaceBindings)
.endSpec()
.build();
TaskRun createdTaskRun = tektonClient.v1beta1().taskRuns().inNamespace(NAMESPACE).resource(taskRun).create();
return createdTaskRun.getMetadata().getName();
}

96
src/main/resources/application.properties

@ -1,54 +1,55 @@
#Example deploy - mvn deploy -Dquarkus.profile=stage -Dquarkus.kubernetes.deploy=true
# quarkus.rest-client."rest.CreateScanService".url=https://localhost:8080/
# quarkus.rest-client."rest.CreateScanService".scope=javax.inject.Singleton
# couchdb.name=scan-results
# couchdb.url=https://localhost:5984
# quarkus.hibernate-orm.database.generation=drop-and-create
#temporary fix, we need to enable it with a working devservices setup
%dev.quarkus.kerberos.enabled=false
%dev.quarkus.security.auth.enabled-in-dev-mode=false
#Also tried
#%dev.quarkus.security.enabled=false
#%dev.quarkus.http.auth.proactive=false
#%dev.quarkus.http.auth.basic=false
#%dev.quarkus.http.auth.permission.permit1.paths=/Ping/Ping
#%dev.quarkus.http.auth.permission.permit1.policy=permit
#%dev.quarkus.http.auth.permission.permit1.methods=GET,HEAD
#%quarkus.arc.unremovable-types=io.quarkiverse.kerberos.*,io.quarkiverse.kerberos.KerberosPrincipal
#%dev.quarkus.kerberos.keytab-path= HTTP_osh-pct-security-tooling.apps.ocp-c1.prod.psi.redhat.com@IPA.REDHAT.COM.keytab
#%dev.quarkus.kerberos.service-principal-name= HTTP/osh-pct-security-tooling.apps.ocp-c1.prod.psi.redhat.com@IPA.REDHAT.COM
%dev.quarkus.security.auth.enabled-in-dev-mode=true
##########################################
# Data Source #
##########################################
%dev.quarkus.datasource.devservices.enabled=true
%dev.quarkus.datasource.db-kind = postgresql
quarkus.datasource.db-kind = postgresql
%dev.quarkus.datasource.username = quarkus
%dev.quarkus.datasource.password = quarkus
#%dev.quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/hibernate_db
%dev.quarkus.hibernate-orm.database.generation=drop-and-create
%stage.quarkus.kubernetes-config.secrets.enabled=true
quarkus.kubernetes-config.secrets=postgresql
%stage.quarkus.kubernetes-config.secrets=postgresql
%stage.quarkus.datasource.jdbc.url=jdbc:postgresql://postgresql:5432/${database-name}
%stage.quarkus.datasource.username=${database-user}
%stage.quarkus.datasource.password=${database-password}
%stage.quarkus.hibernate-orm.database.generation=drop-and-create
# Production settings. We db-name and the user are located on a config map (database-envs). The password is located on a
# secret (database-envs).
%prod.quarkus.openshift.env.mapping.db-password.from-secret=database-envs
%prod.quarkus.openshift.env.mapping.db-password.with-key=POSTGRESQL_PASSWORD
%prod.quarkus.openshift.env.mapping.db-user.from-configmap=database-envs-osh
%prod.quarkus.openshift.env.mapping.db-user.with-key=POSTGRESQL_USER
%prod.quarkus.openshift.env.mapping.db-name.from-configmap=database-envs-osh
%prod.quarkus.openshift.env.mapping.db-name.with-key=POSTGRESQL_DATABASE
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://postgresql:5432/${db-name}
%prod.quarkus.datasource.username=${db-user}
%prod.quarkus.datasource.password=${db-password}
%prod.quarkus.hibernate-orm.database.generation.create-schemas=true
%prod.quarkus.hibernate-orm.database.generation=update
#Always provide swagger ui
quarkus.swagger-ui.always-include=true
%dev.quarkus.openshift.service-account=osh-wrapper-client-sa
%dev.quarkus.openshift.namespace=pct-security-tooling
%prod.quarkus.http.root-path=/osh-wrapper/
%stage.quarkus.openshift.name=osh
quarkus.openshift.service-account=osh-wrapper-client-sa
%stage.quarkus.openshift.labels.env=stage
%stage.quarkus.log.level=DEBUG
quarkus.arc.remove-unused-beans=false
#%stage.quarkus.http.root-path=/stage/
#Only in Quarkus > 3.x
%stage.quarkus.openshift.route.tls.termination=edge
@ -58,6 +59,26 @@ quarkus.arc.remove-unused-beans=false
%stage.quarkus.openshift.route.tls.insecure-edge-termination-policy=redirect
%stage.quarkus.openshift.namespace=pct-security-tooling
#Production settings
#Always provide swagger ui
# Probably we need to check these 2 settings
%prod.quarkus.openshift.service-account=osh
%prod.quarkus.openshift.namespace=psse-scanchain-prod
%prod.quarkus.openshift.name=osh
%prod.quarkus.openshift.labels.env=prod
%prod.quarkus.log.level=DEBUG
#Only in Quarkus > 3.x
%prod.quarkus.openshift.route.tls.termination=edge
#As we cant create a edge terminated route (quarkus <3.x) lets disable route creation for now
%prod.quarkus.openshift.route.expose=false
%prod.quarkus.openshift.route.target-port=https
%prod.quarkus.openshift.route.tls.insecure-edge-termination-policy=redirect
##########################################
# Kerberos Specifics #
##########################################
@ -73,12 +94,43 @@ quarkus.arc.remove-unused-beans=false
%stage.quarkus.openshift.config-map-volumes.osh-wrapper-config-vol.items."linux-krb5.conf".path=linux-krb5.conf
%stage.quarkus.openshift.mounts.osh-wrapper-config-vol.read-only=true
## Production settings
%prod.quarkus.openshift.secret-volumes.osh-wrapper.secret-name=kerberos-keytab-osh
%prod.quarkus.openshift.mounts.osh-wrapper.path=/kerberos
%prod.quarkus.openshift.mounts.osh-wrapper.read-only=true
%prod.quarkus.kerberos.keytab-path= /kerberos/kerberos-keytab-osh
%prod.quarkus.kerberos.service-principal-name= HTTP/prodsec-scanchain.apps.ocp-c1.prod.psi.redhat.com@IPA.REDHAT.COM
%prod.quarkus.openshift.mounts.osh-wrapper-config-vol.path=/etc/krb5.conf
%prod.quarkus.openshift.mounts.osh-wrapper-config-vol.sub-path=linux-krb5.conf
%prod.quarkus.openshift.config-map-volumes.osh-wrapper-config-vol.config-map-name=kerberos-config
%prod.quarkus.openshift.config-map-volumes.osh-wrapper-config-vol.items."linux-krb5.conf".path=linux-krb5.conf
%prod.quarkus.openshift.mounts.osh-wrapper-config-vol.read-only=true
##########################################
# Tekton Specifics (Used in app) #
##########################################
tekton.pipeline.ref=osh-client-from-source
tekton.task.ref=osh-scan-task
tekton.scmscan.task.ref=osh-scan-scm-task
tekton.brewscan.task.ref=osh-scan-task
tekton.service-account=${quarkus.openshift.service-account}
##########################################
# PNC Settings #
##########################################
pnc.api-url=http://orch.psi.redhat.com
##########################################
# PSSaaS Kerberos bypass (OSH-154) #
##########################################
quarkus.http.auth.basic=true
quarkus.security.users.embedded.enabled=true
quarkus.security.users.embedded.plain-text=true
quarkus.openshift.env.mapping.kerb-bypass-password.from-secret=kerb-bypass
quarkus.openshift.env.mapping.kerb-bypass-password.with-key=PASSWORD
%prod.quarkus.security.users.embedded.users.pssaas=${kerb-bypass-password}
%stage.quarkus.security.users.embedded.users.pssaas=${kerb-bypass-password}
%dev.quarkus.security.users.embedded.users.pssaas=pssaas

19
src/test/java/com/redhat/pctsec/model/test/PNCBuildTest.java

@ -0,0 +1,19 @@
package com.redhat.pctsec.model.test;
import com.redhat.pctsec.model.PNCBuild;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
@QuarkusTest
public class PNCBuildTest {
@Test
public void testBuildFetch(){
PNCBuild pb = new PNCBuild("AZAQZSPFDRQAA");
System.out.println(pb.SCMURL());
System.out.println(pb.revision());
}
}

3
src/test/java/com/redhat/pctsec/model/osh/paramMapperTest.java → src/test/java/com/redhat/pctsec/model/test/paramMapperTest.java

@ -1,5 +1,6 @@
package com.redhat.pctsec.model.osh;
package com.redhat.pctsec.model.test;
import com.redhat.pctsec.model.osh.paramMapper;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
Loading…
Cancel
Save