├── chapter14 ├── Multicluster-Deployment │ ├── kustomization.yaml │ ├── managedclusterset.yaml │ ├── GitOpsCluster │ │ ├── managedclustersetbinding.yaml │ │ ├── placement.yaml │ │ └── gitopscluster.yaml │ ├── Rolebindings │ │ ├── pipeline-service-role.yaml │ │ └── pipeline-cicd-service-rolebinding.yaml │ ├── PipelineRun │ │ └── quarkus-multicluster-pr.yaml │ ├── applicationset.yaml │ └── Pipeline │ │ └── quarkus-multicluster-pi.yaml ├── Governance │ ├── namespace.yaml │ ├── kustomization.yaml │ ├── placementrule.yaml │ ├── placementbinding.yaml │ └── policy.yaml ├── Build │ ├── README.md │ ├── Pipeline │ │ ├── namespace.yaml │ │ └── quarkus-build-pi.yaml │ └── PipelineRun │ │ └── quarkus-build-pr.yaml ├── Deploy │ ├── README.md │ ├── Rolebindings │ │ ├── pipeline-service-role.yaml │ │ └── pipeline-cicd-service-rolebinding.yaml │ ├── argo-app.yaml │ ├── PipelineRun │ │ └── quarkus-build-and-deploy-pr.yaml │ └── Pipeline │ │ └── quarkus-build-and-deploy-pi.yaml ├── DevSecOps │ ├── README.md │ ├── argo-app-v1.yaml │ ├── argo-app-v2.yaml │ ├── PipelineRun │ │ ├── quarkus-devsecops-v1-pr.yaml │ │ └── quarkus-devsecops-v2-pr.yaml │ ├── Task │ │ ├── stackrox-image-check.yaml │ │ └── s2i-java.yaml │ └── Pipeline │ │ ├── quarkus-devsecops-v2-pi.yaml │ │ └── quarkus-devsecops-v1-pi.yaml ├── link-image-registry-secret.sh └── change-repo-urls.sh ├── chapter11 ├── acm-model │ ├── namespace.yaml │ ├── channel.yaml │ ├── kustomization.yaml │ ├── placementrule.yaml │ ├── application.yaml │ └── subscription.yaml ├── governance │ ├── namespace.yaml │ ├── kustomization.yaml │ ├── placementrule.yaml │ ├── placementbinding.yaml │ └── policy.yaml ├── argocd │ ├── managedclusterset.yaml │ ├── kustomization.yaml │ ├── managedclustersetbinding.yaml │ ├── placement.yaml │ ├── gitopscluster.yaml │ └── applicationset.yaml └── acm-observability │ ├── thanos-object-storage.yaml │ └── alertmanager.yaml ├── quarkus-getting-started ├── src │ ├── main │ │ ├── resources │ │ │ ├── application.properties │ │ │ └── META-INF │ │ │ │ └── resources │ │ │ │ └── index.html │ │ ├── java │ │ │ └── org │ │ │ │ └── acme │ │ │ │ └── getting │ │ │ │ └── started │ │ │ │ ├── GreetingService.java │ │ │ │ └── GreetingResource.java │ │ └── docker │ │ │ ├── Dockerfile.native-micro │ │ │ ├── Dockerfile.native │ │ │ ├── Dockerfile.multistage │ │ │ ├── Dockerfile.legacy-jar │ │ │ └── Dockerfile.jvm │ └── test │ │ └── java │ │ └── org │ │ └── acme │ │ └── getting │ │ └── started │ │ ├── GreetingResourceIT.java │ │ └── GreetingResourceTest.java ├── .dockerignore-bkp ├── .mvn │ └── wrapper │ │ ├── maven-wrapper.jar │ │ └── maven-wrapper.properties ├── .s2i │ └── environment ├── k8s │ ├── overlay │ │ ├── v1 │ │ │ └── kustomization.yaml │ │ └── v2 │ │ │ └── kustomization.yaml │ └── base │ │ ├── kustomization.yaml │ │ ├── route.yaml │ │ ├── service.yaml │ │ └── deployment.yaml ├── .gitignore ├── README.md ├── pom.xml ├── mvnw.cmd └── mvnw ├── sample-go-app └── clouds-api │ ├── k8s │ ├── kustomization.yaml │ ├── route.yaml │ ├── service.yaml │ └── deployment.yaml │ ├── go.mod │ ├── Dockerfile │ ├── TESTING.md │ ├── go.sum │ ├── clouds_test.go │ └── clouds.go ├── chapter10 ├── clouds-api-gitops │ ├── overlays │ │ └── dev │ │ │ ├── namespace.yaml │ │ │ └── kustomization.yaml │ └── base │ │ ├── kustomization.yaml │ │ ├── route.yaml │ │ ├── service.yaml │ │ └── deployment.yaml ├── config │ ├── cicd │ │ ├── namespaces │ │ │ └── cicd-environment.yaml │ │ ├── rolebindings │ │ │ ├── pipeline-service-role.yaml │ │ │ ├── pipeline-dev-service-rolebinding.yaml │ │ │ ├── pipeline-cicd-service-rolebinding.yaml │ │ │ └── registry-pull-rolebinding.yaml │ │ ├── kustomization.yaml │ │ ├── tasks │ │ │ ├── apply-manifest-file.yaml │ │ │ ├── change-image-tag.yaml │ │ │ ├── golang-unit-test.yaml │ │ │ └── check-route-health.yaml │ │ ├── pipelinerun │ │ │ └── build-v1.yaml │ │ └── pipeline │ │ │ └── build-app.yaml │ └── argocd │ │ ├── argocd-project.yaml │ │ ├── argocd-app-dev.yaml │ │ ├── argocd-app-qa.yaml │ │ └── argocd-app-prod.yaml ├── change-repo-urls.sh └── README.md ├── chapter09 ├── PipelineRun │ ├── pvc.yaml │ └── clouds-api-build-deploy.yaml ├── Trigger │ ├── clouds-api-el.yaml │ ├── clouds-api-tb.yaml │ ├── clouds-api-trigger.yaml │ └── clouds-api-tt.yaml ├── Tasks │ ├── apply-manifests-taskrun.yaml │ ├── git-clone-taskrun.yaml │ ├── apply-manifests.yaml │ ├── update-image-version.yaml │ └── check-route-health.yaml ├── Pipeline │ └── build-deploy.yaml └── README.md ├── chapter05 ├── none-install-config.yaml ├── 1.168.192.in-addr.arpa ├── ocp.hybridcloud.com.db ├── pxe-menu-file ├── azure-install-config.yaml ├── aws-install-config.yaml ├── gcp-install-config.yaml ├── dhcpd.conf ├── named.conf └── haproxy.cfg ├── LICENSE ├── chapter06 └── new-master-machine.yaml └── README.md /chapter14/Multicluster-Deployment/kustomization.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /chapter11/acm-model/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: clouds-api-dev -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | # Quarkus Configuration file 2 | # key = value 3 | -------------------------------------------------------------------------------- /chapter11/governance/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: acm-policies-sample -------------------------------------------------------------------------------- /chapter14/Governance/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: acm-policies-sample -------------------------------------------------------------------------------- /sample-go-app/clouds-api/k8s/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - deployment.yaml 3 | - service.yaml 4 | - route.yaml 5 | -------------------------------------------------------------------------------- /quarkus-getting-started/.dockerignore-bkp: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/ 6 | -------------------------------------------------------------------------------- /chapter14/Build/README.md: -------------------------------------------------------------------------------- 1 | 2 | oc apply -f Pipeline/namespace.yaml 3 | oc apply -f Pipeline/quarkus-build-pi.yaml 4 | 5 | oc apply -f PipelineRun/quarkus-build-pr.yaml -------------------------------------------------------------------------------- /chapter11/argocd/managedclusterset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.open-cluster-management.io/v1beta1 2 | kind: ManagedClusterSet 3 | metadata: 4 | name: all-clusters 5 | spec: {} 6 | -------------------------------------------------------------------------------- /chapter14/Build/Pipeline/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: chap14-review-cicd 5 | labels: 6 | argocd.argoproj.io/managed-by: openshift-gitops 7 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/managedclusterset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.open-cluster-management.io/v1beta1 2 | kind: ManagedClusterSet 3 | metadata: 4 | name: all-clusters 5 | spec: {} 6 | -------------------------------------------------------------------------------- /chapter10/clouds-api-gitops/overlays/dev/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: clouds-api-dev 5 | labels: 6 | argocd.argoproj.io/managed-by: openshift-gitops -------------------------------------------------------------------------------- /quarkus-getting-started/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PacktPublishing/OpenShift-Multi-Cluster-Management-Handbook/HEAD/quarkus-getting-started/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /chapter10/clouds-api-gitops/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - deployment.yaml 6 | - service.yaml 7 | - route.yaml 8 | 9 | -------------------------------------------------------------------------------- /chapter10/config/cicd/namespaces/cicd-environment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | argocd.argoproj.io/managed-by: openshift-gitops 6 | name: cicd 7 | spec: {} 8 | status: {} 9 | -------------------------------------------------------------------------------- /chapter09/PipelineRun/pvc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolumeClaim 3 | metadata: 4 | name: source-pvc 5 | spec: 6 | accessModes: 7 | - ReadWriteOnce 8 | resources: 9 | requests: 10 | storage: 500Mi -------------------------------------------------------------------------------- /chapter09/Trigger/clouds-api-el.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: EventListener 3 | metadata: 4 | name: clouds-api-el 5 | spec: 6 | serviceAccountName: pipeline 7 | triggers: 8 | - triggerRef: clouds-api-trigger 9 | -------------------------------------------------------------------------------- /chapter11/argocd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - managedclusterset.yaml 6 | - managedclustersetbinding.yaml 7 | - placement.yaml 8 | - gitopscluster.yaml 9 | -------------------------------------------------------------------------------- /chapter11/argocd/managedclustersetbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.open-cluster-management.io/v1beta1 2 | kind: ManagedClusterSetBinding 3 | metadata: 4 | name: all-clusters 5 | namespace: openshift-gitops 6 | spec: 7 | clusterSet: all-clusters 8 | -------------------------------------------------------------------------------- /quarkus-getting-started/.s2i/environment: -------------------------------------------------------------------------------- 1 | MAVEN_S2I_ARTIFACT_DIRS=target/quarkus-app 2 | S2I_SOURCE_DEPLOYMENTS_FILTER=app lib quarkus quarkus-run.jar 3 | JAVA_OPTIONS=-Dquarkus.http.host=0.0.0.0 4 | AB_JOLOKIA_OFF=true 5 | JAVA_APP_JAR=/deployments/quarkus-run.jar 6 | -------------------------------------------------------------------------------- /chapter11/governance/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - namespace.yaml 6 | - policy.yaml 7 | - placementrule.yaml 8 | - placementbinding.yaml 9 | 10 | namespace: acm-policies-sample -------------------------------------------------------------------------------- /chapter14/Governance/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | resources: 5 | - namespace.yaml 6 | - policy.yaml 7 | - placementrule.yaml 8 | - placementbinding.yaml 9 | 10 | namespace: acm-policies-sample -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/GitOpsCluster/managedclustersetbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.open-cluster-management.io/v1beta1 2 | kind: ManagedClusterSetBinding 3 | metadata: 4 | name: default 5 | namespace: openshift-gitops 6 | spec: 7 | clusterSet: default 8 | -------------------------------------------------------------------------------- /chapter14/Deploy/README.md: -------------------------------------------------------------------------------- 1 | 2 | oc apply -f Pipeline/quarkus-build-and-deploy-pi.yaml 3 | oc apply -f Rolebindings/pipeline-cicd-service-rolebinding.yaml 4 | oc apply -f Rolebindings/pipeline-service-role.yaml 5 | 6 | oc apply -f PipelineRun/quarkus-build-and-deploy-pr.yaml 7 | -------------------------------------------------------------------------------- /chapter11/acm-model/channel.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1 2 | kind: Channel 3 | metadata: 4 | name: cloud-api-github 5 | namespace: clouds-api-dev 6 | spec: 7 | pathname: https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git 8 | type: Git 9 | -------------------------------------------------------------------------------- /chapter14/DevSecOps/README.md: -------------------------------------------------------------------------------- 1 | 2 | oc apply -f Task/s2i-java.yaml 3 | oc apply -f Pipeline/quarkus-devsecops-v1-pi.yaml 4 | oc apply -f Pipeline/quarkus-devsecops-v2-pi.yaml 5 | 6 | oc apply -f PipelineRun/quarkus-devsecops-v1-pr.yaml 7 | oc apply -f PipelineRun/quarkus-devsecops-v2-pr.yaml -------------------------------------------------------------------------------- /chapter11/acm-model/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | namespace: clouds-api-dev 5 | 6 | resources: 7 | - namespace.yaml 8 | - application.yaml 9 | - channel.yaml 10 | - placementrule.yaml 11 | - subscription.yaml -------------------------------------------------------------------------------- /quarkus-getting-started/k8s/overlay/v1/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | namespace: chap14-review-cicd 5 | 6 | bases: 7 | - ../../base 8 | 9 | images: 10 | - name: changeme 11 | newName: image-path-changeme 12 | newTag: "v1" -------------------------------------------------------------------------------- /quarkus-getting-started/k8s/overlay/v2/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | namespace: chap14-review-cicd 5 | 6 | bases: 7 | - ../../base 8 | 9 | images: 10 | - name: changeme 11 | newName: image-path-changeme 12 | newTag: "v2" -------------------------------------------------------------------------------- /sample-go-app/clouds-api/k8s/route.yaml: -------------------------------------------------------------------------------- 1 | kind: Route 2 | apiVersion: route.openshift.io/v1 3 | metadata: 4 | name: clouds-api 5 | labels: 6 | app: clouds-api 7 | spec: 8 | to: 9 | kind: Service 10 | name: clouds-api 11 | weight: 100 12 | port: 13 | targetPort: 8080 -------------------------------------------------------------------------------- /quarkus-getting-started/k8s/base/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | commonLabels: 5 | app: quarkus-quickstarts 6 | 7 | namespace: chap14-review-cicd 8 | 9 | resources: 10 | - deployment.yaml 11 | - service.yaml 12 | - route.yaml -------------------------------------------------------------------------------- /chapter11/acm-model/placementrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1 2 | kind: PlacementRule 3 | metadata: 4 | name: cloud-api-placement 5 | namespace: clouds-api-dev 6 | labels: 7 | app: cloud-api 8 | spec: 9 | clusterSelector: 10 | matchLabels: 11 | env: dev 12 | -------------------------------------------------------------------------------- /sample-go-app/clouds-api/k8s/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: clouds-api 6 | name: clouds-api 7 | spec: 8 | type: ClusterIP 9 | ports: 10 | - protocol: TCP 11 | port: 8080 12 | targetPort: 8080 13 | selector: 14 | app: clouds-api -------------------------------------------------------------------------------- /sample-go-app/clouds-api/go.mod: -------------------------------------------------------------------------------- 1 | module clouds 2 | 3 | go 1.16 4 | 5 | require ( 6 | github.com/BurntSushi/toml v0.4.1 // indirect 7 | github.com/gorilla/context v1.1.1 // indirect 8 | github.com/gorilla/mux v1.8.0 9 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 10 | gopkg.in/yaml.v2 v2.4.0 // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /chapter10/clouds-api-gitops/base/route.yaml: -------------------------------------------------------------------------------- 1 | kind: Route 2 | apiVersion: route.openshift.io/v1 3 | metadata: 4 | name: clouds-api 5 | namespace: clouds-api 6 | labels: 7 | app: clouds-api 8 | spec: 9 | to: 10 | kind: Service 11 | name: clouds-api 12 | weight: 100 13 | port: 14 | targetPort: 8080 -------------------------------------------------------------------------------- /chapter11/argocd/placement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.open-cluster-management.io/v1beta1 2 | kind: Placement 3 | metadata: 4 | name: all-clusters 5 | namespace: openshift-gitops 6 | spec: 7 | predicates: 8 | - requiredClusterSelector: 9 | labelSelector: 10 | matchLabels: 11 | vendor: OpenShift 12 | -------------------------------------------------------------------------------- /quarkus-getting-started/k8s/base/route.yaml: -------------------------------------------------------------------------------- 1 | kind: Route 2 | apiVersion: route.openshift.io/v1 3 | metadata: 4 | name: quarkus-quickstarts 5 | labels: 6 | app: quarkus-quickstarts 7 | spec: 8 | to: 9 | kind: Service 10 | name: quarkus-quickstarts 11 | weight: 100 12 | port: 13 | targetPort: 8080-tcp -------------------------------------------------------------------------------- /quarkus-getting-started/src/test/java/org/acme/getting/started/GreetingResourceIT.java: -------------------------------------------------------------------------------- 1 | package org.acme.getting.started; 2 | 3 | import io.quarkus.test.junit.QuarkusIntegrationTest; 4 | 5 | @QuarkusIntegrationTest 6 | public class GreetingResourceIT extends GreetingResourceTest { 7 | 8 | // Execute the same tests but in native mode. 9 | } -------------------------------------------------------------------------------- /chapter10/clouds-api-gitops/base/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: clouds-api 6 | name: clouds-api 7 | namespace: clouds-api 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - protocol: TCP 12 | port: 8080 13 | targetPort: 8080 14 | selector: 15 | app: clouds-api -------------------------------------------------------------------------------- /sample-go-app/clouds-api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine AS builder 2 | WORKDIR /app 3 | COPY ./clouds.go ./clouds_test.go ./go.mod ./ 4 | RUN go get clouds 5 | RUN CGO_ENABLED=0 GOOS=linux go build -o main . 6 | 7 | FROM registry.access.redhat.com/ubi8/ubi-micro 8 | WORKDIR / 9 | COPY --from=builder /app/main / 10 | EXPOSE 8080 11 | CMD ["./main"] 12 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/java/org/acme/getting/started/GreetingService.java: -------------------------------------------------------------------------------- 1 | package org.acme.getting.started; 2 | 3 | import javax.enterprise.context.ApplicationScoped; 4 | 5 | @ApplicationScoped 6 | public class GreetingService { 7 | 8 | public String greeting(String name) { 9 | return "hello " + name; 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/GitOpsCluster/placement.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cluster.open-cluster-management.io/v1beta1 2 | kind: Placement 3 | metadata: 4 | name: all-clusters 5 | namespace: openshift-gitops 6 | spec: 7 | predicates: 8 | - requiredClusterSelector: 9 | labelSelector: 10 | matchLabels: 11 | vendor: OpenShift 12 | -------------------------------------------------------------------------------- /chapter09/Trigger/clouds-api-tb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: TriggerBinding 3 | metadata: 4 | name: clouds-api-tb 5 | spec: 6 | params: 7 | - name: git-repo-url 8 | value: $(body.repository.url) 9 | - name: git-repo-name 10 | value: $(body.repository.name) 11 | - name: git-revision 12 | value: $(body.head_commit.id) 13 | -------------------------------------------------------------------------------- /chapter14/Deploy/Rolebindings/pipeline-service-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-clusterrole 6 | rules: 7 | - apiGroups: 8 | - argoproj.io 9 | resources: 10 | - appprojects 11 | - applications 12 | verbs: 13 | - patch 14 | - get 15 | - create 16 | -------------------------------------------------------------------------------- /chapter10/config/cicd/rolebindings/pipeline-service-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-clusterrole 6 | rules: 7 | - apiGroups: 8 | - argoproj.io 9 | resources: 10 | - appprojects 11 | - applications 12 | verbs: 13 | - patch 14 | - get 15 | - create 16 | -------------------------------------------------------------------------------- /chapter11/governance/placementrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1 2 | kind: PlacementRule 3 | metadata: 4 | name: placement-policy-etcdencryption 5 | spec: 6 | clusterConditions: 7 | - status: "True" 8 | type: ManagedClusterConditionAvailable 9 | clusterSelector: 10 | matchExpressions: 11 | - {key: vendor, operator: In, values: ["OpenShift"]} -------------------------------------------------------------------------------- /chapter14/Governance/placementrule.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1 2 | kind: PlacementRule 3 | metadata: 4 | name: placement-policy-etcdencryption 5 | spec: 6 | clusterConditions: 7 | - status: "True" 8 | type: ManagedClusterConditionAvailable 9 | clusterSelector: 10 | matchExpressions: 11 | - {key: vendor, operator: In, values: ["OpenShift"]} -------------------------------------------------------------------------------- /chapter09/Tasks/apply-manifests-taskrun.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: TaskRun 3 | metadata: 4 | name: run-apply-manifests 5 | spec: 6 | taskRef: 7 | name: apply-manifests 8 | params: 9 | - name: manifest_dir 10 | value: "./sample-go-app/clouds-api/k8s" 11 | workspaces: 12 | - name: source 13 | persistentVolumeClaim: 14 | claimName: source-pvc 15 | -------------------------------------------------------------------------------- /chapter10/config/cicd/rolebindings/pipeline-dev-service-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-dev-service-role-binding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: view 10 | subjects: 11 | - kind: ServiceAccount 12 | name: pipeline 13 | namespace: cicd -------------------------------------------------------------------------------- /chapter11/acm-model/application.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: app.k8s.io/v1beta1 2 | kind: Application 3 | metadata: 4 | name: cloud-api 5 | namespace: clouds-api-dev 6 | spec: 7 | componentKinds: 8 | - group: apps.open-cluster-management.io 9 | kind: Subscription 10 | descriptor: {} 11 | selector: 12 | matchExpressions: 13 | - key: app 14 | operator: In 15 | values: 16 | - cloud-api -------------------------------------------------------------------------------- /chapter10/config/argocd/argocd-project.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: AppProject 3 | metadata: 4 | name: clouds-api 5 | namespace: openshift-gitops 6 | spec: 7 | clusterResourceWhitelist: 8 | - group: '*' 9 | kind: '*' 10 | description: 'ArgoCD Project dedicated for clouds-api application' 11 | destinations: 12 | - namespace: '*' 13 | server: '*' 14 | sourceRepos: 15 | - '*' 16 | -------------------------------------------------------------------------------- /chapter11/governance/placementbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: PlacementBinding 3 | metadata: 4 | name: binding-policy-etcdencryption 5 | placementRef: 6 | name: placement-policy-etcdencryption 7 | kind: PlacementRule 8 | apiGroup: apps.open-cluster-management.io 9 | subjects: 10 | - name: policy-etcdencryption 11 | kind: Policy 12 | apiGroup: policy.open-cluster-management.io 13 | -------------------------------------------------------------------------------- /chapter14/Governance/placementbinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: PlacementBinding 3 | metadata: 4 | name: binding-policy-etcdencryption 5 | placementRef: 6 | name: placement-policy-etcdencryption 7 | kind: PlacementRule 8 | apiGroup: apps.open-cluster-management.io 9 | subjects: 10 | - name: policy-etcdencryption 11 | kind: Policy 12 | apiGroup: policy.open-cluster-management.io 13 | -------------------------------------------------------------------------------- /chapter10/config/cicd/rolebindings/pipeline-cicd-service-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-cicd-service-role-binding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: pipelines-clusterrole 10 | subjects: 11 | - kind: ServiceAccount 12 | name: pipeline 13 | namespace: cicd 14 | -------------------------------------------------------------------------------- /chapter10/clouds-api-gitops/overlays/dev/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | 4 | commonLabels: 5 | environment: dev 6 | 7 | namespace: clouds-api-dev 8 | 9 | bases: 10 | - ../../base 11 | 12 | resources: 13 | - namespace.yaml 14 | 15 | images: 16 | - name: quay.io/gfontana/clouds-api 17 | newName: image-registry.openshift-image-registry.svc:5000/cicd/clouds-api 18 | newTag: changeme -------------------------------------------------------------------------------- /chapter14/Deploy/Rolebindings/pipeline-cicd-service-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-cicd-service-role-binding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: pipelines-clusterrole 10 | subjects: 11 | - kind: ServiceAccount 12 | name: pipeline 13 | namespace: chap14-review-cicd 14 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/Rolebindings/pipeline-service-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-cicd-appset-role-binding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: pipelines-appset-clusterrole 10 | subjects: 11 | - kind: ServiceAccount 12 | name: pipeline 13 | namespace: chap14-review-cicd 14 | -------------------------------------------------------------------------------- /chapter10/config/cicd/kustomization.yaml: -------------------------------------------------------------------------------- 1 | namespace: cicd 2 | 3 | resources: 4 | - namespaces/cicd-environment.yaml 5 | - rolebindings/pipeline-service-role.yaml 6 | - rolebindings/pipeline-cicd-service-rolebinding.yaml 7 | - rolebindings/pipeline-dev-service-rolebinding.yaml 8 | - rolebindings/registry-pull-rolebinding.yaml 9 | - tasks/apply-manifest-file.yaml 10 | - tasks/check-route-health.yaml 11 | - tasks/golang-unit-test.yaml 12 | - pipeline/build-app.yaml -------------------------------------------------------------------------------- /chapter11/argocd/gitopscluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1beta1 2 | kind: GitOpsCluster 3 | metadata: 4 | name: argo-acm-clusters 5 | namespace: openshift-gitops 6 | spec: 7 | argoServer: 8 | cluster: local-cluster 9 | argoNamespace: openshift-gitops 10 | placementRef: 11 | kind: Placement 12 | apiVersion: cluster.open-cluster-management.io/v1beta1 13 | name: all-clusters 14 | namespace: openshift-gitops 15 | -------------------------------------------------------------------------------- /chapter11/acm-model/subscription.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1 2 | kind: Subscription 3 | metadata: 4 | name: cloud-api-subscription 5 | namespace: clouds-api-dev 6 | annotations: 7 | apps.open-cluster-management.io/git-path: sample-go-app/clouds-api/k8s/ 8 | labels: 9 | app: cloud-api 10 | spec: 11 | channel: clouds-api-dev/cloud-api-github 12 | placement: 13 | placementRef: 14 | name: cloud-api-placement 15 | kind: PlacementRule -------------------------------------------------------------------------------- /chapter11/acm-observability/thanos-object-storage.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: thanos-object-storage 5 | namespace: open-cluster-management-observability 6 | type: Opaque 7 | stringData: 8 | thanos.yaml: | 9 | type: AZURE 10 | config: 11 | storage_account: $STORAGEACCOUNT 12 | storage_account_key: $STORAGEKEY 13 | container: $CONTAINERBLOB 14 | endpoint: blob.core.windows.net 15 | max_retries: 0 16 | -------------------------------------------------------------------------------- /quarkus-getting-started/.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .project 3 | .classpath 4 | .settings/ 5 | bin/ 6 | 7 | # IntelliJ 8 | .idea 9 | *.ipr 10 | *.iml 11 | *.iws 12 | 13 | # NetBeans 14 | nb-configuration.xml 15 | 16 | # Visual Studio Code 17 | .vscode 18 | 19 | # OSX 20 | .DS_Store 21 | 22 | # Vim 23 | *.swp 24 | *.swo 25 | 26 | # patch 27 | *.orig 28 | *.rej 29 | 30 | # Maven 31 | target/ 32 | pom.xml.tag 33 | pom.xml.releaseBackup 34 | pom.xml.versionsBackup 35 | release.properties -------------------------------------------------------------------------------- /quarkus-getting-started/k8s/base/service.yaml: -------------------------------------------------------------------------------- 1 | kind: Service 2 | apiVersion: v1 3 | metadata: 4 | name: quarkus-quickstarts 5 | labels: 6 | app: quarkus-quickstarts 7 | spec: 8 | ports: 9 | - name: 8080-tcp 10 | protocol: TCP 11 | port: 8080 12 | targetPort: 8080 13 | - name: 8443-tcp 14 | protocol: TCP 15 | port: 8443 16 | targetPort: 8443 17 | selector: 18 | app: quarkus-quickstarts 19 | deployment: quarkus-quickstarts 20 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/GitOpsCluster/gitopscluster.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps.open-cluster-management.io/v1beta1 2 | kind: GitOpsCluster 3 | metadata: 4 | name: argo-acm-clusters 5 | namespace: openshift-gitops 6 | spec: 7 | argoServer: 8 | cluster: local-cluster 9 | argoNamespace: openshift-gitops 10 | placementRef: 11 | kind: Placement 12 | apiVersion: cluster.open-cluster-management.io/v1beta1 13 | name: all-clusters 14 | namespace: openshift-gitops 15 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/Rolebindings/pipeline-cicd-service-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | creationTimestamp: null 5 | name: pipelines-appset-clusterrole 6 | rules: 7 | - apiGroups: 8 | - argoproj.io 9 | resources: 10 | - applicationsets 11 | verbs: 12 | - patch 13 | - get 14 | - create 15 | - apiGroups: 16 | - cluster.open-cluster-management.io 17 | resources: 18 | - placements 19 | verbs: 20 | - patch 21 | - get 22 | - create 23 | -------------------------------------------------------------------------------- /chapter14/Deploy/argo-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: quarkus-quickstarts 5 | namespace: openshift-gitops 6 | spec: 7 | project: default 8 | source: 9 | repoURL: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 10 | path: quarkus-getting-started/k8s/overlay/v1/ 11 | targetRevision: main 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: default 15 | syncPolicy: 16 | automated: 17 | selfHeal: true 18 | -------------------------------------------------------------------------------- /chapter14/DevSecOps/argo-app-v1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: quarkus-quickstarts 5 | namespace: openshift-gitops 6 | spec: 7 | project: default 8 | source: 9 | repoURL: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 10 | path: quarkus-getting-started/k8s/overlay/v1/ 11 | targetRevision: main 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: default 15 | syncPolicy: 16 | automated: 17 | selfHeal: true 18 | -------------------------------------------------------------------------------- /chapter14/DevSecOps/argo-app-v2.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: quarkus-quickstarts 5 | namespace: openshift-gitops 6 | spec: 7 | project: default 8 | source: 9 | repoURL: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 10 | path: quarkus-getting-started/k8s/overlay/v2/ 11 | targetRevision: main 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: default 15 | syncPolicy: 16 | automated: 17 | selfHeal: true 18 | -------------------------------------------------------------------------------- /chapter10/config/argocd/argocd-app-dev.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: clouds-app-dev 5 | namespace: openshift-gitops 6 | spec: 7 | project: clouds-api 8 | source: 9 | repoURL: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 10 | path: chapter10/clouds-api-gitops/overlays/dev 11 | targetRevision: dev 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: default 15 | syncPolicy: 16 | automated: 17 | selfHeal: true 18 | -------------------------------------------------------------------------------- /chapter10/config/argocd/argocd-app-qa.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: clouds-app-qa 5 | namespace: openshift-gitops 6 | spec: 7 | project: clouds-api 8 | source: 9 | repoURL: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 10 | path: chapter10/clouds-api-gitops/overlays/qa 11 | targetRevision: qa 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: default 15 | syncPolicy: 16 | automated: 17 | selfHeal: true 18 | -------------------------------------------------------------------------------- /chapter10/config/argocd/argocd-app-prod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: clouds-app-prod 5 | namespace: openshift-gitops 6 | spec: 7 | project: clouds-api 8 | source: 9 | repoURL: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 10 | path: chapter10/clouds-api-gitops/overlays/prod 11 | targetRevision: main 12 | destination: 13 | server: 'https://kubernetes.default.svc' 14 | namespace: default 15 | syncPolicy: 16 | automated: 17 | selfHeal: true 18 | -------------------------------------------------------------------------------- /chapter05/none-install-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | baseDomain: hybridmycloud.com 3 | compute: 4 | - hyperthreading: Enabled 5 | name: worker 6 | replicas: 2 7 | controlPlane: 8 | hyperthreading: Enabled 9 | name: master 10 | replicas: 3 11 | metadata: 12 | name: ocp 13 | networking: 14 | clusterNetwork: 15 | - cidr: 10.128.0.0/14 16 | hostPrefix: 23 17 | networkType: OpenShiftSDN 18 | serviceNetwork: 19 | - 172.30.0.0/16 20 | platform: 21 | none: {} 22 | fips: false 23 | pullSecret: '' 24 | sshKey: '' -------------------------------------------------------------------------------- /chapter09/Tasks/git-clone-taskrun.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: TaskRun 3 | metadata: 4 | name: git-clone 5 | spec: 6 | taskRef: 7 | name: git-clone 8 | kind: ClusterTask 9 | params: 10 | - name: url 11 | value: "https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git" 12 | - name: subdirectory 13 | value: "" 14 | - name: deleteExisting 15 | value: "true" 16 | - name: revision 17 | value: "main" 18 | workspaces: 19 | - name: output 20 | persistentVolumeClaim: 21 | claimName: source-pvc 22 | -------------------------------------------------------------------------------- /sample-go-app/clouds-api/k8s/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: clouds-api 6 | name: clouds-api 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: clouds-api 12 | template: 13 | metadata: 14 | labels: 15 | app: clouds-api 16 | spec: 17 | containers: 18 | - image: quay.io/gfontana/clouds-api:latest 19 | imagePullPolicy: Always 20 | name: clouds-api 21 | ports: 22 | - containerPort: 8080 23 | protocol: TCP 24 | -------------------------------------------------------------------------------- /chapter10/clouds-api-gitops/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: clouds-api 6 | name: clouds-api 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: clouds-api 12 | template: 13 | metadata: 14 | labels: 15 | app: clouds-api 16 | spec: 17 | containers: 18 | - image: quay.io/gfontana/clouds-api:latest 19 | imagePullPolicy: Always 20 | name: clouds-api 21 | ports: 22 | - containerPort: 8080 23 | protocol: TCP 24 | -------------------------------------------------------------------------------- /chapter10/config/cicd/rolebindings/registry-pull-rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | creationTimestamp: null 5 | name: registry-pull-rolebinding 6 | namespace: cicd 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: system:image-puller 11 | subjects: 12 | - apiGroup: rbac.authorization.k8s.io 13 | kind: Group 14 | name: system:serviceaccounts:clouds-api-dev 15 | - apiGroup: rbac.authorization.k8s.io 16 | kind: Group 17 | name: system:serviceaccounts:clouds-api-qa 18 | - apiGroup: rbac.authorization.k8s.io 19 | kind: Group 20 | name: system:serviceaccounts:clouds-api-prod -------------------------------------------------------------------------------- /chapter10/config/cicd/tasks/apply-manifest-file.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: apply-manifest-file 5 | spec: 6 | workspaces: 7 | - name: source 8 | params: 9 | - name: manifest 10 | description: The manifest file to apply 11 | type: string 12 | steps: 13 | - name: apply 14 | image: registry.redhat.io/openshift4/ose-cli:latest 15 | workingDir: /workspace/source 16 | command: ["/bin/bash", "-c"] 17 | args: 18 | - |- 19 | echo Applying manifest $(inputs.params.manifest) 20 | oc apply -f $(inputs.params.manifest) 21 | echo ----------------------------------- 22 | -------------------------------------------------------------------------------- /chapter09/Trigger/clouds-api-trigger.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: Trigger 3 | metadata: 4 | name: clouds-api-trigger 5 | spec: 6 | serviceAccountName: pipeline 7 | interceptors: 8 | - ref: 9 | name: "github" 10 | params: 11 | - name: "secretRef" 12 | value: 13 | secretName: github-secret 14 | secretKey: secretToken 15 | - name: "eventTypes" 16 | value: ["push"] 17 | bindings: 18 | - ref: clouds-api-tb 19 | template: 20 | ref: clouds-api-tt 21 | --- 22 | apiVersion: v1 23 | kind: Secret 24 | metadata: 25 | name: github-secret 26 | type: Opaque 27 | stringData: 28 | secretToken: "tekton" -------------------------------------------------------------------------------- /chapter10/config/cicd/pipelinerun/build-v1.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | name: build-v1-pipelinerun 5 | spec: 6 | pipelineRef: 7 | name: build-app 8 | params: 9 | - name: git-url 10 | value: https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git 11 | - name: git-revision 12 | value: dev 13 | - name: IMAGE 14 | value: image-registry.openshift-image-registry.svc:5000/cicd/clouds-api:v1.0 15 | workspaces: 16 | - name: shared-workspace 17 | volumeClaimTemplate: 18 | spec: 19 | accessModes: 20 | - ReadWriteOnce 21 | resources: 22 | requests: 23 | storage: 500Mi 24 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/java/org/acme/getting/started/GreetingResource.java: -------------------------------------------------------------------------------- 1 | package org.acme.getting.started; 2 | 3 | import javax.inject.Inject; 4 | import javax.ws.rs.GET; 5 | import javax.ws.rs.Path; 6 | import javax.ws.rs.Produces; 7 | import javax.ws.rs.core.MediaType; 8 | 9 | @Path("/hello") 10 | public class GreetingResource { 11 | 12 | @Inject 13 | GreetingService service; 14 | 15 | @GET 16 | @Produces(MediaType.TEXT_PLAIN) 17 | @Path("/greeting/{name}") 18 | public String greeting(String name) { 19 | return service.greeting(name); 20 | } 21 | 22 | @GET 23 | @Produces(MediaType.TEXT_PLAIN) 24 | public String hello() { 25 | return "hello"; 26 | } 27 | } -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/docker/Dockerfile.native-micro: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a distroless container that runs the Quarkus application in native (no JVM) mode 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Pnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native-micro -t quarkus/getting-started . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/getting-started 15 | # 16 | ### 17 | FROM quay.io/quarkus/quarkus-micro-image:1.0 18 | COPY target/*-runner /application 19 | 20 | EXPOSE 8080 21 | USER 1001 22 | 23 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 24 | -------------------------------------------------------------------------------- /sample-go-app/clouds-api/TESTING.md: -------------------------------------------------------------------------------- 1 | # Testing using cURL and jq 2 | 3 | ## Testing GET 4 | curl http://localhost:8080/cloud | jq 5 | 6 | ## Testing POST 7 | curl -X POST -d '{"Id": "5", "Title": "Alibaba", "desc": "Alibaba Cloud", "content": "Alibaba Cloud"}' -H "Content-Type: application/json" http://localhost:8080/cloud | jq 8 | curl http://localhost:8080/cloud | jq 9 | 10 | ## Testing PUT 11 | curl -X PUT -d '{"Id": "5", "Title": "Alibaba v2", "desc": "Alibaba Cloud v2", "content": "Alibaba Cloud v2"}' -H "Content-Type: application/json" http://localhost:8080/cloud/5 | jq 12 | curl http://localhost:8080/cloud | jq 13 | 14 | ## Testing DELETE 15 | curl -X DELETE http://localhost:8080/cloud/5 16 | curl http://localhost:8080/cloud | jq 17 | -------------------------------------------------------------------------------- /chapter09/PipelineRun/clouds-api-build-deploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | name: build-deploy-api-pipelinerun 5 | spec: 6 | pipelineRef: 7 | name: build-and-deploy 8 | params: 9 | - name: deployment-name 10 | value: clouds-api 11 | - name: git-url 12 | value: https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git 13 | - name: IMAGE 14 | value: image-registry.openshift-image-registry.svc:5000/pipelines-sample/clouds-api 15 | workspaces: 16 | - name: shared-workspace 17 | volumeClaimTemplate: 18 | spec: 19 | accessModes: 20 | - ReadWriteOnce 21 | resources: 22 | requests: 23 | storage: 500Mi 24 | -------------------------------------------------------------------------------- /chapter05/1.168.192.in-addr.arpa : -------------------------------------------------------------------------------- 1 | $TTL 1W 2 | @ IN SOA bastion.ocp.hybridcloud.com. root.ocp.hybridcloud.com. ( 3 | 3 ;Serial 4 | 21600 ;Refresh 5 | 3600 ;Retry 6 | 604800 ;Expire 7 | 86400 ;Minimum TTL 8 | ) 9 | ;End Common Header Definition 10 | 11 | ; name servers 12 | IN NS bastion.ocp.hybridcloud.com. 13 | 14 | 90.1.168.192.in-addr.arpa. IN PTR bootstrap.ocp.hybridcloud.com.; 15 | 91.1.168.192.in-addr.arpa. IN PTR master1.ocp.hybridcloud.com.; 16 | 92.1.168.192.in-addr.arpa. IN PTR master2.ocp.hybridcloud.com.; 17 | 93.1.168.192.in-addr.arpa. IN PTR master3.ocp.hybridcloud.com.; 18 | 101.1.168.192.in-addr.arpa. IN PTR worker1.ocp.hybridcloud.com.; 19 | 102.1.168.192.in-addr.arpa. IN PTR worker2.ocp.hybridcloud.com.; 20 | -------------------------------------------------------------------------------- /chapter09/Tasks/apply-manifests.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: apply-manifests 5 | spec: 6 | workspaces: 7 | - name: source 8 | params: 9 | - name: manifest_dir 10 | description: The directory in source that contains yaml manifests 11 | type: string 12 | default: "./sample-go-app/clouds-api/k8s" 13 | steps: 14 | - name: apply 15 | image: registry.redhat.io/openshift4/ose-cli:latest 16 | workingDir: /workspace/source 17 | command: ["/bin/bash", "-c"] 18 | args: 19 | - |- 20 | echo Applying manifests in $(inputs.params.manifest_dir) directory 21 | oc apply -k $(inputs.params.manifest_dir) 22 | echo ----------------------------------- 23 | -------------------------------------------------------------------------------- /chapter09/Tasks/update-image-version.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: update-image-version 5 | spec: 6 | params: 7 | - name: deployment 8 | description: The name of the deployment patch the image 9 | type: string 10 | - name: IMAGE 11 | description: Location of image to be patched with 12 | type: string 13 | steps: 14 | - name: patch 15 | image: registry.redhat.io/openshift4/ose-cli:latest 16 | command: ["/bin/bash", "-c"] 17 | args: 18 | - |- 19 | oc patch deployment $(inputs.params.deployment) --patch='{"spec":{"template":{"spec":{ 20 | "containers":[{ 21 | "name": "$(inputs.params.deployment)", 22 | "image":"$(inputs.params.IMAGE)" 23 | }] 24 | }}}}' 25 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Pnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/getting-started . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/getting-started 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /chapter14/link-image-registry-secret.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "================================================" 4 | echo "" 5 | echo "Script to link the image registry secret which contains the credentials with pipeline serviceaccount" 6 | echo "Created by: Giovanni Fontana" 7 | echo "" 8 | echo "================================================" 9 | 10 | echo "** Input the full path to where the image registry secret file is located (e.g.: /tmp/demo-ocp-secret.yml): " 11 | read secret_path 12 | echo "" 13 | 14 | secret_name=`oc apply -f $secret_path --namespace=chap14-review-cicd --dry-run=client -o jsonpath='{.metadata.name}'` 15 | oc apply -f $secret_path --namespace=chap14-review-cicd 16 | oc patch serviceaccount pipeline -p '{"secrets": [{"name": "'$secret_name'"}]}' --namespace=chap14-review-cicd 17 | 18 | oc secrets link default $secret_name --for=pull -n chap14-review-cicd 19 | 20 | echo "" 21 | echo "** Secret created and linked to pipeline SA" 22 | -------------------------------------------------------------------------------- /chapter05/ocp.hybridcloud.com.db: -------------------------------------------------------------------------------- 1 | ;[1] Begin Common Header Definition 2 | $TTL 86400 3 | @ IN SOA bastion.ocp.hybridcloud.com. root.ocp.hybridcloud.com. ( 4 | 3 ;Serial 5 | 21600 ;Refresh 6 | 3600 ;Retry 7 | 604800 ;Expire 8 | 86400 ;Minimum TTL 9 | ) 10 | ;End Common Header Definition 11 | 12 | 13 | ;Name Server Information [2] 14 | IN NS bastion.ocp.hybridcloud.com. 15 | 16 | ;IP address of Name Server [3] 17 | bastion IN A 192.168.1.200 18 | 19 | ;api internal and external purposes [4] 20 | api IN A 192.168.1.200 21 | api-int IN A 192.168.1.200 22 | 23 | ;wildcard application [5] 24 | *.apps IN A 192.168.1.200 25 | 26 | ;bootstrap node to start cluster install only [6] 27 | bootstrap IN A 192.168.1.90 28 | 29 | ;master nodes [7] 30 | master1 IN A 192.168.1.91 31 | master2 IN A 192.168.1.92 32 | master3 IN A 192.168.1.93 33 | 34 | ;worker nodes [8] 35 | worker1 IN A 192.168.1.101 36 | worker2 IN A 192.168.1.102 37 | -------------------------------------------------------------------------------- /sample-go-app/clouds-api/go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= 2 | github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= 3 | github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= 4 | github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= 5 | github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= 6 | github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= 7 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 8 | gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= 9 | gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= 10 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 11 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 12 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/test/java/org/acme/getting/started/GreetingResourceTest.java: -------------------------------------------------------------------------------- 1 | package org.acme.getting.started; 2 | 3 | import static io.restassured.RestAssured.given; 4 | import static org.hamcrest.CoreMatchers.is; 5 | 6 | import java.util.UUID; 7 | 8 | import org.junit.jupiter.api.Test; 9 | 10 | import io.quarkus.test.junit.QuarkusTest; 11 | 12 | @QuarkusTest 13 | public class GreetingResourceTest { 14 | 15 | @Test 16 | public void testHelloEndpoint() { 17 | given() 18 | .when().get("/hello") 19 | .then() 20 | .statusCode(200) 21 | .body(is("hello")); 22 | } 23 | 24 | @Test 25 | public void testGreetingEndpoint() { 26 | String uuid = UUID.randomUUID().toString(); 27 | given() 28 | .pathParam("name", uuid) 29 | .when().get("/hello/greeting/{name}") 30 | .then() 31 | .statusCode(200) 32 | .body(is("hello " + uuid)); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /chapter10/config/cicd/tasks/change-image-tag.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: change-image-tag 5 | spec: 6 | workspaces: 7 | - name: source 8 | params: 9 | - name: manifest 10 | description: The manifest file to apply 11 | type: string 12 | default: "./chapter10/clouds-api-gitops/overlays/qa/kustomization.yaml" 13 | - name: new-tag 14 | description: The manifest file to apply 15 | type: string 16 | steps: 17 | - name: commit-push-changes-gitops 18 | image: alpine/git:v2.30.2 19 | workingDir: "$(workspaces.config-source.path)" 20 | script: | 21 | #!/usr/bin/env sh 22 | set -e 23 | 24 | eval $(ssh-agent) 25 | ssh-add ~/.ssh/id_* 26 | 27 | git config --global user.email "tekton@tekton.dev" 28 | git config --global user.name "Tekton Pipeline" 29 | git add . 30 | git commit --allow-empty -m "[Tekton] updating $(params.environment)" 31 | git push origin main 32 | -------------------------------------------------------------------------------- /chapter14/Deploy/PipelineRun/quarkus-build-and-deploy-pr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: quarkus-build-and-deploy-pr 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - name: APP_NAME 9 | value: quarkus-quickstarts 10 | - name: GIT_REPO 11 | value: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | - name: GIT_REVISION 13 | value: '' 14 | - name: IMAGE_NAME 15 | value: >- 16 | image-path-changeme:v1 17 | - name: PATH_CONTEXT 18 | value: quarkus-getting-started 19 | - name: VERSION 20 | value: openjdk-17-ubi8 21 | pipelineRef: 22 | name: quarkus-build-and-deploy 23 | serviceAccountName: pipeline 24 | timeout: 1h0m0s 25 | workspaces: 26 | - name: workspace 27 | volumeClaimTemplate: 28 | metadata: 29 | creationTimestamp: null 30 | spec: 31 | accessModes: 32 | - ReadWriteOnce 33 | resources: 34 | requests: 35 | storage: 1Gi -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/docker/Dockerfile.multistage: -------------------------------------------------------------------------------- 1 | ## Stage 1 : build with maven builder image with native capabilities 2 | FROM quay.io/quarkus/ubi-quarkus-native-image:22.2-java17 AS build 3 | COPY --chown=1001:1001 ../../../mvnw /code/mvnw 4 | COPY --chown=1001:1001 ../../../.mvn /code/.mvn 5 | COPY --chown=1001:1001 ../../../pom.xml /code/ 6 | USER 1001 7 | WORKDIR /code 8 | RUN ./mvnw -B org.apache.maven.plugins:maven-dependency-plugin:3.1.2:go-offline 9 | COPY src /code/src 10 | RUN ./mvnw package -Pnative 11 | 12 | FROM registry.access.redhat.com/ubi8/ubi-minimal 13 | WORKDIR /work/ 14 | COPY --from=build /code/target/*-runner /work/application 15 | RUN chmod 775 /work /work/application \ 16 | && chown -R 1001 /work \ 17 | && chmod -R "g+rwX" /work \ 18 | && chown -R 1001:root /work \ 19 | && microdnf update -y \ 20 | && rpm -e --nodeps $(rpm -qa '*rpm*' '*dnf*' '*libsolv*' '*hawkey*' 'yum*') 21 | # SECURITY FIX: Line above added to remove package manager from image 22 | 23 | EXPOSE 8080 24 | USER 1001 25 | 26 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 27 | -------------------------------------------------------------------------------- /chapter10/config/cicd/tasks/golang-unit-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: golang-unit-test 5 | spec: 6 | workspaces: 7 | - name: source 8 | params: 9 | - name: context 10 | description: path to the directory to use as context. 11 | default: "./sample-go-app/clouds-api" 12 | - name: version 13 | description: golang version to use for tests 14 | default: "latest" 15 | - name: module-name 16 | description: golang module-name to get dependencies 17 | default: "clouds" 18 | - name: flags 19 | description: flags to use for the test command 20 | default: -race -cover -v 21 | - name: packages 22 | description: "packages to test (default: .)" 23 | default: "." 24 | steps: 25 | - name: unit-test 26 | image: docker.io/library/golang:$(params.version) 27 | workingDir: /workspace/source 28 | script: | 29 | cd $(params.context) 30 | go get $(params.module-name) 31 | go test $(params.flags) $(params.packages) 32 | -------------------------------------------------------------------------------- /chapter05/pxe-menu-file: -------------------------------------------------------------------------------- 1 | UI vesamenu.c32 2 | MENU COLOR sel 4 #ffffff std 3 | MENU COLOR title 0 #ffffff 4 | TIMEOUT 120 5 | PROMPT 0 6 | 7 | MENU TITLE OPENSHIFT 4.X AGNOSTIC PXE MENU 8 | 9 | LABEL BOOTSTRAP NODE 10 | KERNEL networkboot/coreOS/rhcos-live-kernel-x86_64 11 | APPEND initrd=networkboot/coreOS/rhcos-live-initramfs.x86_64.img,networkboot/coreOS/rhcos-live-rootfs.x86_64.img coreos.inst.install_dev=/dev/sda coreos.inst.ignition_url=http://192.168.1.200:81/ignition/bootstrap.ign 12 | 13 | LABEL MASTER NODE 14 | KERNEL networkboot/coreOS/rhcos-live-kernel-x86_64 15 | APPEND initrd=networkboot/coreOS/rhcos-live-initramfs.x86_64.img,networkboot/coreOS/rhcos-live-rootfs.x86_64.img coreos.inst.install_dev=/dev/sda coreos.inst.ignition_url=http://192.168.1.200:81/ignition/master.ign 16 | 17 | LABEL WORKER NODE 18 | KERNEL networkboot/coreOS/rhcos-live-kernel-x86_64 19 | APPEND initrd=networkboot/coreOS/rhcos-live-initramfs.x86_64.img,networkboot/coreOS/rhcos-live-rootfs.x86_64.img coreos.inst.install_dev=/dev/sda coreos.inst.ignition_url=http://192.168.1.200:81/ignition/worker.ign 20 | -------------------------------------------------------------------------------- /chapter05/azure-install-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | baseDomain: hybridcloud.com 3 | controlPlane: 4 | hyperthreading: Enabled 5 | name: master 6 | platform: 7 | azure: 8 | osDisk: 9 | diskSizeGB: 1024 10 | type: Standard_D8s_v3 11 | replicas: 3 12 | compute: 13 | - hyperthreading: Enabled 14 | name: worker 15 | platform: 16 | azure: 17 | type: Standard_D2s_v3 18 | osDisk: diskSizeGB: 512 19 | zones: 20 | - "1" 21 | - "2" 22 | - "3" 23 | replicas: 5 24 | metadata: 25 | name: test-cluster 26 | networking: 27 | clusterNetwork: 28 | - cidr: 10.128.0.0/14 29 | hostPrefix: 23 30 | machineNetwork: 31 | - cidr: 10.0.0.0/16 32 | networkType: OpenShiftSDN 33 | serviceNetwork: 34 | - 172.30.0.0/16 35 | platform: 36 | azure: 37 | BaseDomainResourceGroupName: resource_group 38 | region: centralus 39 | resourceGroupName: existing_resource_group 40 | outboundType: Loadbalancer 41 | cloudName: AzurePublicCloud 42 | pullSecret: '{"auths": ...}' -------------------------------------------------------------------------------- /quarkus-getting-started/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Packt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /chapter14/Build/PipelineRun/quarkus-build-pr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: quarkus-quickstarts- 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - name: APP_NAME 9 | value: quarkus-quickstarts 10 | - name: GIT_REPO 11 | value: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | - name: GIT_REVISION 13 | value: '' 14 | - name: IMAGE_NAME 15 | value: >- 16 | image-path-changeme:v1 17 | - name: PATH_CONTEXT 18 | value: quarkus-getting-started 19 | - name: K8S_MANIFESTS_PATH 20 | value: "quarkus-getting-started/k8s/overlay/v1/" 21 | - name: VERSION 22 | value: openjdk-17-ubi8 23 | pipelineRef: 24 | name: quarkus-build 25 | serviceAccountName: pipeline 26 | timeout: 1h0m0s 27 | workspaces: 28 | - name: workspace 29 | volumeClaimTemplate: 30 | metadata: 31 | creationTimestamp: null 32 | spec: 33 | accessModes: 34 | - ReadWriteOnce 35 | resources: 36 | requests: 37 | storage: 1Gi -------------------------------------------------------------------------------- /chapter14/DevSecOps/PipelineRun/quarkus-devsecops-v1-pr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: quarkus-devsecops-v1-pr 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - name: APP_NAME 9 | value: quarkus-quickstarts 10 | - name: GIT_REPO 11 | value: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | - name: GIT_REVISION 13 | value: '' 14 | - name: IMAGE_NAME 15 | value: >- 16 | image-path-changeme:v1 17 | - name: PATH_CONTEXT 18 | value: quarkus-getting-started 19 | - name: VERSION 20 | value: openjdk-17-ubi8 21 | - name: ARGO_APP_PATH 22 | value: "chapter14/DevSecOps/argo-app-v1.yaml" 23 | pipelineRef: 24 | name: quarkus-devsecops-v1 25 | serviceAccountName: pipeline 26 | timeout: 1h0m0s 27 | workspaces: 28 | - name: workspace 29 | volumeClaimTemplate: 30 | metadata: 31 | creationTimestamp: null 32 | spec: 33 | accessModes: 34 | - ReadWriteOnce 35 | resources: 36 | requests: 37 | storage: 1Gi -------------------------------------------------------------------------------- /chapter14/DevSecOps/PipelineRun/quarkus-devsecops-v2-pr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: quarkus-devsecops-v2-pr 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - name: APP_NAME 9 | value: quarkus-quickstarts 10 | - name: GIT_REPO 11 | value: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | - name: GIT_REVISION 13 | value: '' 14 | - name: IMAGE_NAME 15 | value: >- 16 | image-path-changeme:v2 17 | - name: PATH_CONTEXT 18 | value: quarkus-getting-started 19 | - name: VERSION 20 | value: openjdk-17-ubi8 21 | - name: ARGO_APP_PATH 22 | value: "chapter14/DevSecOps/argo-app-v2.yaml" 23 | pipelineRef: 24 | name: quarkus-devsecops-v2 25 | serviceAccountName: pipeline 26 | timeout: 1h0m0s 27 | workspaces: 28 | - name: workspace 29 | volumeClaimTemplate: 30 | metadata: 31 | creationTimestamp: null 32 | spec: 33 | accessModes: 34 | - ReadWriteOnce 35 | resources: 36 | requests: 37 | storage: 1Gi -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/PipelineRun/quarkus-multicluster-pr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: quarkus-devsecops-v1-pr 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - name: APP_NAME 9 | value: quarkus-quickstarts 10 | - name: GIT_REPO 11 | value: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | - name: GIT_REVISION 13 | value: '' 14 | - name: IMAGE_NAME 15 | value: >- 16 | image-path-changeme:v2 17 | - name: PATH_CONTEXT 18 | value: quarkus-getting-started 19 | - name: VERSION 20 | value: openjdk-17-ubi8 21 | - name: ARGO_APP_PATH 22 | value: "chapter14/Multicluster-Deployment/applicationset.yaml" 23 | pipelineRef: 24 | name: quarkus-devsecops-v1 25 | serviceAccountName: pipeline 26 | timeout: 1h0m0s 27 | workspaces: 28 | - name: workspace 29 | volumeClaimTemplate: 30 | metadata: 31 | creationTimestamp: null 32 | spec: 33 | accessModes: 34 | - ReadWriteOnce 35 | resources: 36 | requests: 37 | storage: 1Gi -------------------------------------------------------------------------------- /chapter10/change-repo-urls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "================================================" 4 | echo "" 5 | echo "Change the references to your forked Git repo" 6 | echo "Created by: Giovanni Fontana" 7 | echo "" 8 | echo "================================================" 9 | 10 | echo "** Input your github username: " 11 | read repo_user 12 | echo "" 13 | echo "** Changing ArgoCD and Pipeline manifests to your forked repo (https://github.com/$repo_user/Openshift-Multi-Cluster-management/)" 14 | 15 | sed -i "s/PacktPublishing/$repo_user/" ./config/argocd/argocd-app-dev.yaml 16 | sed -i "s/PacktPublishing/$repo_user/" ./config/argocd/argocd-app-qa.yaml 17 | sed -i "s/PacktPublishing/$repo_user/" ./config/argocd/argocd-app-prod.yaml 18 | sed -i "s/PacktPublishing/$repo_user/" ./config/cicd/pipelinerun/build-v1.yaml 19 | 20 | echo "" 21 | echo "** Manifest files changed. Pushing changes to GitHub (please inform your GitHub user and password if asked)." 22 | 23 | git add ./config/argocd/* ./config/cicd/pipelinerun/build-v1.yaml >>/dev/null 24 | git commit -m 'Changed ArgoCD and Pipeline manifests to forked repo' >>/dev/null 25 | git push -u origin main >>/dev/null 26 | 27 | echo "" 28 | echo "** References changed to your forked repository" -------------------------------------------------------------------------------- /quarkus-getting-started/k8s/base/deployment.yaml: -------------------------------------------------------------------------------- 1 | kind: Deployment 2 | apiVersion: apps/v1 3 | metadata: 4 | name: quarkus-quickstarts 5 | labels: 6 | app: quarkus-quickstarts 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: quarkus-quickstarts 12 | template: 13 | metadata: 14 | creationTimestamp: null 15 | labels: 16 | app: quarkus-quickstarts 17 | deployment: quarkus-quickstarts 18 | spec: 19 | containers: 20 | - name: quarkus-quickstarts 21 | image: >- 22 | changeme 23 | ports: 24 | - containerPort: 8080 25 | protocol: TCP 26 | - containerPort: 8443 27 | protocol: TCP 28 | resources: {} 29 | terminationMessagePath: /dev/termination-log 30 | terminationMessagePolicy: File 31 | imagePullPolicy: Always 32 | restartPolicy: Always 33 | terminationGracePeriodSeconds: 30 34 | dnsPolicy: ClusterFirst 35 | securityContext: {} 36 | schedulerName: default-scheduler 37 | strategy: 38 | type: RollingUpdate 39 | rollingUpdate: 40 | maxUnavailable: 25% 41 | maxSurge: 25% 42 | revisionHistoryLimit: 10 43 | progressDeadlineSeconds: 600 -------------------------------------------------------------------------------- /chapter09/Trigger/clouds-api-tt.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: triggers.tekton.dev/v1beta1 2 | kind: TriggerTemplate 3 | metadata: 4 | name: clouds-api-tt 5 | spec: 6 | params: 7 | - name: git-repo-url 8 | description: The git repository url 9 | - name: git-revision 10 | description: The git revision 11 | default: master 12 | - name: git-repo-name 13 | description: The name of the deployment to be created / patched 14 | resourcetemplates: 15 | - apiVersion: tekton.dev/v1beta1 16 | kind: PipelineRun 17 | metadata: 18 | generateName: build-deploy- 19 | spec: 20 | serviceAccountName: pipeline 21 | pipelineRef: 22 | name: build-and-deploy 23 | params: 24 | - name: deployment-name 25 | value: clouds-api 26 | - name: git-url 27 | value: $(tt.params.git-repo-url) 28 | - name: git-revision 29 | value: $(tt.params.git-revision) 30 | - name: IMAGE 31 | value: image-registry.openshift-image-registry.svc:5000/pipelines-sample/clouds-api 32 | workspaces: 33 | - name: shared-workspace 34 | volumeClaimTemplate: 35 | spec: 36 | accessModes: 37 | - ReadWriteOnce 38 | resources: 39 | requests: 40 | storage: 500Mi 41 | -------------------------------------------------------------------------------- /chapter05/aws-install-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | baseDomain: hybridcloud.com 3 | credentialsMode: Mint 4 | controlPlane: 5 | hyperthreading: Enabled 6 | name: master 7 | platform: 8 | aws: 9 | zones: 10 | - us-west-2a 11 | - us-west-2b 12 | rootVolume: 13 | iops: 4000 14 | size: 500 15 | type: io1 16 | type: m5.xlarge 17 | replicas: 3 18 | compute: 19 | - hyperthreading: Enabled 20 | name: worker 21 | platform: 22 | aws: 23 | rootVolume: 24 | iops: 2000 25 | size: 500 26 | type: io1 27 | type: c5.4xlarge 28 | zones: 29 | - us-west-2c 30 | replicas: 3 31 | metadata: 32 | name: test-cluster 33 | networking: 34 | clusterNetwork: 35 | - cidr: 10.128.0.0/14 36 | hostPrefix: 23 37 | machineNetwork: 38 | - cidr: 10.0.0.0/16 39 | networkType: OpenShiftSDN 40 | serviceNetwork: 41 | - 172.30.0.0/16 42 | platform: 43 | aws: 44 | region: us-west-2 45 | userTags: 46 | adminContact: jdoe 47 | costCenter: 7536 48 | amiID: ami-96c6f8f7 49 | serviceEndpoints: 50 | - name: ec2 51 | url: https://vpce-id.ec2.us-west-2.vpce.amazonaws.com 52 | fips: false 53 | sshKey: ssh-ed25519 AAAA... 54 | pullSecret: '{"auths": ...}' -------------------------------------------------------------------------------- /chapter05/gcp-install-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | baseDomain: hybridcloud.com 3 | controlPlane: 4 | hyperthreading: Enabled 5 | name: master 6 | platform: 7 | gcp: 8 | type: n2-standard-4 9 | zones: 10 | - us-central1-a 11 | - us-central1-c 12 | osDisk: 13 | diskType: pd-ssd 14 | diskSizeGB: 1024 15 | encryptionKey: 16 | kmsKey: 17 | name: worker-key 18 | keyRing: test-machine-keys 19 | location: global 20 | projectID: project-id 21 | replicas: 3 22 | compute: 23 | - hyperthreading: Enabled 24 | name: worker 25 | platform: 26 | gcp: 27 | type: n2-standard-4 28 | zones: 29 | - us-central1-a 30 | - us-central1-c 31 | osDisk: 32 | diskType: pd-standard 33 | diskSizeGB: 128 34 | encryptionKey: 35 | kmsKey: 36 | name: worker-key 37 | keyRing: test-machine-keys 38 | location: global 39 | projectID: project-id 40 | replicas: 3 41 | metadata: 42 | name: test-cluster 43 | networking: 44 | clusterNetwork: 45 | - cidr: 10.128.0.0/14 46 | hostPrefix: 23 47 | machineNetwork: 48 | - cidr: 10.0.0.0/16 49 | networkType: OpenShiftSDN 50 | serviceNetwork: 51 | - 172.30.0.0/16 52 | platform: 53 | gcp: 54 | projectID: openshift-production 55 | region: us-central1 56 | pullSecret: '{"auths": ...}' 57 | fips: false 58 | sshKey: ssh-ed25519 AAAA... -------------------------------------------------------------------------------- /chapter06/new-master-machine.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: machine.openshift.io/v1beta1 2 | kind: Machine 3 | metadata: 4 | finalizers: 5 | - machine.machine.openshift.io 6 | labels: 7 | machine.openshift.io/cluster-api-cluster: ocp-sgw5f 8 | machine.openshift.io/cluster-api-machine-role: master 9 | machine.openshift.io/cluster-api-machine-type: master 10 | machine.openshift.io/region: "" 11 | machine.openshift.io/zone: "" 12 | manager: cluster-bootstrap 13 | operation: Update 14 | name: ocp-master-4 15 | namespace: openshift-machine-api 16 | selfLink: /apis/machine.openshift.io/v1beta1/namespaces/openshift-machine-api/machines/ocp-master-4 17 | spec: 18 | metadata: {} 19 | providerSpec: 20 | value: 21 | apiVersion: vsphereprovider.openshift.io/v1beta1 22 | credentialsSecret: 23 | name: vsphere-cloud-credentials 24 | diskGiB: 120 25 | kind: VSphereMachineProviderSpec 26 | memoryMiB: 16384 27 | metadata: 28 | creationTimestamp: null 29 | network: 30 | devices: 31 | - networkName: net-prod-01 32 | numCPUs: 4 33 | numCoresPerSocket: 2 34 | snapshot: "" 35 | template: ocp-sgw5f-rhcos 36 | userDataSecret: 37 | name: master-user-data 38 | workspace: 39 | datacenter: MYDC 40 | datastore: DATASTORE01 41 | folder: /MYDC/vm/Openshift_PROD 42 | resourcePool: /MYDC/host/DS01/Resources 43 | server: vcenter01.mydc.hybridcloud.com 44 | -------------------------------------------------------------------------------- /chapter11/argocd/applicationset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: cloud-api 5 | namespace: openshift-gitops 6 | spec: 7 | generators: 8 | - clusterDecisionResource: 9 | configMapRef: acm-placement 10 | labelSelector: 11 | matchLabels: 12 | cluster.open-cluster-management.io/placement: cloud-api-placement 13 | requeueAfterSeconds: 180 14 | template: 15 | metadata: 16 | name: cloud-api-{{name}} 17 | labels: 18 | velero.io/exclude-from-backup: "true" 19 | spec: 20 | project: default 21 | source: 22 | repoURL: https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git 23 | targetRevision: main 24 | path: sample-go-app/clouds-api/k8s/ 25 | destination: 26 | namespace: cloud-api 27 | server: "{{server}}" 28 | syncPolicy: 29 | automated: 30 | selfHeal: false 31 | prune: true 32 | syncOptions: 33 | - CreateNamespace=true 34 | - PrunePropagationPolicy=orphan 35 | --- 36 | apiVersion: cluster.open-cluster-management.io/v1beta1 37 | kind: Placement 38 | metadata: 39 | name: cloud-api-placement 40 | namespace: openshift-gitops 41 | spec: 42 | predicates: 43 | - requiredClusterSelector: 44 | labelSelector: 45 | matchExpressions: 46 | - key: env 47 | operator: In 48 | values: 49 | - dev 50 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/applicationset.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ApplicationSet 3 | metadata: 4 | name: quarkus-quickstarts-appset 5 | namespace: openshift-gitops 6 | spec: 7 | generators: 8 | - clusterDecisionResource: 9 | configMapRef: acm-placement 10 | labelSelector: 11 | matchLabels: 12 | cluster.open-cluster-management.io/placement: prod-clusters 13 | requeueAfterSeconds: 180 14 | template: 15 | metadata: 16 | name: quarkus-quickstart-{{name}} 17 | labels: 18 | velero.io/exclude-from-backup: "true" 19 | spec: 20 | project: default 21 | source: 22 | repoURL: https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git 23 | targetRevision: main 24 | path: quarkus-getting-started/k8s/overlay/v2/ 25 | destination: 26 | namespace: chap14-review-cicd 27 | server: "{{server}}" 28 | syncPolicy: 29 | automated: 30 | selfHeal: false 31 | prune: true 32 | syncOptions: 33 | - CreateNamespace=true 34 | - PrunePropagationPolicy=orphan 35 | --- 36 | apiVersion: cluster.open-cluster-management.io/v1beta1 37 | kind: Placement 38 | metadata: 39 | name: prod-clusters 40 | namespace: openshift-gitops 41 | spec: 42 | predicates: 43 | - requiredClusterSelector: 44 | labelSelector: 45 | matchExpressions: 46 | - key: env 47 | operator: In 48 | values: 49 | - prod 50 | -------------------------------------------------------------------------------- /chapter11/acm-observability/alertmanager.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | slack_api_url: 'https://hooks.slack.com/services/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' 3 | resolve_timeout: 1m 4 | 5 | route: 6 | receiver: 'slack-notifications' 7 | group_by: ['alertname', 'cluster', 'service'] 8 | group_wait: 10s 9 | group_interval: 30s 10 | repeat_interval: 30m 11 | 12 | routes: 13 | - receiver: slack-notifications 14 | match: 15 | severity: critical|warning 16 | 17 | 18 | 19 | receivers: 20 | - name: 'slack-notifications' 21 | slack_configs: 22 | - channel: '#alertmanager-service' 23 | send_resolved: true 24 | icon_url: https://avatars3.githubusercontent.com/u/3380462 25 | title: |- 26 | [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }} 27 | {{- if gt (len .CommonLabels) (len .GroupLabels) -}} 28 | {{" "}}( 29 | {{- with .CommonLabels.Remove .GroupLabels.Names }} 30 | {{- range $index, $label := .SortedPairs -}} 31 | {{ if $index }}, {{ end }} 32 | {{- $label.Name }}="{{ $label.Value -}}" 33 | {{- end }} 34 | {{- end -}} 35 | ) 36 | {{- end }} 37 | text: >- 38 | {{ range .Alerts -}} 39 | *Alert:* {{ .Annotations.title }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }} 40 | 41 | *Description:* {{ .Annotations.description }} 42 | 43 | *Details:* 44 | {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}` 45 | {{ end }} 46 | {{ end }} 47 | 48 | -------------------------------------------------------------------------------- /chapter05/dhcpd.conf: -------------------------------------------------------------------------------- 1 | # DHCP Server Configuration file. 2 | #[1] 3 | ddns-update-style interim; 4 | ignore client-updates; 5 | authoritative; 6 | allow booting; 7 | allow bootp; 8 | allow unknown-clients; 9 | default-lease-time 3600; 10 | default-lease-time 900; 11 | max-lease-time 7200; 12 | 13 | #[2] 14 | subnet 192.168.1.0 netmask 255.255.255.0 { 15 | option routers 192.168.1.254; 16 | option domain-name-servers 192.168.1.200; 17 | option ntp-servers 192.168.1.200; 18 | next-server 192.168.1.200; #[2.1] 19 | 20 | #filename "pxelinux.0";#[2.2] 21 | #[3] 22 | group { 23 | host bootstrap { 24 | hardware ethernet 50:6b:8d:aa:aa:aa; 25 | fixed-address 192.168.1.90; 26 | option host-name "bootstrap.ocp.hybridcloud.com"; 27 | allow booting; 28 | } 29 | 30 | host master1 { 31 | hardware ethernet 50:6b:8d:bb:bb:bb; 32 | fixed-address 192.168.1.91; 33 | option host-name "master1.ocp.hybridcloud.com"; 34 | allow booting; 35 | } 36 | 37 | host master2 { 38 | hardware ethernet 50:6b:8d:cc:cc:cc; 39 | fixed-address 192.168.1.92 ; 40 | option host-name "master2.ocp.hybridcloud.com"; 41 | allow booting; 42 | } 43 | 44 | host master3 { 45 | hardware ethernet 50:6b:8d:dd:dd:dd; 46 | fixed-address 192.168.1.93 ; 47 | option host-name "master3.ocp.hybridcloud.com"; 48 | allow booting; 49 | } 50 | 51 | host worker1 { 52 | hardware ethernet 50:6b:8d:11:11:11; 53 | fixed-address 192.168.1.101; 54 | option host-name "worker1.ocp.hybridcloud.com"; 55 | allow booting; 56 | } 57 | 58 | host worker2 { 59 | hardware ethernet 50:6b:8d:22:22:22; 60 | fixed-address 192.168.1.102; 61 | option host-name "worker2.ocp.hybridcloud.com"; 62 | allow booting; 63 | } 64 | 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /chapter10/config/cicd/pipeline/build-app.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: build-app 5 | spec: 6 | workspaces: 7 | - name: shared-workspace 8 | params: 9 | - name: git-url 10 | type: string 11 | description: url of the git repo for the code of deployment 12 | - name: git-revision 13 | type: string 14 | description: revision to be used from repo of the code for deployment 15 | - name: IMAGE 16 | type: string 17 | description: image to be build from the code 18 | - name: CONTEXT 19 | type: string 20 | description: Path to the application source code directory 21 | default: "./sample-go-app/clouds-api/" 22 | tasks: 23 | - name: fetch-repository 24 | taskRef: 25 | name: git-clone 26 | kind: ClusterTask 27 | workspaces: 28 | - name: output 29 | workspace: shared-workspace 30 | params: 31 | - name: url 32 | value: $(params.git-url) 33 | - name: subdirectory 34 | value: "" 35 | - name: deleteExisting 36 | value: "true" 37 | - name: revision 38 | value: $(params.git-revision) 39 | - name: golang-unit-test 40 | taskRef: 41 | name: golang-unit-test 42 | params: 43 | - name: context 44 | value: $(params.CONTEXT) 45 | - name: module-name 46 | value: "clouds" 47 | workspaces: 48 | - name: source 49 | workspace: shared-workspace 50 | runAfter: 51 | - fetch-repository 52 | - name: build-image 53 | taskRef: 54 | name: buildah 55 | kind: ClusterTask 56 | params: 57 | - name: IMAGE 58 | value: $(params.IMAGE) 59 | - name: CONTEXT 60 | value: $(params.CONTEXT) 61 | workspaces: 62 | - name: source 63 | workspace: shared-workspace 64 | runAfter: 65 | - golang-unit-test 66 | -------------------------------------------------------------------------------- /chapter11/governance/policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: Policy 3 | metadata: 4 | name: policy-etcdencryption 5 | annotations: 6 | policy.open-cluster-management.io/standards: NIST SP 800-53 7 | policy.open-cluster-management.io/categories: SC System and Communications Protection 8 | policy.open-cluster-management.io/controls: SC-28 Protection Of Information At Rest 9 | spec: 10 | remediationAction: inform 11 | disabled: false 12 | policy-templates: 13 | - objectDefinition: 14 | apiVersion: policy.open-cluster-management.io/v1 15 | kind: ConfigurationPolicy 16 | metadata: 17 | name: enable-etcd-encryption 18 | spec: 19 | remediationAction: inform 20 | severity: low 21 | object-templates: 22 | - complianceType: musthave 23 | objectDefinition: 24 | apiVersion: config.openshift.io/v1 25 | kind: APIServer 26 | metadata: 27 | name: cluster 28 | spec: 29 | encryption: 30 | type: aescbc 31 | - objectDefinition: 32 | apiVersion: policy.open-cluster-management.io/v1 33 | kind: ConfigurationPolicy 34 | metadata: 35 | name: enable-etcd-encryption-status-kubeapi 36 | spec: 37 | remediationAction: inform 38 | severity: low 39 | object-templates: 40 | - complianceType: musthave 41 | objectDefinition: 42 | apiVersion: operator.openshift.io/v1 43 | kind: KubeAPIServer 44 | metadata: 45 | name: cluster 46 | status: 47 | conditions: 48 | - message: 'All resources encrypted: secrets, configmaps' 49 | reason: EncryptionCompleted 50 | -------------------------------------------------------------------------------- /chapter14/Governance/policy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: policy.open-cluster-management.io/v1 2 | kind: Policy 3 | metadata: 4 | name: policy-etcdencryption 5 | annotations: 6 | policy.open-cluster-management.io/standards: NIST SP 800-53 7 | policy.open-cluster-management.io/categories: SC System and Communications Protection 8 | policy.open-cluster-management.io/controls: SC-28 Protection Of Information At Rest 9 | spec: 10 | remediationAction: inform 11 | disabled: false 12 | policy-templates: 13 | - objectDefinition: 14 | apiVersion: policy.open-cluster-management.io/v1 15 | kind: ConfigurationPolicy 16 | metadata: 17 | name: enable-etcd-encryption 18 | spec: 19 | remediationAction: inform 20 | severity: low 21 | object-templates: 22 | - complianceType: musthave 23 | objectDefinition: 24 | apiVersion: config.openshift.io/v1 25 | kind: APIServer 26 | metadata: 27 | name: cluster 28 | spec: 29 | encryption: 30 | type: aescbc 31 | - objectDefinition: 32 | apiVersion: policy.open-cluster-management.io/v1 33 | kind: ConfigurationPolicy 34 | metadata: 35 | name: enable-etcd-encryption-status-kubeapi 36 | spec: 37 | remediationAction: inform 38 | severity: low 39 | object-templates: 40 | - complianceType: musthave 41 | objectDefinition: 42 | apiVersion: operator.openshift.io/v1 43 | kind: KubeAPIServer 44 | metadata: 45 | name: cluster 46 | status: 47 | conditions: 48 | - message: 'All resources encrypted: secrets, configmaps' 49 | reason: EncryptionCompleted 50 | -------------------------------------------------------------------------------- /chapter09/Tasks/check-route-health.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: check-app-health 5 | spec: 6 | params: 7 | - name: deployment 8 | description: The name of the deployment patch the image 9 | type: string 10 | - name: route 11 | description: The name of the deployment to check 12 | type: string 13 | default: clouds-api 14 | - name: subpath 15 | description: API sub-path 16 | type: string 17 | default: "cloud" 18 | steps: 19 | - name: apply 20 | image: registry.redhat.io/openshift4/ose-cli:latest 21 | workingDir: /workspace/source 22 | command: ["/bin/bash", "-c"] 23 | args: 24 | - |- 25 | echo "Waiting for application $(inputs.params.deployment) to be ready." 26 | 27 | TIMEOUT=0 28 | pod_status=`oc get pods -l app=$(inputs.params.deployment) -o jsonpath='{.items[0].status.phase}'` 29 | while [ "$pod_status" != "Running" ]; do 30 | echo "Pod is not ready yet. Current pod status is $pod_status ..." 31 | sleep 2 32 | if [ $TIMEOUT -gt 30 ]; then #1 MINUTE TIMEOUT 33 | echo "Timeout reached... Check the status of the deployment." 34 | exit 1 35 | fi 36 | TIMEOUT=$(($TIMEOUT+1)) 37 | pod_status=`oc get pods -l app=$(inputs.params.deployment) -o jsonpath='{.items[0].status.phase}'` 38 | done 39 | 40 | echo "Checking if application is available at the route endpoint" 41 | url=`oc get route $(inputs.params.route) -o jsonpath='{.spec.host}'` 42 | result=`curl -s "http://${url}/$(inputs.params.subpath)"` 43 | 44 | if [ ! -z "$result" ]; then 45 | echo "Application is available at http://${url}/$(inputs.params.subpath)" 46 | fi 47 | 48 | echo ----------------------------------- 49 | -------------------------------------------------------------------------------- /chapter10/config/cicd/tasks/check-route-health.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: check-app-health 5 | spec: 6 | params: 7 | - name: deployment 8 | description: The name of the deployment patch the image 9 | type: string 10 | - name: route 11 | description: The name of the deployment to check 12 | type: string 13 | default: clouds-api 14 | - name: subpath 15 | description: API sub-path 16 | type: string 17 | default: "cloud" 18 | - name: namespace 19 | description: namespace 20 | type: string 21 | steps: 22 | - name: apply 23 | image: registry.redhat.io/openshift4/ose-cli:latest 24 | workingDir: /workspace/source 25 | command: ["/bin/bash", "-c"] 26 | args: 27 | - |- 28 | echo "Waiting for application $(inputs.params.deployment) to be ready." 29 | 30 | TIMEOUT=0 31 | pod_status=`oc get pods -l app=$(inputs.params.deployment) -o jsonpath='{.items[0].status.phase}' -n $(inputs.params.namespace)` 32 | while [ "$pod_status" != "Running" ]; do 33 | echo "Pod is not ready yet. Current pod status is $pod_status ..." 34 | sleep 2 35 | if [ $TIMEOUT -gt 30 ]; then #1 MINUTE TIMEOUT 36 | echo "Timeout reached... Check the status of the deployment." 37 | exit 1 38 | fi 39 | TIMEOUT=$(($TIMEOUT+1)) 40 | pod_status=`oc get pods -l app=$(inputs.params.deployment) -o jsonpath='{.items[0].status.phase}' -n $(inputs.params.namespace)` 41 | done 42 | 43 | echo "Checking if application is available at the route endpoint" 44 | url=`oc get route $(inputs.params.route) -o jsonpath='{.spec.host}' -n $(inputs.params.namespace)` 45 | result=`curl -s "http://${url}/$(inputs.params.subpath)"` 46 | 47 | if [ ! -z "$result" ]; then 48 | echo "Application is available at http://${url}/$(inputs.params.subpath)" 49 | fi 50 | 51 | echo ----------------------------------- 52 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/docker/Dockerfile.legacy-jar: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Dquarkus.package.type=legacy-jar 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.legacy-jar -t quarkus/getting-started-legacy-jar . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/getting-started-legacy-jar 15 | # 16 | # If you want to include the debug port into your docker image 17 | # you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050 18 | # 19 | # Then run the container using : 20 | # 21 | # docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-legacy-jar 22 | # 23 | ### 24 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 25 | 26 | ARG JAVA_PACKAGE=java-11-openjdk-headless 27 | ARG RUN_JAVA_VERSION=1.3.8 28 | ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' 29 | # Install java and the run-java script 30 | # Also set up permissions for user `1001` 31 | RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ 32 | && microdnf update \ 33 | && microdnf clean all \ 34 | && mkdir /deployments \ 35 | && chown 1001 /deployments \ 36 | && chmod "g+rwX" /deployments \ 37 | && chown 1001:root /deployments \ 38 | && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ 39 | && chown 1001 /deployments/run-java.sh \ 40 | && chmod 540 /deployments/run-java.sh \ 41 | && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security 42 | 43 | # Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. 44 | ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" 45 | COPY target/lib/* /deployments/lib/ 46 | COPY target/*-runner.jar /deployments/app.jar 47 | 48 | EXPOSE 8080 49 | USER 1001 50 | 51 | ENTRYPOINT [ "/deployments/run-java.sh" ] 52 | -------------------------------------------------------------------------------- /chapter05/named.conf: -------------------------------------------------------------------------------- 1 | options { 2 | listen-on port 53 { 127.0.0.1; 192.168.1.200; }; 3 | listen-on-v6 port 53 { ::1; }; 4 | directory "/var/named"; 5 | dump-file "/var/named/data/cache_dump.db"; 6 | statistics-file "/var/named/data/named_stats.txt"; 7 | memstatistics-file "/var/named/data/named_mem_stats.txt"; 8 | secroots-file "/var/named/data/named.secroots"; 9 | recursing-file "/var/named/data/named.recursing"; 10 | allow-query { any; }; 11 | forwarders { 192.168.1.1; }; 12 | 13 | /* 14 | - If you are building an AUTHORITATIVE DNS server, do NOT enable recursion. 15 | - If you are building a RECURSIVE (caching) DNS server, you need to enable 16 | recursion. 17 | - If your recursive DNS server has a public IP address, you MUST enable access 18 | control to limit queries to your legitimate users. Failing to do so will 19 | cause your server to become part of large scale DNS amplification 20 | attacks. Implementing BCP38 within your network would greatly 21 | reduce such attack surface 22 | */ 23 | recursion yes; 24 | 25 | dnssec-enable yes; 26 | dnssec-validation yes; 27 | 28 | managed-keys-directory "/var/named/dynamic"; 29 | 30 | pid-file "/run/named/named.pid"; 31 | session-keyfile "/run/named/session.key"; 32 | 33 | /* https://fedoraproject.org/wiki/Changes/CryptoPolicy */ 34 | include "/etc/crypto-policies/back-ends/bind.config"; 35 | }; 36 | 37 | logging { 38 | channel default_debug { 39 | file "data/named.run"; 40 | severity dynamic; 41 | }; 42 | }; 43 | 44 | zone "." IN { 45 | type hint; 46 | file "named.ca"; 47 | }; 48 | 49 | include "/etc/named.rfc1912.zones"; 50 | include "/etc/named.root.key"; 51 | 52 | zone "ocp.hybridmycloud.com" IN { 53 | type master; 54 | file "/var/named/ocp.hybridmycloud.com.db"; 55 | allow-query { any; }; 56 | allow-transfer { none; }; 57 | allow-update { none; }; 58 | }; 59 | 60 | zone "1.168.192.in-addr.arpa" IN { 61 | type master; 62 | file "/var/named/1.168.192.in-addr.arpa"; 63 | allow-update { none; }; 64 | }; 65 | 66 | -------------------------------------------------------------------------------- /chapter14/Build/Pipeline/quarkus-build-pi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: quarkus-build 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - default: quarkus-quickstarts 9 | name: APP_NAME 10 | type: string 11 | - default: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | name: GIT_REPO 13 | type: string 14 | - default: '' 15 | name: GIT_REVISION 16 | type: string 17 | - default: >- 18 | image-registry.openshift-image-registry.svc:5000/chap14-review-cicd/quarkus-quickstarts 19 | name: IMAGE_NAME 20 | type: string 21 | - default: quarkus-getting-started 22 | name: PATH_CONTEXT 23 | type: string 24 | - name: K8S_MANIFESTS_PATH 25 | type: string 26 | - default: openjdk-17-ubi8 27 | name: VERSION 28 | type: string 29 | tasks: 30 | - name: fetch-repository 31 | params: 32 | - name: url 33 | value: $(params.GIT_REPO) 34 | - name: revision 35 | value: $(params.GIT_REVISION) 36 | - name: subdirectory 37 | value: '' 38 | - name: deleteExisting 39 | value: 'true' 40 | taskRef: 41 | kind: ClusterTask 42 | name: git-clone 43 | workspaces: 44 | - name: output 45 | workspace: workspace 46 | - name: build 47 | params: 48 | - name: IMAGE 49 | value: $(params.IMAGE_NAME) 50 | - name: TLSVERIFY 51 | value: 'false' 52 | - name: PATH_CONTEXT 53 | value: $(params.PATH_CONTEXT) 54 | - name: VERSION 55 | value: $(params.VERSION) 56 | runAfter: 57 | - fetch-repository 58 | taskRef: 59 | kind: ClusterTask 60 | name: s2i-java 61 | workspaces: 62 | - name: source 63 | workspace: workspace 64 | - name: deploy 65 | params: 66 | - name: SCRIPT 67 | value: oc apply -k $(params.K8S_MANIFESTS_PATH) 68 | runAfter: 69 | - build 70 | taskRef: 71 | kind: ClusterTask 72 | name: openshift-client 73 | workspaces: 74 | - name: manifest-dir 75 | workspace: workspace 76 | workspaces: 77 | - name: workspace 78 | -------------------------------------------------------------------------------- /chapter09/Pipeline/build-deploy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: build-and-deploy 5 | spec: 6 | workspaces: 7 | - name: shared-workspace 8 | params: 9 | - name: deployment-name 10 | type: string 11 | description: name of the deployment to be patched 12 | - name: git-url 13 | type: string 14 | description: url of the git repo for the code of deployment 15 | - name: git-revision 16 | type: string 17 | description: revision to be used from repo of the code for deployment 18 | default: "main" 19 | - name: IMAGE 20 | type: string 21 | description: image to be build from the code 22 | - name: CONTEXT 23 | type: string 24 | description: Path to the application source code directory 25 | default: "./sample-go-app/clouds-api/" 26 | tasks: 27 | - name: fetch-repository 28 | taskRef: 29 | name: git-clone 30 | kind: ClusterTask 31 | workspaces: 32 | - name: output 33 | workspace: shared-workspace 34 | params: 35 | - name: url 36 | value: $(params.git-url) 37 | - name: subdirectory 38 | value: "" 39 | - name: deleteExisting 40 | value: "true" 41 | - name: revision 42 | value: $(params.git-revision) 43 | - name: build-image 44 | taskRef: 45 | name: buildah 46 | kind: ClusterTask 47 | params: 48 | - name: IMAGE 49 | value: $(params.IMAGE) 50 | - name: CONTEXT 51 | value: $(params.CONTEXT) 52 | workspaces: 53 | - name: source 54 | workspace: shared-workspace 55 | runAfter: 56 | - fetch-repository 57 | - name: apply-manifests 58 | taskRef: 59 | name: apply-manifests 60 | workspaces: 61 | - name: source 62 | workspace: shared-workspace 63 | runAfter: 64 | - build-image 65 | - name: update-image-version 66 | taskRef: 67 | name: update-image-version 68 | params: 69 | - name: deployment 70 | value: $(params.deployment-name) 71 | - name: IMAGE 72 | value: $(params.IMAGE) 73 | runAfter: 74 | - apply-manifests 75 | - name: check-app-health 76 | taskRef: 77 | name: check-app-health 78 | params: 79 | - name: deployment 80 | value: $(params.deployment-name) 81 | runAfter: 82 | - update-image-version 83 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/docker/Dockerfile.jvm: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in JVM mode 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.jvm -t quarkus/getting-started-jvm . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/getting-started-jvm 15 | # 16 | # If you want to include the debug port into your docker image 17 | # you will have to expose the debug port (default 5005) like this : EXPOSE 8080 5050 18 | # 19 | # Then run the container using : 20 | # 21 | # docker run -i --rm -p 8080:8080 -p 5005:5005 -e JAVA_ENABLE_DEBUG="true" quarkus/getting-started-jvm 22 | # 23 | ### 24 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 25 | 26 | ARG JAVA_PACKAGE=java-11-openjdk-headless 27 | ARG RUN_JAVA_VERSION=1.3.8 28 | ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' 29 | # Install java and the run-java script 30 | # Also set up permissions for user `1001` 31 | RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} \ 32 | && microdnf update \ 33 | && microdnf clean all \ 34 | && mkdir /deployments \ 35 | && chown 1001 /deployments \ 36 | && chmod "g+rwX" /deployments \ 37 | && chown 1001:root /deployments \ 38 | && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh \ 39 | && chown 1001 /deployments/run-java.sh \ 40 | && chmod 540 /deployments/run-java.sh \ 41 | && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security 42 | 43 | # Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size. 44 | ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" 45 | # We make four distinct layers so if there are application changes the library layers can be re-used 46 | COPY --chown=1001 target/quarkus-app/lib/ /deployments/lib/ 47 | COPY --chown=1001 target/quarkus-app/*.jar /deployments/ 48 | COPY --chown=1001 target/quarkus-app/app/ /deployments/app/ 49 | COPY --chown=1001 target/quarkus-app/quarkus/ /deployments/quarkus/ 50 | 51 | EXPOSE 8080 52 | USER 1001 53 | 54 | ENTRYPOINT [ "/deployments/run-java.sh" ] 55 | -------------------------------------------------------------------------------- /chapter05/haproxy.cfg : -------------------------------------------------------------------------------- 1 | # Global settings 2 | 3 | global 4 | maxconn 20000 5 | log /dev/log local0 info 6 | chroot /var/lib/haproxy 7 | pidfile /var/run/haproxy.pid 8 | user haproxy 9 | group haproxy 10 | daemon 11 | 12 | # turn on stats unix socket 13 | stats socket /var/lib/haproxy/stats 14 | 15 | defaults 16 | mode http 17 | log global 18 | option httplog 19 | option dontlognull 20 | option forwardfor except 127.0.0.0/8 21 | option redispatch 22 | retries 3 23 | timeout http-request 10s 24 | timeout queue 1m 25 | timeout connect 10s 26 | timeout client 300s 27 | timeout server 300s 28 | timeout http-keep-alive 10s 29 | timeout check 10s 30 | maxconn 20000 31 | 32 | # Enable haproxy status endpoint 33 | 34 | listen stats 35 | bind :9000 36 | mode http 37 | stats enable 38 | stats uri / 39 | 40 | # OpenShift API (port 6443) 41 | 42 | frontend openshift-api-server 43 | bind *:6443 44 | default_backend openshift-api-server 45 | mode tcp 46 | option tcplog 47 | 48 | backend openshift-api-server 49 | balance source 50 | mode tcp 51 | 52 | # bootstrap line below can be removed after the cluster is deployed 53 | server bootstrap 192.168.1.90:6443 check 54 | server master1 192.168.1.91:6443 check 55 | server master2 192.168.1.92:6443 check 56 | server master3 192.168.1.93:6443 check 57 | 58 | # machine-config-server API (port 22623) 59 | frontend machine-config-server 60 | bind *:22623 61 | default_backend machine-config-server 62 | mode tcp 63 | option tcplog 64 | 65 | backend machine-config-server 66 | balance source 67 | mode tcp 68 | 69 | # bootstrap line below can be removed after the cluster is deployed 70 | server bootstrap 192.168.1.90:22623 check 71 | server master1 192.168.1.91:22623 check 72 | server master2 192.168.1.92:22623 check 73 | server master3 192.168.1.93:22623 check 74 | 75 | # Applications HTTP (port 80) 76 | frontend ingress-http 77 | bind *:80 78 | default_backend ingress-http 79 | mode tcp 80 | option tcplog 81 | 82 | backend ingress-http 83 | balance source 84 | mode tcp 85 | server worker1 192.168.1.101:80 check # [1] 86 | server worker2 192.168.1.102:80 check # [1] 87 | 88 | # Applications HTTPS (port 443) 89 | frontend ingress-https 90 | bind *:443 91 | default_backend ingress-https 92 | mode tcp 93 | option tcplog 94 | 95 | backend ingress-https 96 | balance source 97 | mode tcp 98 | server worker0 192.168.1.101:443 check # [1] 99 | server worker1 192.168.1.102:443 check # [1] 100 | -------------------------------------------------------------------------------- /chapter14/DevSecOps/Task/stackrox-image-check.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Task 4 | metadata: 5 | name: stackrox-image-check 6 | namespace: chap14-review-cicd 7 | labels: 8 | app.kubernetes.io/version: "0.1" 9 | annotations: 10 | tekton.dev/tags: security 11 | tekton.dev/categories: Security 12 | tekton.dev/displayName: "Policy check an image with StackRox/RHACS" 13 | tekton.dev/platforms: "linux/amd64" 14 | tekton.dev/pipelines.minVersion: "0.18.0" 15 | spec: 16 | description: >- 17 | Policy check an image with StackRox/RHACS 18 | 19 | This tasks allows you to check an image against build-time policies 20 | and apply enforcement to fail builds. It's a companion to the 21 | stackrox-image-scan task, which returns full vulnerability scan 22 | results for an image. 23 | params: 24 | - name: rox_central_endpoint 25 | type: string 26 | description: | 27 | Secret containing the address:port tuple for StackRox Central) 28 | (example - rox.stackrox.io:443) 29 | - name: rox_api_token 30 | type: string 31 | description: Secret containing the StackRox API token with CI permissions 32 | - name: image 33 | type: string 34 | description: | 35 | Full name of image to scan (example -- gcr.io/rox/sample:5.0-rc1) 36 | - name: insecure-skip-tls-verify 37 | type: string 38 | description: | 39 | When set to `"true"`, skip verifying the TLS certs of the Central 40 | endpoint. Defaults to `"false"`. 41 | default: "false" 42 | results: 43 | - name: check_output 44 | description: Output of `roxctl image check` 45 | steps: 46 | - name: rox-image-check 47 | image: docker.io/centos@sha256:a1801b843b1bfaf77c501e7a6d3f709401a1e0c83863037fa3aab063a7fdb9dc 48 | env: 49 | - name: ROX_API_TOKEN 50 | valueFrom: 51 | secretKeyRef: 52 | name: $(params.rox_api_token) 53 | key: rox_api_token 54 | - name: ROX_CENTRAL_ENDPOINT 55 | valueFrom: 56 | secretKeyRef: 57 | name: $(params.rox_central_endpoint) 58 | key: rox_central_endpoint 59 | script: | 60 | #!/usr/bin/env bash 61 | set +x 62 | curl -s -k -L -H "Authorization: Bearer $ROX_API_TOKEN" \ 63 | "https://$ROX_CENTRAL_ENDPOINT/api/cli/download/roxctl-linux" \ 64 | --output ./roxctl \ 65 | > /dev/null 66 | chmod +x ./roxctl > /dev/null 67 | ./roxctl image check \ 68 | $( [ "$(params.insecure-skip-tls-verify)" = "true" ] && \ 69 | echo -n "--insecure-skip-tls-verify") \ 70 | -e "$ROX_CENTRAL_ENDPOINT" --image "$(params.image)" 71 | -------------------------------------------------------------------------------- /chapter09/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 9 - OpenShift Pipelines - Tekton 2 | 3 | List of commands to copy and paste: 4 | 5 | **Install the tkn CLI** 6 | 7 | ``` 8 | tar -xvzf tkn-linux-amd64-0.17.2.tar.gz 9 | sudo cp tkn /usr/local/bin 10 | tkn version 11 | ``` 12 | 13 | **Using tkn** 14 | 15 | ``` 16 | oc login -u https://:6443 17 | tkn clustertasks ls 18 | ``` 19 | 20 | **Creating a new (custom) Task** 21 | 22 | ``` 23 | oc new-project pipelines-sample 24 | oc get serviceaccount pipeline 25 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Tasks/apply-manifests.yaml 26 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Tasks/update-image-version.yaml 27 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Tasks/check-route-health.yaml 28 | tkn tasks ls 29 | ``` 30 | 31 | **TaskRun** 32 | 33 | ``` 34 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/PipelineRun/pvc.yaml 35 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Tasks/git-clone-taskrun.yaml 36 | tkn taskrun logs git-clone -f 37 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Tasks/apply-manifests-taskrun.yaml 38 | tkn taskrun logs run-apply-manifests -f 39 | ``` 40 | 41 | **Pipeline** 42 | 43 | ``` 44 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Pipeline/build-deploy.yaml 45 | tkn pipelines ls 46 | ``` 47 | 48 | **PipelineRun** 49 | 50 | ``` 51 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/PipelineRun/clouds-api-build-deploy.yaml 52 | tkn pipelinerun logs build-deploy-api-pipelinerun -f 53 | ``` 54 | 55 | **Using a Trigger with GitHub Webhook** 56 | 57 | ``` 58 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Trigger/clouds-api-tb.yaml 59 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Trigger/clouds-api-tt.yaml 60 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Trigger/clouds-api-trigger.yaml 61 | oc apply -f https://raw.githubusercontent.com/PacktPublishing/Openshift-Multi-Cluster-management/main/chapter06/Trigger/clouds-api-el.yaml 62 | oc expose svc el-clouds-api-el 63 | echo "$(oc get route el-clouds-api-el --template='http://{{.spec.host}}')" 64 | git commit -m "empty-commit" --allow-empty && git push origin main 65 | ``` 66 | -------------------------------------------------------------------------------- /chapter14/Deploy/Pipeline/quarkus-build-and-deploy-pi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: quarkus-build-and-deploy 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - default: quarkus-quickstarts 9 | name: APP_NAME 10 | type: string 11 | - default: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | name: GIT_REPO 13 | type: string 14 | - default: '' 15 | name: GIT_REVISION 16 | type: string 17 | - default: >- 18 | image-registry.openshift-image-registry.svc:5000/chap14-review-cicd/quarkus-quickstarts 19 | name: IMAGE_NAME 20 | type: string 21 | - default: quarkus-getting-started 22 | name: PATH_CONTEXT 23 | type: string 24 | - default: openjdk-17-ubi8 25 | name: VERSION 26 | type: string 27 | tasks: 28 | - name: fetch-repository 29 | params: 30 | - name: url 31 | value: $(params.GIT_REPO) 32 | - name: revision 33 | value: $(params.GIT_REVISION) 34 | - name: subdirectory 35 | value: '' 36 | - name: deleteExisting 37 | value: 'true' 38 | taskRef: 39 | kind: ClusterTask 40 | name: git-clone 41 | workspaces: 42 | - name: output 43 | workspace: workspace 44 | - name: build 45 | params: 46 | - name: IMAGE 47 | value: $(params.IMAGE_NAME) 48 | - name: TLSVERIFY 49 | value: 'false' 50 | - name: PATH_CONTEXT 51 | value: $(params.PATH_CONTEXT) 52 | - name: VERSION 53 | value: $(params.VERSION) 54 | runAfter: 55 | - fetch-repository 56 | taskRef: 57 | kind: ClusterTask 58 | name: s2i-java 59 | workspaces: 60 | - name: source 61 | workspace: workspace 62 | - name: deploy 63 | params: 64 | - name: SCRIPT 65 | value: >- 66 | set -euxo pipefail; 67 | oc apply -f chapter14/Deploy/argo-app.yaml; 68 | counter=0; 69 | timeout=120; 70 | while [[ $(oc get application quarkus-quickstarts -o jsonpath='{.status.health.status}' -n openshift-gitops) != "Healthy" ]]; 71 | do 72 | if [ $counter -gt $timeout ]; then 73 | echo 'Timeout reached! Inspect the application on OpenShift to check its status...'; 74 | exit 1; 75 | fi; 76 | echo 'App not healthy yet, waiting more 5 seconds...'; 77 | sleep 5; 78 | counter=$((counter+1)) 79 | done; 80 | echo 'App deployment finished and healthy'; 81 | runAfter: 82 | - build 83 | taskRef: 84 | kind: ClusterTask 85 | name: openshift-client 86 | workspaces: 87 | - name: manifest-dir 88 | workspace: workspace 89 | workspaces: 90 | - name: workspace 91 | -------------------------------------------------------------------------------- /quarkus-getting-started/README.md: -------------------------------------------------------------------------------- 1 | # Getting started with Quarkus 2 | 3 | This is a minimal CRUD service exposing a couple of endpoints over REST. 4 | 5 | Under the hood, this demo uses: 6 | 7 | - RESTEasy to expose the REST endpoints 8 | - REST-assured and JUnit 5 for endpoint testing 9 | 10 | ## Requirements 11 | 12 | To compile and run this demo you will need: 13 | 14 | - JDK 11+ 15 | - GraalVM 16 | 17 | ### Configuring GraalVM and JDK 11+ 18 | 19 | Make sure that both the `GRAALVM_HOME` and `JAVA_HOME` environment variables have 20 | been set, and that a JDK 11+ `java` command is on the path. 21 | 22 | See the [Building a Native Executable guide](https://quarkus.io/guides/building-native-image-guide) 23 | for help setting up your environment. 24 | 25 | ## Building the application 26 | 27 | Launch the Maven build on the checked out sources of this demo: 28 | 29 | > ./mvnw package 30 | 31 | ### Live coding with Quarkus 32 | 33 | The Maven Quarkus plugin provides a development mode that supports 34 | live coding. To try this out: 35 | 36 | > ./mvnw quarkus:dev 37 | 38 | This command will leave Quarkus running in the foreground listening on port 8080. 39 | 40 | 1. Visit the default endpoint: [http://127.0.0.1:8080](http://127.0.0.1:8080). 41 | - Make a simple change to [src/main/resources/META-INF/resources/index.html](src/main/resources/META-INF/resources/index.html) file. 42 | - Refresh the browser to see the updated page. 43 | 2. Visit the `/hello` endpoint: [http://127.0.0.1:8080/hello](http://127.0.0.1:8080/hello) 44 | - Update the response in [src/main/java/org/acme/quickstart/GreetingResource.java](src/main/java/org/acme/quickstart/GreetingResource.java). Replace `hello` with `hello there` in the `hello()` method. 45 | - Refresh the browser. You should now see `hello there`. 46 | - Undo the change, so the method returns `hello` again. 47 | - Refresh the browser. You should now see `hello`. 48 | 49 | ### Run Quarkus in JVM mode 50 | 51 | When you're done iterating in developer mode, you can run the application as a 52 | conventional jar file. 53 | 54 | First compile it: 55 | 56 | > ./mvnw package 57 | 58 | Then run it: 59 | 60 | > java -jar ./target/quarkus-app/quarkus-run.jar 61 | 62 | Have a look at how fast it boots, or measure the total native memory consumption. 63 | 64 | ### Run Quarkus as a native executable 65 | 66 | You can also create a native executable from this application without making any 67 | source code changes. A native executable removes the dependency on the JVM: 68 | everything needed to run the application on the target platform is included in 69 | the executable, allowing the application to run with minimal resource overhead. 70 | 71 | Compiling a native executable takes a bit longer, as GraalVM performs additional 72 | steps to remove unnecessary codepaths. Use the `native` profile to compile a 73 | native executable: 74 | 75 | > ./mvnw package -Dnative 76 | 77 | After getting a cup of coffee, you'll be able to run this executable directly: 78 | 79 | > ./target/getting-started-1.0.0-SNAPSHOT-runner 80 | -------------------------------------------------------------------------------- /chapter14/change-repo-urls.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "================================================" 4 | echo "" 5 | echo "Change the references to your forked Git repo" 6 | echo "Created by: Giovanni Fontana" 7 | echo "" 8 | echo "================================================" 9 | 10 | echo "** Input your github username: " 11 | read repo_user 12 | echo "" 13 | echo "** Changing ArgoCD and Pipeline manifests to your forked repo (https://github.com/$repo_user/Openshift-Multi-Cluster-management/)" 14 | 15 | sed -i "s/PacktPublishing/$repo_user/" ./Build/Pipeline/quarkus-build-pi.yaml 16 | sed -i "s/PacktPublishing/$repo_user/" ./Build/PipelineRun/quarkus-build-pr.yaml 17 | sed -i "s/PacktPublishing/$repo_user/" ./Deploy/argo-app.yaml 18 | sed -i "s/PacktPublishing/$repo_user/" ./Deploy/Pipeline/quarkus-build-and-deploy-pi.yaml 19 | sed -i "s/PacktPublishing/$repo_user/" ./Deploy/PipelineRun/quarkus-build-and-deploy-pr.yaml 20 | sed -i "s/PacktPublishing/$repo_user/" ./DevSecOps/argo-app-v1.yaml 21 | sed -i "s/PacktPublishing/$repo_user/" ./DevSecOps/argo-app-v2.yaml 22 | sed -i "s/PacktPublishing/$repo_user/" ./DevSecOps/Pipeline/quarkus-devsecops-v1-pi.yaml 23 | sed -i "s/PacktPublishing/$repo_user/" ./DevSecOps/Pipeline/quarkus-devsecops-v2-pi.yaml 24 | sed -i "s/PacktPublishing/$repo_user/" ./DevSecOps/PipelineRun/quarkus-devsecops-v1-pr.yaml 25 | sed -i "s/PacktPublishing/$repo_user/" ./DevSecOps/PipelineRun/quarkus-devsecops-v2-pr.yaml 26 | sed -i "s/PacktPublishing/$repo_user/" ./Multicluster-Deployment/applicationset.yaml 27 | sed -i "s/PacktPublishing/$repo_user/" ./Multicluster-Deployment/Pipeline/quarkus-multicluster-pi.yaml 28 | sed -i "s/PacktPublishing/$repo_user/" ./Multicluster-Deployment/PipelineRun/quarkus-multicluster-pr.yaml 29 | 30 | echo "** Input the full path to the image in your image registry (e.g.: quay-registry-quay-openshift-operators.apps.ocpcluster.example.com/demo/quarkus-quickstarts): " 31 | read registry_path 32 | echo "" 33 | echo "** Changing Image Registry path:" 34 | 35 | sed -i "s~image-path-changeme~$registry_path~" ./Build/PipelineRun/quarkus-build-pr.yaml 36 | sed -i "s~image-path-changeme~$registry_path~" ./Deploy/PipelineRun/quarkus-build-and-deploy-pr.yaml 37 | sed -i "s~image-path-changeme~$registry_path~" ./DevSecOps/PipelineRun/quarkus-devsecops-v1-pr.yaml 38 | sed -i "s~image-path-changeme~$registry_path~" ./DevSecOps/PipelineRun/quarkus-devsecops-v2-pr.yaml 39 | sed -i "s~image-path-changeme~$registry_path~" ./Multicluster-Deployment/PipelineRun/quarkus-multicluster-pr.yaml 40 | sed -i "s~image-path-changeme~$registry_path~" ../quarkus-getting-started/k8s/overlay/v1/kustomization.yaml 41 | sed -i "s~image-path-changeme~$registry_path~" ../quarkus-getting-started/k8s/overlay/v2/kustomization.yaml 42 | 43 | echo "" 44 | echo "** Manifest files changed. Pushing changes to GitHub (please inform your GitHub user and password if asked)." 45 | 46 | cd .. 47 | git add * >>/dev/null 48 | git commit -m 'Changed to forked repo' >>/dev/null 49 | git push -u origin main >>/dev/null 50 | 51 | echo "" 52 | echo "** References changed to your forked repository" -------------------------------------------------------------------------------- /chapter14/DevSecOps/Pipeline/quarkus-devsecops-v2-pi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: quarkus-devsecops-v2 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - default: quarkus-quickstarts 9 | name: APP_NAME 10 | type: string 11 | - default: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | name: GIT_REPO 13 | type: string 14 | - default: '' 15 | name: GIT_REVISION 16 | type: string 17 | - default: >- 18 | image-registry.openshift-image-registry.svc:5000/chap14-review-cicd/quarkus-quickstarts 19 | name: IMAGE_NAME 20 | type: string 21 | - default: quarkus-getting-started 22 | name: PATH_CONTEXT 23 | type: string 24 | - name: acs_central_endpoint 25 | type: string 26 | default: "acs-secret" 27 | - name: acs_api_token 28 | type: string 29 | default: "acs-secret" 30 | - name: ARGO_APP_PATH 31 | type: string 32 | tasks: 33 | - name: fetch-repository 34 | params: 35 | - name: url 36 | value: $(params.GIT_REPO) 37 | - name: revision 38 | value: $(params.GIT_REVISION) 39 | - name: subdirectory 40 | value: '' 41 | - name: deleteExisting 42 | value: 'true' 43 | taskRef: 44 | kind: ClusterTask 45 | name: git-clone 46 | workspaces: 47 | - name: output 48 | workspace: workspace 49 | - name: build 50 | params: 51 | - name: IMAGE 52 | value: $(params.IMAGE_NAME) 53 | - name: CONTEXT 54 | value: $(params.PATH_CONTEXT) 55 | - name: DOCKERFILE 56 | value: src/main/docker/Dockerfile.multistage 57 | - name: TLSVERIFY 58 | value: 'false' 59 | runAfter: 60 | - fetch-repository 61 | taskRef: 62 | kind: ClusterTask 63 | name: buildah 64 | workspaces: 65 | - name: source 66 | workspace: workspace 67 | - name: security-check 68 | params: 69 | - name: rox_central_endpoint 70 | value: $(params.acs_central_endpoint) 71 | - name: rox_api_token 72 | value: $(params.acs_api_token) 73 | - name: image 74 | value: $(params.IMAGE_NAME) 75 | - name: insecure-skip-tls-verify 76 | value: "true" 77 | taskRef: 78 | kind: Task 79 | name: stackrox-image-check 80 | runAfter: 81 | - build 82 | - name: deploy 83 | params: 84 | - name: SCRIPT 85 | value: >- 86 | set -euxo pipefail; 87 | oc apply -f $(params.ARGO_APP_PATH); 88 | counter=0; 89 | timeout=120; 90 | while [[ $(oc get application quarkus-quickstarts -o jsonpath='{.status.health.status}' -n openshift-gitops) != "Healthy" ]]; 91 | do 92 | if [ $counter -gt $timeout ]; then 93 | echo 'Timeout reached'; 94 | exit 1; 95 | fi; 96 | echo 'App not healthy yet, waiting more 5 seconds...'; 97 | sleep 5; 98 | counter=$((counter+1)) 99 | done; 100 | echo 'App deployment finished and healthy'; 101 | runAfter: 102 | - security-check 103 | taskRef: 104 | kind: ClusterTask 105 | name: openshift-client 106 | workspaces: 107 | - name: manifest-dir 108 | workspace: workspace 109 | workspaces: 110 | - name: workspace 111 | -------------------------------------------------------------------------------- /chapter10/README.md: -------------------------------------------------------------------------------- 1 | # Chapter 10 - OpenShift GitOps - ArgoCD 2 | 3 | List of commands to copy and paste: 4 | 5 | **Intalling argocd cli** 6 | 7 | sudo curl -sSL -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 8 | sudo chmod +x /usr/local/bin/argocd 9 | argocd version 10 | 11 | **Configuring ArgoCD for multi-cluster** 12 | 13 | API_NEWCLUSTER=api.ocp.example.com 14 | NEWCLUSTER_USER=admin 15 | 16 | API_OCPARGOCLUSTER=api.ocp-argo.example.com 17 | OCPARGOCLUSTER_USER=admin 18 | 19 | oc login -u $NEWCLUSTER_USER https://$API_NEWCLUSTER:6443 20 | oc login -u $OCPARGOCLUSTER_USER https://$API_OCPARGOCLUSTER:6443 21 | oc config get-contexts 22 | oc config set-context prd-cluster --cluster=newcluster --user=admin 23 | oc get route openshift-gitops-server -n openshift-gitops -o jsonpath='{.spec.host}' 24 | oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 25 | argocd login --insecure openshift-gitops-server-openshift-gitops.apps.example.com 26 | argocd cluster add prd-cluster -y 27 | 28 | **Building new image version** 29 | 30 | GITHUB_USER= 31 | git clone https://github.com/$GITHUB_USER/Openshift-Multi-Cluster-management.git 32 | cd Openshift-Multi-Cluster-management/chapter07 33 | ./change-repo-urls.sh 34 | cd .. 35 | git checkout -b dev 36 | vim ./sample-go-app/clouds-api/clouds.go 37 | func homePage(w http.ResponseWriter, r *http.Request) { 38 | fmt.Fprintf(w, "Welcome to the HomePage! Version=1.0") 39 | fmt.Println("Endpoint Hit: homePage") 40 | } 41 | git add ./sample-go-app/clouds-api/clouds.go 42 | git commit -m 'Version 1.0 changes' 43 | git push -u origin dev 44 | oc apply -k ./chapter07/config/cicd 45 | oc apply -f ./chapter07/config/cicd/pipelinerun/build-v1.yaml -n cicd 46 | tkn pipelinerun logs build-v1-pipelinerun -f -n cicd 47 | 48 | **Deploying in Development** 49 | 50 | sed -i 's/changeme/v1.0/' ./chapter07/clouds-api-gitops/overlays/dev/kustomization.yaml 51 | git add chapter07/clouds-api-gitops/overlays/dev/kustomization.yaml 52 | git commit -m 'updating kustomization file for v1.0' 53 | git push -u origin dev 54 | oc apply -f ./chapter07/config/argocd/argocd-project.yaml 55 | oc apply -f ./chapter07/config/argocd/argocd-app-dev.yaml 56 | echo "$(oc get route openshift-gitops-server -n openshift-gitops --template='https://{{.spec.host}}')" 57 | oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 58 | curl $(oc get route clouds-api -n clouds-api-dev --template='http://{{.spec.host}}') 59 | 60 | **Promoting to QA** 61 | 62 | git checkout -b qa 63 | cp -r ./chapter07/clouds-api-gitops/overlays/dev/ ./chapter07/clouds-api-gitops/overlays/qa/ 64 | sed -i 's/dev/qa/' ./chapter07/clouds-api-gitops/overlays/qa/namespace.yaml ./chapter07/clouds-api-gitops/overlays/qa/kustomization.yaml 65 | git add ./chapter07/clouds-api-gitops/overlays/qa 66 | git commit -m 'Promoting v1.0 to QA' 67 | git push -u origin qa 68 | oc apply -f ./chapter07/config/argocd/argocd-app-qa.yaml 69 | curl $(oc get route clouds-api -n clouds-api-qa --template='http://{{.spec.host}}') 70 | 71 | **Promoting to Production** 72 | 73 | git checkout -b pre-prod 74 | cp -r chapter07/clouds-api-gitops/overlays/dev/ chapter07/clouds-api-gitops/overlays/prod/ 75 | sed -i 's/dev/prod/' ./chapter07/clouds-api-gitops/overlays/prod/namespace.yaml ./chapter07/clouds-api-gitops/overlays/prod/kustomization.yaml 76 | git add ./chapter07/clouds-api-gitops/overlays/prod 77 | git commit -m 'Promoting v1.0 to Prod' 78 | git push -u origin pre-prod 79 | git checkout main 80 | oc apply -f ./chapter07/config/argocd/argocd-app-prod.yaml 81 | curl $(oc get route clouds-api -n clouds-api-prod --template='http://{{.spec.host}}') 82 | -------------------------------------------------------------------------------- /chapter14/Multicluster-Deployment/Pipeline/quarkus-multicluster-pi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: quarkus-multicluster 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - default: quarkus-quickstarts 9 | name: APP_NAME 10 | type: string 11 | - default: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | name: GIT_REPO 13 | type: string 14 | - default: '' 15 | name: GIT_REVISION 16 | type: string 17 | - default: >- 18 | image-registry.openshift-image-registry.svc:5000/chap14-review-cicd/quarkus-quickstarts 19 | name: IMAGE_NAME 20 | type: string 21 | - default: quarkus-getting-started 22 | name: PATH_CONTEXT 23 | type: string 24 | - name: acs_central_endpoint 25 | type: string 26 | default: "acs-secret" 27 | - name: acs_api_token 28 | type: string 29 | default: "acs-secret" 30 | - name: ARGO_APP_PATH 31 | type: string 32 | tasks: 33 | - name: fetch-repository 34 | params: 35 | - name: url 36 | value: $(params.GIT_REPO) 37 | - name: revision 38 | value: $(params.GIT_REVISION) 39 | - name: subdirectory 40 | value: '' 41 | - name: deleteExisting 42 | value: 'true' 43 | taskRef: 44 | kind: ClusterTask 45 | name: git-clone 46 | workspaces: 47 | - name: output 48 | workspace: workspace 49 | - name: build 50 | params: 51 | - name: IMAGE 52 | value: $(params.IMAGE_NAME) 53 | - name: CONTEXT 54 | value: $(params.PATH_CONTEXT) 55 | - name: DOCKERFILE 56 | value: src/main/docker/Dockerfile.multistage 57 | - name: TLSVERIFY 58 | value: 'false' 59 | runAfter: 60 | - fetch-repository 61 | taskRef: 62 | kind: ClusterTask 63 | name: buildah 64 | workspaces: 65 | - name: source 66 | workspace: workspace 67 | - name: security-check 68 | params: 69 | - name: rox_central_endpoint 70 | value: $(params.acs_central_endpoint) 71 | - name: rox_api_token 72 | value: $(params.acs_api_token) 73 | - name: image 74 | value: $(params.IMAGE_NAME) 75 | - name: insecure-skip-tls-verify 76 | value: "true" 77 | taskRef: 78 | kind: Task 79 | name: stackrox-image-check 80 | runAfter: 81 | - build 82 | - name: deploy 83 | params: 84 | - name: SCRIPT 85 | value: >- 86 | set -euxo pipefail; 87 | oc apply -f $(params.ARGO_APP_PATH); 88 | counter=0; 89 | timeout=120; 90 | while [[ $(oc get applicationset quarkus-quickstarts-appset -o jsonpath='{.status.health.status}' -n openshift-gitops) != "Healthy" ]]; 91 | do 92 | if [ $counter -gt $timeout ]; then 93 | echo 'Timeout reached'; 94 | exit 1; 95 | fi; 96 | echo 'App not healthy yet, waiting more 5 seconds...'; 97 | sleep 5; 98 | counter=$((counter+1)) 99 | done; 100 | echo 'App deployment finished and healthy'; 101 | runAfter: 102 | - security-check 103 | taskRef: 104 | kind: ClusterTask 105 | name: openshift-client 106 | workspaces: 107 | - name: manifest-dir 108 | workspace: workspace 109 | workspaces: 110 | - name: workspace 111 | -------------------------------------------------------------------------------- /chapter14/DevSecOps/Pipeline/quarkus-devsecops-v1-pi.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: quarkus-devsecops-v1 5 | namespace: chap14-review-cicd 6 | spec: 7 | params: 8 | - default: quarkus-quickstarts 9 | name: APP_NAME 10 | type: string 11 | - default: 'https://github.com/PacktPublishing/Openshift-Multi-Cluster-management.git' 12 | name: GIT_REPO 13 | type: string 14 | - default: '' 15 | name: GIT_REVISION 16 | type: string 17 | - default: >- 18 | image-registry.openshift-image-registry.svc:5000/chap14-review-cicd/quarkus-quickstarts 19 | name: IMAGE_NAME 20 | type: string 21 | - default: quarkus-getting-started 22 | name: PATH_CONTEXT 23 | type: string 24 | - default: openjdk-17-ubi8 25 | name: VERSION 26 | type: string 27 | - name: acs_central_endpoint 28 | type: string 29 | default: "acs-secret" 30 | - name: acs_api_token 31 | type: string 32 | default: "acs-secret" 33 | - name: ARGO_APP_PATH 34 | type: string 35 | tasks: 36 | - name: fetch-repository 37 | params: 38 | - name: url 39 | value: $(params.GIT_REPO) 40 | - name: revision 41 | value: $(params.GIT_REVISION) 42 | - name: subdirectory 43 | value: '' 44 | - name: deleteExisting 45 | value: 'true' 46 | taskRef: 47 | kind: ClusterTask 48 | name: git-clone 49 | workspaces: 50 | - name: output 51 | workspace: workspace 52 | - name: build 53 | params: 54 | - name: IMAGE 55 | value: $(params.IMAGE_NAME) 56 | - name: TLSVERIFY 57 | value: 'false' 58 | - name: PATH_CONTEXT 59 | value: $(params.PATH_CONTEXT) 60 | - name: VERSION 61 | value: $(params.VERSION) 62 | runAfter: 63 | - fetch-repository 64 | taskRef: 65 | kind: Task 66 | name: s2i-java-old-version 67 | workspaces: 68 | - name: source 69 | workspace: workspace 70 | - name: security-check 71 | params: 72 | - name: rox_central_endpoint 73 | value: $(params.acs_central_endpoint) 74 | - name: rox_api_token 75 | value: $(params.acs_api_token) 76 | - name: image 77 | value: $(params.IMAGE_NAME) 78 | - name: insecure-skip-tls-verify 79 | value: "true" 80 | taskRef: 81 | kind: Task 82 | name: stackrox-image-check 83 | runAfter: 84 | - build 85 | - name: deploy 86 | params: 87 | - name: SCRIPT 88 | value: >- 89 | set -euxo pipefail; 90 | oc apply -f $(params.ARGO_APP_PATH); 91 | counter=0; 92 | timeout=120; 93 | while [[ $(oc get application quarkus-quickstarts -o jsonpath='{.status.health.status}' -n openshift-gitops) != "Healthy" ]]; 94 | do 95 | if [ $counter -gt $timeout ]; then 96 | echo 'Timeout reached'; 97 | exit 1; 98 | fi; 99 | echo 'App not healthy yet, waiting more 5 seconds...'; 100 | sleep 5; 101 | counter=$((counter+1)) 102 | done; 103 | echo 'App deployment finished and healthy'; 104 | runAfter: 105 | - security-check 106 | taskRef: 107 | kind: ClusterTask 108 | name: openshift-client 109 | workspaces: 110 | - name: manifest-dir 111 | workspace: workspace 112 | workspaces: 113 | - name: workspace 114 | -------------------------------------------------------------------------------- /quarkus-getting-started/src/main/resources/META-INF/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OpenShift Multi-cluster Management - Quarkus Sample - 1.0.0-SNAPSHOT 6 | 99 | 100 | 101 | 102 | 105 | 106 |
107 |
108 |

This is a sample using Quarkus.

109 | 110 |

Reference

111 | 112 |

This sample has been extracted from 113 | Getting started with Quarkus.

114 | 115 |

Why do you see this?

116 | 117 |

This page is served by Quarkus. The source is in 118 | src/main/resources/META-INF/resources/index.html.

119 | 120 |

What can I do from here?

121 | 122 |

If not already done, run the application in dev mode using: mvn quarkus:dev. 123 |

124 |
    125 |
  • Add REST resources, Servlets, functions and other services in src/main/java.
  • 126 |
  • Your static assets are located in src/main/resources/META-INF/resources.
  • 127 |
  • Configure your application in src/main/resources/application.properties. 128 |
  • 129 |
130 | 131 |

How do I get rid of this page?

132 |

Just delete the src/main/resources/META-INF/resources/index.html file.

133 |
134 |
135 |
136 |

Application

137 |
    138 |
  • GroupId: org.acme
  • 139 |
  • ArtifactId: getting-started
  • 140 |
  • Version: 1.0.0-SNAPSHOT
  • 141 |
  • Quarkus Version: 0.11.0
  • 142 |
143 |
144 |
145 |

Next steps

146 | 151 |
152 |
153 |
154 | 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /quarkus-getting-started/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | org.acme 6 | getting-started 7 | 1.0.0-SNAPSHOT 8 | 9 | 10 | quarkus-bom 11 | io.quarkus 12 | 2.11.2.Final 13 | 3.8.1 14 | 3.0.0-M7 15 | UTF-8 16 | 11 17 | 11 18 | true 19 | 20 | 21 | 22 | 23 | 24 | ${quarkus.platform.group-id} 25 | ${quarkus.platform.artifact-id} 26 | ${quarkus.platform.version} 27 | pom 28 | import 29 | 30 | 31 | 32 | 33 | 34 | 35 | io.quarkus 36 | quarkus-resteasy-reactive 37 | 38 | 39 | io.quarkus 40 | quarkus-junit5 41 | test 42 | 43 | 44 | io.rest-assured 45 | rest-assured 46 | test 47 | 48 | 49 | 50 | 51 | 52 | 53 | maven-compiler-plugin 54 | ${compiler-plugin.version} 55 | 56 | 57 | maven-surefire-plugin 58 | ${surefire-plugin.version} 59 | 60 | 61 | org.jboss.logmanager.LogManager 62 | ${maven.home} 63 | 64 | 65 | 66 | 67 | ${quarkus.platform.group-id} 68 | quarkus-maven-plugin 69 | ${quarkus.platform.version} 70 | 71 | 72 | 73 | build 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | native 85 | 86 | 87 | native 88 | 89 | 90 | 91 | native 92 | 93 | 94 | 95 | 96 | maven-failsafe-plugin 97 | ${surefire-plugin.version} 98 | 99 | 100 | 101 | integration-test 102 | verify 103 | 104 | 105 | 106 | ${project.build.directory}/${project.build.finalName}-runner 107 | org.jboss.logmanager.LogManager 108 | ${maven.home} 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /chapter14/DevSecOps/Task/s2i-java.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: s2i-java-old-version 5 | namespace: chap14-review-cicd 6 | spec: 7 | description: >- 8 | s2i-java task clones a Git repository and builds and pushes a container 9 | image using S2I and a Java builder image. 10 | params: 11 | - default: latest 12 | description: The tag of java imagestream for java version 13 | name: VERSION 14 | type: string 15 | - default: . 16 | description: The location of the path to run s2i from 17 | name: PATH_CONTEXT 18 | type: string 19 | - default: 'true' 20 | description: >- 21 | Verify the TLS on the registry endpoint (for push/pull to a non-TLS 22 | registry) 23 | name: TLSVERIFY 24 | type: string 25 | - default: '' 26 | description: Additional Maven arguments 27 | name: MAVEN_ARGS_APPEND 28 | type: string 29 | - default: 'false' 30 | description: Remove the Maven repository after the artifact is built 31 | name: MAVEN_CLEAR_REPO 32 | type: string 33 | - default: '' 34 | description: The base URL of a mirror used for retrieving artifacts 35 | name: MAVEN_MIRROR_URL 36 | type: string 37 | - description: Location of the repo where image has to be pushed 38 | name: IMAGE 39 | type: string 40 | - default: >- 41 | registry.redhat.io/rhel8/buildah@sha256:0a86ecbdfbe86e9d225b7fe4b090a0dd6d323f8afdfdf2bd933ff223ddb53320 42 | description: The location of the buildah builder image. 43 | name: BUILDER_IMAGE 44 | type: string 45 | - default: 'false' 46 | description: Skip pushing the built image 47 | name: SKIP_PUSH 48 | type: string 49 | results: 50 | - description: Digest of the image just built. 51 | name: IMAGE_DIGEST 52 | type: string 53 | steps: 54 | - args: 55 | - |- 56 | echo "MAVEN_CLEAR_REPO=$(params.MAVEN_CLEAR_REPO)" > env-file 57 | 58 | [[ '$(params.MAVEN_ARGS_APPEND)' != "" ]] && 59 | echo "MAVEN_ARGS_APPEND=$(params.MAVEN_ARGS_APPEND)" >> env-file 60 | 61 | [[ '$(params.MAVEN_MIRROR_URL)' != "" ]] && 62 | echo "MAVEN_MIRROR_URL=$(params.MAVEN_MIRROR_URL)" >> env-file 63 | 64 | echo "Generated Env file" 65 | echo "------------------------------" 66 | cat env-file 67 | echo "------------------------------" 68 | command: 69 | - /bin/sh 70 | - '-c' 71 | env: 72 | - name: HOME 73 | value: /tekton/home 74 | image: >- 75 | registry.redhat.io/ocp-tools-4-tech-preview/source-to-image-rhel8@sha256:98d8cb3a255641ca6a1bce854e5e2460c20de9fb9b28e3cc67eb459f122873dd 76 | name: gen-env-file 77 | resources: {} 78 | volumeMounts: 79 | - mountPath: /env-params 80 | name: envparams 81 | workingDir: /env-params 82 | - command: 83 | - s2i 84 | - build 85 | - $(params.PATH_CONTEXT) 86 | - >- 87 | image-registry.openshift-image-registry.svc:5000/openshift/ubi8-openjdk-11:1.10 88 | - '--image-scripts-url' 89 | - 'image:///usr/local/s2i' 90 | - '--as-dockerfile' 91 | - /gen-source/Dockerfile.gen 92 | - '--environment-file' 93 | - /env-params/env-file 94 | env: 95 | - name: HOME 96 | value: /tekton/home 97 | image: >- 98 | registry.redhat.io/ocp-tools-4-tech-preview/source-to-image-rhel8@sha256:98d8cb3a255641ca6a1bce854e5e2460c20de9fb9b28e3cc67eb459f122873dd 99 | name: generate 100 | resources: {} 101 | volumeMounts: 102 | - mountPath: /gen-source 103 | name: gen-source 104 | - mountPath: /env-params 105 | name: envparams 106 | workingDir: $(workspaces.source.path) 107 | - image: $(params.BUILDER_IMAGE) 108 | name: build-and-push 109 | resources: {} 110 | script: > 111 | buildah bud --storage-driver=vfs --tls-verify=$(params.TLSVERIFY) \ 112 | --layers -f /gen-source/Dockerfile.gen -t $(params.IMAGE) . 113 | 114 | [[ "$(params.SKIP_PUSH)" == "true" ]] && echo "Push skipped" && exit 0 115 | 116 | buildah push --storage-driver=vfs --tls-verify=$(params.TLSVERIFY) \ 117 | --digestfile $(workspaces.source.path)/image-digest $(params.IMAGE) \ 118 | docker://$(params.IMAGE) 119 | 120 | cat $(workspaces.source.path)/image-digest | tee 121 | /tekton/results/IMAGE_DIGEST 122 | securityContext: 123 | capabilities: 124 | add: 125 | - SETFCAP 126 | volumeMounts: 127 | - mountPath: /var/lib/containers 128 | name: varlibcontainers 129 | - mountPath: /gen-source 130 | name: gen-source 131 | workingDir: /gen-source 132 | volumes: 133 | - emptyDir: {} 134 | name: varlibcontainers 135 | - emptyDir: {} 136 | name: gen-source 137 | - emptyDir: {} 138 | name: envparams 139 | workspaces: 140 | - mountPath: /workspace/source 141 | name: source 142 | -------------------------------------------------------------------------------- /sample-go-app/clouds-api/clouds_test.go: -------------------------------------------------------------------------------- 1 | // main_test.go 2 | 3 | package main 4 | 5 | import ( 6 | "bytes" 7 | "os" 8 | "strings" 9 | "testing" 10 | 11 | "net/http" 12 | "net/http/httptest" 13 | 14 | "github.com/gorilla/mux" 15 | ) 16 | 17 | func TestMain(m *testing.M) { 18 | initCloudsObject() 19 | code := m.Run() 20 | os.Exit(code) 21 | } 22 | 23 | func TestReturnAllClouds(t *testing.T) { 24 | 25 | req, err := http.NewRequest("GET", "/cloud", nil) 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | rr := httptest.NewRecorder() 31 | handler := http.HandlerFunc(returnAllClouds) 32 | handler.ServeHTTP(rr, req) 33 | 34 | expected := `[{"Id":"1","Title":"AWS","desc":"Amazon Web Services","content":"Amazon Web Services, Inc. is a subsidiary of Amazon providing on-demand cloud computing platforms and APIs to individuals, companies, and governments, on a metered pay-as-you-go basis."},{"Id":"2","Title":"Azure","desc":"Microsoft Azure","content":"Microsoft Azure, often referred to as Azure, is a cloud computing service operated by Microsoft for application management via Microsoft-managed data centers."},{"Id":"3","Title":"GCP","desc":"Google Cloud Platform","content":"Google Cloud Platform, offered by Google, is a suite of cloud computing services that runs on the same infrastructure that Google uses internally for its end-user products, such as Google Search, Gmail, Google Drive, and YouTube."},{"Id":"4","Title":"IBM Cloud","desc":"IBM Cloud","content":"IBM cloud computing is a set of cloud computing services for business offered by the information technology company IBM."}]` 35 | 36 | checkResponseCode(t, http.StatusOK, rr.Code) 37 | checkResponseBody(t, expected, rr.Body.String()) 38 | } 39 | 40 | func TestReturnSingleCloud(t *testing.T) { 41 | 42 | req, err := http.NewRequest("GET", "/cloud/1", nil) 43 | if err != nil { 44 | t.Fatal(err) 45 | } 46 | 47 | rr := httptest.NewRecorder() 48 | 49 | //Hack to try to fake gorilla/mux vars 50 | vars := map[string]string{ 51 | "id": "1", 52 | } 53 | req = mux.SetURLVars(req, vars) 54 | 55 | returnSingleCloud(rr, req) 56 | 57 | expected := `{"Id":"1","Title":"AWS","desc":"Amazon Web Services","content":"Amazon Web Services, Inc. is a subsidiary of Amazon providing on-demand cloud computing platforms and APIs to individuals, companies, and governments, on a metered pay-as-you-go basis."}` 58 | 59 | checkResponseCode(t, http.StatusOK, rr.Code) 60 | checkResponseBody(t, expected, rr.Body.String()) 61 | } 62 | 63 | func TestReturnSingleCloudNotFound(t *testing.T) { 64 | req, err := http.NewRequest("GET", "/cloud/9999", nil) 65 | if err != nil { 66 | t.Fatal(err) 67 | } 68 | 69 | rr := httptest.NewRecorder() 70 | 71 | //Hack to try to fake gorilla/mux vars 72 | vars := map[string]string{ 73 | "id": "99999", 74 | } 75 | req = mux.SetURLVars(req, vars) 76 | 77 | returnSingleCloud(rr, req) 78 | 79 | expected := `{"Id":"","Title":"Not Found","desc":"Not Found","content":"Not Found"}` 80 | 81 | checkResponseCode(t, http.StatusNotFound, rr.Code) 82 | checkResponseBody(t, expected, rr.Body.String()) 83 | } 84 | 85 | func TestCreateNewCloud(t *testing.T) { 86 | 87 | expected := `{"Id":"5","Title":"Alibaba","desc":"Alibaba Cloud","content":"Alibaba Cloud"}` 88 | var jsonStr = []byte(expected) 89 | 90 | req, err := http.NewRequest("POST", "/cloud", bytes.NewBuffer(jsonStr)) 91 | if err != nil { 92 | t.Fatal(err) 93 | } 94 | req.Header.Set("Content-Type", "application/json") 95 | rr := httptest.NewRecorder() 96 | handler := http.HandlerFunc(createNewCloud) 97 | handler.ServeHTTP(rr, req) 98 | 99 | checkResponseCode(t, http.StatusOK, rr.Code) 100 | checkResponseBody(t, expected, rr.Body.String()) 101 | } 102 | 103 | func TestUpdateCloud(t *testing.T) { 104 | expected := `{"Id":"5","Title":"Alibaba v2","desc":"Alibaba Cloud v2","content":"Alibaba Cloud v2"}` 105 | var jsonStr = []byte(expected) 106 | 107 | req, err := http.NewRequest("PUT", "/cloud", bytes.NewBuffer(jsonStr)) 108 | if err != nil { 109 | t.Fatal(err) 110 | } 111 | req.Header.Set("Content-Type", "application/json") 112 | rr := httptest.NewRecorder() 113 | handler := http.HandlerFunc(createNewCloud) 114 | handler.ServeHTTP(rr, req) 115 | 116 | checkResponseCode(t, http.StatusOK, rr.Code) 117 | checkResponseBody(t, expected, rr.Body.String()) 118 | } 119 | 120 | func TestDeleteCloud(t *testing.T) { 121 | 122 | req, err := http.NewRequest("DELETE", "/cloud/5", nil) 123 | if err != nil { 124 | t.Fatal(err) 125 | } 126 | 127 | rr := httptest.NewRecorder() 128 | 129 | //Hack to try to fake gorilla/mux vars 130 | vars := map[string]string{ 131 | "id": "5", 132 | } 133 | req = mux.SetURLVars(req, vars) 134 | 135 | deleteCloud(rr, req) 136 | 137 | expected := `` 138 | 139 | checkResponseCode(t, http.StatusOK, rr.Code) 140 | checkResponseBody(t, expected, rr.Body.String()) 141 | } 142 | 143 | func checkResponseCode(t *testing.T, expected, actual int) { 144 | if expected != actual { 145 | t.Errorf("Expected response code %d. Got %d\n", expected, actual) 146 | } 147 | } 148 | 149 | func checkResponseBody(t *testing.T, expected string, actual string) { 150 | if strings.TrimSpace(actual) != strings.TrimSpace(expected) { 151 | t.Errorf("Expected %s array. Got %s", expected, actual) 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /sample-go-app/clouds-api/clouds.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "log" 9 | "net/http" 10 | "os" 11 | "os/signal" 12 | "syscall" 13 | "time" 14 | 15 | "github.com/gorilla/mux" 16 | "gopkg.in/natefinch/lumberjack.v2" 17 | ) 18 | 19 | // Existing code from above 20 | func handleRequests() { 21 | myRouter := mux.NewRouter().StrictSlash(true) 22 | myRouter.HandleFunc("/", homePage) 23 | myRouter.HandleFunc("/cloud", returnAllClouds).Methods("GET") 24 | myRouter.HandleFunc("/cloud/{id}", returnSingleCloud).Methods("GET") 25 | myRouter.HandleFunc("/cloud", createNewCloud).Methods("POST") 26 | myRouter.HandleFunc("/cloud/{id}", deleteCloud).Methods("DELETE") 27 | myRouter.HandleFunc("/cloud/{id}", updateCloud).Methods("PUT") 28 | 29 | srv := &http.Server{ 30 | Handler: myRouter, 31 | Addr: ":8080", 32 | ReadTimeout: 10 * time.Second, 33 | WriteTimeout: 10 * time.Second, 34 | } 35 | 36 | log.Println("Starting Server") 37 | 38 | log.Fatal(http.ListenAndServe(":8080", myRouter)) 39 | // Graceful Shutdown 40 | waitForShutdown(srv) 41 | } 42 | 43 | func waitForShutdown(srv *http.Server) { 44 | interruptChan := make(chan os.Signal, 1) 45 | signal.Notify(interruptChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) 46 | 47 | // Block until we receive our signal. 48 | <-interruptChan 49 | 50 | // Create a deadline to wait for. 51 | ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 52 | defer cancel() 53 | srv.Shutdown(ctx) 54 | 55 | log.Println("Shutting down") 56 | os.Exit(0) 57 | } 58 | 59 | func main() { 60 | 61 | // Configure Logging 62 | LOG_FILE_LOCATION := os.Getenv("LOG_FILE_LOCATION") 63 | if LOG_FILE_LOCATION != "" { 64 | log.SetOutput(&lumberjack.Logger{ 65 | Filename: LOG_FILE_LOCATION, 66 | MaxSize: 500, // megabytes 67 | MaxBackups: 3, 68 | MaxAge: 28, //days 69 | Compress: true, // disabled by default 70 | }) 71 | } 72 | 73 | initCloudsObject() 74 | handleRequests() 75 | } 76 | 77 | func returnSingleCloud(w http.ResponseWriter, r *http.Request) { 78 | vars := mux.Vars(r) 79 | key := vars["id"] 80 | 81 | for _, cloud := range Clouds { 82 | if cloud.Id == key { 83 | json.NewEncoder(w).Encode(cloud) 84 | return 85 | } 86 | } 87 | w.WriteHeader(http.StatusNotFound) 88 | json.NewEncoder(w).Encode(Cloud{Id: "", Title: "Not Found", Desc: "Not Found", Content: "Not Found"}) 89 | } 90 | 91 | func createNewCloud(w http.ResponseWriter, r *http.Request) { 92 | reqBody, _ := ioutil.ReadAll(r.Body) 93 | var cloud Cloud 94 | json.Unmarshal(reqBody, &cloud) 95 | Clouds = append(Clouds, cloud) 96 | 97 | json.NewEncoder(w).Encode(cloud) 98 | } 99 | 100 | func deleteCloud(w http.ResponseWriter, r *http.Request) { 101 | vars := mux.Vars(r) 102 | id := vars["id"] 103 | for index, cloud := range Clouds { 104 | if cloud.Id == id { 105 | Clouds = append(Clouds[:index], Clouds[index+1:]...) 106 | return 107 | } 108 | } 109 | w.WriteHeader(http.StatusNotFound) 110 | json.NewEncoder(w).Encode(Cloud{Id: "", Title: "Not Found", Desc: "Not Found", Content: "Not Found"}) 111 | } 112 | 113 | func updateCloud(w http.ResponseWriter, r *http.Request) { 114 | vars := mux.Vars(r) 115 | id := vars["id"] 116 | 117 | for index, cloud := range Clouds { 118 | if cloud.Id == id { 119 | reqBody, _ := ioutil.ReadAll(r.Body) 120 | var cloud Cloud 121 | json.Unmarshal(reqBody, &cloud) 122 | Clouds[index] = cloud 123 | 124 | json.NewEncoder(w).Encode(cloud) 125 | return 126 | } 127 | } 128 | w.WriteHeader(http.StatusNotFound) 129 | json.NewEncoder(w).Encode(Cloud{Id: "", Title: "Not Found", Desc: "Not Found", Content: "Not Found"}) 130 | } 131 | 132 | type Cloud struct { 133 | Id string `json:"Id"` 134 | Title string `json:"Title"` 135 | Desc string `json:"desc"` 136 | Content string `json:"content"` 137 | } 138 | 139 | var Clouds []Cloud 140 | 141 | func returnAllClouds(w http.ResponseWriter, r *http.Request) { 142 | fmt.Println("Endpoint Hit: returnAllClouds") 143 | json.NewEncoder(w).Encode(Clouds) 144 | } 145 | 146 | func homePage(w http.ResponseWriter, r *http.Request) { 147 | fmt.Fprintf(w, "Welcome to the HomePage!") 148 | fmt.Println("Endpoint Hit: homePage") 149 | } 150 | 151 | func initCloudsObject() { 152 | Clouds = []Cloud{ 153 | Cloud{Id: "1", Title: "AWS", Desc: "Amazon Web Services", Content: "Amazon Web Services, Inc. is a subsidiary of Amazon providing on-demand cloud computing platforms and APIs to individuals, companies, and governments, on a metered pay-as-you-go basis."}, 154 | Cloud{Id: "2", Title: "Azure", Desc: "Microsoft Azure", Content: "Microsoft Azure, often referred to as Azure, is a cloud computing service operated by Microsoft for application management via Microsoft-managed data centers."}, 155 | Cloud{Id: "3", Title: "GCP", Desc: "Google Cloud Platform", Content: "Google Cloud Platform, offered by Google, is a suite of cloud computing services that runs on the same infrastructure that Google uses internally for its end-user products, such as Google Search, Gmail, Google Drive, and YouTube."}, 156 | Cloud{Id: "4", Title: "IBM Cloud", Desc: "IBM Cloud", Content: "IBM cloud computing is a set of cloud computing services for business offered by the information technology company IBM."}, 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # OpenShift Multi-Cluster Management Handbook 5 | 6 | OpenShift Multi-Cluster Management Handbook 7 | 8 | This is the code repository for [Openshift Multi-Cluster Management Handbook](https://www.packtpub.com/product/openshift-multi-cluster-management-handbook/9781803235288), published by Packt. 9 | 10 | **Go from architecture to pipelines using GitOps** 11 | 12 | ## What is this book about? 13 | For IT professionals working with Red Hat OpenShift Container Platform, the key to maximizing efficiency is understanding the powerful and resilient options to maintain the software development platform with minimal effort. OpenShift Multi-Cluster Management Handbook is a deep dive into the technology, containing knowledge essential for anyone who wants to work with OpenShift. 14 | 15 | This book covers the following exciting features: 16 | * Understand the important aspects of OpenShift cluster architecture 17 | * Design your infrastructure to run across hybrid clouds 18 | * Define the best strategy for multitenancy on OpenShift 19 | * Discover efficient troubleshooting strategies with OpenShift 20 | * Build and deploy your applications using OpenShift Pipelines (Tekton) 21 | * Work with ArgoCD to deploy your applications using GitOps practices 22 | * Monitor your clusters’ security using Red Hat Advanced Cluster Security 23 | 24 | If you feel this book is for you, get your [copy](https://www.amazon.com/dp/1803235284) today! 25 | 26 | https://www.packtpub.com/ 28 | 29 | ## Instructions and Navigations 30 | All of the code is organized into folders. For example, Chapter14. 31 | 32 | The code will look like the following: 33 | ``` 34 | SELECT 35 | COUNT(DISTINCT Column1) AS Count_column1, 36 | System.TIMESTAMP() AS Time 37 | FROM Input TIMESTAMP BY TIME 38 | GROUP BY 39 | TumblingWindow(second, 2) 40 | ``` 41 | 42 | **Following is what you need for this book:** 43 | This book is for a wide range of IT professionals using or looking to use OpenShift with a hybrid/multi-cloud approach. In this book, IT architects will find practical guidance on OpenShift clusters’ architecture, while Sysadmins, SREs, and IT operators will learn more about OpenShift deployment, troubleshooting, networking, security, and tools to manage multiple clusters from a single pane. For DevOps engineers, this book covers CI/CD strategies for multiple clusters using GitOps. Equipped with just basic knowledge of containerization and Kubernetes, you’re ready to get started. 44 | 45 | With the following software and hardware list you can run all code files present in the book (Chapter 1-15). 46 | ### Software and Hardware List 47 | | Chapter | Software required | OS required | 48 | | -------- | ------------------------------------ | ----------------------------------- | 49 | | 1-15 | OpenShift Client | Windows, Mac OS X, and Linux (Any) | 50 | | 1-15 | OpenShift Installer | Mac OS X, and Linux (Any) | 51 | | 1-15 | CodeReady Containers (CRC) | Windows, Mac OS X, and Linux (Any) | 52 | 53 | We also provide a PDF file that has color images of the screenshots/diagrams used in this book. [Click here to download it]( https://static.packt-cdn.com/downloads/9781803235288_ColorImages.pdf). 54 | 55 | ### Related products 56 | * Hybrid Cloud Infrastructure and Operations Explained [[Packt]](https://www.packtpub.com/product/hybrid-cloud-infrastructure-and-operations-explained/9781803248318) [[Amazon]](https://www.amazon.com/dp/1803248319) 57 | 58 | * Building CI/CD Systems Using Tekton [[Packt]](https://www.packtpub.com/product/building-cicd-systems-using-tekton/9781801078214) [[Amazon]](https://www.amazon.in//dp/1801078211) 59 | 60 | ## Get to Know the Author 61 | **Giovanni Fontana** 62 | is a solution architect working for large companies in the US Northeast region from different industries such as finance and the health sector. He is a Red Hat Certified Architect, owning many certificates covering RHEL, OpenShift, Ansible, and others. In the cloud and DevOps domain, he has been working with activities such as process assessment and design; pre-sales, architecture design, and implementation of container-based platforms such as Red Hat OpenShift Container Platform, hybrid/multi cloud management tools; automation design and implementation using Ansible, and others. Before his current position, he was a principal consultant with much hands-on experience, providing services for many large companies and also acting as a technical leader for a talented team of consultants at Red Hat in Brazil. Now as an OpenShift specialist solution architect, he helps customers to solve pain points and reach their targets by adopting Red Hat’s open source technologies. 63 | At Red Hat, Giovanni has been recognized with important awards such as Red Hat President's Club, Top Gun, and Champions awards. 64 | 65 | **Rafael Pecora** 66 | started his first journey with technology at the age of 15 and since then, he has been dedicating himself to technology. He has more than 23 years dedicated to IT, a profession that is always evolving and shaping itself on cutting-edge innovation. Passionate about IT, he has focused his entire career on IT infrastructure, from traditional data centers to current cloud technologies. Currently, he develops his professional activity as a cloud solution architect in container technology and public clouds, with the aim of bringing his knowledge and improvement to clients that work in the financial, health and insurance, mid-market, and public sector, and helping them adopt hybrid cloud infrastructure with better resiliency for their customers. At Red Hat, Rafael has achieved more than 40 projects as an OpenShift consultant, acting on many industry projects, and has been recognized by customers and also recognized with Service Star and Champions awards. 67 | 68 | ### Download a free PDF 69 | 70 | If you have already purchased a print or Kindle version of this book, you can get a DRM-free PDF version at no cost.
Simply click on the link to claim your free PDF.
71 |

https://packt.link/free-ebook/9781803235288

-------------------------------------------------------------------------------- /quarkus-getting-started/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /quarkus-getting-started/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | --------------------------------------------------------------------------------