├── scripts
├── apply.sh
├── acm
│ ├── 1-apply-channel.sh
│ ├── 2-apply-dev.sh
│ ├── 3-apply-test.sh
│ ├── 4-apply-prod.sh
│ └── 5-spply-cicd.sh
├── apply-home.sh
├── apply-ocplab.sh
├── apply-pipelinerun.sh
└── siege.sh
├── .gitignore
├── docs
├── img
│ ├── argocd.png
│ ├── cicd-flow.png
│ ├── topology.png
│ ├── monitoring.png
│ ├── screenshot.png
│ ├── tekton-rerun.png
│ └── client-server-database.png
└── swagger
│ └── swagger-2.0.json
├── clusters
├── local.home
│ └── overlays
│ │ ├── cicd
│ │ ├── patch-pvc-block.yaml
│ │ ├── pipeline-rolebinding.yaml
│ │ └── kustomization.yaml
│ │ ├── prod
│ │ └── kustomization.yaml
│ │ ├── test
│ │ └── kustomization.yaml
│ │ ├── dev
│ │ └── kustomization.yaml
│ │ └── pipelinerun
│ │ ├── apps
│ │ └── kustomization.yaml
│ │ ├── push-to-prod-client
│ │ └── kustomization.yaml
│ │ └── push-to-prod-server
│ │ └── kustomization.yaml
├── aws.cluster
│ └── overlays
│ │ ├── cicd
│ │ ├── kustomization.yaml
│ │ └── pipeline-rolebinding.yaml
│ │ ├── dev
│ │ └── kustomization.yaml
│ │ ├── prod
│ │ └── kustomization.yaml
│ │ ├── test
│ │ └── kustomization.yaml
│ │ └── pipelinerun
│ │ └── kustomization.yaml
└── rhpds
│ └── overlays
│ ├── dev
│ └── kustomization.yaml
│ ├── prod
│ └── kustomization.yaml
│ ├── test
│ └── kustomization.yaml
│ ├── cicd
│ ├── pipeline-rolebinding.yaml
│ └── kustomization.yaml
│ └── pipelinerun
│ ├── apps
│ └── kustomization.yaml
│ ├── push-to-prod-client
│ └── kustomization.yaml
│ └── push-to-prod-server
│ └── kustomization.yaml
├── components
├── apps
│ ├── slack-message-handler
│ │ └── base
│ │ │ ├── kustomization.yaml
│ │ │ ├── route.yaml
│ │ │ ├── service.yaml
│ │ │ └── deployment.yaml
│ ├── client
│ │ └── base
│ │ │ ├── config
│ │ │ └── config.js
│ │ │ ├── client-service.yaml
│ │ │ ├── kustomization.yaml
│ │ │ ├── client-route.yaml
│ │ │ └── client-deployment.yaml
│ ├── monitor
│ │ └── base
│ │ │ ├── kustomization.yaml
│ │ │ └── grafana-quarkus-dashboard.yaml
│ ├── database
│ │ └── base
│ │ │ ├── db-pvc.yaml
│ │ │ ├── db-service.yaml
│ │ │ ├── kustomization.yaml
│ │ │ ├── config
│ │ │ ├── 90-init-database.sh
│ │ │ ├── schema.sql
│ │ │ └── import.sql
│ │ │ ├── db-secret.yaml
│ │ │ └── db-deployment.yaml
│ └── server
│ │ └── base
│ │ ├── server-sm.yaml
│ │ ├── default-view-rolebinding.yaml
│ │ ├── config
│ │ └── application.properties
│ │ ├── kustomization.yaml
│ │ ├── server-service.yaml
│ │ ├── server-route.yaml
│ │ └── server-deployment.yaml
└── tekton
│ ├── tasks
│ └── base
│ │ ├── m2-cache-pvc.yaml
│ │ ├── npm-cache-pvc.yaml
│ │ ├── dependency-cache-pvc.yaml
│ │ ├── task-yq.yaml
│ │ ├── task-deploy.yaml
│ │ ├── task-git.yaml
│ │ ├── task-tekton.yaml
│ │ ├── task-variables.yaml
│ │ ├── task-push-image.yaml
│ │ ├── kustomization.yaml
│ │ ├── task-kustomize.yaml
│ │ ├── task-npm-quality.yaml
│ │ ├── task-npm.yaml
│ │ ├── task-create-pr.yaml
│ │ ├── task-run-pipeline.yaml
│ │ ├── task-create-commit-list.yaml
│ │ ├── task-send-to-webhook-slack.yaml
│ │ ├── task-binary-s2i.yaml
│ │ ├── task-update-image.yaml
│ │ └── task-buildah.yaml
│ ├── pipelines
│ ├── client
│ │ └── base
│ │ │ ├── kustomization.yaml
│ │ │ └── client-pipeline.yaml
│ ├── push-prod-pr
│ │ └── base
│ │ │ ├── kustomization.yaml
│ │ │ ├── gitops-manifests-pvc.yaml
│ │ │ └── push-prod-pr-pipeline.yaml
│ └── server
│ │ └── base
│ │ ├── secrets
│ │ └── maven-repo-creds.yaml
│ │ ├── config
│ │ ├── newman-dev-env.json
│ │ ├── newman-prod-env.json
│ │ ├── newman-test-env.json
│ │ └── settings.xml
│ │ ├── kustomization.yaml
│ │ ├── server-post-prod-pipeline.yaml
│ │ └── server-pipeline.yaml
│ └── triggers
│ └── base
│ ├── argocd-notification-triggerbinding.yaml
│ ├── slack-message-eventlistener.yaml
│ ├── kustomization.yaml
│ ├── slack-message-triggerbinding.yaml
│ ├── server-post-prod-triggertemplate.yaml
│ ├── client-eventlistener.yaml
│ ├── server-eventlistener.yaml
│ ├── server-post-prod-eventlistener.yaml
│ ├── client-triggertemplate.yaml
│ ├── server-triggertemplate.yaml
│ └── slack-message-triggertemplate.yaml
├── environments
└── overlays
│ ├── monitor
│ ├── README.md
│ └── kustomization.yaml
│ ├── cicd
│ ├── workspace-template-cm.yaml
│ ├── acs-external-secret.yaml
│ ├── upload-sbom-secret.yaml
│ ├── slack-deployments-webhook-external-secret.yaml
│ ├── prod-network-policy.yaml
│ ├── gitops-network-policy.yaml
│ ├── github-external-secret.yaml
│ ├── docker-external-secret.yaml
│ ├── kustomization.yaml
│ └── setup-local-credentials-job.yaml
│ ├── prod
│ ├── cicd-pipeline-view.yaml
│ ├── kustomization.yaml
│ ├── cicd-networkpolicy.yaml
│ └── post-sync-pipeline-job.yaml
│ ├── dev
│ ├── kustomization.yaml
│ └── cicd-networkpolicy.yaml
│ └── test
│ ├── kustomization.yaml
│ └── cicd-networkpolicy.yaml
├── pipelinerun.sh
├── bootstrap.sh
├── bootstrap
└── argocd
│ └── apps
│ └── overlays
│ ├── rhpds
│ ├── kustomization.yaml
│ └── values.yaml
│ ├── aws.cluster
│ ├── kustomization.yaml
│ └── values.yaml
│ └── local.home
│ ├── kustomization.yaml
│ └── values.yaml
└── README.md
/scripts/apply.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../clusters/overlays/ocplab/tools/argocd
--------------------------------------------------------------------------------
/scripts/acm/1-apply-channel.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../../manifests/tools/acm/channel/base/
--------------------------------------------------------------------------------
/scripts/acm/2-apply-dev.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../../manifests/tools/acm/app/overlays/dev/
--------------------------------------------------------------------------------
/scripts/acm/3-apply-test.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../../manifests/tools/acm/app/overlays/test
--------------------------------------------------------------------------------
/scripts/acm/4-apply-prod.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../../manifests/tools/acm/app/overlays/prod
--------------------------------------------------------------------------------
/scripts/apply-home.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../clusters/overlays/home/tools/argocd/manager
--------------------------------------------------------------------------------
/scripts/apply-ocplab.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../clusters/overlays/ocplab/tools/argocd/manager
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .dockerconfigjson
2 | .vscode
3 | optional
4 | charts
5 | *eso-token*
6 |
--------------------------------------------------------------------------------
/scripts/acm/5-spply-cicd.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../../manifests/tools/acm/cicd/overlays/default
--------------------------------------------------------------------------------
/docs/img/argocd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/argocd.png
--------------------------------------------------------------------------------
/docs/img/cicd-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/cicd-flow.png
--------------------------------------------------------------------------------
/docs/img/topology.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/topology.png
--------------------------------------------------------------------------------
/docs/img/monitoring.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/monitoring.png
--------------------------------------------------------------------------------
/docs/img/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/screenshot.png
--------------------------------------------------------------------------------
/docs/img/tekton-rerun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/tekton-rerun.png
--------------------------------------------------------------------------------
/clusters/local.home/overlays/cicd/patch-pvc-block.yaml:
--------------------------------------------------------------------------------
1 | - op: replace
2 | path: /spec/storageClassName
3 | value: iscsi
--------------------------------------------------------------------------------
/components/apps/slack-message-handler/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | - service.yaml
3 | - deployment.yaml
4 | - route.yaml
--------------------------------------------------------------------------------
/docs/img/client-server-database.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnunn-gitops/product-catalog/HEAD/docs/img/client-server-database.png
--------------------------------------------------------------------------------
/components/apps/client/base/config/config.js:
--------------------------------------------------------------------------------
1 | window.ENV = {
2 | "API_URL":"http://localhost:8080",
3 | "API_KEY":" 43fbc9b33302db65d58553e27d1679ac"
4 | }
--------------------------------------------------------------------------------
/components/apps/monitor/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - grafana-quarkus-dashboard.yaml
--------------------------------------------------------------------------------
/scripts/apply-pipelinerun.sh:
--------------------------------------------------------------------------------
1 | oc apply -k ../manifests/tekton/pipelineruns/client/base -n product-catalog-cicd
2 | oc apply -k ../manifests/tekton/pipelineruns/server/base -n product-catalog-cicd
--------------------------------------------------------------------------------
/clusters/aws.cluster/overlays/cicd/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | bases:
5 | - ../../../../environments/overlays/cicd
6 |
7 | resources:
8 | - pipeline-rolebinding.yaml
--------------------------------------------------------------------------------
/components/apps/database/base/db-pvc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolumeClaim
3 | metadata:
4 | name: productdb
5 | spec:
6 | accessModes:
7 | - ReadWriteOnce
8 | resources:
9 | requests:
10 | storage: "1Gi"
--------------------------------------------------------------------------------
/components/tekton/tasks/base/m2-cache-pvc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolumeClaim
3 | metadata:
4 | name: m2-cache
5 | spec:
6 | resources:
7 | requests:
8 | storage: 10Gi
9 | accessModes:
10 | - ReadWriteOnce
--------------------------------------------------------------------------------
/components/tekton/pipelines/client/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | generatorOptions:
5 | disableNameSuffixHash: true
6 |
7 | resources:
8 | # Client pipeline
9 | - client-pipeline.yaml
--------------------------------------------------------------------------------
/environments/overlays/monitor/README.md:
--------------------------------------------------------------------------------
1 | #### Overview
2 |
3 | Deploys just grafana and relies on [app monitoring](https://docs.openshift.com/container-platform/4.6/monitoring/enabling-monitoring-for-user-defined-projects.html) being enabled in the OpenShift cluster.
--------------------------------------------------------------------------------
/components/tekton/pipelines/push-prod-pr/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | generatorOptions:
5 | disableNameSuffixHash: true
6 |
7 | resources:
8 | - gitops-manifests-pvc.yaml
9 | - push-prod-pr-pipeline.yaml
--------------------------------------------------------------------------------
/components/tekton/tasks/base/npm-cache-pvc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolumeClaim
3 | metadata:
4 | name: npm-cache
5 | spec:
6 | resources:
7 | requests:
8 | storage: 10Gi
9 | volumeMode: Filesystem
10 | accessModes:
11 | - ReadWriteOnce
--------------------------------------------------------------------------------
/pipelinerun.sh:
--------------------------------------------------------------------------------
1 | if [ $# -lt 1 ]; then
2 | echo "No cluster name specified, please specify a cluster "
3 | exit 1
4 | else
5 | CLUSTER=$1
6 | echo "Running pipelines for cluster: ${CLUSTER}"
7 | fi
8 | kustomize build clusters/${CLUSTER}/overlays/pipelinerun/apps | oc apply -f -
--------------------------------------------------------------------------------
/components/tekton/tasks/base/dependency-cache-pvc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolumeClaim
3 | metadata:
4 | name: dependency-cache
5 | spec:
6 | resources:
7 | requests:
8 | storage: 10Gi
9 | volumeMode: Filesystem
10 | accessModes:
11 | - ReadWriteOnce
--------------------------------------------------------------------------------
/scripts/siege.sh:
--------------------------------------------------------------------------------
1 | COUNT=50
2 |
3 | SERVER_HOST=server-product-catalog-prod.apps.home.ocplab.com
4 |
5 | siege -r $COUNT -c 50 -v http://${SERVER_HOST}/api/product &
6 | siege -r $COUNT -c 50 -v http://${SERVER_HOST}/api/product/count &
7 | siege -r $COUNT -c 50 -v http://${SERVER_HOST}/api/category &
8 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/push-prod-pr/base/gitops-manifests-pvc.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: PersistentVolumeClaim
3 | metadata:
4 | name: gitops-manifests
5 | spec:
6 | resources:
7 | requests:
8 | storage: 1Gi
9 | volumeMode: Filesystem
10 | accessModes:
11 | - ReadWriteOnce
--------------------------------------------------------------------------------
/components/apps/server/base/server-sm.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: monitoring.coreos.com/v1
2 | kind: ServiceMonitor
3 | metadata:
4 | name: server
5 | spec:
6 | selector:
7 | matchLabels:
8 | quarkus-prometheus: "true"
9 | endpoints:
10 | - port: http
11 | path: /q/metrics
12 | scheme: http
--------------------------------------------------------------------------------
/environments/overlays/cicd/workspace-template-cm.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ConfigMap
3 | metadata:
4 | name: workspace-template
5 | data:
6 | workspace-template.yaml: |
7 | spec:
8 | accessModes:
9 | - ReadWriteOnce
10 | resources:
11 | requests:
12 | storage: 5Gi
--------------------------------------------------------------------------------
/bootstrap.sh:
--------------------------------------------------------------------------------
1 | if [ $# -lt 1 ]; then
2 | echo "No overlay specified, please specify an overlay from bootstrap/overlays"
3 | exit 1
4 | else
5 | OVERLAY=$1
6 | echo "Deploying product catalog to cluster ${OVERLAY}"
7 | fi
8 | kustomize build bootstrap/argocd/apps/overlays/${OVERLAY} --enable-helm | oc apply -f -
--------------------------------------------------------------------------------
/components/apps/server/base/default-view-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: default-view
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: ClusterRole
8 | name: view
9 | subjects:
10 | - kind: ServiceAccount
11 | name: default
--------------------------------------------------------------------------------
/environments/overlays/monitor/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-monitor
5 |
6 | commonAnnotations:
7 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true
8 |
9 | bases:
10 | - ../../../components/apps/monitor/base
--------------------------------------------------------------------------------
/clusters/aws.cluster/overlays/dev/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newTag: latest
7 | - name: quay.io/gnunn/server
8 | newName: quay.io/gnunn/server
9 | newTag: f08be80-110331912
10 | resources:
11 | - ../../../../environments/overlays/dev
--------------------------------------------------------------------------------
/clusters/aws.cluster/overlays/prod/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newTag: latest
7 | - name: quay.io/gnunn/server
8 | newName: quay.io/gnunn/server
9 | newTag: f08be80-110331912
10 | resources:
11 | - ../../../../environments/overlays/prod
--------------------------------------------------------------------------------
/clusters/aws.cluster/overlays/test/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newTag: latest
7 | - name: quay.io/gnunn/server
8 | newName: quay.io/gnunn/server
9 | newTag: f08be80-110331912
10 | resources:
11 | - ../../../../environments/overlays/test
--------------------------------------------------------------------------------
/environments/overlays/prod/cicd-pipeline-view.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: cicd-view-prod
5 | roleRef:
6 | apiGroup: rbac.authorization.k8s.io
7 | kind: ClusterRole
8 | name: view
9 | subjects:
10 | - kind: ServiceAccount
11 | name: pipeline
12 | namespace: product-catalog-cicd
--------------------------------------------------------------------------------
/components/tekton/triggers/base/argocd-notification-triggerbinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: triggers.tekton.dev/v1beta1
2 | kind: TriggerBinding
3 | metadata:
4 | name: argocd-notification
5 | spec:
6 | params:
7 | - name: state
8 | value: $(body.state)
9 | - name: application
10 | value: $(body.application)
11 | - name: description
12 | value: $(body.description)
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/secrets/maven-repo-creds.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | annotations:
5 | sealedsecrets.bitnami.com/managed: "true"
6 | argocd.argoproj.io/compare-options: IgnoreExtraneous
7 | name: maven-repo-creds
8 | type: Opaque
9 | data:
10 | MAVEN_SERVER_USERNAME: YWRtaW4K
11 | MAVEN_SERVER_PASSWORD: YWRtaW4xMjMK
--------------------------------------------------------------------------------
/bootstrap/argocd/apps/overlays/rhpds/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-gitops
5 |
6 | helmCharts:
7 | - name: argocd-app-of-app
8 | version: 0.2.6
9 | repo: https://gnunn-gitops.github.io/helm-charts
10 | valuesFile: values.yaml
11 | namespace: openshift-gitops
12 | releaseName: product-catalog
--------------------------------------------------------------------------------
/bootstrap/argocd/apps/overlays/aws.cluster/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-gitops
5 |
6 | helmCharts:
7 | - name: argocd-app-of-app
8 | version: 0.2.6
9 | repo: https://gnunn-gitops.github.io/helm-charts
10 | valuesFile: values.yaml
11 | namespace: openshift-gitops
12 | releaseName: product-catalog
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/dev/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newName: quay.io/gnunn/client
7 | newTag: b8a2b2a-4074585724
8 | - name: quay.io/gnunn/server
9 | newName: quay.io/gnunn/server
10 | newTag: 7f192d4-1427400123
11 | resources:
12 | - ../../../../environments/overlays/dev
13 |
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/prod/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newName: quay.io/gnunn/client
7 | newTag: b8a2b2a-135791192
8 | - name: quay.io/gnunn/server
9 | newName: quay.io/gnunn/server
10 | newTag: 7f192d4-806338677
11 | resources:
12 | - ../../../../environments/overlays/prod
13 |
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/test/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newName: quay.io/gnunn/client
7 | newTag: b8a2b2a-4074585724
8 | - name: quay.io/gnunn/server
9 | newName: quay.io/gnunn/server
10 | newTag: 7f192d4-1427400123
11 | resources:
12 | - ../../../../environments/overlays/test
13 |
--------------------------------------------------------------------------------
/bootstrap/argocd/apps/overlays/local.home/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-gitops
5 |
6 | helmCharts:
7 | - name: argocd-app-of-app
8 | version: 0.4.0
9 | repo: https://gnunn-gitops.github.io/helm-charts
10 | valuesFile: values.yaml
11 | namespace: openshift-gitops
12 | releaseName: product-catalog
13 |
--------------------------------------------------------------------------------
/environments/overlays/prod/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-prod
5 |
6 | resources:
7 | - cicd-networkpolicy.yaml
8 | - cicd-pipeline-view.yaml
9 | - ../../../components/apps/database/base
10 | - ../../../components/apps/server/base
11 | - ../../../components/apps/client/base
12 | - post-sync-pipeline-job.yaml
13 |
--------------------------------------------------------------------------------
/components/tekton/triggers/base/slack-message-eventlistener.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: EventListener
4 | metadata:
5 | name: slack-message
6 | spec:
7 | serviceAccountName: pipeline
8 | triggers:
9 | - name: slack-message-webhook
10 | bindings:
11 | - kind: TriggerBinding
12 | ref: slack-message
13 | template:
14 | ref: slack-message
15 |
--------------------------------------------------------------------------------
/components/apps/client/base/client-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: client
5 | labels:
6 | app: client
7 | app.kubernetes.io/name: client
8 | app.kubernetes.io/component: frontend
9 | app.kubernetes.io/instance: client
10 | spec:
11 | ports:
12 | - name: http
13 | port: 8080
14 | selector:
15 | name: client
16 | sessionAffinity: None
17 | type: ClusterIP
--------------------------------------------------------------------------------
/components/apps/database/base/db-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: productdb
5 | labels:
6 | app: server
7 | app.kubernetes.io/name: productdb
8 | app.kubernetes.io/component: database
9 | app.kubernetes.io/instance: productdb
10 | app.kubernetes.io/part-of: product-catalog
11 | spec:
12 | ports:
13 | - name: tcp
14 | port: 3306
15 | selector:
16 | name: productdb
--------------------------------------------------------------------------------
/clusters/local.home/overlays/prod/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newName: quay.io/gnunn/client
7 | newTag: 573225d-2Wwj1vjyzni1zhDinJsSfUs3y4y
8 | - name: quay.io/gnunn/server
9 | newName: quay.io/gnunn/server
10 | newTag: a5eaf2d-2vXnMar5rd141i41lJwrpmbYidT
11 | resources:
12 | - ../../../../environments/overlays/prod
13 |
--------------------------------------------------------------------------------
/clusters/local.home/overlays/test/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newName: quay.io/gnunn/client
7 | newTag: fff9592-2fbdBT1Wxzx9uBS8uCeR2uyIsyr
8 | - name: quay.io/gnunn/server
9 | newName: quay.io/gnunn/server
10 | newTag: d32ef18-31EwNRt10WqDiW10HGw7FfaqjL5
11 | resources:
12 | - ../../../../environments/overlays/test
13 |
--------------------------------------------------------------------------------
/environments/overlays/cicd/acs-external-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: external-secrets.io/v1
2 | kind: ExternalSecret
3 | metadata:
4 | name: roxsecrets
5 | namespace: product-catalog-cicd
6 | spec:
7 | refreshInterval: 1h
8 | secretStoreRef:
9 | kind: SecretStore
10 | name: product-catalog
11 | target:
12 | name: roxsecrets
13 | creationPolicy: Owner
14 | dataFrom:
15 | - extract:
16 | key: ACS_SCAN_IMAGE
17 |
--------------------------------------------------------------------------------
/clusters/local.home/overlays/dev/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | images:
5 | - name: quay.io/gnunn/client
6 | newName: quay.io/gnunn/client
7 | newTag: fff9592-2fbdBT1Wxzx9uBS8uCeR2uyIsyr
8 | - name: quay.io/gnunn/server
9 | newName: quay.io/gnunn/server
10 | newTag: d32ef18-31EwNRt10WqDiW10HGw7FfaqjL5
11 |
12 | resources:
13 | - ../../../../environments/overlays/dev
14 |
--------------------------------------------------------------------------------
/environments/overlays/cicd/upload-sbom-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: external-secrets.io/v1
2 | kind: ExternalSecret
3 | metadata:
4 | name: upload-sbom
5 | namespace: product-catalog-cicd
6 | spec:
7 | refreshInterval: 1h
8 | secretStoreRef:
9 | kind: SecretStore
10 | name: product-catalog
11 | target:
12 | name: upload-sbom
13 | creationPolicy: Owner
14 | dataFrom:
15 | - extract:
16 | key: UPLOAD_SBOM_OIDC
17 |
--------------------------------------------------------------------------------
/components/apps/server/base/config/application.properties:
--------------------------------------------------------------------------------
1 | # Product Datasource
2 | quarkus.datasource.db-kind=mariadb
3 | quarkus.datasource.jdbc.url=jdbc:mariadb://productdb:3306/productdb
4 | quarkus.datasource.username=productdb
5 | quarkus.datasource.password=Demo1234
6 | quarkus.datasource.jdbc.min-size=1
7 | quarkus.datasource.jdbc.max-size=5
8 | quarkus.hibernate-orm.database.generation=none
9 |
10 | # CORS
11 | quarkus.http.cors=true
12 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/config/newman-dev-env.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "30c331d4-e961-4606-aecb-5a60e8e15213",
3 | "name": "product-catalog-dev-service",
4 | "values": [
5 | {
6 | "key": "host",
7 | "value": "server.product-catalog-dev:8080",
8 | "enabled": true
9 | },
10 | {
11 | "key": "scheme",
12 | "value": "http",
13 | "enabled": true
14 | }
15 | ],
16 | "_postman_variable_scope": "environment"
17 | }
18 |
--------------------------------------------------------------------------------
/environments/overlays/dev/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-dev
5 |
6 | bases:
7 | - cicd-networkpolicy.yaml
8 | - ../../../components/apps/database/base
9 | - ../../../components/apps/client/base
10 | - ../../../components/apps/server/base
11 |
12 | images:
13 | - name: quay.io/gnunn/client
14 | newTag: dev
15 | - name: quay.io/gnunn/server
16 | newTag: dev
--------------------------------------------------------------------------------
/components/apps/client/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | # generatorOptions:
5 | # disableNameSuffixHash: true
6 | # labels:
7 | # app.kubernetes.io/part-of: product-catalog
8 |
9 | # configMapGenerator:
10 | # - name: client
11 | # files:
12 | # - config/config.js
13 |
14 | resources:
15 | - client-service.yaml
16 | - client-route.yaml
17 | - client-deployment.yaml
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/config/newman-prod-env.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "30c331d4-e961-4606-aecb-5a60e8e15213",
3 | "name": "product-catalog-dev-service",
4 | "values": [
5 | {
6 | "key": "host",
7 | "value": "server.product-catalog-prod:8080",
8 | "enabled": true
9 | },
10 | {
11 | "key": "scheme",
12 | "value": "http",
13 | "enabled": true
14 | }
15 | ],
16 | "_postman_variable_scope": "environment"
17 | }
18 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/config/newman-test-env.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": "30c331d4-e961-4606-aecb-5a60e8e15213",
3 | "name": "product-catalog-dev-service",
4 | "values": [
5 | {
6 | "key": "host",
7 | "value": "server.product-catalog-test:8080",
8 | "enabled": true
9 | },
10 | {
11 | "key": "scheme",
12 | "value": "http",
13 | "enabled": true
14 | }
15 | ],
16 | "_postman_variable_scope": "environment"
17 | }
18 |
--------------------------------------------------------------------------------
/environments/overlays/test/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-test
5 |
6 | bases:
7 | - cicd-networkpolicy.yaml
8 | - ../../../components/apps/database/base
9 | - ../../../components/apps/client/base
10 | - ../../../components/apps/server/base
11 |
12 | images:
13 | - name: quay.io/gnunn/client
14 | newTag: test
15 | - name: quay.io/gnunn/server
16 | newTag: test
--------------------------------------------------------------------------------
/components/apps/monitor/base/grafana-quarkus-dashboard.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: grafana.integreatly.org/v1beta1
2 | kind: GrafanaDashboard
3 | metadata:
4 | name: quarkus-dashboard
5 | labels:
6 | app: grafana
7 | spec:
8 | instanceSelector:
9 | matchLabels:
10 | instance: grafana
11 | folder: product-catalog
12 | url: https://raw.githubusercontent.com/gnunn-gitops/product-catalog/main/components/apps/monitor/base/quarkus-dashboard.json
13 |
--------------------------------------------------------------------------------
/environments/overlays/cicd/slack-deployments-webhook-external-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: external-secrets.io/v1
2 | kind: ExternalSecret
3 | metadata:
4 | name: slack-deployments-webhook
5 | namespace: product-catalog-cicd
6 | spec:
7 | secretStoreRef:
8 | kind: SecretStore
9 | name: product-catalog
10 | target:
11 | name: slack-deployments-webhook
12 | data:
13 | - secretKey: url
14 | remoteRef:
15 | key: SLACK_DEPLOYMENTS
16 |
--------------------------------------------------------------------------------
/environments/overlays/dev/cicd-networkpolicy.yaml:
--------------------------------------------------------------------------------
1 | kind: NetworkPolicy
2 | apiVersion: networking.k8s.io/v1
3 | metadata:
4 | name: allow-namespace-cicd
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | name: server
9 | ingress:
10 | - from:
11 | - namespaceSelector:
12 | matchLabels:
13 | kubernetes.io/metadata.name: product-catalog-cicd
14 | ports:
15 | - protocol: TCP
16 | port: 8080
17 | policyTypes:
18 | - Ingress
--------------------------------------------------------------------------------
/environments/overlays/prod/cicd-networkpolicy.yaml:
--------------------------------------------------------------------------------
1 | kind: NetworkPolicy
2 | apiVersion: networking.k8s.io/v1
3 | metadata:
4 | name: allow-namespace-cicd
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | name: server
9 | ingress:
10 | - from:
11 | - namespaceSelector:
12 | matchLabels:
13 | kubernetes.io/metadata.name: product-catalog-cicd
14 | ports:
15 | - protocol: TCP
16 | port: 8080
17 | policyTypes:
18 | - Ingress
--------------------------------------------------------------------------------
/environments/overlays/test/cicd-networkpolicy.yaml:
--------------------------------------------------------------------------------
1 | kind: NetworkPolicy
2 | apiVersion: networking.k8s.io/v1
3 | metadata:
4 | name: allow-namespace-cicd
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | name: server
9 | ingress:
10 | - from:
11 | - namespaceSelector:
12 | matchLabels:
13 | kubernetes.io/metadata.name: product-catalog-cicd
14 | ports:
15 | - protocol: TCP
16 | port: 8080
17 | policyTypes:
18 | - Ingress
--------------------------------------------------------------------------------
/environments/overlays/cicd/prod-network-policy.yaml:
--------------------------------------------------------------------------------
1 | kind: NetworkPolicy
2 | apiVersion: networking.k8s.io/v1
3 | metadata:
4 | name: allow-namespace-prod
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | eventlistener: server-post-prod
9 | ingress:
10 | - from:
11 | - namespaceSelector:
12 | matchLabels:
13 | kubernetes.io/metadata.name: product-catalog-prod
14 | ports:
15 | - protocol: TCP
16 | port: 8080
17 | policyTypes:
18 | - Ingress
--------------------------------------------------------------------------------
/environments/overlays/cicd/gitops-network-policy.yaml:
--------------------------------------------------------------------------------
1 | kind: NetworkPolicy
2 | apiVersion: networking.k8s.io/v1
3 | metadata:
4 | name: allow-namespace-gitops
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | eventlistener: server-post-prod
9 | ingress:
10 | - from:
11 | - namespaceSelector:
12 | matchLabels:
13 | kubernetes.io/metadata.name: product-catalog-gitops
14 | ports:
15 | - protocol: TCP
16 | port: 8080
17 | policyTypes:
18 | - Ingress
--------------------------------------------------------------------------------
/components/apps/client/base/client-route.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: route.openshift.io/v1
2 | kind: Route
3 | metadata:
4 | name: client
5 | labels:
6 | app: client
7 | app.kubernetes.io/name: client
8 | app.kubernetes.io/component: frontend
9 | app.kubernetes.io/instance: client
10 | endpoint: client
11 | spec:
12 | tls:
13 | termination: edge
14 | insecureEdgeTerminationPolicy: Redirect
15 | port:
16 | targetPort: http
17 | to:
18 | kind: Service
19 | name: client
20 |
--------------------------------------------------------------------------------
/components/apps/server/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | generatorOptions:
5 | disableNameSuffixHash: true
6 | labels:
7 | app.kubernetes.io/part-of: product-catalog
8 |
9 | configMapGenerator:
10 | - name: server
11 | files:
12 | - config/application.properties
13 |
14 | resources:
15 | - default-view-rolebinding.yaml
16 | - server-service.yaml
17 | - server-route.yaml
18 | - server-deployment.yaml
19 | - server-sm.yaml
--------------------------------------------------------------------------------
/components/apps/server/base/server-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: server
5 | labels:
6 | app: server
7 | app.kubernetes.io/name: server
8 | app.kubernetes.io/component: backend
9 | app.kubernetes.io/instance: server
10 | app.kubernetes.io/part-of: product-catalog
11 | quarkus-prometheus: "true"
12 | spec:
13 | ports:
14 | - name: http
15 | port: 8080
16 | selector:
17 | name: server
18 | sessionAffinity: None
19 | type: ClusterIP
--------------------------------------------------------------------------------
/clusters/aws.cluster/overlays/pipelinerun/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-cicd
5 |
6 | resources:
7 | - ../../../../components/tekton/pipelineruns/client/base
8 | - ../../../../components/tekton/pipelineruns/server/base
9 |
10 | patches:
11 | - target:
12 | kind: PipelineRun
13 | patch: |-
14 | - op: add
15 | path: /spec/params/-
16 | value:
17 | name: cluster
18 | value: aws.cluster
19 |
--------------------------------------------------------------------------------
/components/apps/database/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | generatorOptions:
5 | disableNameSuffixHash: true
6 | labels:
7 | app.kubernetes.io/part-of: product-catalog
8 |
9 | configMapGenerator:
10 | - name: productdb-init
11 | files:
12 | - config/90-init-database.sh
13 | - config/import.sql
14 | - config/schema.sql
15 |
16 | resources:
17 | - db-pvc.yaml
18 | - db-secret.yaml
19 | - db-service.yaml
20 | - db-deployment.yaml
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-yq.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: yq
5 | spec:
6 | workspaces:
7 | - name: source
8 | params:
9 | - name: commands
10 | type: string
11 | description: The set of commands to run
12 | steps:
13 | - name: yq
14 | workingDir: $(workspaces.source.path)
15 | image: mikefarah/yq:3.3.2
16 | script: |
17 | #!/usr/bin/env sh
18 | echo "Running: '$(params.commands)'"
19 | $(params.commands)
--------------------------------------------------------------------------------
/components/tekton/triggers/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | resources:
5 | - server-eventlistener.yaml
6 | - server-triggertemplate.yaml
7 | - client-eventlistener.yaml
8 | - client-triggertemplate.yaml
9 | - argocd-notification-triggerbinding.yaml
10 | - server-post-prod-eventlistener.yaml
11 | - server-post-prod-triggertemplate.yaml
12 | - slack-message-eventlistener.yaml
13 | - slack-message-triggerbinding.yaml
14 | - slack-message-triggertemplate.yaml
--------------------------------------------------------------------------------
/components/apps/server/base/server-route.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: route.openshift.io/v1
2 | kind: Route
3 | metadata:
4 | name: server
5 | labels:
6 | app: server
7 | app.kubernetes.io/name: server
8 | app.kubernetes.io/component: backend
9 | app.kubernetes.io/instance: server
10 | app.kubernetes.io/part-of: product-catalog
11 | endpoint: server
12 | spec:
13 | tls:
14 | termination: edge
15 | insecureEdgeTerminationPolicy: Redirect
16 | port:
17 | targetPort: http
18 | to:
19 | kind: Service
20 | name: server
21 |
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-deploy.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: deploy
5 | spec:
6 | params:
7 | - name: NAME
8 | type: string
9 | - name: NAMESPACE
10 | type: string
11 | steps:
12 | - name: run-commands
13 | image: quay.io/openshift/origin-cli:latest
14 | script: |
15 | #!/usr/bin/env bash
16 |
17 | oc rollout restart deployment/$(inputs.params.NAME) -n $(inputs.params.NAMESPACE)
18 | oc rollout status deploy/$(inputs.params.NAME) -n $(inputs.params.NAMESPACE)
--------------------------------------------------------------------------------
/environments/overlays/cicd/github-external-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: external-secrets.io/v1
2 | kind: ExternalSecret
3 | metadata:
4 | name: github
5 | namespace: product-catalog-cicd
6 | spec:
7 | refreshInterval: 1h
8 | secretStoreRef:
9 | kind: SecretStore
10 | name: product-catalog
11 | target:
12 | name: github
13 | template:
14 | metadata:
15 | annotations:
16 | tekton.dev/git-0: https://github.com
17 | type: kubernetes.io/basic-auth
18 | creationPolicy: Owner
19 | dataFrom:
20 | - extract:
21 | key: GITHUB
22 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | generatorOptions:
5 | disableNameSuffixHash: true
6 |
7 | configMapGenerator:
8 | - name: maven-settings
9 | files:
10 | - config/settings.xml
11 | - name: newman-env
12 | files:
13 | - config/newman-dev-env.json
14 | - config/newman-test-env.json
15 | - config/newman-prod-env.json
16 |
17 | resources:
18 | - secrets/maven-repo-creds.yaml
19 | # Server pipeline
20 | - server-pipeline.yaml
21 | - server-post-prod-pipeline.yaml
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-git.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: git
5 | spec:
6 | workspaces:
7 | - name: source
8 | params:
9 | - name: commands
10 | type: string
11 | description: The set of commands to run
12 | stepTemplate:
13 | env:
14 | - name: "HOME"
15 | value: "/tekton/home"
16 | steps:
17 | - name: git
18 | workingDir: $(workspaces.source.path)
19 | image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.12.1
20 | script: |
21 | #!/usr/bin/env sh
22 | $(params.commands)
23 |
--------------------------------------------------------------------------------
/environments/overlays/cicd/docker-external-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: external-secrets.io/v1
2 | kind: ExternalSecret
3 | metadata:
4 | name: dest-docker-config
5 | namespace: product-catalog-cicd
6 | spec:
7 | refreshInterval: 1h
8 | secretStoreRef:
9 | name: product-catalog
10 | kind: SecretStore
11 | target:
12 | template:
13 | type: kubernetes.io/dockerconfigjson
14 | data:
15 | .dockerconfigjson: "{{ .docker_secret | toString }}"
16 | name: dest-docker-config
17 | creationPolicy: Owner
18 | data:
19 | - secretKey: docker_secret
20 | remoteRef:
21 | key: DOCKER_CONFIG_JSON
22 |
--------------------------------------------------------------------------------
/components/tekton/triggers/base/slack-message-triggerbinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: triggers.tekton.dev/v1beta1
2 | kind: TriggerBinding
3 | metadata:
4 | name: slack-message
5 | spec:
6 | params:
7 | - name: git_revision
8 | value: $(body.git_revision)
9 | - name: git_url
10 | value: $(body.git_url)
11 | - name: git_source_url
12 | value: $(body.git_source_url)
13 | - name: image_dest_url
14 | value: $(body.image_dest_url)
15 | - name: image_dest_tag
16 | value: $(body.image_dest_tag)
17 | - name: cluster
18 | value: $(body.cluster)
19 | - name: app
20 | value: $(body.app)
21 |
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-tekton.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: tkn
5 | spec:
6 | params:
7 | - name: commands
8 | type: string
9 | description: The tkn commands to run
10 | steps:
11 | - name: tkn
12 | image: quay.io/rhcanada/tkn-cli:0.17.2
13 | script: |
14 | #!/usr/bin/env sh
15 | echo "Running command '$(params.commands)'"
16 | $(params.commands)
17 | volumeMounts:
18 | - name: templates
19 | mountPath: /templates
20 | volumes:
21 | - name: templates
22 | configMap:
23 | name: workspace-template
24 | optional: true
--------------------------------------------------------------------------------
/components/apps/slack-message-handler/base/route.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: route.openshift.io/v1
2 | kind: Route
3 | metadata:
4 | labels:
5 | app: slack-message-handler
6 | app.kubernetes.io/component: slack-message-handler
7 | app.kubernetes.io/instance: slack-message-handler
8 | app.kubernetes.io/name: slack-message-handler
9 | app.openshift.io/runtime-version: latest
10 | name: slack-message-handler
11 | spec:
12 | port:
13 | targetPort: 8080-tcp
14 | tls:
15 | insecureEdgeTerminationPolicy: Redirect
16 | termination: edge
17 | to:
18 | kind: Service
19 | name: slack-message-handler
20 | weight: 100
21 | wildcardPolicy: None
22 |
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-variables.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: variables-from-k8s
5 | spec:
6 | results:
7 | - name: acs_central_endpoint
8 | workspaces:
9 | - name: acs-central
10 | optional: true
11 | steps:
12 | - name: get-variables
13 | image: quay.io/openshift/origin-cli:latest
14 | script: |
15 | #!/usr/bin/env sh
16 | if [ $(workspaces.acs-central.bound) == "true" ] ; then
17 | cat $(workspaces.acs-central.path)/rox_central_endpoint > $(results.acs_central_endpoint.path)
18 | else
19 | echo "not-set" > $(results.acs_central_endpoint.path)
20 | fi
--------------------------------------------------------------------------------
/components/apps/database/base/config/90-init-database.sh:
--------------------------------------------------------------------------------
1 | init_database() {
2 | local thisdir
3 | local init_data_file
4 | thisdir=$(dirname ${BASH_SOURCE[0]})
5 |
6 | init_data_file=$(readlink -f ${thisdir}/../mysql-data/schema.sql)
7 | log_info "Initializing the database schema from file ${init_data_file}..."
8 | mysql $mysql_flags ${MYSQL_DATABASE} < ${init_data_file}
9 |
10 | init_data_file=$(readlink -f ${thisdir}/../mysql-data/import.sql)
11 | log_info "Initializing the database data from file ${init_data_file}..."
12 | mysql $mysql_flags ${MYSQL_DATABASE} < ${init_data_file}
13 | }
14 |
15 | if ! [ -v MYSQL_RUNNING_AS_SLAVE ] && $MYSQL_DATADIR_FIRST_INIT ; then
16 | init_database
17 | fi
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/cicd/pipeline-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: cicd-pipeline-edit
5 | namespace: product-catalog-dev
6 | roleRef:
7 | apiGroup: rbac.authorization.k8s.io
8 | kind: ClusterRole
9 | name: edit
10 | subjects:
11 | - kind: ServiceAccount
12 | name: pipeline
13 | namespace: product-catalog-cicd
14 | ---
15 | apiVersion: rbac.authorization.k8s.io/v1
16 | kind: RoleBinding
17 | metadata:
18 | name: cicd-pipeline-edit
19 | namespace: product-catalog-test
20 | roleRef:
21 | apiGroup: rbac.authorization.k8s.io
22 | kind: ClusterRole
23 | name: edit
24 | subjects:
25 | - kind: ServiceAccount
26 | name: pipeline
27 | namespace: product-catalog-cicd
28 |
--------------------------------------------------------------------------------
/clusters/aws.cluster/overlays/cicd/pipeline-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: cicd-pipeline-edit
5 | namespace: product-catalog-dev
6 | roleRef:
7 | apiGroup: rbac.authorization.k8s.io
8 | kind: ClusterRole
9 | name: edit
10 | subjects:
11 | - kind: ServiceAccount
12 | name: pipeline
13 | namespace: product-catalog-cicd
14 | ---
15 | apiVersion: rbac.authorization.k8s.io/v1
16 | kind: RoleBinding
17 | metadata:
18 | name: cicd-pipeline-edit
19 | namespace: product-catalog-test
20 | roleRef:
21 | apiGroup: rbac.authorization.k8s.io
22 | kind: ClusterRole
23 | name: edit
24 | subjects:
25 | - kind: ServiceAccount
26 | name: pipeline
27 | namespace: product-catalog-cicd
28 |
--------------------------------------------------------------------------------
/components/tekton/triggers/base/server-post-prod-triggertemplate.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: TriggerTemplate
4 | metadata:
5 | name: server-post-prod
6 | spec:
7 | resourcetemplates:
8 | - apiVersion: tekton.dev/v1
9 | kind: PipelineRun
10 | metadata:
11 | annotations:
12 | argocd.argoproj.io/compare-options: IgnoreExtraneous
13 | argocd.argoproj.io/sync-options: Prune=false
14 | labels:
15 | tekton.dev/pipeline: server-post-prod
16 | generateName: server-post-prod-webhook-
17 | spec:
18 | pipelineRef:
19 | name: server-post-prod
20 | workspaces:
21 | - name: newman-env
22 | configMap:
23 | name: newman-env
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/pipelinerun/apps/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-cicd
5 |
6 | resources:
7 | - ../../../../../components/tekton/pipelineruns/client/base
8 | - ../../../../../components/tekton/pipelineruns/server/base
9 |
10 | patches:
11 | - target:
12 | kind: PipelineRun
13 | patch: |-
14 | - op: add
15 | path: /spec/params/-
16 | value:
17 | name: cluster
18 | value: local.home
19 | - op: add
20 | path: /spec/params/-
21 | value:
22 | name: acs-secret
23 | value: roxsecrets
24 | - op: add
25 | path: /spec/params/-
26 | value:
27 | name: slack-secret
28 | value: slack-deployments-webhook
--------------------------------------------------------------------------------
/components/apps/slack-message-handler/base/service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | annotations:
5 | app.openshift.io/connects-to: '[{"apiVersion":"apps/v1","kind":"Deployment","name":"el-slack-message"}]'
6 | labels:
7 | app: slack-message-handler
8 | app.kubernetes.io/component: slack-message-handler
9 | app.kubernetes.io/instance: slack-message-handler
10 | app.kubernetes.io/name: slack-message-handler
11 | app.openshift.io/runtime-version: latest
12 | name: slack-message-handler
13 | spec:
14 | ports:
15 | - name: 8080-tcp
16 | port: 8080
17 | - name: 8443-tcp
18 | port: 8443
19 | - name: 8778-tcp
20 | port: 8778
21 | selector:
22 | app: slack-message-handler
23 | deployment: slack-message-handler
24 |
--------------------------------------------------------------------------------
/components/tekton/triggers/base/client-eventlistener.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: EventListener
4 | metadata:
5 | name: client
6 | spec:
7 | serviceAccountName: pipeline
8 | triggers:
9 | - name: client-webhook
10 | bindings:
11 | - kind: ClusterTriggerBinding
12 | ref: github-push
13 | template:
14 | ref: client
15 | ---
16 | apiVersion: route.openshift.io/v1
17 | kind: Route
18 | metadata:
19 | name: client-webhook
20 | labels:
21 | app.kubernetes.io/managed-by: EventListener
22 | app.kubernetes.io/part-of: Triggers
23 | eventlistener: client
24 | spec:
25 | port:
26 | targetPort: 8080
27 | to:
28 | kind: "Service"
29 | name: el-client
30 | weight: 100
31 | tls:
32 | termination: edge
--------------------------------------------------------------------------------
/components/tekton/triggers/base/server-eventlistener.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: EventListener
4 | metadata:
5 | name: server
6 | spec:
7 | serviceAccountName: pipeline
8 | triggers:
9 | - name: server-webhook
10 | bindings:
11 | - kind: ClusterTriggerBinding
12 | ref: github-push
13 | template:
14 | ref: server
15 | ---
16 | apiVersion: route.openshift.io/v1
17 | kind: Route
18 | metadata:
19 | name: server-webhook
20 | labels:
21 | app.kubernetes.io/managed-by: EventListener
22 | app.kubernetes.io/part-of: Triggers
23 | eventlistener: server
24 | spec:
25 | port:
26 | targetPort: 8080
27 | to:
28 | kind: "Service"
29 | name: el-server
30 | weight: 100
31 | tls:
32 | termination: edge
--------------------------------------------------------------------------------
/environments/overlays/cicd/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-cicd
5 |
6 | resources:
7 | - workspace-template-cm.yaml
8 | - gitops-network-policy.yaml
9 | - docker-external-secret.yaml
10 | - github-external-secret.yaml
11 | - slack-deployments-webhook-external-secret.yaml
12 | - ../../../components/apps/slack-message-handler/base
13 | - ../../../components/tekton/tasks/base
14 | - ../../../components/tekton/pipelines/client/base
15 | - ../../../components/tekton/pipelines/server/base
16 | - ../../../components/tekton/pipelines/push-prod-pr/base
17 | - ../../../components/tekton/triggers/base
18 | - setup-local-credentials-job.yaml
19 | - acs-external-secret.yaml
20 | - upload-sbom-secret.yaml
21 | - prod-network-policy.yaml
22 |
--------------------------------------------------------------------------------
/components/apps/database/base/db-secret.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | annotations:
5 | template.openshift.io/expose-database_name: '{.data[''database-name'']}'
6 | template.openshift.io/expose-password: '{.data[''database-password'']}'
7 | template.openshift.io/expose-root_password: '{.data[''database-root-password'']}'
8 | template.openshift.io/expose-username: '{.data[''database-user'']}'
9 | labels:
10 | app: server
11 | app.kubernetes.io/name: productdb
12 | app.kubernetes.io/component: database
13 | app.kubernetes.io/instance: productdb
14 | app.kubernetes.io/part-of: product-catalog
15 | name: productdb
16 | stringData:
17 | database-name: productdb
18 | database-password: Demo1234
19 | database-root-password: Demo1234
20 | database-user: productdb
21 |
--------------------------------------------------------------------------------
/clusters/local.home/overlays/pipelinerun/apps/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: product-catalog-cicd
5 |
6 | resources:
7 | - ../../../../../components/tekton/pipelineruns/client/base
8 | - ../../../../../components/tekton/pipelineruns/server/base
9 |
10 | patches:
11 | - target:
12 | kind: PipelineRun
13 | patch: |-
14 | - op: add
15 | path: /spec/params/-
16 | value:
17 | name: cluster
18 | value: local.home
19 | - op: add
20 | path: /spec/workspaces/-
21 | value:
22 | name: slack-secret
23 | secret:
24 | secretName: slack-deployments-webhook
25 | - op: add
26 | path: /spec/workspaces/-
27 | value:
28 | name: acs-central
29 | secret:
30 | secretName: roxsecrets
--------------------------------------------------------------------------------
/environments/overlays/prod/post-sync-pipeline-job.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: batch/v1
2 | kind: Job
3 | metadata:
4 | name: post-sync-pipeline
5 | generateName: post-sync-pipeline-
6 | annotations:
7 | argocd.argoproj.io/hook: PostSync
8 | argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
9 | spec:
10 | template:
11 | spec:
12 | containers:
13 | - image: registry.access.redhat.com/ubi8
14 | command:
15 | - "curl"
16 | - "-X"
17 | - "POST"
18 | - "-H"
19 | - "Content-Type: application/json"
20 | - "--data"
21 | - "{}"
22 | - "--connect-timeout"
23 | - "60"
24 | - "http://el-server-post-prod.product-catalog-cicd:8080"
25 | imagePullPolicy: Always
26 | name: post-sync-pipeline
27 | dnsPolicy: ClusterFirst
28 | restartPolicy: OnFailure
29 | terminationGracePeriodSeconds: 30
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-push-image.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: push-image
5 | spec:
6 | params:
7 | - name: src_image
8 | type: string
9 | - name: dest_image
10 | type: string
11 | - name: dest_tags
12 | type: string
13 | default: ""
14 | steps:
15 | - name: run-commands
16 | image: quay.io/skopeo/stable:v1.13.2
17 | script: |
18 | #!/usr/bin/env bash
19 |
20 | if [ "$(params.dest_tags)" != "" ];
21 | then
22 |
23 | tags=$(params.dest_tags)
24 | for i in ${tags//,/ }
25 | do
26 | echo "Copying image docker://$(params.src_image) to docker://$(params.dest_image):$i"
27 | skopeo copy --src-tls-verify=false --dest-tls-verify=false docker://$(params.src_image) --dest-authfile=/tekton/creds-secrets/dest-docker-config/.dockerconfigjson docker://$(params.dest_image):$i
28 | done
29 | fi
--------------------------------------------------------------------------------
/components/tekton/tasks/base/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | generatorOptions:
5 | disableNameSuffixHash: true
6 |
7 | resources:
8 | # Supporting infra
9 | - m2-cache-pvc.yaml
10 | # - npm-cache-pvc.yaml
11 | - dependency-cache-pvc.yaml
12 | # Tekton tasks
13 | - task-git.yaml
14 | - task-yq.yaml
15 | - https://github.com/redhat-cop/gitops-catalog/openshift-pipelines-tasks/maven/overlays/m2-cache
16 | - task-npm.yaml
17 | - task-npm-quality.yaml
18 | - task-binary-s2i.yaml
19 | - task-buildah.yaml
20 | - task-push-image.yaml
21 | - task-deploy.yaml
22 | - https://github.com/redhat-cop/gitops-catalog/openshift-pipelines-tasks/newman/base
23 | - task-create-pr.yaml
24 | - task-tekton.yaml
25 | - task-send-to-webhook-slack.yaml
26 | - task-kustomize.yaml
27 | # - argocd-sync-and-wait-task.yaml
28 | - task-run-pipeline.yaml
29 | - task-update-image.yaml
30 | - task-variables.yaml
31 | - task-create-commit-list.yaml
--------------------------------------------------------------------------------
/clusters/local.home/overlays/cicd/pipeline-rolebinding.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: rbac.authorization.k8s.io/v1
2 | kind: RoleBinding
3 | metadata:
4 | name: cicd-pipeline-edit
5 | namespace: product-catalog-dev
6 | roleRef:
7 | apiGroup: rbac.authorization.k8s.io
8 | kind: ClusterRole
9 | name: edit
10 | subjects:
11 | - kind: ServiceAccount
12 | name: pipeline
13 | namespace: product-catalog-cicd
14 | ---
15 | apiVersion: rbac.authorization.k8s.io/v1
16 | kind: RoleBinding
17 | metadata:
18 | name: cicd-pipeline-edit
19 | namespace: product-catalog-test
20 | roleRef:
21 | apiGroup: rbac.authorization.k8s.io
22 | kind: ClusterRole
23 | name: edit
24 | subjects:
25 | - kind: ServiceAccount
26 | name: pipeline
27 | namespace: product-catalog-cicd
28 | ---
29 | apiVersion: rbac.authorization.k8s.io/v1
30 | kind: RoleBinding
31 | metadata:
32 | name: cicd-pipeline-edit
33 | namespace: product-catalog-prod
34 | roleRef:
35 | apiGroup: rbac.authorization.k8s.io
36 | kind: ClusterRole
37 | name: view
38 | subjects:
39 | - kind: ServiceAccount
40 | name: github-pipeline
41 | namespace: product-catalog-cicd
--------------------------------------------------------------------------------
/clusters/local.home/overlays/pipelinerun/push-to-prod-client/kustomization.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | - ../../../../../components/tekton/pipelineruns/push-prod-pr/base
3 |
4 | patches:
5 | - target:
6 | kind: PipelineRun
7 | patch: |-
8 | - op: add
9 | path: /spec/params/-
10 | value:
11 | name: cluster
12 | value: local.home
13 | - op: add
14 | path: /spec/params/-
15 | value:
16 | name: app
17 | value: client
18 | - op: add
19 | path: /spec/params/-
20 | value:
21 | name: image_dest_url
22 | value: quay.io/gnunn/client
23 | - op: add
24 | path: /spec/params/-
25 | value:
26 | name: image_dest_tag
27 | value: 7f192d4-1427400123
28 | - op: add
29 | path: /spec/params/-
30 | value:
31 | name: sonarqube_host
32 | value: sonarqube-dev-tools.apps.home.ocplab.com
33 | - op: add
34 | path: /spec/params/-
35 | value:
36 | name: acs_image_scan_results
37 | value: https://central-stackrox.apps.home.ocplab.com/main/vulnerability-management/images/7f192d4-1427400123
38 |
39 |
--------------------------------------------------------------------------------
/clusters/local.home/overlays/pipelinerun/push-to-prod-server/kustomization.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | - ../../../../../components/tekton/pipelineruns/push-prod-pr/base
3 |
4 | patches:
5 | - target:
6 | kind: PipelineRun
7 | patch: |-
8 | - op: add
9 | path: /spec/params/-
10 | value:
11 | name: cluster
12 | value: local.home
13 | - op: add
14 | path: /spec/params/-
15 | value:
16 | name: app
17 | value: server
18 | - op: add
19 | path: /spec/params/-
20 | value:
21 | name: image_dest_url
22 | value: quay.io/gnunn/server
23 | - op: add
24 | path: /spec/params/-
25 | value:
26 | name: image_dest_tag
27 | value: 7f192d4-1427400123
28 | - op: add
29 | path: /spec/params/-
30 | value:
31 | name: sonarqube_host
32 | value: sonarqube-dev-tools.apps.home.ocplab.com
33 | - op: add
34 | path: /spec/params/-
35 | value:
36 | name: acs_image_scan_results
37 | value: https://central-stackrox.apps.home.ocplab.com/main/vulnerability-management/images/7f192d4-1427400123
38 |
39 |
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/pipelinerun/push-to-prod-client/kustomization.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | - ../../../../../components/tekton/pipelineruns/push-prod-pr/base
3 |
4 | patches:
5 | - target:
6 | kind: PipelineRun
7 | patch: |-
8 | - op: add
9 | path: /spec/params/-
10 | value:
11 | name: cluster
12 | value: local.home
13 | - op: add
14 | path: /spec/params/-
15 | value:
16 | name: app
17 | value: client
18 | - op: add
19 | path: /spec/params/-
20 | value:
21 | name: image_dest_url
22 | value: quay.io/gnunn/client
23 | - op: add
24 | path: /spec/params/-
25 | value:
26 | name: image_dest_tag
27 | value: 7f192d4-1427400123
28 | - op: add
29 | path: /spec/params/-
30 | value:
31 | name: sonarqube_host
32 | value: sonarqube-dev-tools.apps.cluster-xjv8v.xjv8v.sandbox1202.opentlc.com
33 | - op: add
34 | path: /spec/params/-
35 | value:
36 | name: acs_image_scan_results
37 | value: https://central-stackrox.apps.cluster-xjv8v.xjv8v.sandbox1202.opentlc.com/vulnerability-management/images/7f192d4-1427400123
38 |
39 |
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/pipelinerun/push-to-prod-server/kustomization.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | - ../../../../../components/tekton/pipelineruns/push-prod-pr/base
3 |
4 | patches:
5 | - target:
6 | kind: PipelineRun
7 | patch: |-
8 | - op: add
9 | path: /spec/params/-
10 | value:
11 | name: cluster
12 | value: local.home
13 | - op: add
14 | path: /spec/params/-
15 | value:
16 | name: app
17 | value: server
18 | - op: add
19 | path: /spec/params/-
20 | value:
21 | name: image_dest_url
22 | value: quay.io/gnunn/server
23 | - op: add
24 | path: /spec/params/-
25 | value:
26 | name: image_dest_tag
27 | value: 7f192d4-1427400123
28 | - op: add
29 | path: /spec/params/-
30 | value:
31 | name: sonarqube_host
32 | value: sonarqube-dev-tools.apps.cluster-xjv8v.xjv8v.sandbox1202.opentlc.com
33 | - op: add
34 | path: /spec/params/-
35 | value:
36 | name: acs_image_scan_results
37 | value: https://central-stackrox.apps.cluster-xjv8v.xjv8v.sandbox1202.opentlc.com/main/vulnerability-management/images/7f192d4-1427400123
38 |
39 |
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-kustomize.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: kustomize
5 | spec:
6 | params:
7 | - name: image-name
8 | type: string
9 | description: "The placeholder image in the deployment to be replaced."
10 | - name: new-image
11 | type: string
12 | description: "The image to update the deployment with."
13 | - name: new-tag
14 | type: string
15 | description: "The image to tag update the deployment with."
16 | - name: overlaypath
17 | type: string
18 | description: "Path to the overlay directory."
19 | steps:
20 | - name: kustomize
21 | workingDir: $(workspaces.source.path)
22 | image: quay.io/redhatworkshops/kustomize-task:v4.0.5
23 | script: |
24 | #!/usr/bin/env /bin/sh
25 | echo "Kustomizing image"
26 | echo "Running: kustomize edit set image $(params.image-name)=$(params.new-image):$(params.new-tag)"
27 | cd $(params.overlaypath)
28 | kustomize edit set image $(params.image-name)=$(params.new-image):$(params.new-tag)
29 |
30 | echo "Updated file kustomization.yaml file"
31 | cat kustomization.yaml
32 | workspaces:
33 | - name: source
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-npm-quality.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: npm-quality
5 | spec:
6 | workspaces:
7 | - name: source
8 | params:
9 | - name: SONAR_SERVER_URL
10 | default: "http://sonarqube.dev-tools:9000"
11 | description: The location of sonarqube, passed as an environment variable SONAR_SERVER_URL
12 | steps:
13 | - name: quality
14 | image: registry.redhat.io/ubi8/nodejs-14:latest
15 | command:
16 | - /bin/sh
17 | - -c
18 | args:
19 | - |-
20 | echo "Performing quality check"
21 | mkdir -p coverage
22 | mkdir -p reports/dependency-check
23 | dependency-check.sh --format ALL -s . --out reports/dependency-check --project "product-catalog-client"
24 | npm run sonar
25 | echo "Quality check complete, see results in sonarqube"
26 | env:
27 | - name: SONAR_SERVER_URL
28 | value: $(params.SONAR_SERVER_URL)
29 | workingDir: $(workspaces.source.path)
30 | volumeMounts:
31 | - name: dependency-cache
32 | mountPath: /opt/dependency-check/data
33 | volumes:
34 | - name: dependency-cache
35 | persistentVolumeClaim:
36 | claimName: dependency-cache
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-npm.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: npm
5 | spec:
6 | workspaces:
7 | - name: source
8 | steps:
9 | - name: npm-install
10 | image: registry.redhat.io/ubi8/nodejs-14:latest
11 | command:
12 | - /bin/sh
13 | - -c
14 | args:
15 | - npm install --package-lock
16 | workingDir: $(workspaces.source.path)
17 | - name: build
18 | image: registry.redhat.io/ubi8/nodejs-14:latest
19 | command:
20 | - /bin/sh
21 | - -c
22 | args:
23 | - npm run build
24 | workingDir: $(workspaces.source.path)
25 | - name: copy-dist
26 | image: registry.redhat.io/ubi8/nodejs-14:latest
27 | command:
28 | - /bin/sh
29 | - -c
30 | args:
31 | - cp -R ./dist/* $(workspaces.source.path)
32 | workingDir: $(workspaces.source.path)
33 | - name: save-commit-sha
34 | image: docker.io/maven:3.6.3-jdk-8
35 | command:
36 | - '/bin/bash'
37 | - '-c'
38 | args:
39 | - |-
40 | mkdir -p $(workspaces.source.path)/git-sha
41 | git rev-parse --short HEAD | tee $(workspaces.source.path)/git-sha/commit-id
42 | workingDir: $(workspaces.source.path)
--------------------------------------------------------------------------------
/bootstrap/argocd/apps/overlays/rhpds/values.yaml:
--------------------------------------------------------------------------------
1 | default:
2 | app:
3 | enabled: true
4 | enableAutoSync: true
5 | autoSyncPrune: false
6 | project: apps-product-catalog
7 | labels:
8 | gitops.openshift.io/controllerNamespace: gitops
9 | destination:
10 | namespace: product-catalog-gitops
11 | server: https://kubernetes.default.svc
12 | source:
13 | repoURL: https://github.com/gnunn-gitops/product-catalog
14 | targetRevision: main
15 |
16 | applications:
17 |
18 | product-catalog-dev:
19 | destination:
20 | namespace: product-catalog-dev
21 | source:
22 | path: clusters/rhpds/overlays/dev
23 |
24 | product-catalog-test:
25 | destination:
26 | namespace: product-catalog-test
27 | source:
28 | path: clusters/rhpds/overlays/test
29 |
30 | product-catalog-prod:
31 | destination:
32 | namespace: product-catalog-prod
33 | source:
34 | path: clusters/rhpds/overlays/prod
35 |
36 | product-catalog-cicd:
37 | destination:
38 | namespace: product-catalog-cicd
39 | source:
40 | path: clusters/rhpds/overlays/cicd
41 |
42 | product-catalog-monitor:
43 | destination:
44 | namespace: product-catalog-monitor
45 | source:
46 | path: environments/overlays/monitor
--------------------------------------------------------------------------------
/bootstrap/argocd/apps/overlays/aws.cluster/values.yaml:
--------------------------------------------------------------------------------
1 | default:
2 | app:
3 | enabled: true
4 | enableAutoSync: true
5 | autoSyncPrune: false
6 | project: apps-product-catalog
7 | labels:
8 | gitops.openshift.io/controllerNamespace: gitops
9 | destination:
10 | namespace: product-catalog-gitops
11 | server: https://kubernetes.default.svc
12 | source:
13 | repoURL: https://github.com/gnunn-gitops/product-catalog
14 | targetRevision: main
15 |
16 | applications:
17 |
18 | product-catalog-dev:
19 | destination:
20 | namespace: product-catalog-dev
21 | source:
22 | path: clusters/aws.cluster/overlays/dev
23 |
24 | product-catalog-test:
25 | destination:
26 | namespace: product-catalog-test
27 | source:
28 | path: clusters/aws.cluster/overlays/test
29 |
30 | product-catalog-prod:
31 | destination:
32 | namespace: product-catalog-prod
33 | source:
34 | path: clusters/aws.cluster/overlays/prod
35 |
36 | product-catalog-cicd:
37 | destination:
38 | namespace: product-catalog-cicd
39 | source:
40 | path: clusters/aws.cluster/overlays/cicd
41 |
42 | product-catalog-monitor:
43 | destination:
44 | namespace: product-catalog-monitor
45 | source:
46 | path: environments/overlays/monitor
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-create-pr.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: task-create-pr
5 | spec:
6 | workspaces:
7 | - name: source
8 | params:
9 | - name: title
10 | type: string
11 | description: PR Title
12 | - name: body
13 | type: string
14 | default: ""
15 | description: The body of the PR request
16 | - name: github_secret
17 | type: string
18 | default: github
19 | description: "The name of the secret that has your github username and token"
20 | steps:
21 | - name: run-commands
22 | image: docker.io/michaelin/github-cli:latest
23 | script: |
24 | #!/usr/bin/env bash
25 |
26 | # git create PR
27 | gh pr create -t "$(params.title)" -b "$(params.body)"
28 | workingDir: $(workspaces.source.path)
29 | env:
30 | - name: GITHUB_TOKEN
31 | valueFrom:
32 | secretKeyRef:
33 | name: $(params.github_secret)
34 | key: password
35 | - name: GITHUB_USER
36 | valueFrom:
37 | secretKeyRef:
38 | name: $(params.github_secret)
39 | key: username
40 | - name: GITHUB_EMAIL
41 | valueFrom:
42 | secretKeyRef:
43 | name: $(params.github_secret)
44 | key: email
45 |
--------------------------------------------------------------------------------
/components/tekton/triggers/base/server-post-prod-eventlistener.yaml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | # Use with post-sync job
4 |
5 | apiVersion: triggers.tekton.dev/v1beta1
6 | kind: EventListener
7 | metadata:
8 | name: server-post-prod
9 | spec:
10 | serviceAccountName: pipeline
11 | triggers:
12 | - name: server-post-prod-webhook
13 | template:
14 | ref: server-post-prod
15 |
16 | # Use with Argo CD Notifications
17 | #
18 | # apiVersion: triggers.tekton.dev/v1beta1
19 | # kind: EventListener
20 | # metadata:
21 | # name: server-post-prod
22 | # spec:
23 | # serviceAccountName: pipeline
24 | # triggers:
25 | # - name: server-post-prod-webhook
26 | # interceptors:
27 | # - name: "Only accept sync succeeded"
28 | # ref:
29 | # name: "cel"
30 | # params:
31 | # - name: "filter"
32 | # value: "body.state in ['success']"
33 | # bindings:
34 | # - kind: TriggerBinding
35 | # ref: argocd-notification
36 | # template:
37 | # ref: server-post-prod
38 | ---
39 | apiVersion: route.openshift.io/v1
40 | kind: Route
41 | metadata:
42 | name: server-post-prod-webhook
43 | labels:
44 | app.kubernetes.io/managed-by: EventListener
45 | app.kubernetes.io/part-of: Triggers
46 | eventlistener: server-post-prod
47 | spec:
48 | port:
49 | targetPort: 8080
50 | to:
51 | kind: "Service"
52 | name: el-server-post-prod
53 | weight: 100
54 | tls:
55 | termination: edge
--------------------------------------------------------------------------------
/components/tekton/triggers/base/client-triggertemplate.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: TriggerTemplate
4 | metadata:
5 | name: client
6 | spec:
7 | params:
8 | - name: git-revision
9 | description: The git revision
10 | default: master
11 | - name: git-repo-url
12 | description: The git repository url
13 | resourcetemplates:
14 | - apiVersion: tekton.dev/v1
15 | kind: PipelineRun
16 | metadata:
17 | annotations:
18 | argocd.argoproj.io/compare-options: IgnoreExtraneous
19 | argocd.argoproj.io/sync-options: Prune=false
20 | labels:
21 | tekton.dev/pipeline: client
22 | generateName: client-webhook-
23 | spec:
24 | pipelineRef:
25 | name: client
26 | params:
27 | - name: git-url
28 | value: $(tt.params.git-repo-url)
29 | - name: git-revision
30 | value: $(tt.params.git-revision)
31 | - name: push-to-prod
32 | value: "true"
33 | workspaces:
34 | - name: git-source
35 | volumeClaimTemplate:
36 | spec:
37 | accessModes:
38 | - ReadWriteOnce
39 | resources:
40 | requests:
41 | storage: 5Gi
42 | - name: gitops-manifests
43 | volumeClaimTemplate:
44 | spec:
45 | accessModes:
46 | - ReadWriteOnce
47 | resources:
48 | requests:
49 | storage: 5Gi
--------------------------------------------------------------------------------
/bootstrap/argocd/apps/overlays/local.home/values.yaml:
--------------------------------------------------------------------------------
1 | default:
2 | app:
3 | enabled: true
4 | enableAutoSync: true
5 | autoSyncPrune: false
6 | project: product-catalog
7 | labels:
8 | gitops.openshift.io/controllerNamespace: gitops
9 | destination:
10 | namespace: product-catalog-gitops
11 | name: in-cluster
12 | source:
13 | repoURL: https://github.com/gnunn-gitops/product-catalog
14 | targetRevision: main
15 |
16 | applications:
17 |
18 | product-catalog-dev:
19 | labels:
20 | app.kubernetes.io/name: product-catalog
21 | destination:
22 | namespace: product-catalog-dev
23 | source:
24 | path: clusters/local.home/overlays/dev
25 |
26 | product-catalog-test:
27 | labels:
28 | app.kubernetes.io/name: product-catalog
29 | destination:
30 | namespace: product-catalog-test
31 | source:
32 | path: clusters/local.home/overlays/test
33 |
34 | product-catalog-prod:
35 | labels:
36 | app.kubernetes.io/name: product-catalog
37 | annotations:
38 | notifications.argoproj.io/subscribe.on-sync-succeeded.server-post-prod: ""
39 | destination:
40 | namespace: product-catalog-prod
41 | source:
42 | path: clusters/local.home/overlays/prod
43 |
44 | product-catalog-cicd:
45 | destination:
46 | namespace: product-catalog-cicd
47 | source:
48 | path: clusters/local.home/overlays/cicd
49 |
50 | product-catalog-monitor:
51 | destination:
52 | namespace: product-catalog-monitor
53 | source:
54 | path: environments/overlays/monitor
55 |
--------------------------------------------------------------------------------
/clusters/rhpds/overlays/cicd/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | bases:
5 | - ../../../../environments/overlays/cicd
6 |
7 | resources:
8 | - pipeline-rolebinding.yaml
9 |
10 | patches:
11 | - target:
12 | kind: TriggerTemplate
13 | name: server
14 | patch: |-
15 | - op: add
16 | path: /spec/resourcetemplates/0/spec/params/-
17 | value:
18 | name: cluster
19 | value: local.home
20 | - op: add
21 | path: /spec/resourcetemplates/0/spec/params/-
22 | value:
23 | name: acs-secret
24 | value: roxsecrets
25 | - target:
26 | kind: TriggerTemplate
27 | name: client
28 | patch: |-
29 | - op: add
30 | path: /spec/resourcetemplates/0/spec/params/-
31 | value:
32 | name: cluster
33 | value: local.home
34 | - op: add
35 | path: /spec/resourcetemplates/0/spec/params/-
36 | value:
37 | name: acs-secret
38 | value: roxsecrets
39 |
40 | # generatorOptions:
41 | # disableNameSuffixHash: true
42 |
43 | # secretGenerator:
44 | # - name: dest-docker-config
45 | # type: kubernetes.io/dockerconfigjson
46 | # files:
47 | # - secrets/.dockerconfigjson
48 |
49 | # patchesJson6902:
50 | # - path: patch-pvc-block.yaml
51 | # target:
52 | # group: ""
53 | # kind: PersistentVolumeClaim
54 | # name: m2-cache
55 | # version: v1
56 | # - path: patch-pvc-block.yaml
57 | # target:
58 | # group: ""
59 | # kind: PersistentVolumeClaim
60 | # name: npm-cache
61 | # version: v1
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-run-pipeline.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: run-tekton-pipeline
5 | spec:
6 | params:
7 | - name: pipeline
8 | type: string
9 | description: The pipeline to execute
10 | - name: args
11 | type: string
12 | description: A space separated list of pipeline arguments (i.e. --param param1=value --param param2=value --workspace workspace)
13 | steps:
14 | - name: tkn
15 | image: quay.io/gnunn/pipelines-cli-tkn-rhel8:v1.6.2-3
16 | script: |
17 | #!/usr/bin/env sh
18 | echo "Starting pipeline with command 'tkn pipeline start $(params.pipeline) $(params.args) --output=json'"
19 | export PIPELINERUN=$(tkn pipeline start $(params.pipeline) $(params.args) --output=json | jq -r .metadata.name)
20 | if [ -z "$PIPELINERUN" ]
21 | then
22 | echo "\$PIPELINERUN is empty, error occurred aborting"
23 | exit 1
24 | fi
25 |
26 | echo "Executing PipelineRun $PIPELINERUN"
27 | tkn pipelinerun logs $PIPELINERUN --follow
28 |
29 | export RESULT=$(oc get pipelinerun $PIPELINERUN -o=jsonpath='{.status.conditions[?(@.type=="Succeeded")].status}')
30 |
31 | if [ "$RESULT" = "True" ]; then
32 | echo "PipelineRun $PIPELINERUN completed successfully"
33 | exit 0
34 | else
35 | echo "PipelineRun $PIPELINERUN failed"
36 | exit 1
37 | fi
38 | volumeMounts:
39 | - name: templates
40 | mountPath: /templates
41 | volumes:
42 | - name: templates
43 | configMap:
44 | name: workspace-template
45 | optional: true
--------------------------------------------------------------------------------
/environments/overlays/cicd/setup-local-credentials-job.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: ServiceAccount
3 | metadata:
4 | name: setup-local-credentials
5 | ---
6 | apiVersion: rbac.authorization.k8s.io/v1
7 | kind: RoleBinding
8 | metadata:
9 | name: setup-local-credentials
10 | roleRef:
11 | apiGroup: rbac.authorization.k8s.io
12 | kind: ClusterRole
13 | name: admin
14 | subjects:
15 | - kind: ServiceAccount
16 | name: setup-local-credentials
17 | namespace: product-catalog-cicd
18 | ---
19 | apiVersion: batch/v1
20 | kind: Job
21 | metadata:
22 | name: setup-local-credentials
23 | annotations:
24 | argocd.argoproj.io/hook: PostSync
25 | argocd.argoproj.io/hook-delete-policy: HookSucceeded
26 | spec:
27 | template:
28 | spec:
29 | containers:
30 | - image: registry.redhat.io/openshift4/ose-cli:v4.9
31 | command:
32 | - /bin/bash
33 | - -c
34 | - |
35 | echo "Linking github secret with pipeline service account"
36 | oc secrets link pipeline github
37 |
38 | echo "Linking dest-docker-config secret with builder service account"
39 | oc secrets link builder dest-docker-config
40 |
41 | echo "Linking dest-docker-config secret with pipeline service account"
42 | oc secrets link pipeline dest-docker-config
43 | # Chains requires imagePullSecrets set
44 | oc patch serviceaccount pipeline -p "{\"imagePullSecrets\": [{\"name\": \"dest-docker-config\"}]}"
45 |
46 | imagePullPolicy: Always
47 | name: setup-local-credentials
48 | serviceAccount: setup-local-credentials
49 | serviceAccountName: setup-local-credentials
50 | dnsPolicy: ClusterFirst
51 | restartPolicy: OnFailure
52 | terminationGracePeriodSeconds: 30
--------------------------------------------------------------------------------
/components/apps/database/base/config/schema.sql:
--------------------------------------------------------------------------------
1 | DROP TABLE IF EXISTS `categories`;
2 |
3 | CREATE TABLE `categories` (
4 | `id` int(11) NOT NULL AUTO_INCREMENT,
5 | `created` date DEFAULT NULL,
6 | `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
7 | `modified` datetime(6) DEFAULT NULL,
8 | `name` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
9 | PRIMARY KEY (`id`)
10 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
11 |
12 | --
13 | -- Table structure for table `products`
14 | --
15 |
16 | DROP TABLE IF EXISTS `products`;
17 |
18 | CREATE TABLE `products` (
19 | `id` int(11) NOT NULL AUTO_INCREMENT,
20 | `created` date DEFAULT NULL,
21 | `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
22 | `modified` datetime(6) DEFAULT NULL,
23 | `name` varchar(128) COLLATE utf8mb4_unicode_ci NOT NULL,
24 | `price` double NOT NULL,
25 | `category_id` int(11) NOT NULL,
26 | PRIMARY KEY (`id`),
27 | KEY `FKog2rp4qthbtt2lfyhfo32lsw9` (`category_id`),
28 | CONSTRAINT `FKog2rp4qthbtt2lfyhfo32lsw9` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`)
29 | ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
30 |
31 | --
32 | -- Table structure for table `users`
33 | --
34 |
35 | DROP TABLE IF EXISTS `users`;
36 |
37 | CREATE TABLE `users` (
38 | `id` int(11) NOT NULL AUTO_INCREMENT,
39 | `created_at` datetime(6) DEFAULT NULL,
40 | `email` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
41 | `iteration_count` int(11) DEFAULT NULL,
42 | `password_hash` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
43 | `salt` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
44 | PRIMARY KEY (`id`)
45 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-create-commit-list.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: create-commit-list
5 | spec:
6 | description: >-
7 | This task creates a message with a link to the commit list between current deployment and PR
8 | params:
9 | - name: deployment
10 | description: name of the deployment
11 | - name: container
12 | description: the ordinal position in the container (0,1,2) in .spec.template.spec.containers
13 | default: "0"
14 | - name: namespace
15 | description: namespace where the deployment is located
16 | - name: image_tag
17 | description: tag of the image that is expected to be deployed
18 | - name: git_source_url
19 | description: The URL of the repo containing the source code, used to construct a link for code changes
20 | results:
21 | - description: The message or link reflecting the list of commits between current image and proposed image
22 | name: commit-list-message
23 | steps:
24 | - name: create-commit-list
25 | image: quay.io/gnunn/tools:4.10-1
26 | script: |
27 | echo "#### Checking current tag in namespace $(params.namespace) ####"
28 | CURRENT_TAG=$(oc get deploy $(params.deployment) -n $(params.namespace) -o jsonpath="{.spec.template.spec.containers[$(params.container)].image}" | cut -d ":" -f2)
29 | CURRENT_COMMIT=${CURRENT_TAG%-*}
30 | echo "Currently deployed commit is $CURRENT_COMMIT"
31 |
32 | NEW_TAG=$(params.image_tag)
33 | NEW_COMMIT=${NEW_TAG%-*}
34 | echo "New commit in PR will be $NEW_COMMIT"
35 |
36 | if [ "$CURRENT_COMMIT" == "$NEW_COMMIT" ]; then
37 | echo -n "No code changes between images" > $(results.commit-list-message.path)
38 | else
39 | echo -n "[$CURRENT_COMMIT to $NEW_COMMIT]($(params.git_source_url)/compare/$CURRENT_COMMIT..$NEW_COMMIT)" > $(results.commit-list-message.path)
40 | fi
--------------------------------------------------------------------------------
/components/tekton/triggers/base/server-triggertemplate.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: TriggerTemplate
4 | metadata:
5 | name: server
6 | spec:
7 | params:
8 | - name: git-revision
9 | description: The git revision
10 | default: master
11 | - name: git-repo-url
12 | description: The git repository url
13 | resourcetemplates:
14 | - apiVersion: tekton.dev/v1
15 | kind: PipelineRun
16 | metadata:
17 | annotations:
18 | argocd.argoproj.io/compare-options: IgnoreExtraneous
19 | argocd.argoproj.io/sync-options: Prune=false
20 | labels:
21 | tekton.dev/pipeline: server
22 | generateName: server-webhook-
23 | spec:
24 | pipelineRef:
25 | name: server
26 | params:
27 | - name: source_git_url
28 | #value: $(tt.params.git-repo-url)
29 | value: "https://github.com/gnunn-gitops/product-catalog-server"
30 | - name: source_git_revision
31 | value: $(tt.params.git-revision)
32 | - name: MAVEN_MIRROR_URL
33 | value: http://nexus:8081/content/groups/public/
34 | - name: push-to-prod
35 | value: "false"
36 | workspaces:
37 | - name: git-source
38 | volumeClaimTemplate:
39 | spec:
40 | accessModes:
41 | - ReadWriteOnce
42 | resources:
43 | requests:
44 | storage: 5Gi
45 | - name: gitops-manifests
46 | volumeClaimTemplate:
47 | spec:
48 | accessModes:
49 | - ReadWriteOnce
50 | resources:
51 | requests:
52 | storage: 5Gi
53 | - name: maven-settings
54 | configmap:
55 | name: maven-settings
56 | - name: newman-env
57 | configMap:
58 | name: newman-env
59 |
--------------------------------------------------------------------------------
/components/apps/client/base/client-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: client
5 | annotations:
6 | app.openshift.io/connects-to: server
7 | app.openshift.io/vcs-ref: master
8 | app.openshift.io/vcs-uri: 'https://github.com/gnunn-gitops/product-catalog-client'
9 | labels:
10 | app: client
11 | app.kubernetes.io/name: client
12 | app.kubernetes.io/component: frontend
13 | app.kubernetes.io/instance: client
14 | app.openshift.io/runtime: nodejs
15 | app.kubernetes.io/part-of: product-catalog
16 | spec:
17 | selector:
18 | matchLabels:
19 | name: client
20 | replicas: 1
21 | template:
22 | metadata:
23 | labels:
24 | name: client
25 | spec:
26 | containers:
27 | - name: client
28 | image: quay.io/gnunn/client:latest
29 | imagePullPolicy: Always
30 | ports:
31 | - containerPort: 8080
32 | protocol: TCP
33 | name: http
34 | # volumeMounts:
35 | # - mountPath: /opt/app-root/src/config.js
36 | # name: config-data
37 | # subPath: config.js
38 | resources:
39 | requests:
40 | memory: "50Mi"
41 | cpu: "50m"
42 | limits:
43 | memory: "100Mi"
44 | livenessProbe:
45 | httpGet:
46 | path: /health.html
47 | port: 8080
48 | initialDelaySeconds: 3
49 | periodSeconds: 10
50 | readinessProbe:
51 | httpGet:
52 | path: /health.html
53 | port: 8080
54 | scheme: HTTP
55 | timeoutSeconds: 1
56 | periodSeconds: 10
57 | successThreshold: 1
58 | failureThreshold: 3
59 | terminationMessagePath: /dev/termination-log
60 | terminationMessagePolicy: File
61 | # volumes:
62 | # - configMap:
63 | # name: client
64 | # name: config-data
65 |
--------------------------------------------------------------------------------
/components/tekton/triggers/base/slack-message-triggertemplate.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: triggers.tekton.dev/v1beta1
3 | kind: TriggerTemplate
4 | metadata:
5 | name: slack-message
6 | spec:
7 | params:
8 | - name: git_revision
9 | description: The git revision
10 | default: main
11 | - name: git_url
12 | description: The git repository url
13 | - name: git_source_url
14 | description: The git repository source code URL
15 | - name: image_dest_url
16 | description: External registry location of image to push without tag
17 | - name: image_dest_tag
18 | description: Tag of image to push to production
19 | - name: cluster
20 | description: Cluster to push to
21 | - name: app
22 | description: Either 'server' or 'client'
23 | resourcetemplates:
24 | - apiVersion: tekton.dev/v1
25 | kind: PipelineRun
26 | metadata:
27 | labels:
28 | tekton.dev/pipeline: push-prod-pr
29 | generateName: slack-message-webhook-
30 | spec:
31 | pipelineRef:
32 | name: push-prod-pr
33 | params:
34 | - name: git_url
35 | value: $(tt.params.git_url)
36 | - name: git_revision
37 | value: $(tt.params.git_revision)
38 | - name: git_source_url
39 | value: $(tt.params.git_source_url)
40 | - name: image_dest_tag
41 | value: $(tt.params.image_dest_tag)
42 | - name: image_dest_url
43 | value: $(tt.params.image_dest_url)
44 | - name: cluster
45 | value: $(tt.params.cluster)
46 | - name: app
47 | value: $(tt.params.app)
48 | workspaces:
49 | - name: gitops-manifests
50 | volumeClaimTemplate:
51 | spec:
52 | accessModes:
53 | - ReadWriteOnce
54 | resources:
55 | requests:
56 | storage: 5Gi
57 | - name: acs-central
58 | secret:
59 | secretName: roxsecrets
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/server-post-prod-pipeline.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Pipeline
3 | metadata:
4 | name: server-post-prod
5 | spec:
6 | workspaces:
7 | - name: newman-env
8 | - name: slack-secret
9 | optional: true
10 | tasks:
11 | - name: prod-test
12 | taskRef:
13 | name: newman
14 | params:
15 | - name: COLLECTION
16 | value: https://raw.githubusercontent.com/gnunn-gitops/product-catalog-server/master/tests/product-catalog-server-tests.json
17 | - name: ENVIRONMENT
18 | value: newman-prod-env.json
19 | workspaces:
20 | - name: newman-env
21 | workspace: newman-env
22 | finally:
23 | # - name: notify
24 | # taskRef:
25 | # name: send-to-webhook-slack
26 | # when:
27 | # - input: "$(workspaces.slack-secret.bound)"
28 | # operator: in
29 | # values: ["true"]
30 | # params:
31 | # - name: message
32 | # value: "Production has been synchronized by ArgoCD, test status: $(tasks.prod-test.status)"
33 | # workspaces:
34 | # - name: slack-secret
35 | # workspace: slack-secret
36 | # Add when pipelines updated to version of Tekton that supports using when expressions
37 | - name: notify-succeeded
38 | when:
39 | - input: $(tasks.prod-test.status)
40 | operator: in
41 | values: ["Succeeded"]
42 | taskRef:
43 | name: send-to-webhook-slack
44 | params:
45 | - name: message
46 | value: "SUCCEEDED: Production has been synchronized by ArgoCD"
47 | workspaces:
48 | - name: slack-secret
49 | workspace: slack-secret
50 | - name: notify-failed
51 | when:
52 | - input: $(tasks.prod-test.status)
53 | operator: in
54 | values: ["Failed"]
55 | taskRef:
56 | name: send-to-webhook-slack
57 | params:
58 | - name: message
59 | value: "FAILED: Production has been synchronized by ArgoCD"
60 | workspaces:
61 | - name: slack-secret
62 | workspace: slack-secret
--------------------------------------------------------------------------------
/components/apps/database/base/config/import.sql:
--------------------------------------------------------------------------------
1 | INSERT INTO `categories` (`id`, `name`, `description`, `created`, `modified`) VALUES
2 | (1, 'Smartphone', 'Not a stupid phone', '2015-08-02 23:56:46', '2016-12-20 06:51:25'),
3 | (2, 'Tablet', 'A small smartphone-laptop mix', '2015-08-02 23:56:46', '2016-12-20 06:51:42'),
4 | (3, 'Ultrabook', 'Ultra portable and powerful laptop', '2016-12-20 13:51:15', '2016-12-20 06:51:52');
5 |
6 | INSERT INTO `products` (`id`, `name`, `description`, `price`, `category_id`, `created`, `modified`) VALUES
7 | (1, 'ASUS Zenbook 3', 'The most powerful and ultraportable Zenbook ever', 1799, 3, '2016-12-20 13:53:00', '2016-12-20 06:53:00'),
8 | (2, 'Dell XPS 13', 'Super powerful and portable ultrabook with ultra thin bezel infinity display', 2199, 3, '2016-12-20 13:53:34', '2016-12-20 06:53:34'),
9 | (3, 'Samsung Galaxy S7', 'Define what a phone can do', 649, 1, '2016-12-20 13:54:16', '2016-12-20 06:54:16'),
10 | (4, 'Samsung Galaxy Tab S2', 'Latest Generation of Samsung Galaxy Tab Series tablet', 599, 2, '2016-12-20 13:54:43', '2016-12-20 06:54:43'),
11 | (5, 'Apple iPad Pro', 'Powerful, thin, and light tablet from Apple', 899, 2, '2016-12-20 13:55:02', '2016-12-20 06:55:02'),
12 | (6, 'Google Pixel', 'World''s leading smartphone camera, first phone by Google.', 649, 1, '2016-12-20 13:55:23', '2016-12-20 06:55:23'),
13 | (7, 'Oneplus 3T', 'Never Settle', 439, 1, '2016-12-20 13:59:06', '2016-12-20 06:59:06'),
14 | (8, 'Asus Zenfone 3 Deluxe', 'Super powerful and gorgeously designed phablet', 799, 1, '2016-12-20 13:59:37', '2016-12-20 06:59:37'),
15 | (9, 'Xiaomi Mi Mix', 'Bezelless. Powerful. Gorgeous.', 699, 1, '2016-12-20 14:00:20', '2016-12-20 07:00:20'),
16 | (10, 'Huawei P9', 'First Leica Branded Dual-camera Smartphone', 499, 1, '2016-12-20 14:00:45', '2016-12-20 07:00:45'),
17 | (11, 'Xiaomi Mi 5S', 'First Xiaomi smartphone to come with light-sensitive camera', 349, 1, '2016-12-20 14:01:40', '2016-12-20 07:10:14'),
18 | (12, 'LG V20', 'Superb dual camera, Space-grade Aluminum build, fantastic sound quality', 749, 1, '2016-12-20 14:02:28', '2016-12-20 07:02:28');
19 |
20 | INSERT INTO `users` (`id`, `email`, `password_hash`, `salt`, `iteration_count`, `created_at`) VALUES
21 | (1, 'demo@demo.com', '/TVyvAPSryEfGlyEFmNq14Q/prbJU7U=', 'YYONLJPUCmUeISgDxyTREg==', 10, '2019-11-23 02:54:42');
22 |
--------------------------------------------------------------------------------
/components/apps/slack-message-handler/base/deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | annotations:
5 | app.openshift.io/connects-to: '[{"apiVersion":"apps/v1","kind":"Deployment","name":"el-slack-message"}]'
6 | labels:
7 | app: slack-message-handler
8 | app.kubernetes.io/component: slack-message-handler
9 | app.kubernetes.io/instance: slack-message-handler
10 | app.kubernetes.io/name: slack-message-handler
11 | app.openshift.io/runtime: quarkus
12 | app.openshift.io/runtime-namespace: product-catalog-cicd
13 | name: slack-message-handler
14 | spec:
15 | progressDeadlineSeconds: 600
16 | replicas: 1
17 | revisionHistoryLimit: 10
18 | selector:
19 | matchLabels:
20 | app: slack-message-handler
21 | strategy:
22 | rollingUpdate:
23 | maxSurge: 25%
24 | maxUnavailable: 25%
25 | type: RollingUpdate
26 | template:
27 | metadata:
28 | annotations:
29 | openshift.io/generated-by: OpenShiftWebConsole
30 | labels:
31 | app: slack-message-handler
32 | deployment: slack-message-handler
33 | spec:
34 | containers:
35 | - image: quay.io/gnunn/slack-message-handler:latest
36 | imagePullPolicy: Always
37 | name: slack-message-handler
38 | resources:
39 | requests:
40 | memory: "200Mi"
41 | cpu: "50m"
42 | limits:
43 | memory: "512Mi"
44 | livenessProbe:
45 | httpGet:
46 | path: /q/health/live
47 | port: 8080
48 | initialDelaySeconds: 3
49 | periodSeconds: 10
50 | readinessProbe:
51 | httpGet:
52 | path: /q/health/ready
53 | port: 8080
54 | scheme: HTTP
55 | timeoutSeconds: 1
56 | periodSeconds: 10
57 | successThreshold: 1
58 | failureThreshold: 3
59 | ports:
60 | - containerPort: 8080
61 | protocol: TCP
62 | - containerPort: 8443
63 | protocol: TCP
64 | - containerPort: 8778
65 | protocol: TCP
66 | terminationMessagePath: /dev/termination-log
67 | terminationMessagePolicy: File
68 | dnsPolicy: ClusterFirst
69 | restartPolicy: Always
70 | schedulerName: default-scheduler
71 | terminationGracePeriodSeconds: 30
72 |
--------------------------------------------------------------------------------
/components/apps/server/base/server-deployment.yaml:
--------------------------------------------------------------------------------
1 | # Note not currently working, pods constantly terminating and restarting
2 | # Using DC for now but preserved here to come back to later
3 | apiVersion: apps/v1
4 | kind: Deployment
5 | metadata:
6 | name: server
7 | annotations:
8 | app.openshift.io/connects-to: database
9 | app.openshift.io/vcs-ref: master
10 | app.openshift.io/vcs-uri: 'https://github.com/gnunn-gitops/product-catalog-server'
11 | labels:
12 | app: server
13 | app.kubernetes.io/name: server
14 | app.kubernetes.io/component: backend
15 | app.kubernetes.io/instance: server
16 | app.openshift.io/runtime: quarkus
17 | app.kubernetes.io/part-of: product-catalog
18 | spec:
19 | selector:
20 | matchLabels:
21 | name: server
22 | replicas: 1
23 | template:
24 | metadata:
25 | labels:
26 | name: server
27 | quarkus-prometheus: "true"
28 | spec:
29 | containers:
30 | - name: server
31 | env:
32 | - name: QUARKUS_KUBERNETES_CONFIG_ENABLED
33 | value: "true"
34 | - name: QUARKUS_KUBERNETES_CONFIG_CONFIG_MAPS
35 | value: server
36 | # - name: JAVA_OPTIONS
37 | # value: >-
38 | # -Dquarkus.kubernetes-config.enabled=true
39 | # -Dquarkus.kubernetes-config.config-maps=server
40 | image: quay.io/gnunn/server:latest
41 | imagePullPolicy: Always
42 | ports:
43 | - containerPort: 8080
44 | protocol: TCP
45 | name: http
46 | - containerPort: 8443
47 | protocol: TCP
48 | - containerPort: 8778
49 | protocol: TCP
50 | resources:
51 | requests:
52 | memory: "250Mi"
53 | cpu: "100m"
54 | limits:
55 | memory: "512Mi"
56 | livenessProbe:
57 | httpGet:
58 | path: /q/health/live
59 | port: 8080
60 | initialDelaySeconds: 3
61 | periodSeconds: 10
62 | readinessProbe:
63 | httpGet:
64 | path: /q/health/ready
65 | port: 8080
66 | scheme: HTTP
67 | timeoutSeconds: 1
68 | periodSeconds: 10
69 | successThreshold: 1
70 | failureThreshold: 3
71 | terminationMessagePath: /dev/termination-log
72 | terminationMessagePolicy: File
--------------------------------------------------------------------------------
/clusters/local.home/overlays/cicd/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | bases:
5 | - ../../../../environments/overlays/cicd
6 |
7 | resources:
8 | - pipeline-rolebinding.yaml
9 |
10 | patches:
11 | - target:
12 | kind: TriggerTemplate
13 | name: server-post-prod
14 | patch: |-
15 | - op: add
16 | path: /spec/resourcetemplates/0/spec/workspaces/-
17 | value:
18 | name: slack-secret
19 | secret:
20 | secretName: slack-deployments-webhook
21 | - target:
22 | kind: TriggerTemplate
23 | name: server
24 | patch: |-
25 | - op: add
26 | path: /spec/resourcetemplates/0/spec/params/-
27 | value:
28 | name: cluster
29 | value: local.home
30 | - op: add
31 | path: /spec/resourcetemplates/0/spec/workspaces/-
32 | value:
33 | name: acs-central
34 | secret:
35 | secretName: roxsecrets
36 | - op: add
37 | path: /spec/resourcetemplates/0/spec/workspaces/-
38 | value:
39 | name: upload-sbom
40 | secret:
41 | secretName: upload-sbom
42 | - op: add
43 | path: /spec/resourcetemplates/0/spec/workspaces/-
44 | value:
45 | name: slack-secret
46 | secret:
47 | secretName: slack-deployments-webhook
48 | - target:
49 | kind: TriggerTemplate
50 | name: client
51 | patch: |-
52 | - op: add
53 | path: /spec/resourcetemplates/0/spec/params/-
54 | value:
55 | name: cluster
56 | value: local.home
57 | - op: add
58 | path: /spec/resourcetemplates/0/spec/workspaces/-
59 | value:
60 | name: acs-central
61 | secret:
62 | secretName: roxsecrets
63 | - op: add
64 | path: /spec/resourcetemplates/0/spec/workspaces/-
65 | value:
66 | name: slack-secret
67 | secret:
68 | secretName: slack-deployments-webhook
69 |
70 | # generatorOptions:
71 | # disableNameSuffixHash: true
72 |
73 | # secretGenerator:
74 | # - name: dest-docker-config
75 | # type: kubernetes.io/dockerconfigjson
76 | # files:
77 | # - secrets/.dockerconfigjson
78 |
79 | # patchesJson6902:
80 | # - path: patch-pvc-block.yaml
81 | # target:
82 | # group: ""
83 | # kind: PersistentVolumeClaim
84 | # name: m2-cache
85 | # version: v1
86 | # - path: patch-pvc-block.yaml
87 | # target:
88 | # group: ""
89 | # kind: PersistentVolumeClaim
90 | # name: npm-cache
91 | # version: v1
92 |
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-send-to-webhook-slack.yaml:
--------------------------------------------------------------------------------
1 | # Adapted from Tekton Catalog item
2 | # https://github.com/tektoncd/catalog/tree/main/task/send-to-webhook-slack/0.1
3 | apiVersion: tekton.dev/v1
4 | kind: Task
5 | metadata:
6 | name: send-to-webhook-slack
7 | labels:
8 | app.kubernetes.io/version: "0.1"
9 | annotations:
10 | tekton.dev/pipelines.minVersion: "0.12.1"
11 | tekton.dev/tags: messaging
12 | spec:
13 | description: >-
14 | These tasks post a simple message to a slack channel.
15 | This task uses Incoming Webhooks of slack to send the message.
16 | params:
17 | - name: message
18 | type: string
19 | description: Basic message, markdown can be used for formatting
20 | - name: console_message
21 | type: string
22 | description: Message to log to console
23 | default: ""
24 | - name: message_type
25 | type: string
26 | description: The type of message to send, can be set to "raw" or "markdown". If set to "raw" the user is expected to provide a full json payload conforming to slack's specifications.
27 | default: "markdown"
28 | workspaces:
29 | - name: slack-secret
30 | optional: true
31 | steps:
32 | - name: post
33 | image: registry.redhat.io/openshift4/ose-tools-rhel8:v4.10
34 | script: |
35 | #!/bin/sh
36 |
37 | echo "Preparing to send message..."
38 |
39 | MESSAGE=$(cat <<-END
40 | $(params.message)
41 | END
42 | )
43 |
44 | CONSOLE_MESSAGE=$(cat <<-END
45 | $(params.console_message)
46 | END
47 | )
48 |
49 | # Echo message locally for logging purposes
50 | if [ -n "$CONSOLE_MESSAGE" ]; then
51 | echo "$CONSOLE_MESSAGE"
52 | elif [ -n "$MESSAGE" ]; then
53 | echo "$MESSAGE"
54 | fi
55 |
56 | if [ $(workspaces.slack-secret.bound) == "true" ] ; then
57 | if [ -f "$(workspaces.slack-secret.path)/url" ]; then
58 | printf "\nSending to slack...\n\n"
59 | URL=$(cat $(workspaces.slack-secret.path)/url)
60 |
61 | if [ "$(params.message_type)" == "raw" ]; then
62 | echo "Sending raw message to slack"
63 | /usr/bin/curl -s -S -X POST -H 'Content-type: application/json' --data "${MESSAGE}" $URL
64 | else
65 | echo "Sending message to slack"
66 | /usr/bin/curl -s -S -X POST -H 'Content-type: application/json' --data '{"type": "mrkdwn", "text":"$(params.message)"}' $URL
67 | fi
68 | fi
69 | else
70 | echo "Note: Slack message was not sent as it was not configured"
71 | fi
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-binary-s2i.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: binary-s2i
5 | spec:
6 | workspaces:
7 | - name: source
8 | params:
9 | - name: directory
10 | description: The sub-directory to use for the wildcard build
11 | type: string
12 | default: ""
13 | - name: file
14 | description: The file to use for the s2i binary build, can be a wildcard. If it resolves to multiple files the first one is used
15 | type: string
16 | default: ""
17 | - name: buildconfig
18 | type: string
19 | - name: IMAGE
20 | type: string
21 | description: "Only needed if using chains to automatically specify sign the image"
22 | default: ""
23 | results:
24 | - description: The build generated by this task
25 | name: build
26 | - description: The digest for the image created
27 | name: IMAGE_DIGEST
28 | - description: The URL for the image
29 | name: IMAGE_URL
30 | steps:
31 | - name: s2i-build
32 | image: quay.io/openshift/origin-cli:latest
33 | script: |
34 | #!/usr/bin/env bash
35 |
36 | if [[ "$(params.directory)" == "" && "$(params.file)" == "" ]]
37 | then
38 | echo "The task must have either directory or file parameters set"
39 | exit 1
40 | fi
41 |
42 | if [ "$(params.directory)" != "" ];
43 | then
44 | oc start-build $(params.buildconfig) --from-dir=$(params.directory) --wait=true > output.txt
45 | else
46 | FILE_PATH="$(ls $(params.file))"
47 | echo "Using file ${FILE_PATH} for binary build"
48 | oc start-build $(params.buildconfig) --from-file="${FILE_PATH}" --wait=true > output.txt
49 | fi
50 |
51 | BUILD=$(grep -oP '(?<=build\.build\.openshift\.io\/).\S*' output.txt)
52 | echo -n "$BUILD" > $(results.build.path)
53 | echo "Build created was $BUILD"
54 |
55 | STATUS=$(oc get build $BUILD -o=jsonpath='{.status.phase}')
56 | if [ "$STATUS" == "Failed" ];
57 | then
58 | echo "Build $BUILD failed"
59 | exit 1
60 | fi
61 |
62 | DIGEST=$(oc get build $BUILD -o jsonpath="{.status.output.to.imageDigest}")
63 | echo -n "$DIGEST" > $(results.IMAGE_DIGEST.path)
64 | echo "Digest for image build was $DIGEST"
65 |
66 | IMAGE_URL=$(oc get build $BUILD -o jsonpath="{.status.outputDockerImageReference}")
67 | IMAGE_URL="${IMAGE_URL%:*}"
68 | echo -n "$IMAGE_URL" > $(results.IMAGE_URL.path)
69 | echo "Image was pushed to: $IMAGE_URL"
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/config/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | org.sonarsource.scanner.maven
4 |
5 |
6 |
7 |
8 | nexus-releases
9 | ${env.MAVEN_SERVER_USERNAME}
10 | ${env.MAVEN_SERVER_PASSWORD}
11 |
12 |
13 | nexus-snapshots
14 | ${env.MAVEN_SERVER_USERNAME}
15 | ${env.MAVEN_SERVER_PASSWORD}
16 |
17 |
18 |
19 |
20 | local-repository
21 | Nexus Maven Mirror
22 | https://nexus-dev-tools.apps.hub.ocplab.com/content/groups/public
23 | *
24 |
25 |
26 |
27 |
28 |
29 | nexus-internal
30 |
31 | https://nexus-dev-tools.apps.hub.ocplab.com/content/repositories/snapshots
32 | https://nexus-dev-tools.apps.hub.ocplab.com//content/repositories/releases
33 |
37 |
38 |
39 |
40 | sonar
41 |
42 |
43 | https://sonarqube-dev-tools.apps.hub.ocplab.com
44 |
45 | admin
46 | R@dhat1234
47 |
52 |
53 |
54 |
55 | pipeline
56 |
57 | /workspace/app-binary
58 |
59 |
60 |
61 |
62 |
63 | nexus-internal
64 | sonar
65 | pipeline
66 |
67 |
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-update-image.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | name: update-image
5 | spec:
6 | workspaces:
7 | - name: gitops-manifests
8 | params:
9 | - name: git_revision
10 | type: string
11 | default: main
12 | - name: path
13 | type: string
14 | description: The path of the kustomization file which we will use to update the image reference
15 | - name: image
16 | type: string
17 | description: The name of the image that is being updated
18 | - name: image_tag
19 | type: string
20 | description: The tag of the new image that will be deployed
21 | - name: push_retry_count
22 | type: string
23 | description: The number of times to re-attempt a push to git in case of failure (does a push-pull with retry)
24 | default: "3"
25 | results:
26 | - description: Whether the image was updated and committed
27 | name: image_updated
28 | - description: The short commit hash for the update
29 | name: image_updated_short_commit
30 | stepTemplate:
31 | env:
32 | - name: "HOME"
33 | value: "/tekton/home"
34 | steps:
35 | - name: update-image
36 | workingDir: $(workspaces.gitops-manifests.path)
37 | image: quay.io/redhatworkshops/kustomize-task:v4.0.5
38 | script: |
39 | echo "Kustomizing image"
40 | echo "Running: kustomize edit set image $(params.image)=$(params.image):$(params.image_tag)"
41 |
42 | cd $(params.path)
43 | kustomize edit set image $(params.image)=$(params.image):$(params.image_tag)
44 |
45 | echo "Updated file kustomization.yaml file"
46 | cat kustomization.yaml
47 | - name: commit-and-push-change
48 | workingDir: $(workspaces.gitops-manifests.path)
49 | image: docker.io/alpine/git:v2.26.2@sha256:23618034b0be9205d9cc0846eb711b12ba4c9b468efdd8a59aac1d7b1a23363f
50 | script: |
51 | if git diff --exit-code;
52 | then
53 | echo "No changes staged, skipping add/commit"
54 | echo -n "false" > $(results.image_updated.path)
55 | else
56 | echo "Changes made, committing"
57 | git config --global user.name "pipeline"
58 | git config --global user.email "pipelines@nomail.com"
59 | git add -u
60 | git commit -m 'Update image in git to $(params.image):$(params.image_tag)'
61 | echo "Running 'git push origin HEAD:$(params.git_revision)'"
62 |
63 |
64 | n=0
65 | until [ "$n" -ge $(params.push_retry_count) ]
66 | do
67 | git push origin HEAD:$(params.git_revision) && break
68 | git pull origin HEAD:$(params.git_revision)
69 | n=$((n+1))
70 | done
71 |
72 | if [ "$n" -ge $(params.push_retry_count) ];
73 | then
74 | echo "Failed to push change to git"
75 | exit 1
76 | fi
77 |
78 | echo -n "true" > $(results.image_updated.path)
79 | git rev-parse --short HEAD > $(results.image_updated_short_commit.path)
80 | fi
--------------------------------------------------------------------------------
/components/apps/database/base/db-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: productdb
5 | labels:
6 | app: productdb
7 | app.kubernetes.io/name: productdb
8 | app.kubernetes.io/component: database
9 | app.kubernetes.io/part-of: product-catalog
10 | app.kubernetes.io/instance: database
11 | app.openshift.io/runtime: mariadb
12 | spec:
13 | replicas: 1
14 | selector:
15 | matchLabels:
16 | name: productdb
17 | strategy:
18 | type: Recreate
19 | template:
20 | metadata:
21 | annotations:
22 | alpha.image.policy.openshift.io/resolve-names: '*'
23 | labels:
24 | name: productdb
25 | spec:
26 | containers:
27 | - name: productdb
28 | image: registry.redhat.io/rhel8/mariadb-103:1
29 | imagePullPolicy: Always
30 | resources:
31 | requests:
32 | memory: "100Mi"
33 | cpu: "100m"
34 | limits:
35 | memory: "250Mi"
36 | ports:
37 | - containerPort: 3306
38 | env:
39 | - name: MYSQL_USER
40 | valueFrom:
41 | secretKeyRef:
42 | name: productdb
43 | key: database-user
44 | - name: MYSQL_PASSWORD
45 | valueFrom:
46 | secretKeyRef:
47 | name: productdb
48 | key: database-password
49 | - name: MYSQL_ROOT_PASSWORD
50 | valueFrom:
51 | secretKeyRef:
52 | name: productdb
53 | key: database-root-password
54 | - name: MYSQL_DATABASE
55 | valueFrom:
56 | secretKeyRef:
57 | name: productdb
58 | key: database-name
59 | readinessProbe:
60 | exec:
61 | command:
62 | - /bin/sh
63 | - -i
64 | - -c
65 | - MYSQL_PWD="$MYSQL_PASSWORD" mysql -h 127.0.0.1 -u $MYSQL_USER -D $MYSQL_DATABASE
66 | -e 'SELECT 1'
67 | initialDelaySeconds: 5
68 | timeoutSeconds: 1
69 | livenessProbe:
70 | initialDelaySeconds: 30
71 | tcpSocket:
72 | port: 3306
73 | timeoutSeconds: 1
74 | volumeMounts:
75 | - mountPath: /var/lib/mysql/data
76 | name: productdb-data
77 | - mountPath: /opt/app-root/src/mysql-init/90-init-data.sh
78 | name: productdb-init
79 | subPath: 90-init-database.sh
80 | - mountPath: /opt/app-root/src/mysql-data/import.sql
81 | name: productdb-init
82 | subPath: import.sql
83 | - mountPath: /opt/app-root/src/mysql-data/schema.sql
84 | name: productdb-init
85 | subPath: schema.sql
86 | volumes:
87 | - name: productdb-data
88 | persistentVolumeClaim:
89 | claimName: productdb
90 | - configMap:
91 | name: productdb-init
92 | name: productdb-init
--------------------------------------------------------------------------------
/components/tekton/tasks/base/task-buildah.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Task
3 | metadata:
4 | annotations:
5 | manifestival: new
6 | tekton.dev/pipelines.minVersion: 0.12.1
7 | tekton.dev/tags: image-build
8 | labels:
9 | app.kubernetes.io/version: "0.1"
10 | name: buildah
11 | spec:
12 | description: |-
13 | Buildah task builds source into a container image and then pushes it to a container registry.
14 | Buildah Task builds source into a container image using Project Atomic's Buildah build tool.It uses Buildah's support for building from Dockerfiles, using its buildah bud command.This command executes the directives in the Dockerfile to assemble a container image, then pushes that image to a container registry.
15 | params:
16 | - description: Reference of the image buildah will produce.
17 | name: IMAGE
18 | type: string
19 | - default: registry.redhat.io/rhel8/buildah@sha256:0a86ecbdfbe86e9d225b7fe4b090a0dd6d323f8afdfdf2bd933ff223ddb53320
20 | description: The location of the buildah builder image.
21 | name: BUILDER_IMAGE
22 | type: string
23 | - default: vfs
24 | description: Set buildah storage driver
25 | name: STORAGE_DRIVER
26 | type: string
27 | - default: ./Dockerfile
28 | description: Path to the Dockerfile to build.
29 | name: DOCKERFILE
30 | type: string
31 | - default: .
32 | description: Path to the directory to use as context.
33 | name: CONTEXT
34 | type: string
35 | - default: "true"
36 | description: Verify the TLS on the registry endpoint (for push/pull to a non-TLS
37 | registry)
38 | name: TLSVERIFY
39 | type: string
40 | - default: oci
41 | description: The format of the built container, oci or docker
42 | name: FORMAT
43 | type: string
44 | - default: ""
45 | description: Extra parameters passed for the build command when building images.
46 | name: BUILD_EXTRA_ARGS
47 | type: string
48 | - default: ""
49 | description: Extra parameters passed for the push command when pushing images.
50 | name: PUSH_EXTRA_ARGS
51 | type: string
52 | - default: "false"
53 | description: Skip pushing the built image
54 | name: SKIP_PUSH
55 | type: string
56 | results:
57 | - description: Digest of the image just built.
58 | name: IMAGE_DIGEST
59 | type: string
60 | - name: IMAGE_URL
61 | description: Image repository where the built image would be pushed to
62 | steps:
63 | - image: $(params.BUILDER_IMAGE)
64 | name: build-and-push
65 | script: |
66 | pwd
67 | ls
68 |
69 | buildah --storage-driver=$(params.STORAGE_DRIVER) bud \
70 | $(params.BUILD_EXTRA_ARGS) --format=$(params.FORMAT) \
71 | --tls-verify=$(params.TLSVERIFY) --no-cache \
72 | -f $(params.DOCKERFILE) -t $(params.IMAGE) $(params.CONTEXT)
73 |
74 | [[ "$(params.SKIP_PUSH)" == "true" ]] && echo "Push skipped" && exit 0
75 | buildah --storage-driver=$(params.STORAGE_DRIVER) push \
76 | $(params.PUSH_EXTRA_ARGS) --tls-verify=$(params.TLSVERIFY) \
77 | --digestfile $(workspaces.source.path)/image-digest $(params.IMAGE) \
78 | docker://$(params.IMAGE)
79 | cat $(workspaces.source.path)/image-digest | tee /tekton/results/IMAGE_DIGEST
80 | echo "$(params.IMAGE)" | tee $(results.IMAGE_URL.path)
81 | securityContext:
82 | capabilities:
83 | add:
84 | - SETFCAP
85 | volumeMounts:
86 | - mountPath: /var/lib/containers
87 | name: varlibcontainers
88 | workingDir: $(workspaces.source.path)
89 | volumes:
90 | - name: varlibcontainers
91 | workspaces:
92 | - name: source
93 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/push-prod-pr/base/push-prod-pr-pipeline.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Pipeline
3 | metadata:
4 | name: push-prod-pr
5 | spec:
6 | workspaces:
7 | - name: gitops-manifests
8 | - name: acs-central
9 | optional: true
10 | params:
11 | - name: git_revision
12 | type: string
13 | default: main
14 | - name: git_url
15 | type: string
16 | default: https://github.com/gnunn-gitops/product-catalog
17 | - name: git_source_url
18 | description: The URL of the repo containing the source code for the application, used to construct a link for code changes
19 | - name: image_dest_url
20 | type: string
21 | description: External registry location of image to push without tag
22 | - name: image_dest_tag
23 | type: string
24 | description: Tag of image to push to production
25 | - name: cluster
26 | type: string
27 | description: Cluster to push to
28 | - name: app
29 | type: string
30 | description: Either 'server' or 'client'
31 | - name: sonarqube_host
32 | type: string
33 | description: Hostname for sonarqube
34 | default: sonarqube-dev-tools.apps.hub.ocplab.com
35 | tasks:
36 | - name: variables
37 | taskRef:
38 | name: variables-from-k8s
39 | workspaces:
40 | - name: acs-central
41 | workspace: acs-central
42 | - name: get-image-digest
43 | taskRef:
44 | kind: Task
45 | params:
46 | - name: pathInRepo
47 | value: task/image-tag-to-digest/1.0/image-tag-to-digest.yaml
48 | resolver: git
49 | runAfter:
50 | - variables
51 | params:
52 | - name: image_dest_url
53 | value: $(params.image_dest_url)
54 | - name: image_dest_tag
55 | value: $(params.image_dest_tag)
56 | - name: clone
57 | taskRef:
58 | resolver: cluster
59 | params:
60 | - name: kind
61 | value: task
62 | - name: name
63 | value: git-clone
64 | - name: namespace
65 | value: openshift-pipelines
66 | runAfter:
67 | - get-image-digest
68 | workspaces:
69 | - name: output
70 | workspace: gitops-manifests
71 | params:
72 | - name: URL
73 | value: "$(params.git_url)"
74 | - name: REVISION
75 | value: "$(params.git_revision)"
76 | - name: DELETE_EXISTING
77 | value: "true"
78 | - name: branch
79 | taskRef:
80 | name: git
81 | runAfter:
82 | - clone
83 | workspaces:
84 | - name: source
85 | workspace: gitops-manifests
86 | params:
87 | - name: commands
88 | value: |
89 | git checkout -b push-$(params.image_dest_tag)
90 | - name: update-image
91 | taskRef:
92 | name: update-image
93 | runAfter:
94 | - branch
95 | params:
96 | - name: git_revision
97 | value: "push-$(params.image_dest_tag)"
98 | - name: path
99 | value: clusters/$(params.cluster)/overlays/prod
100 | - name: image
101 | value: "$(params.image_dest_url)"
102 | - name: image_tag
103 | value: $(params.image_dest_tag)
104 | workspaces:
105 | - name: gitops-manifests
106 | workspace: gitops-manifests
107 | - name: create-commit-list
108 | taskRef:
109 | name: create-commit-list
110 | runAfter:
111 | - update-image
112 | params:
113 | - name: deployment
114 | value: $(params.app)
115 | - name: namespace
116 | value: product-catalog-prod
117 | - name: image_tag
118 | value: $(params.image_dest_tag)
119 | - name: git_source_url
120 | value: $(params.git_source_url)
121 | - name: prod-pr-deploy
122 | taskRef:
123 | name: task-create-pr
124 | kind: Task
125 | runAfter:
126 | - create-commit-list
127 | workspaces:
128 | - name: source
129 | workspace: gitops-manifests
130 | when:
131 | - input: "$(tasks.update-image.results.image_updated)"
132 | operator: in
133 | values: ["true"]
134 | params:
135 | - name: title
136 | value: Update $(params.app) image to $(params.image_dest_tag)
137 | - name: body
138 | value: |-
139 | ## Security Checklist
140 |
141 | - [ ] [Quay Image Vulnerabilities](https://$(params.image_dest_url):$(params.image_dest_tag))
142 | - [ ] [Advanced Cluster Security Image Vulnerabilities and Policies](https://$(tasks.variables.results.acs_central_endpoint)/main/vulnerability-management/images/$(tasks.get-image-digest.results.image_digest))
143 | - [ ] [Sonarqube Results](https://$(params.sonarqube_host)/dashboard?id=product-catalog-$(params.app))
144 |
145 | ## Code Changes
146 | - [ ] $(tasks.create-commit-list.results.commit-list-message)
147 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Introduction
2 |
3 | This is an OpenShift demo showing how to do GitOps in a kubernetes way using tools like [ArgoCD](https://argoproj.github.io/argo-cd/) and [Kustomize](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/). The demo application is a three tier application using React for the front-end with Quarkus providing APIs as the back-end. The back-end was originally written in PHP and then ported to Quarkus. The application itself is a simple product catalog:
4 |
5 | 
6 |
7 | The topology view in OpenShift shows the three tiers of the application:
8 |
9 | 
10 |
11 | ### Running demo locally
12 |
13 | To run the demo locally on your laptop, you will need to have a MySQL or MariaDB database available. You will need to create a product database using the SQL in this repo and then update the quarkus application.properties file to reflect the location of the database.
14 |
15 | The following repos will need to be cloned:
16 |
17 | * [product-catalog-client](https://github.com/gnunn-gitops/product-catalog-client)
18 | * [product-catalog-server](https://github.com/gnunn-gitops/product-catalog-server)
19 |
20 |
21 | To run the quarkus application, execute ```mvn quarkus:dev``` from the root directory.
22 |
23 | To run the client application, go into the client directory and run ```npm run start```.
24 |
25 | ### Install on OpenShift
26 |
27 | This application makes heavy use of Kustomize and ArgoCD to deploy the application in a GitOps manner. I had originally thought to make this demo
28 | consumeable for others but as I've extended it to more and more infrastructure (github/slack/etc) it's becoming challenging. At this point this repo
29 | is more of a reference example then a demo someone else can run.
30 |
31 | If you really want to to deploy this application into your own cluster,
32 | you will need to create a new repo and setup Kustomize overlays that point to this repo. Since Kustomize supports referencing remote resources you do not need
33 | to fork this repo, a new one will suffice.
34 |
35 | This project requires Nexus and SonarQube be available, this project used to deploy them directly but I have opted to move these as a separate deployment so it can be shared amongst multiple projects. To see how I deploy them visit the [dev-tools](https://github.com/gnunn-gitops/dev-tools) repository.
36 |
37 | *Deprecated* In order to make this easier, I had created a [product-catalog-template](https://github.com/gnunn-gitops/product-catalog-template) . It includes detailed instructions with regards to pre-requisities and what needs to be modified to deploy the demo in your own cluster.
38 |
39 | Once deployed in your cluster under ArgoCD it should appear as follows:
40 |
41 | 
42 |
43 | ### Test CI/CD Pipelines
44 |
45 | The demo uses OpenShift Pipelines to build the client and server images for the application. The demo does not install PipelineRun objects via ArgoCD since these objects are transitory and not meant to be managed by a GitOps tool. To load the initial PipelineRun objects, use the following command:
46 |
47 | ```
48 | oc apply -k manifests/tekton/pipelineruns/client/base
49 | oc apply -k manifests/tekton/pipelineruns/server/base
50 | ```
51 |
52 | To test the pipelines are actually taking changes, you can add a logo to the product catalog. The code to do this is commented out and can be found in the [nav.jsx](https://github.com/gnunn1/quarkus-product-catalog/blob/master/client/src/js/components/layouts/nav.jsx#L45) file.
53 |
54 | Once you make the code change, start the client pipeline. Note that in OpenShift Pipelines the GUI does not support creating a new PipelineRunTask with a workspace, if you want to drive it from a GUI go into the PipelineRuns and simple rerun an existing one.
55 |
56 | 
57 |
58 | ### Test Prod Pipeline
59 |
60 | The demo uses a pipeline called ```push-prod-pr``` that creates a pull request in github. When the pull request is merged ArgoCD will see the change in git and automatically deploy the updated image for you. The client and server pipelines can run the push-prod-pr automatically if you set the ```push-to-prod``` parameter to true to have it trigger the pipeline automatically. The default for this parameter is false.
61 |
62 | For the server pipeline the process has been enhanced so that a post-sync hook in ArgoCD will trigger a pipeline to run an integration test after the deployment and send a notification of the status to a slack channel. This process is depicted in the diagram below.
63 |
64 | 
65 |
66 | To execute the pipelines you will need to create pipelinerun objects, base versions are available in ```manifests/tekton/pipelineruns```. A script is also available at ```scripts/apply-pipelineruns.sh``` to load the client and server pipelineruns however you will need to modify the pipelineruns to reflect your cluster and enterprise registry.
67 |
68 | ### Enterprise Registry
69 |
70 | The demo is used and tested primarily with an enterprise registry, in my case I use quay.io. See the [product-catalog-template](https://github.com/gnunn-gitops/product-catalog-template) for more information on this.
71 |
72 | The demo uses the git commit hash to tag the client and server images in the registry, when using quay.io it is highly recommended to deploy the Container Security Operator so that quay vulnerability scans are shown. From a demo perspective, I find showing how older images have more vulnerabilities highlights the benefits of using Red Hat base images.
73 |
74 | ### Monitoring
75 |
76 | A basic monitoring system is installed as part of the demo, as a pre-requisite it requires [monitoring for user-defined projects](https://docs.openshift.com/container-platform/4.6/monitoring/enabling-monitoring-for-user-defined-projects.html) to be enabled in OpenShift.
77 |
78 | This demo deploys grafana into the ```product-catalog-monitor``` namespace along with a simple dashboard for the server application. The dashboard tracks JVM metrics as well as API calls to the server, with no load the API call metrics will be flat and that is normal:
79 |
80 | 
81 |
82 | There's a sample siege script that can be used to drive some load if desired under scripts, you will need to update the script to reflect the endpoints in your cluster.
83 |
84 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/client/base/client-pipeline.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Pipeline
3 | metadata:
4 | name: client
5 | spec:
6 | workspaces:
7 | - name: git-source
8 | - name: gitops-manifests
9 | - name: slack-secret
10 | optional: true
11 | - name: acs-central
12 | optional: true
13 | params:
14 | - name: source_git_revision
15 | type: string
16 | default: master
17 | - name: source_git_url
18 | type: string
19 | default: https://github.com/gnunn-gitops/product-catalog-client
20 | - name: gitops_git_revision
21 | type: string
22 | default: main
23 | - name: gitops_git_url
24 | type: string
25 | default: https://github.com/gnunn-gitops/product-catalog
26 | - name: image_dest_url
27 | type: string
28 | description: External registry location to copy image to
29 | default: quay.io/gnunn/client
30 | - name: cluster
31 | type: string
32 | description: Cluster to push to
33 | default: "local.home"
34 | - name: sonarqube_host
35 | default: sonarqube-dev-tools.apps.hub.ocplab.com
36 | description: Where sonarqube is located to support project scanning
37 | tasks:
38 | - name: acquire-lease
39 | taskRef:
40 | kind: Task
41 | params:
42 | - name: pathInRepo
43 | value: task/acquire-lease/1.0/acquire-lease.yaml
44 | resolver: git
45 | params:
46 | - name: lease-name
47 | value: "$(context.pipeline.name)"
48 | - name: owner
49 | value: "$(context.pipelineRun.name)"
50 | - name: variables
51 | taskRef:
52 | name: variables-from-k8s
53 | runAfter:
54 | - acquire-lease
55 | workspaces:
56 | - name: acs-central
57 | workspace: acs-central
58 | - name: clone
59 | taskRef:
60 | resolver: cluster
61 | params:
62 | - name: kind
63 | value: task
64 | - name: name
65 | value: git-clone
66 | - name: namespace
67 | value: openshift-pipelines
68 | runAfter:
69 | - variables
70 | workspaces:
71 | - name: output
72 | workspace: git-source
73 | params:
74 | - name: URL
75 | value: "$(params.source_git_url)"
76 | - name: REVISION
77 | value: "$(params.source_git_revision)"
78 | - name: DELETE_EXISTING
79 | value: "true"
80 | - name: generate-id
81 | taskRef:
82 | kind: Task
83 | params:
84 | - name: pathInRepo
85 | value: task/generate-build-id/1.0/generate-build-id.yaml
86 | resolver: git
87 | runAfter:
88 | - clone
89 | workspaces:
90 | - name: source
91 | workspace: git-source
92 | - name: build
93 | taskRef:
94 | name: npm
95 | kind: Task
96 | runAfter:
97 | - generate-id
98 | workspaces:
99 | - name: source
100 | workspace: git-source
101 | - name: quality
102 | taskRef:
103 | name: npm-quality
104 | kind: Task
105 | runAfter:
106 | - build
107 | workspaces:
108 | - name: source
109 | workspace: git-source
110 | - name: build-image
111 | taskRef:
112 | name: buildah
113 | kind: Task
114 | workspaces:
115 | - name: source
116 | workspace: git-source
117 | runAfter:
118 | - quality
119 | params:
120 | - name: IMAGE
121 | value: $(params.image_dest_url):latest
122 | - name: DOCKERFILE
123 | value: ./Containerfile
124 | - name: acs-scan-image
125 | taskRef:
126 | kind: Task
127 | params:
128 | - name: pathInRepo
129 | value: task/acs-image-scan/1.0/acs-image-scan.yaml
130 | resolver: git
131 | runAfter:
132 | - build-image
133 | params:
134 | - name: output_format
135 | value: table
136 | - name: image
137 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
138 | when:
139 | - input: "$(workspaces.acs-central.bound)"
140 | operator: in
141 | values: ["true"]
142 | workspaces:
143 | - name: acs-central
144 | workspace: acs-central
145 | - name: acs-check-image
146 | taskRef:
147 | kind: Task
148 | params:
149 | - name: pathInRepo
150 | value: task/acs-image-check/1.0/acs-image-check.yaml
151 | resolver: git
152 | runAfter:
153 | - acs-scan-image
154 | params:
155 | - name: image
156 | value: quay.io/gnunn/client@$(tasks.build-image.results.IMAGE_DIGEST)
157 | when:
158 | - input: "$(workspaces.acs-central.bound)"
159 | operator: in
160 | values: ["true"]
161 | workspaces:
162 | - name: acs-central
163 | workspace: acs-central
164 | - name: notify-on-scan-fail
165 | taskRef:
166 | name: send-to-webhook-slack
167 | kind: Task
168 | runAfter:
169 | - acs-check-image
170 | when:
171 | - input: "$(tasks.acs-check-image.results.check_passed)"
172 | operator: in
173 | values: ["false"]
174 | params:
175 | - name: message
176 | value: |-
177 | *Client Image Scan Failed*
178 | The image scan for client:$(tasks.generate-id.results.tag_id) failed, please view test results here: https://acs_central_host/main/vulnerability-management/images/$(tasks.build-image.results.IMAGE_DIGEST)
179 | workspaces:
180 | - name: slack-secret
181 | workspace: slack-secret
182 | - name: tag-dev-image
183 | taskRef:
184 | name: push-image
185 | kind: Task
186 | runAfter:
187 | - build-image
188 | params:
189 | - name: src_image
190 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
191 | - name: dest_image
192 | value: $(params.image_dest_url)
193 | - name: dest_tags
194 | value: $(tasks.generate-id.results.tag_id),dev
195 | - name: clone-gitops-manifests
196 | taskRef:
197 | resolver: cluster
198 | params:
199 | - name: kind
200 | value: task
201 | - name: name
202 | value: git-clone
203 | - name: namespace
204 | value: openshift-pipelines
205 | runAfter:
206 | - tag-dev-image
207 | workspaces:
208 | - name: output
209 | workspace: gitops-manifests
210 | params:
211 | - name: URL
212 | value: "$(params.gitops_git_url)"
213 | - name: REVISION
214 | value: "$(params.gitops_git_revision)"
215 | - name: DELETE_EXISTING
216 | value: "true"
217 | - name: dev-update-image
218 | taskRef:
219 | name: update-image
220 | runAfter:
221 | - clone-gitops-manifests
222 | params:
223 | - name: git_revision
224 | value: "$(params.gitops_git_revision)"
225 | - name: path
226 | value: clusters/$(params.cluster)/overlays/dev
227 | - name: image
228 | value: "$(params.image_dest_url)"
229 | - name: image_tag
230 | value: $(tasks.generate-id.results.tag_id)
231 | workspaces:
232 | - name: gitops-manifests
233 | workspace: gitops-manifests
234 | - name: dev-gitops-deploy
235 | taskRef:
236 | kind: Task
237 | params:
238 | - name: pathInRepo
239 | value: task/argocd-sync-and-wait/1.0/argocd-sync-and-wait.yaml
240 | resolver: git
241 | runAfter:
242 | - dev-update-image
243 | params:
244 | - name: application_name
245 | value: product-catalog-gitops/product-catalog-dev
246 | - name: revision
247 | value: $(params.gitops_git_revision)
248 | - name: deployment
249 | value: client
250 | - name: namespace
251 | value: product-catalog-dev
252 | - name: image_tag
253 | value: $(tasks.generate-id.results.tag_id)
254 | - name: tag-test-image
255 | taskRef:
256 | name: push-image
257 | kind: Task
258 | runAfter:
259 | - dev-gitops-deploy
260 | params:
261 | - name: src_image
262 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
263 | - name: dest_image
264 | value: $(params.image_dest_url)
265 | - name: dest_tags
266 | value: $(tasks.generate-id.results.tag_id),test,latest
267 | - name: test-update-image
268 | taskRef:
269 | name: update-image
270 | runAfter:
271 | - tag-test-image
272 | params:
273 | - name: git_revision
274 | value: "$(params.gitops_git_revision)"
275 | - name: path
276 | value: clusters/$(params.cluster)/overlays/test
277 | - name: image
278 | value: "$(params.image_dest_url)"
279 | - name: image_tag
280 | value: $(tasks.generate-id.results.tag_id)
281 | workspaces:
282 | - name: gitops-manifests
283 | workspace: gitops-manifests
284 | - name: test-gitops-deploy
285 | taskRef:
286 | kind: Task
287 | params:
288 | - name: pathInRepo
289 | value: task/argocd-sync-and-wait/1.0/argocd-sync-and-wait.yaml
290 | resolver: git
291 | runAfter:
292 | - test-update-image
293 | params:
294 | - name: application_name
295 | value: product-catalog-gitops/product-catalog-test
296 | - name: revision
297 | value: $(params.gitops_git_revision)
298 | - name: deployment
299 | value: client
300 | - name: namespace
301 | value: product-catalog-test
302 | - name: image_tag
303 | value: $(tasks.generate-id.results.tag_id)
304 | - name: notify-build-complete
305 | taskRef:
306 | name: send-to-webhook-slack
307 | kind: Task
308 | runAfter:
309 | - test-gitops-deploy
310 | - notify-on-scan-fail
311 | params:
312 | - name: console_message
313 | value: |-
314 | Client Build $(tasks.generate-id.results.tag_id) Completed
315 |
316 | The build of image $(params.image_dest_url):$(tasks.generate-id.results.tag_id) has been completed
317 |
318 | * Quay Image: https://$(params.image_dest_url):$(tasks.generate-id.results.tag_id)
319 | * ACS Scan: https://$(tasks.variables.results.acs_central_endpoint)/main/vulnerability-management/images/$(tasks.build-image.results.IMAGE_DIGEST)
320 | * SonarQube Results: https://$(params.sonarqube_host)/dashboard?id=product-catalog-client
321 | - name: message_type
322 | value: raw
323 | - name: message
324 | value: |-
325 | {
326 | "blocks": [
327 | {
328 | "type": "header",
329 | "text": {
330 | "type": "plain_text",
331 | "text": "Client Pipeline Complete",
332 | "emoji": true
333 | }
334 | },
335 | {
336 | "type": "section",
337 | "text": {
338 | "type": "mrkdwn",
339 | "text": "Client pipeline for image $(tasks.generate-id.results.tag_id) has completed"
340 | }
341 | },
342 | {
343 | "type": "divider"
344 | },
345 | {
346 | "type": "section",
347 | "text": {
348 | "type": "mrkdwn",
349 | "text": "*Pipeline Results*"
350 | }
351 | },
352 | {
353 | "type": "section",
354 | "text": {
355 | "type": "mrkdwn",
356 | "text": "* <$(params.image_dest_url):$(tasks.generate-id.results.tag_id)|Quay Image>\n* \n* "
357 | }
358 | },
359 | {
360 | "type": "divider"
361 | },
362 | {
363 | "type": "section",
364 | "text": {
365 | "type": "mrkdwn",
366 | "text": "To push this specific release to production, use the button below to create a new pull request to be approved."
367 | }
368 | },
369 | {
370 | "type": "divider"
371 | },
372 | {
373 | "type": "actions",
374 | "elements": [
375 | {
376 | "type": "button",
377 | "text": {
378 | "type": "plain_text",
379 | "text": "Create Release Pull Request",
380 | "emoji": true
381 | },
382 | "value": "client,$(params.image_dest_url),$(tasks.generate-id.results.tag_id),$(params.cluster)",
383 | }
384 | ]
385 | }
386 | ]
387 | }
388 | workspaces:
389 | - name: slack-secret
390 | workspace: slack-secret
391 | finally:
392 | - name: release-lease
393 | taskRef:
394 | kind: Task
395 | params:
396 | - name: pathInRepo
397 | value: task/release-lease/1.0/release-lease.yaml
398 | resolver: git
399 | params:
400 | - name: lease-name
401 | value: "$(context.pipeline.name)"
402 | - name: notify-on-fail
403 | taskRef:
404 | name: send-to-webhook-slack
405 | kind: Task
406 | when:
407 | - input: $(tasks.status)
408 | operator: in
409 | values: ["Failed"]
410 | - input: "$(workspaces.slack-secret.bound)"
411 | operator: in
412 | values: ["true"]
413 | params:
414 | - name: message
415 | value: "Some tasks in the $(context.pipeline.name) have failed in pipelinerun $(context.pipelinerun.name) failed, please investigate"
416 | workspaces:
417 | - name: slack-secret
418 | workspace: slack-secret
419 |
--------------------------------------------------------------------------------
/components/tekton/pipelines/server/base/server-pipeline.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tekton.dev/v1
2 | kind: Pipeline
3 | metadata:
4 | name: server
5 | spec:
6 | workspaces:
7 | - name: git-source
8 | - name: maven-settings
9 | - name: newman-env
10 | - name: gitops-manifests
11 | - name: slack-secret
12 | optional: true
13 | - name: acs-central
14 | optional: true
15 | - name: upload-sbom
16 | optional: true
17 | params:
18 | - name: source_git_revision
19 | type: string
20 | default: master
21 | - name: source_git_url
22 | type: string
23 | default: https://github.com/gnunn-gitops/product-catalog-server
24 | - name: gitops_git_revision
25 | type: string
26 | default: main
27 | - name: gitops_git_url
28 | type: string
29 | default: https://github.com/gnunn-gitops/product-catalog
30 | - name: api_test_collection_url
31 | type: string
32 | default: https://raw.githubusercontent.com/gnunn-gitops/product-catalog-server/master/tests/product-catalog-server-tests.json
33 | - name: MAVEN_MIRROR_URL
34 | default: ""
35 | - name: image_dest_url
36 | type: string
37 | description: External registry location to copy image to
38 | default: quay.io/gnunn/server
39 | - name: cluster
40 | type: string
41 | description: Cluster to push to
42 | default: "local.home"
43 | - name: MAVEN_IMAGE
44 | default: image-registry.openshift-image-registry.svc:5000/openshift/java:openjdk-11-ubi8
45 | - name: sonarqube_host
46 | default: sonarqube-dev-tools.apps.hub.ocplab.com
47 | description: Where sonarqube is located to support project scanning
48 | tasks:
49 | - name: acquire-lease
50 | taskRef:
51 | kind: Task
52 | params:
53 | - name: pathInRepo
54 | value: task/acquire-lease/1.0/acquire-lease.yaml
55 | resolver: git
56 | params:
57 | - name: lease-name
58 | value: "$(context.pipeline.name)"
59 | - name: owner
60 | value: "$(context.pipelineRun.name)"
61 | - name: variables
62 | taskRef:
63 | name: variables-from-k8s
64 | runAfter:
65 | - acquire-lease
66 | workspaces:
67 | - name: acs-central
68 | workspace: acs-central
69 | - name: clone
70 | taskRef:
71 | resolver: cluster
72 | params:
73 | - name: kind
74 | value: task
75 | - name: name
76 | value: git-clone
77 | - name: namespace
78 | value: openshift-pipelines
79 | runAfter:
80 | - variables
81 | workspaces:
82 | - name: output
83 | workspace: git-source
84 | params:
85 | - name: URL
86 | value: "$(params.source_git_url)"
87 | - name: REVISION
88 | value: "$(params.source_git_revision)"
89 | - name: DELETE_EXISTING
90 | value: "true"
91 | - name: generate-id
92 | taskRef:
93 | kind: Task
94 | params:
95 | - name: pathInRepo
96 | value: task/generate-build-id/1.0/generate-build-id.yaml
97 | resolver: git
98 | runAfter:
99 | - clone
100 | workspaces:
101 | - name: source
102 | workspace: git-source
103 | - name: build
104 | taskRef:
105 | name: maven
106 | kind: Task
107 | workspaces:
108 | - name: source
109 | workspace: git-source
110 | - name: maven-settings
111 | workspace: maven-settings
112 | runAfter:
113 | - generate-id
114 | params:
115 | - name: MAVEN_IMAGE
116 | value: $(params.MAVEN_IMAGE)
117 | - name: MAVEN_MIRROR_URL
118 | value: "$(params.MAVEN_MIRROR_URL)"
119 | - name: MAVEN_REPO_CONFIG_SECRET
120 | value: "maven-repo-creds"
121 | - name: GOALS
122 | value:
123 | - "package"
124 | - "deploy"
125 | - name: quality
126 | taskRef:
127 | name: maven
128 | kind: Task
129 | workspaces:
130 | - name: source
131 | workspace: git-source
132 | - name: maven-settings
133 | workspace: maven-settings
134 | runAfter:
135 | - build
136 | params:
137 | - name: MAVEN_IMAGE
138 | value: $(params.MAVEN_IMAGE)
139 | - name: MAVEN_MIRROR_URL
140 | value: "$(params.MAVEN_MIRROR_URL)"
141 | - name: MAVEN_REPO_CONFIG_SECRET
142 | value: "maven-repo-creds"
143 | - name: GOALS
144 | value:
145 | - "sonar:sonar"
146 | - "-Pquality"
147 | - name: build-image
148 | taskRef:
149 | name: buildah
150 | kind: Task
151 | workspaces:
152 | - name: source
153 | workspace: git-source
154 | runAfter:
155 | - quality
156 | params:
157 | - name: IMAGE
158 | value: $(params.image_dest_url):latest
159 | - name: DOCKERFILE
160 | value: ./Containerfile
161 | - name: tag-dev-image
162 | taskRef:
163 | name: push-image
164 | kind: Task
165 | runAfter:
166 | - verify-signature
167 | params:
168 | - name: src_image
169 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
170 | - name: dest_image
171 | value: $(params.image_dest_url)
172 | - name: dest_tags
173 | value: "$(tasks.generate-id.results.tag_id),dev"
174 | - name: verify-signature
175 | taskRef:
176 | kind: Task
177 | params:
178 | - name: pathInRepo
179 | value: task/verify-signature/1.0/verify-signature.yaml
180 | resolver: git
181 | runAfter:
182 | - build-image
183 | params:
184 | - name: tuf_url
185 | value: https://tuf-trusted-artifact-signer.apps.hub.ocplab.com
186 | - name: oidc_issuer_url
187 | value: https://sso.ocplab.com/realms/ocplab
188 | - name: fulcio_url
189 | value: https://fulcio-server-trusted-artifact-signer.apps.hub.ocplab.com
190 | - name: rekor_url
191 | value: https://rekor-server-trusted-artifact-signer.apps.hub.ocplab.com
192 | - name: certificate_identity
193 | value: tekton-builder@rhdp.com
194 | - name: image_url
195 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
196 | - name: acs-scan-image
197 | taskRef:
198 | kind: Task
199 | params:
200 | - name: pathInRepo
201 | value: task/acs-image-scan/1.0/acs-image-scan.yaml
202 | resolver: git
203 | runAfter:
204 | - verify-signature
205 | params:
206 | - name: output_format
207 | value: table
208 | - name: image
209 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
210 | when:
211 | - input: "$(workspaces.acs-central.bound)"
212 | operator: in
213 | values: ["true"]
214 | workspaces:
215 | - name: acs-central
216 | workspace: acs-central
217 | - name: acs-check-image
218 | taskRef:
219 | kind: Task
220 | params:
221 | - name: pathInRepo
222 | value: task/acs-image-check/1.0/acs-image-check.yaml
223 | resolver: git
224 | runAfter:
225 | - acs-scan-image
226 | params:
227 | - name: image
228 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
229 | when:
230 | - input: "$(workspaces.acs-central.bound)"
231 | operator: in
232 | values: ["true"]
233 | workspaces:
234 | - name: acs-central
235 | workspace: acs-central
236 | - name: generate-sbom
237 | taskRef:
238 | kind: Task
239 | params:
240 | - name: pathInRepo
241 | value: task/acs-image-sbom/1.0/acs-image-sbom.yaml
242 | resolver: git
243 | runAfter:
244 | - acs-check-image
245 | params:
246 | - name: image
247 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
248 | - name: cyclonedxHostUrl
249 | value: https://server.apps.hub.ocplab.com
250 | when:
251 | - input: "$(workspaces.acs-central.bound)"
252 | operator: in
253 | values: ["true"]
254 | workspaces:
255 | - name: acs-central
256 | workspace: acs-central
257 | - name: upload-sbom
258 | workspace: upload-sbom
259 | - name: notify-on-scan-fail
260 | taskRef:
261 | name: send-to-webhook-slack
262 | kind: Task
263 | runAfter:
264 | - generate-sbom
265 | when:
266 | - input: "$(tasks.acs-check-image.results.check_passed)"
267 | operator: in
268 | values: ["false"]
269 | params:
270 | - name: message
271 | value: |-
272 | *Server Image Scan Failed*
273 | The image scan for server:$(tasks.generate-id.results.tag_id) failed, please view test results here: https://$(tasks.variables.results.acs_central_endpoint)/main/vulnerability-management/images/$(tasks.build-image.results.IMAGE_DIGEST)
274 | workspaces:
275 | - name: slack-secret
276 | workspace: slack-secret
277 | - name: clone-gitops-manifests
278 | taskRef:
279 | resolver: cluster
280 | params:
281 | - name: kind
282 | value: task
283 | - name: name
284 | value: git-clone
285 | - name: namespace
286 | value: openshift-pipelines
287 | runAfter:
288 | - tag-dev-image
289 | workspaces:
290 | - name: output
291 | workspace: gitops-manifests
292 | params:
293 | - name: URL
294 | value: "$(params.gitops_git_url)"
295 | - name: REVISION
296 | value: "$(params.gitops_git_revision)"
297 | - name: DELETE_EXISTING
298 | value: "true"
299 | - name: dev-update-image
300 | taskRef:
301 | name: update-image
302 | runAfter:
303 | - clone-gitops-manifests
304 | params:
305 | - name: url
306 | value: "$(params.gitops_git_url)"
307 | - name: git_revision
308 | value: "$(params.gitops_git_revision)"
309 | - name: path
310 | value: clusters/$(params.cluster)/overlays/dev
311 | - name: image
312 | value: "$(params.image_dest_url)"
313 | - name: image_tag
314 | value: "$(tasks.generate-id.results.tag_id)"
315 | workspaces:
316 | - name: gitops-manifests
317 | workspace: gitops-manifests
318 | - name: dev-gitops-deploy
319 | taskRef:
320 | kind: Task
321 | params:
322 | - name: pathInRepo
323 | value: task/argocd-sync-and-wait/1.0/argocd-sync-and-wait.yaml
324 | resolver: git
325 | runAfter:
326 | - dev-update-image
327 | params:
328 | - name: application_name
329 | value: product-catalog-gitops/product-catalog-dev
330 | - name: revision
331 | value: $(params.gitops_git_revision)
332 | - name: deployment
333 | value: server
334 | - name: namespace
335 | value: product-catalog-dev
336 | - name: image_tag
337 | value: "$(tasks.generate-id.results.tag_id)"
338 | - name: dev-test
339 | taskRef:
340 | name: newman
341 | kind: Task
342 | runAfter:
343 | - dev-gitops-deploy
344 | params:
345 | - name: COLLECTION
346 | value: $(params.api_test_collection_url)
347 | - name: ENVIRONMENT
348 | value: newman-dev-env.json
349 | workspaces:
350 | - name: newman-env
351 | workspace: newman-env
352 | - name: tag-test-image
353 | taskRef:
354 | name: push-image
355 | kind: Task
356 | runAfter:
357 | - dev-test
358 | params:
359 | - name: src_image
360 | value: $(params.image_dest_url)@$(tasks.build-image.results.IMAGE_DIGEST)
361 | - name: dest_image
362 | value: $(params.image_dest_url)
363 | - name: dest_tags
364 | value: test
365 | - name: test-update-image
366 | taskRef:
367 | name: update-image
368 | runAfter:
369 | - tag-test-image
370 | params:
371 | - name: git_revision
372 | value: "$(params.gitops_git_revision)"
373 | - name: path
374 | value: clusters/$(params.cluster)/overlays/test
375 | - name: image
376 | value: "$(params.image_dest_url)"
377 | - name: image_tag
378 | value: "$(tasks.generate-id.results.tag_id)"
379 | workspaces:
380 | - name: gitops-manifests
381 | workspace: gitops-manifests
382 | - name: test-gitops-deploy
383 | taskRef:
384 | kind: Task
385 | params:
386 | - name: pathInRepo
387 | value: task/argocd-sync-and-wait/1.0/argocd-sync-and-wait.yaml
388 | resolver: git
389 | runAfter:
390 | - test-update-image
391 | params:
392 | - name: application_name
393 | value: product-catalog-gitops/product-catalog-test
394 | - name: revision
395 | value: $(params.gitops_git_revision)
396 | - name: deployment
397 | value: server
398 | - name: namespace
399 | value: product-catalog-test
400 | - name: image_tag
401 | value: "$(tasks.generate-id.results.tag_id)"
402 | - name: test-test
403 | taskRef:
404 | name: newman
405 | kind: Task
406 | runAfter:
407 | - test-gitops-deploy
408 | params:
409 | - name: COLLECTION
410 | value: $(params.api_test_collection_url)
411 | - name: ENVIRONMENT
412 | value: newman-test-env.json
413 | workspaces:
414 | - name: newman-env
415 | workspace: newman-env
416 | - name: notify-build-complete
417 | taskRef:
418 | name: send-to-webhook-slack
419 | kind: Task
420 | runAfter:
421 | - test-test
422 | - notify-on-scan-fail
423 | params:
424 | - name: console_message
425 | value: |-
426 | Server Build $(tasks.generate-id.results.tag_id) Completed
427 |
428 | The build of image $(params.image_dest_url):$(tasks.generate-id.results.tag_id) has been completed
429 |
430 | * Quay Image: https://$(params.image_dest_url):$(tasks.generate-id.results.tag_id)
431 | * ACS Scan: https://$(tasks.variables.results.acs_central_endpoint)/main/vulnerability-management/images/$(tasks.build-image.results.IMAGE_DIGEST)
432 | * SonarQube Results: https://$(params.sonarqube_host)/dashboard?id=product-catalog-server
433 | - name: message_type
434 | value: raw
435 | - name: message
436 | value: |-
437 | {
438 | "blocks": [
439 | {
440 | "type": "header",
441 | "text": {
442 | "type": "plain_text",
443 | "text": "Server Pipeline Complete",
444 | "emoji": true
445 | }
446 | },
447 | {
448 | "type": "section",
449 | "text": {
450 | "type": "mrkdwn",
451 | "text": "Server pipeline for image $(tasks.generate-id.results.tag_id) has completed"
452 | }
453 | },
454 | {
455 | "type": "divider"
456 | },
457 | {
458 | "type": "section",
459 | "text": {
460 | "type": "mrkdwn",
461 | "text": "*Pipeline Results*"
462 | }
463 | },
464 | {
465 | "type": "section",
466 | "text": {
467 | "type": "mrkdwn",
468 | "text": "* \n* \n* "
469 | }
470 | },
471 | {
472 | "type": "divider"
473 | },
474 | {
475 | "type": "section",
476 | "text": {
477 | "type": "mrkdwn",
478 | "text": "To push this specific release to production, use the button below to create a new pull request to be approved."
479 | }
480 | },
481 | {
482 | "type": "divider"
483 | },
484 | {
485 | "type": "actions",
486 | "elements": [
487 | {
488 | "type": "button",
489 | "text": {
490 | "type": "plain_text",
491 | "text": "Create Release Pull Request :repeat:",
492 | "emoji": true
493 | },
494 | "url": "https://slack-message-handler-product-catalog-cicd.${SUB_DOMAIN}/releaseApp?application=server&cluster=$(params.cluster)&image=$(params.image_dest_url)&tag=$(tasks.generate-id.results.tag_id)"
495 | }
496 | ]
497 | }
498 | ]
499 | }
500 | workspaces:
501 | - name: slack-secret
502 | workspace: slack-secret
503 | finally:
504 | - name: release-lease
505 | taskRef:
506 | kind: Task
507 | params:
508 | - name: pathInRepo
509 | value: task/release-lease/1.0/release-lease.yaml
510 | resolver: git
511 | params:
512 | - name: lease-name
513 | value: "$(context.pipeline.name)"
514 | - name: notify-on-fail
515 | taskRef:
516 | name: send-to-webhook-slack
517 | kind: Task
518 | when:
519 | - input: $(tasks.status)
520 | operator: in
521 | values: ["Failed"]
522 | - input: "$(workspaces.slack-secret.bound)"
523 | operator: in
524 | values: ["true"]
525 | params:
526 | - name: message
527 | value: "Some tasks in the $(context.pipeline.name) have failed in pipelinerun $(context.pipelinerun.name) failed, please investigate"
528 | workspaces:
529 | - name: slack-secret
530 | workspace: slack-secret
531 |
--------------------------------------------------------------------------------
/docs/swagger/swagger-2.0.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger": "2.0",
3 | "info": {
4 | "contact": {
5 | "email": "techsupport@demo.com",
6 | "name": "Product Catalog API Support",
7 | "url": "http://demo.com/contact"
8 | },
9 | "license": {
10 | "name": "Apache 2.0",
11 | "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
12 | },
13 | "title": "Product Catalog API",
14 | "version": "1.0.0"
15 | },
16 | "paths": {
17 | "/api/auth": {
18 | "post": {
19 | "produces": [
20 | "application/json"
21 | ],
22 | "parameters": [],
23 | "responses": {
24 | "200": {
25 | "description": "OK",
26 | "schema": {
27 | "$ref": "#/definitions/LoginResult"
28 | }
29 | }
30 | },
31 | "tags": [
32 | "Authentication"
33 | ],
34 | "description": "Authenticate a user",
35 | "summary": "Login"
36 | }
37 | },
38 | "/api/auth/register": {
39 | "post": {
40 | "consumes": [
41 | "application/x-www-form-urlencoded"
42 | ],
43 | "parameters": [
44 | {
45 | "in": "formData",
46 | "name": "email",
47 | "type": "string"
48 | },
49 | {
50 | "in": "formData",
51 | "name": "password",
52 | "type": "string"
53 | },
54 | {
55 | "in": "formData",
56 | "name": "password_confirmation",
57 | "type": "string"
58 | }
59 | ],
60 | "responses": {
61 | "200": {
62 | "description": "OK"
63 | }
64 | },
65 | "tags": [
66 | "Authentication"
67 | ],
68 | "description": "Register a new user",
69 | "summary": "Register"
70 | }
71 | },
72 | "/api/auth/user": {
73 | "get": {
74 | "produces": [
75 | "application/json"
76 | ],
77 | "parameters": [],
78 | "responses": {
79 | "200": {
80 | "description": "OK",
81 | "schema": {
82 | "$ref": "#/definitions/User"
83 | }
84 | }
85 | },
86 | "tags": [
87 | "Authentication"
88 | ],
89 | "description": "Get the current user",
90 | "summary": "Get user"
91 | }
92 | },
93 | "/api/category": {
94 | "get": {
95 | "produces": [
96 | "application/json"
97 | ],
98 | "parameters": [],
99 | "responses": {
100 | "200": {
101 | "description": "OK",
102 | "schema": {
103 | "items": {
104 | "$ref": "#/definitions/Category"
105 | },
106 | "type": "array"
107 | }
108 | }
109 | },
110 | "tags": [
111 | "Categories"
112 | ]
113 | },
114 | "post": {
115 | "consumes": [
116 | "application/json"
117 | ],
118 | "parameters": [
119 | {
120 | "in": "body",
121 | "name": "body",
122 | "schema": {
123 | "$ref": "#/definitions/Category"
124 | }
125 | }
126 | ],
127 | "responses": {
128 | "200": {
129 | "description": "OK"
130 | }
131 | },
132 | "tags": [
133 | "Categories"
134 | ],
135 | "description": "Create a new category",
136 | "summary": "Create category"
137 | }
138 | },
139 | "/api/category/{id}": {
140 | "delete": {
141 | "parameters": [
142 | {
143 | "format": "int32",
144 | "in": "path",
145 | "name": "id",
146 | "required": true,
147 | "type": "integer"
148 | }
149 | ],
150 | "responses": {
151 | "200": {
152 | "description": "OK"
153 | }
154 | },
155 | "tags": [
156 | "Categories"
157 | ],
158 | "description": "Delete a category",
159 | "summary": "Delete category"
160 | },
161 | "get": {
162 | "produces": [
163 | "application/json"
164 | ],
165 | "parameters": [
166 | {
167 | "format": "int32",
168 | "in": "path",
169 | "name": "id",
170 | "required": true,
171 | "type": "integer"
172 | }
173 | ],
174 | "responses": {
175 | "200": {
176 | "description": "OK",
177 | "schema": {
178 | "$ref": "#/definitions/Category"
179 | }
180 | }
181 | },
182 | "tags": [
183 | "Categories"
184 | ],
185 | "description": "Get specific category by ID",
186 | "summary": "Get category"
187 | },
188 | "put": {
189 | "consumes": [
190 | "application/json"
191 | ],
192 | "produces": [
193 | "application/json"
194 | ],
195 | "parameters": [
196 | {
197 | "format": "int32",
198 | "in": "path",
199 | "name": "id",
200 | "required": true,
201 | "type": "integer"
202 | },
203 | {
204 | "in": "body",
205 | "name": "body",
206 | "schema": {
207 | "$ref": "#/definitions/Category"
208 | }
209 | }
210 | ],
211 | "responses": {
212 | "200": {
213 | "description": "OK",
214 | "schema": {
215 | "$ref": "#/definitions/Category"
216 | }
217 | }
218 | },
219 | "tags": [
220 | "Categories"
221 | ],
222 | "description": "Update an existing category",
223 | "summary": "Update category"
224 | }
225 | },
226 | "/api/product": {
227 | "get": {
228 | "produces": [
229 | "application/json"
230 | ],
231 | "parameters": [
232 | {
233 | "default": "0",
234 | "format": "int32",
235 | "in": "query",
236 | "name": "item_per_page",
237 | "type": "integer"
238 | },
239 | {
240 | "default": "",
241 | "in": "query",
242 | "name": "name",
243 | "type": "string"
244 | },
245 | {
246 | "default": "name",
247 | "in": "query",
248 | "name": "order_by",
249 | "type": "string"
250 | },
251 | {
252 | "default": "asc",
253 | "in": "query",
254 | "name": "order_type",
255 | "type": "string"
256 | },
257 | {
258 | "default": "0",
259 | "format": "int32",
260 | "in": "query",
261 | "name": "page",
262 | "type": "integer"
263 | }
264 | ],
265 | "responses": {
266 | "200": {
267 | "description": "OK",
268 | "schema": {
269 | "items": {
270 | "$ref": "#/definitions/Product"
271 | },
272 | "type": "array"
273 | }
274 | }
275 | },
276 | "tags": [
277 | "Products"
278 | ],
279 | "description": "Get product list with support for paging and ordering",
280 | "summary": "Get product list"
281 | },
282 | "post": {
283 | "consumes": [
284 | "application/x-www-form-urlencoded"
285 | ],
286 | "produces": [
287 | "application/json"
288 | ],
289 | "parameters": [
290 | {
291 | "in": "formData",
292 | "name": "name",
293 | "type": "string"
294 | },
295 | {
296 | "in": "formData",
297 | "name": "description",
298 | "type": "string"
299 | },
300 | {
301 | "format": "int32",
302 | "in": "formData",
303 | "name": "category_id",
304 | "type": "integer"
305 | },
306 | {
307 | "format": "double",
308 | "in": "formData",
309 | "name": "price",
310 | "type": "number"
311 | }
312 | ],
313 | "responses": {
314 | "200": {
315 | "description": "OK",
316 | "schema": {
317 | "$ref": "#/definitions/ProductResult"
318 | }
319 | }
320 | },
321 | "tags": [
322 | "Products"
323 | ],
324 | "description": "Create a new product",
325 | "summary": "Create product"
326 | }
327 | },
328 | "/api/product/count": {
329 | "get": {
330 | "parameters": [],
331 | "responses": {
332 | "200": {
333 | "description": "OK"
334 | }
335 | },
336 | "tags": [
337 | "Products"
338 | ],
339 | "description": "Get the total count of products available",
340 | "summary": "Get product count"
341 | }
342 | },
343 | "/api/product/delete": {
344 | "post": {
345 | "consumes": [
346 | "application/x-www-form-urlencoded"
347 | ],
348 | "parameters": [
349 | {
350 | "in": "formData",
351 | "name": "del_ids[]"
352 | }
353 | ],
354 | "responses": {
355 | "200": {
356 | "description": "OK"
357 | }
358 | },
359 | "tags": [
360 | "Products"
361 | ],
362 | "description": "Delete a set of products as specified by their IDs",
363 | "summary": "Delete a set of products"
364 | }
365 | },
366 | "/api/product/{id}": {
367 | "delete": {
368 | "parameters": [
369 | {
370 | "format": "int32",
371 | "in": "path",
372 | "name": "id",
373 | "required": true,
374 | "type": "integer"
375 | }
376 | ],
377 | "responses": {
378 | "200": {
379 | "description": "OK"
380 | }
381 | },
382 | "tags": [
383 | "Products"
384 | ],
385 | "description": "Delete a single product by ID",
386 | "summary": "Delete product"
387 | },
388 | "get": {
389 | "produces": [
390 | "application/json"
391 | ],
392 | "parameters": [
393 | {
394 | "format": "int32",
395 | "in": "path",
396 | "name": "id",
397 | "required": true,
398 | "type": "integer"
399 | }
400 | ],
401 | "responses": {
402 | "200": {
403 | "description": "OK",
404 | "schema": {
405 | "$ref": "#/definitions/Product"
406 | }
407 | }
408 | },
409 | "tags": [
410 | "Products"
411 | ],
412 | "description": "Get specific product by it's ID",
413 | "summary": "Get product by ID"
414 | },
415 | "put": {
416 | "consumes": [
417 | "application/x-www-form-urlencoded"
418 | ],
419 | "produces": [
420 | "application/json"
421 | ],
422 | "parameters": [
423 | {
424 | "format": "int32",
425 | "in": "path",
426 | "name": "id",
427 | "required": true,
428 | "type": "integer"
429 | },
430 | {
431 | "format": "int32",
432 | "in": "formData",
433 | "name": "id",
434 | "type": "integer"
435 | },
436 | {
437 | "in": "formData",
438 | "name": "name",
439 | "type": "string"
440 | },
441 | {
442 | "in": "formData",
443 | "name": "description",
444 | "type": "string"
445 | },
446 | {
447 | "format": "int32",
448 | "in": "formData",
449 | "name": "category_id",
450 | "type": "integer"
451 | },
452 | {
453 | "format": "double",
454 | "in": "formData",
455 | "name": "price",
456 | "type": "number"
457 | }
458 | ],
459 | "responses": {
460 | "200": {
461 | "description": "OK",
462 | "schema": {
463 | "$ref": "#/definitions/ProductResult"
464 | }
465 | }
466 | },
467 | "tags": [
468 | "Products"
469 | ],
470 | "description": "Update an existing product",
471 | "summary": "Update product"
472 | }
473 | },
474 | "/api/user": {
475 | "post": {
476 | "consumes": [
477 | "application/json"
478 | ],
479 | "parameters": [
480 | {
481 | "in": "body",
482 | "name": "body",
483 | "schema": {
484 | "$ref": "#/definitions/User"
485 | }
486 | }
487 | ],
488 | "responses": {
489 | "200": {
490 | "description": "OK"
491 | }
492 | },
493 | "tags": [
494 | "Users"
495 | ],
496 | "description": "Create a new user",
497 | "summary": "Create user"
498 | }
499 | },
500 | "/api/user/{id}": {
501 | "delete": {
502 | "parameters": [
503 | {
504 | "format": "int32",
505 | "in": "path",
506 | "name": "id",
507 | "required": true,
508 | "type": "integer"
509 | }
510 | ],
511 | "responses": {
512 | "200": {
513 | "description": "OK"
514 | }
515 | },
516 | "tags": [
517 | "Users"
518 | ],
519 | "description": "Delete a user",
520 | "summary": "Delete user"
521 | },
522 | "get": {
523 | "produces": [
524 | "application/json"
525 | ],
526 | "parameters": [
527 | {
528 | "format": "int32",
529 | "in": "path",
530 | "name": "id",
531 | "required": true,
532 | "type": "integer"
533 | }
534 | ],
535 | "responses": {
536 | "200": {
537 | "description": "OK",
538 | "schema": {
539 | "$ref": "#/definitions/User"
540 | }
541 | }
542 | },
543 | "tags": [
544 | "Users"
545 | ],
546 | "description": "Get specific user by it's ID",
547 | "summary": "Get user by ID"
548 | },
549 | "put": {
550 | "consumes": [
551 | "application/json"
552 | ],
553 | "produces": [
554 | "application/json"
555 | ],
556 | "parameters": [
557 | {
558 | "format": "int32",
559 | "in": "path",
560 | "name": "id",
561 | "required": true,
562 | "type": "integer"
563 | },
564 | {
565 | "in": "body",
566 | "name": "body",
567 | "schema": {
568 | "$ref": "#/definitions/User"
569 | }
570 | }
571 | ],
572 | "responses": {
573 | "200": {
574 | "description": "OK",
575 | "schema": {
576 | "$ref": "#/definitions/User"
577 | }
578 | }
579 | },
580 | "tags": [
581 | "Users"
582 | ],
583 | "description": "Update an existing user",
584 | "summary": "Update user"
585 | }
586 | }
587 | },
588 | "definitions": {
589 | "AuthResource": {
590 | "type": "object"
591 | },
592 | "Category": {
593 | "properties": {
594 | "created": {
595 | "$ref": "#/definitions/Date1"
596 | },
597 | "description": {
598 | "type": "string"
599 | },
600 | "id": {
601 | "format": "int32",
602 | "nullable": false,
603 | "type": "integer"
604 | },
605 | "modified": {
606 | "$ref": "#/definitions/LocalDateTime"
607 | },
608 | "name": {
609 | "nullable": false,
610 | "type": "string"
611 | }
612 | },
613 | "required": [
614 | "id",
615 | "name"
616 | ],
617 | "type": "object"
618 | },
619 | "Date": {
620 | "format": "date",
621 | "type": "string"
622 | },
623 | "Date1": {
624 | "format": "date",
625 | "type": "string"
626 | },
627 | "EntityTag": {
628 | "properties": {
629 | "value": {
630 | "type": "string"
631 | },
632 | "weak": {
633 | "type": "boolean"
634 | }
635 | },
636 | "type": "object"
637 | },
638 | "Family": {
639 | "enum": [
640 | "CLIENT_ERROR",
641 | "INFORMATIONAL",
642 | "OTHER",
643 | "REDIRECTION",
644 | "SERVER_ERROR",
645 | "SUCCESSFUL"
646 | ],
647 | "type": "string"
648 | },
649 | "Link": {
650 | "properties": {
651 | "params": {
652 | "$ref": "#/definitions/MapStringString"
653 | },
654 | "rel": {
655 | "type": "string"
656 | },
657 | "rels": {
658 | "$ref": "#/definitions/ListString"
659 | },
660 | "title": {
661 | "type": "string"
662 | },
663 | "type": {
664 | "type": "string"
665 | },
666 | "uri": {
667 | "$ref": "#/definitions/URI"
668 | },
669 | "uriBuilder": {
670 | "$ref": "#/definitions/UriBuilder"
671 | }
672 | },
673 | "type": "object"
674 | },
675 | "ListInteger": {
676 | "$ref": "#/definitions/ListInteger"
677 | },
678 | "ListString": {
679 | "items": {
680 | "type": "string"
681 | },
682 | "type": "array"
683 | },
684 | "LocalDateTime": {
685 | "format": "date-time",
686 | "type": "string"
687 | },
688 | "Locale": {
689 | "properties": {
690 | "country": {
691 | "type": "string"
692 | },
693 | "displayCountry": {
694 | "type": "string"
695 | },
696 | "displayLanguage": {
697 | "type": "string"
698 | },
699 | "displayName": {
700 | "type": "string"
701 | },
702 | "displayScript": {
703 | "type": "string"
704 | },
705 | "displayVariant": {
706 | "type": "string"
707 | },
708 | "extensionKeys": {
709 | "$ref": "#/definitions/SetCharacter"
710 | },
711 | "iSO3Country": {
712 | "type": "string"
713 | },
714 | "iSO3Language": {
715 | "type": "string"
716 | },
717 | "language": {
718 | "type": "string"
719 | },
720 | "script": {
721 | "type": "string"
722 | },
723 | "unicodeLocaleAttributes": {
724 | "$ref": "#/definitions/SetString"
725 | },
726 | "unicodeLocaleKeys": {
727 | "$ref": "#/definitions/SetString"
728 | },
729 | "variant": {
730 | "type": "string"
731 | }
732 | },
733 | "type": "object"
734 | },
735 | "LoginResult": {
736 | "properties": {
737 | "message": {
738 | "type": "string"
739 | },
740 | "this$0": {
741 | "$ref": "#/definitions/AuthResource"
742 | },
743 | "user": {
744 | "$ref": "#/definitions/SecureUser"
745 | }
746 | },
747 | "type": "object"
748 | },
749 | "MapStringNewCookie": {
750 | "additionalProperties": {
751 | "$ref": "#/definitions/NewCookie"
752 | },
753 | "type": "object"
754 | },
755 | "MapStringString": {
756 | "additionalProperties": {
757 | "type": "string"
758 | },
759 | "type": "object"
760 | },
761 | "MediaType": {
762 | "properties": {
763 | "parameters": {
764 | "$ref": "#/definitions/MapStringString"
765 | },
766 | "subtype": {
767 | "type": "string"
768 | },
769 | "type": {
770 | "type": "string"
771 | },
772 | "wildcardSubtype": {
773 | "type": "boolean"
774 | },
775 | "wildcardType": {
776 | "type": "boolean"
777 | }
778 | },
779 | "type": "object"
780 | },
781 | "MultivaluedMapStringObject": {
782 | "additionalProperties": {},
783 | "type": "object"
784 | },
785 | "MultivaluedMapStringString": {
786 | "additionalProperties": {
787 | "type": "string"
788 | },
789 | "type": "object"
790 | },
791 | "NewCookie": {
792 | "properties": {
793 | "comment": {
794 | "type": "string"
795 | },
796 | "domain": {
797 | "type": "string"
798 | },
799 | "expiry": {
800 | "$ref": "#/definitions/Date"
801 | },
802 | "httpOnly": {
803 | "type": "boolean"
804 | },
805 | "maxAge": {
806 | "format": "int32",
807 | "type": "integer"
808 | },
809 | "name": {
810 | "type": "string"
811 | },
812 | "path": {
813 | "type": "string"
814 | },
815 | "secure": {
816 | "type": "boolean"
817 | },
818 | "value": {
819 | "type": "string"
820 | },
821 | "version": {
822 | "format": "int32",
823 | "type": "integer"
824 | }
825 | },
826 | "type": "object"
827 | },
828 | "Product": {
829 | "properties": {
830 | "category": {
831 | "allOf": [
832 | {
833 | "$ref": "#/definitions/Category"
834 | },
835 | {
836 | "nullable": false
837 | }
838 | ]
839 | },
840 | "created": {
841 | "$ref": "#/definitions/Date1"
842 | },
843 | "description": {
844 | "type": "string"
845 | },
846 | "id": {
847 | "format": "int32",
848 | "type": "integer"
849 | },
850 | "modified": {
851 | "$ref": "#/definitions/LocalDateTime"
852 | },
853 | "name": {
854 | "nullable": false,
855 | "type": "string"
856 | },
857 | "price": {
858 | "format": "double",
859 | "nullable": false,
860 | "type": "number"
861 | }
862 | },
863 | "required": [
864 | "category",
865 | "name",
866 | "price"
867 | ],
868 | "type": "object"
869 | },
870 | "ProductResource": {
871 | "properties": {
872 | "count": {
873 | "$ref": "#/definitions/Response"
874 | }
875 | },
876 | "type": "object"
877 | },
878 | "ProductResult": {
879 | "properties": {
880 | "message": {
881 | "type": "string"
882 | },
883 | "product": {
884 | "$ref": "#/definitions/Product"
885 | },
886 | "success": {
887 | "type": "boolean"
888 | },
889 | "this$0": {
890 | "$ref": "#/definitions/ProductResource"
891 | }
892 | },
893 | "type": "object"
894 | },
895 | "Response": {
896 | "properties": {
897 | "allowedMethods": {
898 | "$ref": "#/definitions/SetString"
899 | },
900 | "cookies": {
901 | "$ref": "#/definitions/MapStringNewCookie"
902 | },
903 | "date": {
904 | "$ref": "#/definitions/Date"
905 | },
906 | "entity": {
907 | "type": "object"
908 | },
909 | "entityTag": {
910 | "$ref": "#/definitions/EntityTag"
911 | },
912 | "headers": {
913 | "$ref": "#/definitions/MultivaluedMapStringObject"
914 | },
915 | "language": {
916 | "$ref": "#/definitions/Locale"
917 | },
918 | "lastModified": {
919 | "$ref": "#/definitions/Date"
920 | },
921 | "length": {
922 | "format": "int32",
923 | "type": "integer"
924 | },
925 | "links": {
926 | "$ref": "#/definitions/SetLink"
927 | },
928 | "location": {
929 | "$ref": "#/definitions/URI"
930 | },
931 | "mediaType": {
932 | "$ref": "#/definitions/MediaType"
933 | },
934 | "metadata": {
935 | "$ref": "#/definitions/MultivaluedMapStringObject"
936 | },
937 | "status": {
938 | "format": "int32",
939 | "type": "integer"
940 | },
941 | "statusInfo": {
942 | "$ref": "#/definitions/StatusType"
943 | },
944 | "stringHeaders": {
945 | "$ref": "#/definitions/MultivaluedMapStringString"
946 | }
947 | },
948 | "type": "object"
949 | },
950 | "SecureUser": {
951 | "properties": {
952 | "createdAt": {
953 | "$ref": "#/definitions/LocalDateTime"
954 | },
955 | "email": {
956 | "type": "string"
957 | },
958 | "this$0": {
959 | "$ref": "#/definitions/AuthResource"
960 | }
961 | },
962 | "type": "object"
963 | },
964 | "SetCharacter": {
965 | "items": {
966 | "format": "byte",
967 | "type": "string"
968 | },
969 | "type": "array"
970 | },
971 | "SetLink": {
972 | "items": {
973 | "$ref": "#/definitions/Link"
974 | },
975 | "type": "array"
976 | },
977 | "SetString": {
978 | "items": {
979 | "type": "string"
980 | },
981 | "type": "array"
982 | },
983 | "StatusType": {
984 | "properties": {
985 | "family": {
986 | "$ref": "#/definitions/Family"
987 | },
988 | "reasonPhrase": {
989 | "type": "string"
990 | },
991 | "statusCode": {
992 | "format": "int32",
993 | "type": "integer"
994 | }
995 | },
996 | "type": "object"
997 | },
998 | "URI": {
999 | "format": "uri",
1000 | "type": "string"
1001 | },
1002 | "UriBuilder": {
1003 | "type": "object"
1004 | },
1005 | "User": {
1006 | "properties": {
1007 | "createdAt": {
1008 | "$ref": "#/definitions/LocalDateTime"
1009 | },
1010 | "email": {
1011 | "type": "string"
1012 | },
1013 | "id": {
1014 | "format": "int32",
1015 | "type": "integer"
1016 | },
1017 | "iterations": {
1018 | "format": "int32",
1019 | "type": "integer"
1020 | },
1021 | "passwordHash": {
1022 | "type": "string"
1023 | },
1024 | "salt": {
1025 | "type": "string"
1026 | }
1027 | },
1028 | "type": "object"
1029 | }
1030 | },
1031 | "tags": [
1032 | {
1033 | "description": "An API to manage user authentication and authorization",
1034 | "name": "Authentication"
1035 | },
1036 | {
1037 | "description": "An API to manipulate the categories in the catalog",
1038 | "name": "Categories"
1039 | },
1040 | {
1041 | "description": "An API to manipulate the products in the catalog",
1042 | "name": "Products"
1043 | },
1044 | {
1045 | "description": "An API to manipulate users of the catalog",
1046 | "name": "Users"
1047 | }
1048 | ],
1049 | "x-components": {}
1050 | }
1051 |
--------------------------------------------------------------------------------