├── .gitignore ├── .travis.yml ├── Dockerfile ├── README.adoc ├── _cloud-native-workshop-codeready.yml ├── _modules.yml ├── abtesting.adoc ├── apb ├── Dockerfile ├── Makefile ├── README.md ├── apb.yml ├── playbooks │ ├── codeready-workspaces-operator-installer │ │ ├── README.adoc │ │ ├── custom-resource.yaml │ │ ├── deploy.sh │ │ ├── migrate_1.0_to_1.1.sh │ │ └── migrate_1.1_to_1.2.sh │ ├── deprovision.yml │ ├── provision.yml │ ├── tasks │ │ ├── add_custom_stack.yml │ │ ├── create_project_service_mesh.yml │ │ └── install_etherpad.yml │ └── templates │ │ ├── codeready-user.json.j2 │ │ ├── etherpad │ │ ├── etherpad.txt │ │ └── etherpad.yaml.j2 │ │ ├── kiali.yaml.j2 │ │ ├── project-limits.yaml.j2 │ │ └── stacks │ │ ├── cloud-native-stack.json.j2 │ │ └── stack-permissions.json.j2 ├── requirements-travis.yml └── requirements.yml ├── app-config-thorntail.adoc ├── app-config-vertx.adoc ├── catalog-deployment.adoc ├── catalog-spring-boot-codeready.adoc ├── continuous-delivery.adoc ├── debug-codeready.adoc ├── env-info.adoc ├── fault-tolerance-codeready.adoc ├── gateway-deployment.adoc ├── gateway-vertx-codeready.adoc ├── getting-started-codeready.adoc ├── health.adoc ├── images ├── Screen Shot 2018-07-25 at 09.55.19.png ├── bootstrap-che-build-palette.png ├── bootstrap-che-convert.png ├── bootstrap-che-create-workspace.png ├── bootstrap-che-git-commit.png ├── bootstrap-che-git-profile.png ├── bootstrap-che-import-save.png ├── bootstrap-che-import.png ├── bootstrap-che-maven.png ├── bootstrap-che-register.png ├── bootstrap-che-start-workspace.png ├── bootstrap-che-terminal.png ├── bootstrap-che-wide.png ├── bootstrap-che-workspace.png ├── catalog-service.png ├── cd-github-empty-repo.png ├── cd-github-inventory-repo.png ├── cd-github-new-repo.png ├── cd-github-plus-icon.png ├── cd-github-settings-link.png ├── cd-github-webhook-add.png ├── cd-gogs-empty-repo.png ├── cd-gogs-inventory-repo.png ├── cd-gogs-new-repo.png ├── cd-gogs-plus-icon.png ├── cd-gogs-settings-link.png ├── cd-gogs-signup.png ├── cd-gogs-webhook-add.png ├── cd-pipeline-inprogress.png ├── codeready-account-information.png ├── codeready-authorize-access.png ├── codeready-command-build.png ├── codeready-command-inject-catalog.png ├── codeready-command-inject-gateway.png ├── codeready-command-inject-inventory.png ├── codeready-command-run-gateway-service.png ├── codeready-commands-build.png ├── codeready-commands-deploy.png ├── codeready-convert.png ├── codeready-create-workspace.png ├── codeready-import-save.png ├── codeready-import.png ├── codeready-login.png ├── codeready-maven.png ├── codeready-oauth.png ├── codeready-register.png ├── codeready-run-gateway-100.png ├── codeready-run-gateway-50-50.png ├── codeready-run-gateway-service.png ├── codeready-start-workspace.png ├── codeready-terminal.png ├── codeready-workspace.png ├── codeready.png ├── config-psql-secret.png ├── coolstore-arch-catalog-spring-boot.png ├── coolstore-arch-catalog.png ├── coolstore-arch-gateway-vertx.png ├── coolstore-arch-gateway.png ├── coolstore-arch-inventory-thorntail.png ├── coolstore-arch-inventory-vertx.png ├── coolstore-arch-inventory.png ├── coolstore-arch-webui-nodejs.png ├── coolstore-arch.png ├── coolstore-pods-nodb.png ├── coolstore-web.png ├── debug-che-breakpoint-stop.png ├── debug-che-breakpoint-values.png ├── debug-che-breakpoint.png ├── debug-che-debug-config-1.png ├── debug-che-debug-config-2.png ├── debug-che-debug-config-3.png ├── debug-che-debug-config-4.png ├── debug-che-fabric8.png ├── debug-che-resume.png ├── debug-che-step-over.png ├── debug-che-variables.png ├── debug-che-window-guide.png ├── debug-coolstore-bug-fixed.png ├── debug-coolstore-bug.png ├── debug-idea-add-breakpoint.png ├── debug-idea-debug-config.png ├── debug-idea-debug-vars.png ├── debug-idea-debug-view.png ├── debug-idea-edit-config.png ├── debug-jbds-add-breakpoint.png ├── debug-jbds-debug-config.png ├── debug-jbds-debug-hover.png ├── debug-jbds-debug-vars.png ├── debug-jbds-debug-view.png ├── debug-jbds-import-maven.png ├── eclipse-che-commands-build.png ├── eclipse-che-commands-deploy.png ├── eclipse-che-commands-run.png ├── fault-autoscale-metrics.png ├── fault-autoscale-web.gif ├── fault-autoscale-web.png ├── fault-circuit-breaker.png ├── fault-coolstore-no-cb.png ├── fault-coolstore-with-cb.png ├── fault-scale-up-vs-out.png ├── fault-scale-up.png ├── gateway-service.png ├── health-liveness.png ├── health-metrics-brief.png ├── health-metrics-detailed.png ├── health-readiness.png ├── health-web-details.png ├── health-web-redeploy.png ├── inventory-service-test.png ├── inventory-service-vertx.png ├── inventory-service.png ├── inventory-thorntail-new-class.png ├── kiali-abtesting-100.png ├── kiali-abtesting-50-50.png ├── kiali-graph-param.png ├── kiali-graph.png ├── kiali-login.png ├── kiali-logo.png ├── kiali-trace-detail-view.png ├── kiali-traces-param.png ├── kiali-traces-view.png ├── microprofile-logo.png ├── nodejs-logo.png ├── nodejs-webui-component.png ├── run-icon-springboot.png ├── run-icon-thorntail.png ├── service-catalog.png ├── servicemesh-architecture.png ├── spring-boot-logo.png ├── springboot-catalog-arch.png ├── springboot-catalog-component.png ├── springboot-catalog-project.png ├── springboot-catalog-service-root.png ├── springboot-che-preview-browser.png ├── springboot-che-stop.png ├── thorntail-inventory-codeready-preview-url.png ├── thorntail-inventory-codeready-run-palette.png ├── thorntail-inventory-codeready-run-stop.png ├── thorntail-inventory-component.png ├── thorntail-inventory-project.png ├── thorntail-inventory-service-root.png ├── thorntail-logo.png ├── vertx-event-loop.jpg ├── vertx-event-loop.png ├── vertx-gateway-component.png ├── vertx-gateway-project.png ├── vertx-gateway-service-root.png ├── vertx-inventory-project.png ├── vertx-logo.png ├── wfswarm-inventory-arch.png ├── wfswarm-inventory-che-build.png ├── wfswarm-inventory-che-deployed.png ├── wfswarm-inventory-che-new-class.png ├── wfswarm-inventory-che-preview-browser.png ├── wfswarm-inventory-che-preview-url.png ├── wfswarm-inventory-che-run-palette.png ├── wfswarm-inventory-che-run-stop.png └── wfswarm-inventory-project.png ├── introduction.adoc ├── inventory-deployment.adoc ├── inventory-thorntail-codeready.adoc ├── inventory-vertx-codeready.adoc ├── service-mesh.adoc └── webui-deployment.adoc /.gitignore: -------------------------------------------------------------------------------- 1 | tmp/ 2 | ansible/roles/ 3 | *.retry 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | sudo: required 3 | language: python 4 | python: "2.7" 5 | 6 | services: 7 | - docker 8 | 9 | before_install: 10 | - docker login -u $DOCKER_USER -p $DOCKER_PASS 11 | 12 | install: 13 | - pip install ansible 14 | - ansible-galaxy install -r apb/requirements-travis.yml 15 | - ansible-playbook apb/playbooks/provision.yml --syntax-check 16 | 17 | script: 18 | - cd apb && docker build -t openshiftapb/cloudnative-workshop-apb:$TRAVIS_COMMIT . 19 | 20 | after_success: 21 | - export TAG=`if [ "$TRAVIS_BRANCH" == "master" ]; then echo "latest"; else echo $TRAVIS_BRANCH ; fi` 22 | - docker tag openshiftapb/cloudnative-workshop-apb:$TRAVIS_COMMIT openshiftapb/cloudnative-workshop-apb:$TAG 23 | - docker push openshiftapb/cloudnative-workshop-apb:$TAG -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM osevg/workshopper:latest 2 | 3 | ENV CONTENT_URL_PREFIX="file:///opt/data/workshopper-content" 4 | ENV WORKSHOPS_URLS="file:///opt/data/workshopper-content/_cloud-native-roadshow.yml" 5 | ENV DEFAULT_LAB="roadshow" 6 | 7 | ADD *.adoc /opt/data/workshopper-content/ 8 | ADD *.yml /opt/data/workshopper-content/ 9 | ADD images /opt/data/workshopper-content/images 10 | 11 | USER root 12 | 13 | RUN chown jboss:root -R /opt/data && chmod 777 -R /opt/data 14 | 15 | USER jboss 16 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | == Cloud-Native Workshop image:https://api.travis-ci.org/openshift-labs/cloud-native-guides.svg?branch=ocp-3.11[Build Status,link=https://travis-ci.org/openshift-labs/cloud-native-guides] 2 | 3 | This one day hands-on cloud-native workshops provides developers and introduction to cloud-natives applications and gives them an experience of building cloud-native applications using OpenShift, Spring Boot, WildFly Swarm, Vert.xt and more. 4 | 5 | == Agenda 6 | 7 | * Introduction to Cloud-Native apps 8 | * Building services with Spring Boot 9 | * Building Java EE services with WildFly Swarm 10 | * Building Reactive Services with Vert.x 11 | * Monitoring Application Health 12 | * Fault Tolerance and Service Resilience 13 | * Configuration Management 14 | * Continuous Delivery 15 | * Debugging Services 16 | 17 | 18 | == Install Workshop Infrastructure 19 | 20 | An https://hub.docker.com/r/openshiftapb/cloudnative-workshop-apb[APB^] is provided for 21 | deploying the Cloud-Native Workshop infra (lab instructions, Nexus, Gogs, CodeReady Workspaces, etc) in a project 22 | on an OpenShift cluster via the service catalog. In order to add this APB to the OpenShift service catalog, log in 23 | as cluster admin and perform the following in the `*openshift-ansible-service-broker*` project : 24 | 25 | 1. Edit the `*broker-config*` configmap and add this snippet right after `*registry*`: 26 | 27 | [source,yaml] 28 | ---- 29 | - name: dh 30 | type: dockerhub 31 | org: openshiftapb 32 | tag: ocp-3.11 33 | white_list: [.*-apb$] 34 | ---- 35 | 36 | 2. Redeploy the `*asb*` deployment 37 | 38 | You can https://docs.openshift.com/container-platform/3.11/install_config/oab_broker_configuration.html#oab-config-registry-dockerhub[read more in the docs^] 39 | on how to configure the service catalog. 40 | 41 | TIP: If you are using the _OpenShift Workshop_ in RHPDS, this APB is already available in your service catalog. 42 | 43 | image:images/service-catalog.png?raw=true[^] 44 | 45 | As an alternative, you can also run the APB directly in a pod on OpenShift to install the workshop infra: 46 | 47 | [source,shell] 48 | ---- 49 | oc login 50 | oc new-project lab-infra 51 | oc run apb --restart=Never --image="openshiftapb/cloudnative-workshop-apb:ocp-3.11" \ 52 | -- provision -vvv -e namespace=$(oc project -q) -e openshift_token=$(oc whoami -t) 53 | ---- 54 | 55 | Or if you have Ansible installed locally, you can also run the Ansilbe playbooks directly on your machine: 56 | 57 | [source,shell] 58 | ---- 59 | oc login 60 | oc new-project lab-infra 61 | 62 | ansible-playbook -vvv playbooks/provision.yml \ 63 | -e namespace=$(oc project -q) \ 64 | -e openshift_token=$(oc whoami -t) \ 65 | -e openshift_master_url=$(oc whoami --show-server) 66 | ---- 67 | 68 | == Lab Instructions on OpenShift 69 | 70 | TIP: If you have used the above workshop installer, the lab instructions are already deployed. 71 | 72 | [source,shell] 73 | ---- 74 | oc new-app quay.io/osevg/workshopper:latest --name=guides \ 75 | -p LOG_TO_STDOUT=true \ 76 | -p WORKSHOPS_URLS="https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/ocp-3.11/_cloud-native-workshop-codeready.yml" 77 | oc expose svc/guides 78 | ---- 79 | 80 | == Local Lab Instructions 81 | 82 | [source,shell] 83 | ---- 84 | docker run -it --rm -p 8080:8080 \ 85 | -v $(pwd):/app-data \ 86 | -e LOG_TO_STDOUT=true \ 87 | -e CONTENT_URL_PREFIX="file:///app-data" \ 88 | -e WORKSHOPS_URLS="file:///app-data/_cloud-native-workshop-codeready.yml" \ 89 | quay.io/osevg/workshopper:latest 90 | ---- 91 | -------------------------------------------------------------------------------- /_cloud-native-workshop-codeready.yml: -------------------------------------------------------------------------------- 1 | id: "cloudnative" 2 | name: "OpenShift Cloud-Native Workshop" 3 | 4 | content: 5 | url: https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/ocp-3.11 6 | 7 | vars: 8 | OPENSHIFT_DOCS_BASE: "https://docs.openshift.com/container-platform/3.11" 9 | OPENSHIFT_USER: userX 10 | OPENSHIFT_PASSWORD: PASSWORD 11 | COOLSTORE_PROJECT: coolstoreX 12 | INFRA_PROJECT: infraX 13 | DOWNLOAD_CLIENT_WINDOWS: https://mirror.openshift.com/pub/openshift-v3/clients/3.11.16/windows/oc.zip 14 | DOWNLOAD_CLIENT_MAC: https://mirror.openshift.com/pub/openshift-v3/clients/3.11.16/macosx/oc.tar.gz 15 | DOWNLOAD_CLIENT_LIN64: https://mirror.openshift.com/pub/openshift-v3/clients/3.11.16/linux/oc.tar.gz 16 | LABS_GIT_REPO: https://github.com/openshift-labs/cloud-native-labs.git#ocp-3.11 17 | LABS_DOWNLOAD_URL: https://github.com/openshift-labs/cloud-native-labs/archive/ocp-3.11.zip 18 | WEB_NODEJS_GIT_REPO: https://github.com/openshift-labs/cloud-native-labs/tree/ocp-3.11/web-nodejs 19 | OPENSHIFT_CONSOLE_URL: OPENSHIFT-CONSOLE-URL 20 | APPS_HOSTNAME_SUFFIX: APPS_HOSTNAME_SUFFIX 21 | INVENTORY_ROUTE_HOST: INVENTORY-ROUTE-HOST 22 | CATALOG_ROUTE_HOST: CATALOG-ROUTE-HOST 23 | API_GATEWAY_ROUTE_HOST: API-GATEWAY-ROUTE-HOST 24 | CODEREADY_WORKSPACES_URL: http://codeready-lab-infra.192.168.99.100.nip.io 25 | GIT_URL: http://gogs-lab-infra.192.168.99.100.nip.io 26 | NEXUS_URL: http://nexus.lab-infra.svc:8081/repository/maven-all-public 27 | KIALI_URL: http://kiali-infra.192.168.99.100.nip.io 28 | JAEGER_URL: https://jaeger-query-istio-system.192.168.99.100.nip.io 29 | 30 | modules: 31 | activate: 32 | - introduction 33 | - getting-started-codeready 34 | - inventory-thorntail-codeready 35 | - catalog-spring-boot-codeready 36 | - gateway-vertx-codeready 37 | - webui-deployment 38 | - app-config-thorntail 39 | - health 40 | - fault-tolerance-codeready 41 | - continuous-delivery 42 | - service-mesh 43 | - abtesting 44 | - env-info 45 | -------------------------------------------------------------------------------- /_modules.yml: -------------------------------------------------------------------------------- 1 | config: 2 | renderer: adoc 3 | 4 | modules: 5 | introduction: 6 | name: Introduction 7 | getting-started-codeready: 8 | name: Getting Started 9 | catalog-spring-boot-codeready: 10 | name: Create Catalog Service as a Microservice with Spring Boot 11 | catalog-deployment: 12 | name: Deploy Catalog Service as a Microservice with Spring Boot 13 | inventory-thorntail-codeready: 14 | name: Create Inventory Service as an Enterprise Microservice with Thorntail 15 | inventory-vertx-codeready: 16 | name: Create Inventory Service as a Reactive Microservice with Eclipse Vert.x 17 | inventory-deployment: 18 | name: Deploy Inventory Service 19 | gateway-vertx-codeready: 20 | name: Create Gateway Service as a Reactive Microservice with Eclipse Vert.x 21 | gateway-deployment: 22 | name: Deploy Gateway Service 23 | webui-deployment: 24 | name: Deploy Web UI as a Microservice with with Node.js and AngularJS 25 | health: 26 | name: Monitoring Application Health 27 | fault-tolerance-codeready: 28 | name: Service Resilience and Fault Tolerance 29 | app-config-thorntail: 30 | name: Application Configuration 31 | app-config-vertx: 32 | name: Application Configuration 33 | continuous-delivery: 34 | name: Continuous Delivery 35 | debug-codeready: 36 | name: Debugging Applications 37 | service-mesh: 38 | name: Microservice Tracing with Service Mesh 39 | abtesting: 40 | name: "A/B Testing with Service Mesh" 41 | env-info: 42 | name: "Appendix: Lab Env Info" -------------------------------------------------------------------------------- /abtesting.adoc: -------------------------------------------------------------------------------- 1 | == A/B Testing with Service Mesh 2 | 3 | _10 MINUTE EXERCISE_ 4 | 5 | In this lab you will see how you can use *OpenShift Service Mesh* to do some A/B testing using and route traffic between 2 versions of the Catalog service. 6 | 7 | [sidebar] 8 | .A/B Testing 9 | -- 10 | https://en.wikipedia.org/wiki/A/B_testing[A/B testing^] allows running multiple versions of a functionality in parallel and using analytics of the user behavior it is possible to determine which version is the best. 11 | It is also possible to launch the new features only for a small set of users, to prepare the general avalability of a new feature. 12 | -- 13 | 14 | === Deploying the new Catalog Service 15 | 16 | A new *_Catalog Service v2_* has been implemented in https://golang.org/[Golang^] which uses the same business logic than *_Catalog Service v1_* 17 | except that all product descriptions are returned in **UPPERCASE**. 18 | 19 | Let's deploy the service directly from the git repository using the `*oc new-app*` command. 20 | 21 | In the terminal window type the following command: 22 | ---- 23 | $ oc new-app {{LABS_GIT_REPO}} \ 24 | --strategy=docker \ 25 | --context-dir=catalog-go \ 26 | --name=catalog-v2 \ 27 | --labels app=catalog,group=com.redhat.cloudnative,provider=fabric8,version=2.0 28 | ---- 29 | 30 | TIP: To simplify the lab, we use the same labels for *_catalog_* and *_catalog-v2_* since they are used for the service routing. 31 | 32 | **OpenShift Service Mesh** will be used to route the traffic between the catalog service v1 and v2, so you have to add the Istio sidecar to the *_Catalog Service v2_* using the following command: 33 | 34 | ---- 35 | $ oc patch dc/catalog-v2 --patch \ 36 | '{"spec": {"template": {"metadata": {"annotations": {"sidecar.istio.io/inject": "true"}}}}}' 37 | ---- 38 | 39 | To confirm that the application is successfully deployed, `*run this following command*`: 40 | 41 | ---- 42 | $ oc get pods -lapp=catalog,deploymentconfig=catalog-v2 43 | NAME READY STATUS RESTARTS AGE 44 | catalog-v2-2-7zsxb 2/2 Running 0 1m 45 | ---- 46 | 47 | The status should be **Running** and there should be **2/2** pods in the **Ready** column. 48 | Wait few seconds that the application restarts. 49 | 50 | 51 | === Enabling A/B Testing 52 | 53 | The implementation of such procedure like **A/B Testing** is one are the advantages coming with OpenShift Service Mesh. 54 | For this lab, you want to answer the following question: 55 | 56 | **Do the product descriptions written in uppercase increase sales rate?** 57 | 58 | Let's now create the *_Destination Rule_* resource. 59 | 60 | * A *_Destination Rule_* defines policies that apply to traffic intended for a service after routing has occurred. These rules specify configuration for load balancing, connection pool size from the sidecar, and outlier detection settings to detect and evict unhealthy hosts from the load balancing pool. 61 | 62 | In the Terminal window, `*issue the following command*`: 63 | 64 | ---- 65 | $ cat << EOF | oc create -f - 66 | --- 67 | apiVersion: networking.istio.io/v1alpha3 68 | kind: DestinationRule 69 | metadata: 70 | name: catalog 71 | spec: 72 | host: catalog 73 | subsets: 74 | - labels: 75 | version: "1.0-SNAPSHOT" 76 | name: "version-springboot" 77 | - labels: 78 | version: "2.0" 79 | name: "version-go" 80 | EOF 81 | ---- 82 | 83 | Now you have created a *_Destination Rule_* for *_Catalog Service_* and *_Catalog Service v2_*. 84 | 85 | The last step is to define the rules to distribute the traffic between the services. 86 | 87 | * A **VirtualService** defines a set of traffic routing rules to apply when a host is addressed. Each routing rule defines matching criteria for traffic of a specific protocol. If the traffic is matched, then it is sent to a named destination service (or subset/version of it) defined in the registry. 88 | 89 | In the Terminal window, `*issue the following command*`: 90 | 91 | ---- 92 | $ cat << EOF | oc create -f - 93 | --- 94 | apiVersion: networking.istio.io/v1alpha3 95 | kind: VirtualService 96 | metadata: 97 | name: catalog 98 | spec: 99 | hosts: 100 | - catalog 101 | http: 102 | - route: 103 | - destination: 104 | host: catalog 105 | subset: "version-springboot" 106 | weight: 50 107 | - destination: 108 | host: catalog 109 | subset: "version-go" 110 | weight: 50 111 | EOF 112 | ---- 113 | 114 | Doing so, you route **50%** of the **HTTP traffic** to pods of the *_Catalog Service_* *(subset "version-springboot" ie label "version: 1.0-SNAPSHOT")* and the **50%** remaining to pods of the *_Catalog Service v2_* *(subset "version-go" ie label "version: 2.0")*. 115 | 116 | === Generate HTTP traffic. 117 | 118 | Let's now see the A/B testing with Site Mesh in action. 119 | First, we need to generate HTTP traffic by sending several requests to the *_Gateway Service_* from the *_Istio Gateway_* 120 | 121 | In CodeReady Workspaces, `*click on _Commands Palette_*` and `*click on 'RUN > runGatewayService'*` 122 | 123 | image:{% image_path codeready-command-run-gateway-service.png %}[Commands Palette - RunGatewayService,600] 124 | 125 | You likely see *'Gateway => Catalog Spring Boot (v1)'* or *'Gateway => Catalog GoLang (v2)'* 126 | 127 | image:{% image_path codeready-run-gateway-50-50.png %}[Terminal - RunGatewayService,400] 128 | 129 | TIP: You can also go to the Web interface and refresh the page to see that product descriptions is sometimes in uppercase (v2) or not (v1). 130 | 131 | Go to Kiali to see the traffic distribution between Catalog v1 and v2. 132 | 133 | From the {{ KIALI_URL }}[Kiali Console^], `*click on the 'Graph' link*` in the left navigation and enter the following configuration in the drop down menus: 134 | 135 | * Namespace: **{{COOLSTORE_PROJECT}}** 136 | * Display: **'Traffic Animation'** check 137 | * Edge Label: **Requests percent of total** 138 | * Fetching: **Last 5 min** 139 | 140 | image:{% image_path kiali-abtesting-50-50.png %}[Kiali- Graph,700] 141 | 142 | You can see that the traffic between the two version of the *_Catalog_* is shared equitably (at least very very close). 143 | 144 | After one week trial, you have collected enough information to confirm that product descriptions in uppercase do increate sales rates. 145 | So you will route all the traffic to *_Catalog Service v2_*. Go back to the Terminal and `*run the following command*`: 146 | 147 | ---- 148 | $ cat << EOF | oc replace -f - 149 | --- 150 | apiVersion: networking.istio.io/v1alpha3 151 | kind: VirtualService 152 | metadata: 153 | name: catalog 154 | spec: 155 | hosts: 156 | - catalog 157 | http: 158 | - route: 159 | - destination: 160 | host: catalog 161 | subset: "version-springboot" 162 | weight: 0 163 | - destination: 164 | host: catalog 165 | subset: "version-go" 166 | weight: 100 167 | EOF 168 | ---- 169 | 170 | Now, you likely see only *'Gateway => Catalog GoLang (v2)'* in the *'runGatewayService'* terminal. 171 | 172 | image:{% image_path codeready-run-gateway-100.png %}[Terminal - RunGatewayService,600] 173 | 174 | And from {{ KIALI_URL }}[Kiali Console^], you can visualize that **100%** of the traffic is switching gradually to *_Catalog Service v2_*. 175 | 176 | image:{% image_path kiali-abtesting-100.png %}[Kiali- Graph,700] 177 | 178 | That's all for this lab! You are ready to move on to the next lab. 179 | -------------------------------------------------------------------------------- /apb/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ansibleplaybookbundle/apb-base:release-1.3 2 | 3 | LABEL "com.redhat.apb.spec"=\ 4 | "dmVyc2lvbjogJzEuMC4wJwpuYW1lOiBjbG91ZC1uYXRpdmUtd29ya3Nob3AtYXBiCmRlc2NyaXB0\ 5 | aW9uOiBBUEIgdG8gZGVwbG95IHJlcXVpcmVkIGluZnJhIGNvbXBvbmVudHMgZm9yIENsb3VkLU5h\ 6 | dGl2ZSBXb3Jrc2hvcHMgb24gYW4gT3BlblNoaWZ0IGNsdXN0ZXIKYmluZGFibGU6IEZhbHNlCmFz\ 7 | eW5jOiBvcHRpb25hbAp0YWdzOgotIHdvcmtzaG9wCi0gY2xvdWQtbmF0aXZlCm1ldGFkYXRhOgog\ 8 | IGRlcGVuZGVuY2llczogW10KICBkaXNwbGF5TmFtZTogIkNsb3VkLU5hdGl2ZSBXb3Jrc2hvcCAo\ 9 | Q29kZVJlYWR5KSBJbnN0YWxsZXIiCiAgbG9uZ0Rlc2NyaXB0aW9uOiAiUmVxdWlyZWQgY29tcG9u\ 10 | ZW50cyAoQ29kZVJlYWR5IFdvcmtzcGFjZXMsIE5leHVzLCBHb2dzLCBXb3Jrc2hvcHBlcikiCiAg\ 11 | Y29uc29sZS5vcGVuc2hpZnQuaW8vaWNvbkNsYXNzOiAicGZpY29uIHBmaWNvbi1zZXJ2aWNlcyIK\ 12 | ICBwcm92aWRlckRpc3BsYXlOYW1lOiAiUmVkIEhhdCwgSW5jLiIKcGxhbnM6CiAgLSBuYW1lOiBk\ 13 | ZWZhdWx0CiAgICBkZXNjcmlwdGlvbjogVGhpcyBkZWZhdWx0IHBsYW4gZGVwbG95cyBjbG91ZC1u\ 14 | YXRpdmUtd29ya3Nob3AKICAgIGZyZWU6IFRydWUKICAgIG1ldGFkYXRhOiB7fQogICAgcGFyYW1l\ 15 | dGVyczoKICAgIC0gbmFtZTogb3BlbnNoaWZ0X3VzZXIKICAgICAgdGl0bGU6IFVzZXJuYW1lCiAg\ 16 | ICAgIGRlc2NyaXB0aW9uOiBVc2VyIGlzIHJlcXVpcmVkIGZvciBjcmVhdGluZyBwcm9qZWN0IGFk\ 17 | bWluIHJlc291cmNlcwogICAgICB0eXBlOiBzdHJpbmcKICAgICAgcmVxdWlyZWQ6IHRydWUKICAg\ 18 | ICAgZGlzcGxheV9ncm91cDogT3BlblNoaWZ0IE1hc3RlcgogICAgLSBuYW1lOiBvcGVuc2hpZnRf\ 19 | cGFzc3dvcmQKICAgICAgdGl0bGU6IFBhc3N3b3JkCiAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29y\ 20 | ZCBpcyByZXF1aXJlZCBmb3IgY3JlYXRpbmcgcHJvamVjdCBhZG1pbiByZXNvdXJjZXMKICAgICAg\ 21 | dHlwZTogc3RyaW5nCiAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgIGRpc3BsYXlfdHlwZTogcGFz\ 22 | c3dvcmQKICAgICAgZGlzcGxheV9ncm91cDogT3BlblNoaWZ0IE1hc3RlcgogICAgLSBuYW1lOiB1\ 23 | c2VyX2NvdW50CiAgICAgIHRpdGxlOiBOdW1iZXIgb2YgUGFydGljaXBhbnRzCiAgICAgIGRlc2Ny\ 24 | aXB0aW9uOiBUaGUgbnVtYmVyIG9mIHBhcnRpY2lwYW50cwogICAgICB0eXBlOiBudW1iZXIKICAg\ 25 | ICAgcmVxdWlyZWQ6IHRydWUKICAgICAgZGVmYXVsdDogNTAKICAgICAgZGlzcGxheV90eXBlOiBu\ 26 | dW1iZXIKICAgICAgZGlzcGxheV9ncm91cDogTGFicyAmIEd1aWRlcwogICAgLSBuYW1lOiBvcGVu\ 27 | c2hpZnRfbWFzdGVyX3VybAogICAgICB0aXRsZTogT3BlblNoaWZ0IE1hc3RlciBVUkwKICAgICAg\ 28 | ZGVzY3JpcHRpb246IFRoZSBhZGRyZXNzIHRvIE9wZW5TaGlmdCBtYXN0ZXIgVVJMIHRvIGJlIGRp\ 29 | c3BsYXllZCBpbiB0aGUgbGFiIGd1aWRlIHRvIHBhcnRpY2lwYW50cwogICAgICB0eXBlOiBzdHJp\ 30 | bmcKICAgICAgcmVxdWlyZWQ6IHRydWUKICAgICAgZGlzcGxheV90eXBlOiBzdHJpbmcKICAgICAg\ 31 | ZGlzcGxheV9ncm91cDogTGFicyAmIEd1aWRlcwogICAgLSBuYW1lOiBvcGVuc2hpZnRfdXNlcl9w\ 32 | YXNzd29yZAogICAgICB0aXRsZTogT3BlblNoaWZ0IFVzZXIgUGFzc3dvcmQKICAgICAgZGVzY3Jp\ 33 | cHRpb246IFRoZSBPcGVuU2hpZnQgcGFzc3dvcmQgZm9yIHBhcnRpY2lwYW50cyB0byBiZSBkaXNw\ 34 | bGF5ZWQgaW4gdGhlIGxhYiBndWlkZSB0byBwYXJ0aWNpcGFudHMKICAgICAgdHlwZTogc3RyaW5n\ 35 | CiAgICAgIGRlZmF1bHQ6ICJvcGVuc2hpZnQiCiAgICAgIHJlcXVpcmVkOiB0cnVlCiAgICAgIGRp\ 36 | c3BsYXlfdHlwZTogc3RyaW5nCiAgICAgIGRpc3BsYXlfZ3JvdXA6IExhYnMgJiBHdWlkZXMKICAg\ 37 | IC0gbmFtZTogZ2l0X3JlcG9zaXRvcnlfZ3VpZGVfcGF0aAogICAgICB0aXRsZTogR2l0IFJlcG9z\ 38 | aXRvcnkgR3VpZGUgUGF0aAogICAgICBkZXNjcmlwdGlvbjogVGhlIFBhdGggb2YgdGhlIHJlcG9z\ 39 | aXRvcnkgd2l0aCB0aGUgbGFiIGd1aWRlIGZvciBwYXJ0aWNpcGFudHMgPGdpdGh1Yl9hY2NvdW50\ 40 | Pi88Z2l0aHViX3Byb2plY3Q+CiAgICAgIHR5cGU6IHN0cmluZwogICAgICBkZWZhdWx0OiAib3Bl\ 41 | bnNoaWZ0LWxhYnMvY2xvdWQtbmF0aXZlLWd1aWRlcyIKICAgICAgcmVxdWlyZWQ6IHRydWUKICAg\ 42 | ICAgZGlzcGxheV90eXBlOiBzdHJpbmcKICAgICAgZGlzcGxheV9ncm91cDogTGFicyAmIEd1aWRl\ 43 | cwogICAgLSBuYW1lOiBnaXRfcmVwb3NpdG9yeV9ndWlkZV9yZWZlcmVuY2UKICAgICAgdGl0bGU6\ 44 | IEdpdCBSZXBvc2l0b3J5IEd1aWRlIFJlZmVyZW5jZQogICAgICBkZXNjcmlwdGlvbjogU2V0IHRo\ 45 | aXMgdG8gYSBicmFuY2ggbmFtZSwgdGFnIG9yIG90aGVyIHJlZiBvZiB5b3VyIHJlcG9zaXRvcnkg\ 46 | aWYgeW91IGFyZSBub3QgdXNpbmcgdGhlIGRlZmF1bHQgYnJhbmNoLgogICAgICB0eXBlOiBzdHJp\ 47 | bmcKICAgICAgZGVmYXVsdDogIm9jcC0zLjExIgogICAgICByZXF1aXJlZDogdHJ1ZQogICAgICBk\ 48 | aXNwbGF5X3R5cGU6IHN0cmluZwogICAgICBkaXNwbGF5X2dyb3VwOiBMYWJzICYgR3VpZGVzCiAg\ 49 | ICAtIG5hbWU6IGd1aWRlX25hbWUKICAgICAgdGl0bGU6IEd1aWRlIE5hbWUKICAgICAgZGVzY3Jp\ 50 | cHRpb246IFNldCB0aGUgbmFtZSBvZiB0aGUgZ3VpZGUgZm9yIF9jbG91ZC1uYXRpdmUtd29ya3No\ 51 | b3AtPGd1aWRlX25hbWU+LnltbAogICAgICB0eXBlOiBzdHJpbmcKICAgICAgZGVmYXVsdDogImNv\ 52 | ZGVyZWFkeSIKICAgICAgcmVxdWlyZWQ6IHRydWUKICAgICAgZGlzcGxheV90eXBlOiBzdHJpbmcK\ 53 | ICAgICAgZGlzcGxheV9ncm91cDogTGFicyAmIEd1aWRlcwogICAgLSBuYW1lOiBnaXRfcmVwb3Np\ 54 | dG9yeV9sYWJfcGF0aAogICAgICB0aXRsZTogR2l0IFJlcG9zaXRvcnkgTGFiIFBhdGgKICAgICAg\ 55 | ZGVzY3JpcHRpb246IFRoZSBQYXRoIG9mIHRoZSByZXBvc2l0b3J5IHdpdGggdGhlIGxhYiBmb3Ig\ 56 | cGFydGljaXBhbnRzIDxnaXRodWJfYWNjb3VudD4vPGdpdGh1Yl9wcm9qZWN0PgogICAgICB0eXBl\ 57 | OiBzdHJpbmcKICAgICAgZGVmYXVsdDogIm9wZW5zaGlmdC1sYWJzL2Nsb3VkLW5hdGl2ZS1sYWJz\ 58 | IgogICAgICByZXF1aXJlZDogdHJ1ZQogICAgICBkaXNwbGF5X3R5cGU6IHN0cmluZwogICAgICBk\ 59 | aXNwbGF5X2dyb3VwOiBMYWJzICYgR3VpZGVzCiAgICAtIG5hbWU6IGdpdF9yZXBvc2l0b3J5X2xh\ 60 | Yl9yZWZlcmVuY2UKICAgICAgdGl0bGU6IEdpdCBSZXBvc2l0b3J5IExhYiBSZWZlcmVuY2UKICAg\ 61 | ICAgZGVzY3JpcHRpb246IFNldCB0aGlzIHRvIGEgYnJhbmNoIG5hbWUsIHRhZyBvciBvdGhlciBy\ 62 | ZWYgb2YgeW91ciByZXBvc2l0b3J5IGlmIHlvdSBhcmUgbm90IHVzaW5nIHRoZSBkZWZhdWx0IGJy\ 63 | YW5jaC4KICAgICAgdHlwZTogc3RyaW5nCiAgICAgIGRlZmF1bHQ6ICJvY3AtMy4xMSIKICAgICAg\ 64 | cmVxdWlyZWQ6IHRydWUKICAgICAgZGlzcGxheV90eXBlOiBzdHJpbmcKICAgICAgZGlzcGxheV9n\ 65 | cm91cDogTGFicyAmIEd1aWRlcwogICAgLSBuYW1lOiBpbmZyYXN2Y3NfYWRtX3VzZXIKICAgICAg\ 66 | dGl0bGU6IEluZnJhIFNlcnZpY2VzIEFkbWluIFVzZXIKICAgICAgZGVzY3JpcHRpb246IEFkbWlu\ 67 | IHVzZXIgZm9yIGluZnJhc3RydWN0dXJlIHNlcnZpY2VzIChHb2dzLCBOZXh1cywgLi4uKQogICAg\ 68 | ICB0eXBlOiBzdHJpbmcKICAgICAgZGVmYXVsdDogImFkbWludXNlciIKICAgICAgcmVxdWlyZWQ6\ 69 | IHRydWUKICAgICAgZGlzcGxheV90eXBlOiB0ZXh0CiAgICAgIGRpc3BsYXlfZ3JvdXA6IFdvcmtz\ 70 | aG9wIEluZnJhIFNlcnZpY2VzCiAgICAtIG5hbWU6IGluZnJhc3Zjc19hZG1fcHdkCiAgICAgIHRp\ 71 | dGxlOiBJbmZyYSBTZXJ2aWNlcyBBZG1pbiBQYXNzd29yZAogICAgICBkZXNjcmlwdGlvbjogQWRt\ 72 | aW4gcGFzc3dvcmQgZm9yIGluZnJhc3RydWN0dXJlIHNlcnZpY2VzIChHb2dzLCBOZXh1cywgLi4u\ 73 | KQogICAgICB0eXBlOiBzdHJpbmcKICAgICAgZGVmYXVsdDogImFkbWlucHdkIgogICAgICByZXF1\ 74 | aXJlZDogdHJ1ZQogICAgICBkaXNwbGF5X3R5cGU6IHRleHQKICAgICAgZGlzcGxheV9ncm91cDog\ 75 | V29ya3Nob3AgSW5mcmEgU2VydmljZXMKICAgICAg" 76 | 77 | 78 | COPY playbooks /opt/apb/project 79 | ADD requirements.yml /opt/apb/project/requirements.yml 80 | RUN ansible-galaxy install -r /opt/apb/project/requirements.yml -f 81 | RUN chmod -R g=u /opt/{ansible,apb} 82 | USER apb 83 | -------------------------------------------------------------------------------- /apb/Makefile: -------------------------------------------------------------------------------- 1 | DOCKERHOST = DOCKERHOST 2 | DOCKERORG = DOCKERORG 3 | IMAGENAME = cloud-native-guides-apb 4 | TAG = latest 5 | USER=$(shell id -u) 6 | PWD=$(shell pwd) 7 | build_and_push: apb_build docker_push apb_push 8 | 9 | .PHONY: apb_build 10 | apb_build: 11 | docker run --rm --privileged -v $(PWD):/mnt:z -v $(HOME)/.kube:/.kube -v /var/run/docker.sock:/var/run/docker.sock -u $(USER) docker.io/ansibleplaybookbundle/apb-tools:latest prepare 12 | docker build -t $(DOCKERHOST)/$(DOCKERORG)/$(IMAGENAME):$(TAG) . 13 | 14 | .PHONY: docker_push 15 | docker_push: 16 | docker push $(DOCKERHOST)/$(DOCKERORG)/$(IMAGENAME):$(TAG) 17 | 18 | .PHONY: apb_push 19 | apb_push: 20 | docker run --rm --privileged -v $(PWD):/mnt:z -v $(HOME)/.kube:/.kube -v /var/run/docker.sock:/var/run/docker.sock -u $(USER) docker.io/ansibleplaybookbundle/apb-tools:latest push 21 | -------------------------------------------------------------------------------- /apb/README.md: -------------------------------------------------------------------------------- 1 | Cloud-Native Workshop Installer 2 | ========= 3 | 4 | The provided Ansible Playbook Bundle automates preparing an OpenShift cluster for the Cloud-Native Labs 5 | by deploying required services (lab instructions, Gogs, Nexus, etc) which are used during the labs. 6 | 7 | ## Use an installed APB on OpenShift 8 | Select the item from the catalog. 9 | 10 | ## Development 11 | When you develop the APB you can test on a platform in the following ways. 12 | 13 | ### Install the apb tool 14 | The new `apb` tool will help you develop your APB in an easy way. Download the latest apb tool 15 | from here: [https://github.com/automationbroker/apb/releases](https://github.com/automationbroker/apb/releases) 16 | 17 | The [README.md](https://github.com/automationbroker/apb/blob/master/README.md) in that repository will give you a short getting started very insightful. 18 | 19 | If you're starrting a new APB, you should look into the workflow in the [Getting started doc](https://github.com/automationbroker/apb/blob/master/docs/getting_started.md) 20 | 21 | ### Create a namespace to test 22 | Once logged into your OCP cluster, you must first create a project: 23 | 24 | ```bash 25 | oc new-project cloudnativeguides 26 | ``` 27 | 28 | ### Update the com.redhat.apb.spec LABEL 29 | If you've changed the apb.yml you will need to update the `com.redhat.apb.spec` LABEL with a base64 encoded version of apb.yml. To do this we need to run `apb bundle prepare` 30 | 31 | ```bash 32 | apb bundle prepare 33 | ``` 34 | 35 | ### Building and publishing your APB for testing 36 | 37 | At this point we have a fully formed APB that we can build. In this example, we'll build an APB using the OpenShift build system. Let's first create a `buildconfig` for the APB. Perform this step when you're building a new APB that you haven't previously built on OpenShift: 38 | 39 | ```bash 40 | oc new-build --binary=true --name workshop -n cloudnativeguides 41 | ``` 42 | 43 | To start the build from the current directory and follow the logs: 44 | 45 | ```bash 46 | oc start-build --follow --from-dir . workshop -n cloudnativeguides 47 | ``` 48 | 49 | If the build completes successfully, you'll see some newly available imagestreams: 50 | 51 | ```bash 52 | oc get is 53 | NAME DOCKER REPO TAGS UPDATED 54 | workshop docker-registry.default.svc:5000/cloudnativeguides/workshop latest About a minute ago 55 | ``` 56 | 57 | We can now add the internal OpenShift registry to our list of configured registries: 58 | 59 | ```bash 60 | apb registry add my-registry --type local_openshift --namespaces cloudnativeguides 61 | Getting specs for registry: [my-registry] 62 | INFO Empty AuthType. Assuming credentials are defined in the config... 63 | INFO == REGISTRY CX == 64 | INFO Name: my-registry 65 | INFO Type: local_openshift 66 | INFO Url: 67 | INFO Validating specs... 68 | INFO All specs passed validation! 69 | INFO Registry my-registry has 1 valid APBs available from 1 images scanned 70 | APB IMAGE REGISTRY 71 | ------------------------- -+- ---------------------------------------------------------- -+- ----------- 72 | cloud-native-workshop-apb | docker-registry.default.svc:5000/cloudnativeguides/workshop | my-registry 73 | ``` 74 | 75 | ### Running the APB 76 | Now that `apb` is aware of the `cloud-native-workshop-apb` APB in the registry, we can perform any supported action against the APB. The `apb bundle` subcommand gives you some actions you can perform on a specific bundle in a registry. 77 | 78 | We can `provision` the `cloud-native-workshop-apb` that now exists in the registry by running: 79 | 80 | ```bash 81 | apb bundle provision cloud-native-workshop-apb -n cloudnativeguides --follow 82 | ``` 83 | 84 | The provision command will prompt you for all required parameters to your APB. 85 | 86 | __NOTE__: The `--follow` flag used above will show logs produced by the running APB. 87 | 88 | You can `deprovision` the `cloud-native-workshop-apbb` that now exists in the registry by running: 89 | 90 | ```bash 91 | apb bundle deprovision cloud-native-workshop-apb -n cloudnativeguides --follow 92 | ``` 93 | 94 | The deprovision command will prompt you for the specific instance to delete and all required parameters to your APB. 95 | 96 | ## Advanced options 97 | 98 | |Variable | Default Value | Description | 99 | |---------------------------|--------------------------|---------------| 100 | |`openshift_user` | | Username of the admin user | 101 | |`openshift_password` | | Password of the admin user | 102 | |`user_count` | 50 | Number of Participants | 103 | |`openshift_master_url` | | The address to OpenShift master URL to be displayed in the lab guide to participants | 104 | |`openshift_user_password` | openshift | The OpenShift password for participants to be displayed in the lab guide to participants | 105 | |`git_repository_guide_path` | openshift-labs/cloud-native-guides | The Path of the repository with the lab guide for participants / | 106 | |`git_repository_guide_reference` | ocp-3.11 | Set this to a branch name, tag or other ref of your repository if you are not using the default branch. | 107 | |`guide_name` | codeready | Set the name of the guide for _cloud-native-workshop-.yml | 108 | |`git_repository_lab_path` | openshift-labs/cloud-native-labs | The Path of the repository with the lab for participants / | 109 | |`git_repository_lab_reference` | ocp-3.11 | Set this to a branch name, tag or other ref of your repository if you are not using the default branch | 110 | |`infrasvcs_adm_user` | adminuser | Admin user for infrastructure services (Gogs, Nexus, ...) | 111 | |`infrasvcs_adm_pwd` | adminpwd | Admin password for infrastructure services (Gogs, Nexus, ...) | 112 | -------------------------------------------------------------------------------- /apb/apb.yml: -------------------------------------------------------------------------------- 1 | version: '1.0.0' 2 | name: cloud-native-workshop-apb 3 | description: APB to deploy required infra components for Cloud-Native Workshops on an OpenShift cluster 4 | bindable: False 5 | async: optional 6 | tags: 7 | - workshop 8 | - cloud-native 9 | metadata: 10 | dependencies: [] 11 | displayName: "Cloud-Native Workshop (CodeReady) Installer" 12 | longDescription: "Required components (CodeReady Workspaces, Nexus, Gogs, Workshopper)" 13 | console.openshift.io/iconClass: "pficon pficon-services" 14 | providerDisplayName: "Red Hat, Inc." 15 | plans: 16 | - name: default 17 | description: This default plan deploys cloud-native-workshop 18 | free: True 19 | metadata: {} 20 | parameters: 21 | - name: openshift_user 22 | title: Username 23 | description: User is required for creating project admin resources 24 | type: string 25 | required: true 26 | display_group: OpenShift Master 27 | - name: openshift_password 28 | title: Password 29 | description: Password is required for creating project admin resources 30 | type: string 31 | required: true 32 | display_type: password 33 | display_group: OpenShift Master 34 | - name: user_count 35 | title: Number of Participants 36 | description: The number of participants 37 | type: number 38 | required: true 39 | default: 50 40 | display_type: number 41 | display_group: Labs & Guides 42 | - name: openshift_master_url 43 | title: OpenShift Master URL 44 | description: The address to OpenShift master URL to be displayed in the lab guide to participants 45 | type: string 46 | required: true 47 | display_type: string 48 | display_group: Labs & Guides 49 | - name: openshift_user_password 50 | title: OpenShift User Password 51 | description: The OpenShift password for participants to be displayed in the lab guide to participants 52 | type: string 53 | default: "openshift" 54 | required: true 55 | display_type: string 56 | display_group: Labs & Guides 57 | - name: git_repository_guide_path 58 | title: Git Repository Guide Path 59 | description: The Path of the repository with the lab guide for participants / 60 | type: string 61 | default: "openshift-labs/cloud-native-guides" 62 | required: true 63 | display_type: string 64 | display_group: Labs & Guides 65 | - name: git_repository_guide_reference 66 | title: Git Repository Guide Reference 67 | description: Set this to a branch name, tag or other ref of your repository if you are not using the default branch. 68 | type: string 69 | default: "ocp-3.11" 70 | required: true 71 | display_type: string 72 | display_group: Labs & Guides 73 | - name: guide_name 74 | title: Guide Name 75 | description: Set the name of the guide for _cloud-native-workshop-.yml 76 | type: string 77 | default: "codeready" 78 | required: true 79 | display_type: string 80 | display_group: Labs & Guides 81 | - name: git_repository_lab_path 82 | title: Git Repository Lab Path 83 | description: The Path of the repository with the lab for participants / 84 | type: string 85 | default: "openshift-labs/cloud-native-labs" 86 | required: true 87 | display_type: string 88 | display_group: Labs & Guides 89 | - name: git_repository_lab_reference 90 | title: Git Repository Lab Reference 91 | description: Set this to a branch name, tag or other ref of your repository if you are not using the default branch. 92 | type: string 93 | default: "ocp-3.11" 94 | required: true 95 | display_type: string 96 | display_group: Labs & Guides 97 | - name: infrasvcs_adm_user 98 | title: Infra Services Admin User 99 | description: Admin user for infrastructure services (Gogs, Nexus, ...) 100 | type: string 101 | default: "adminuser" 102 | required: true 103 | display_type: text 104 | display_group: Workshop Infra Services 105 | - name: infrasvcs_adm_pwd 106 | title: Infra Services Admin Password 107 | description: Admin password for infrastructure services (Gogs, Nexus, ...) 108 | type: string 109 | default: "adminpwd" 110 | required: true 111 | display_type: text 112 | display_group: Workshop Infra Services 113 | -------------------------------------------------------------------------------- /apb/playbooks/codeready-workspaces-operator-installer/README.adoc: -------------------------------------------------------------------------------- 1 | ## Operator installer README 2 | 3 | This document explains how to use the Operator installer (deployment script). 4 | 5 | ### Prerequisites 6 | 7 | * a running OpenShift or link:https://docs.okd.io/latest/minishift/index.html[Minishift] instance 8 | * an active session (you should be logged in) 9 | * cluster-admin privileges to register CRD and grant Operator service account cluster admin permissions 10 | ``` 11 | oc login --server=https://your.ip.address.here:8443 -u developer -p developer 12 | ``` 13 | 14 | ### Required Permissions 15 | 16 | To successfully deploy CodeReady Workspaces using this script, cluster-admin privileges are required. The table below lists objects and required permissions: 17 | 18 | [%autowidth] 19 | |=== 20 | | *Kind* | *Name* | *Description* | *Permissions* 21 | | CRD | | Custom Resource definition - CheCluster | cluster-admin 22 | | CR | codeready | Custom Resource of CheCluster Kind | cluster-admin. Alternatively, a clusterrole can be created 23 | | ServiceAccount | codeready-operator | Operator uses this SA to reconcile CRW objects | edit role in a target namespace 24 | | Role | codeready-operator | Scope of permissions for operator service account | cluster-admin 25 | | RoleBinding | codeready-operator | Assign role to service account | edit role in a target namespace 26 | | Deployment | codeready-operator | Deployment with operator image in template spec | edit role in a target namespace 27 | | ClusterRole | codeready-operator | ClusterRole that lets create, update, delete oAuthClients | cluster-admin 28 | | ClusterRoleBinding | ${NAMESPACE}-codeready-operator | ClusterRoleBinding that lets create, update, delete oAuthClients | cluster-admin 29 | | Role | secret-reader | Role that lets read secrets in router namespace | cluster-admin 30 | | RoleBinding | ${NAMESPACE}-codeready-operator | RoleBinding that lets read secrets in router namespace | cluster-admin 31 | |=== 32 | 33 | By default, operator service account gets privileges to list, get, watch, create, update and delete ingresses, routes, service accounts, roles, 34 | rolebindings, pvcs, deployments, configmaps, secrets, as well as run execs into pods, watch events and read pod logs in a target namespace. 35 | 36 | With self signed certificates support enabled, the operator service account will get privileges to read secrets in an OpenShift router namespace. 37 | 38 | With OpenShift oAuth enabled, the operator service account will get privileges to get, list, create, update and delete oAuthclients at a cluster scope. 39 | 40 | ### Quickstart 41 | 42 | The simplest way to run the script is to use all the defaults. 43 | 44 | The following command will grab config from custom-resource.yaml and start an installer image: 45 | 46 | ``` 47 | ./deploy.sh --deploy 48 | ``` 49 | 50 | ### Installation Configuration 51 | 52 | The installer script will use command line args and `link:custom-resource.yaml[custom-resource.yaml]` file to populate Operator CR spec fields. 53 | 54 | #### Configuration 55 | 56 | You can override default envs. Not all configuration parameters are available as flags. Run `./deploy.sh --help` to get a list of all available arguments. 57 | 58 | `link:custom-resource.yaml[custom-resource.yaml]` is a template with CR object holding spec fields that instruct the Operator on how exactly to deploy and configure CodeReady Workspaces. 59 | 60 | #### Examples 61 | 62 | ##### Deploy with all defaults 63 | 64 | The following command will grab config from custom-resource.yaml and start an installer image: 65 | 66 | ``` 67 | ./deploy.sh --deploy 68 | ``` 69 | Specify a project/namespace: 70 | 71 | ``` 72 | ./deploy.sh --deploy -p=mynamespace 73 | ``` 74 | 75 | #### Deploy without support of self signed certs, OpenShift OAuth and a custom server-image 76 | 77 | ``` 78 | ./deploy.sh --deploy --server-image=myserver/image --version=latest --public-certs 79 | ``` 80 | 81 | ##### Deploy with external Red Hat SSO: 82 | 83 | In `link:custom-resource.yaml[custom-resource.yaml]`: 84 | 85 | ``` 86 | auth: 87 | externalIdentityProvider: true 88 | identityProviderURL: 'https://my-keycloak.com' 89 | identityProviderRealm: 'myrealm' 90 | identityProviderClientId: 'myClient' 91 | 92 | ``` 93 | 94 | ##### Deploy with external Red Hat SSO and Postgres DB: 95 | 96 | In `link:custom-resource.yaml[custom-resource.yaml]`: 97 | 98 | ``` 99 | database: 100 | externalDb: true 101 | chePostgresHostname: 'http://postgres' 102 | chePostgresPort: '5432' 103 | chePostgresUser: 'myuser' 104 | chePostgresPassword: 'mypass' 105 | chePostgresDb: 'mydb' 106 | 107 | .... 108 | auth: 109 | externalIdentityProvider: true 110 | identityProviderAdminUserName: 'https://my-keycloak.com' 111 | identityProviderRealm: 'myrealm' 112 | identityProviderClientId: 'myClient' 113 | ``` 114 | 115 | ### External DB and RH SSO Support 116 | 117 | You can connect to external DB and RH SSO instances. The installer supports the following combinations: 118 | 119 | * DB + RH SSO 120 | * RH SSO alone 121 | 122 | External DB + bundled RH SSO isn't currently supported. Provisioning of database and Keycloak realm and client happens only with bundled resources, 123 | i.e. if you are connecting your own DB or Keycloak you need to pre-create resources. Refer to installation docs for more details. 124 | 125 | 126 | ## Upgrade from 1.0.1 to 1.1 127 | 128 | ### Prerequisites 129 | 130 | These are the same Prerequisites as above. 131 | 132 | * a running OpenShift or link:https://docs.okd.io/latest/minishift/index.html[Minishift] instance 133 | * an active session (you should be logged in) 134 | * cluster-admin privileges to register CRD and grant Operator service account cluster admin permissions 135 | ``` 136 | oc login --server=https://your.ip.address.here:8443 -u developer -p developer 137 | ``` 138 | 139 | ### Migration 140 | 141 | CodeReady Workspaces 1.1.0 introduces an Operator that uses controller to watch custom resources. There is no direct upgrade path from CodeReady Workspaces 1.0.1 to CodeReady Workspaces 1.1.0. If you do not have any important workspaces and projects in an existing 1.0.1 namespace, we recommend deleting the 1.0.1 installation and deploying CodeReady Workspaces 1.1.0. 142 | 143 | However, if you want to keep an existing 1.0.1 installation, it is possible to upgrade by deploying the new operator to an existing namespace. 144 | 145 | #### Automated method 146 | 147 | . Run `link:migrate.sh[migrate.sh]` using the name of your existing deployed project / `$targetNamespace`. 148 | 149 | . Check changes in `link:custom-resource.yaml[custom-resource.yaml]`. 150 | 151 | . Run `link:deploy.sh[deploy.sh]` using the parameters for your environment. 152 | 153 | #### Manual method 154 | 155 | . Obtain the current Postgres password (`POSTGRESQL_PASSWORD`) from the existing Postgres deployment environment, or run the following `oc` command against your `$targetNamespace`: 156 | 157 | ``` 158 | oc get deployment postgres -o=jsonpath={'.spec.template.spec.containers[0].env[?(@.name=="POSTGRESQL_PASSWORD")].value'} -n $targetNamespace 159 | ``` 160 | 161 | [start=2] 162 | . Obtain the current Keycloak administrator username and password (`SSO_ADMIN_USERNAME` and `SSO_ADMIN_PASSWORD`) from the existing Keycloak deployment environment, or run the following `oc` command: 163 | 164 | ``` 165 | oc get deployment keycloak -o=jsonpath={'.spec.template.spec.containers[0].env[?(@.name=="SSO_ADMIN_USERNAME")].value'} -n $targetNamespace 166 | oc get deployment keycloak -o=jsonpath={'.spec.template.spec.containers[0].env[?(@.name=="SSO_ADMIN_PASSWORD")].value'} -n $targetNamespace 167 | ``` 168 | 169 | If you have changed the RH SSO administrator password, provide an actual password instead of fetching it from the environment variables. 170 | 171 | [start=3] 172 | . Replace the following values in the `link:custom-resource.yaml[custom-resource.yaml]` file with values you have obtained: 173 | 174 | ``` 175 | spec: 176 | database: 177 | chePostgresPassword: 'password' 178 | auth: 179 | keycloakAdminUserName: 'username' 180 | keycloakAdminPassword: 'password' 181 | ``` 182 | 183 | [start=4] 184 | . Optional. If you have configured OpenShift oAuth, obtain the oAuth secret and set its value in the `link:custom-resource.yaml[custom-resource.yaml]` file: 185 | 186 | To obtain the secret, take the following steps. 187 | 188 | [start=a] 189 | .. Run the following command as the cluster administrator: 190 | 191 | 192 | ``` 193 | oc get oauthclient openshift-identity-provider-h2fh -o=jsonpath={'.secret'} 194 | ``` 195 | 196 | [start=b] 197 | .. Add the following fields to the `spec.auth` section of the `link:custom-resource.yaml[custom-resource.yaml]` file. Replace `$secret` with an actual secret. Set `oAuthClientName` to `'openshift-identity-provider-h2fh'` if not already set. 198 | 199 | ``` 200 | spec: 201 | auth: 202 | oAuthClientName: 'openshift-identity-provider-h2fh' 203 | oAuthSecret: 'secret' 204 | 205 | ``` 206 | 207 | [start=5] 208 | . Save `link:custom-resource.yaml[custom-resource.yaml]` 209 | 210 | [start=6] 211 | . Run the `link:deploy.sh[deploy.sh]` script using parameters for your environment. 212 | 213 | ## Uninstall 214 | 215 | There's no dedicated function in the `link:deploy.sh[deploy.sh]` script that can uninstall CodeReady Workspaces. 216 | 217 | However, you can delete a custom resource, which will delete all associated objects: 218 | 219 | ``` 220 | oc delete checluster/codeready -n $targetNamespace 221 | ``` 222 | 223 | where `$targetNamespace` is an OpenShift project with deployed CodeReady Workspaces (`workspaces` by default). 224 | -------------------------------------------------------------------------------- /apb/playbooks/codeready-workspaces-operator-installer/custom-resource.yaml: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: che 5 | objects: 6 | - apiVersion: org.eclipse.che/v1 7 | kind: CheCluster 8 | metadata: 9 | name: codeready 10 | spec: 11 | server: 12 | cheFlavor: codeready 13 | cheImage: ${SERVER_IMAGE_NAME} 14 | cheImageTag: ${SERVER_IMAGE_TAG} 15 | tlsSupport: ${{TLS_SUPPORT}} 16 | selfSignedCert: ${{SELF_SIGNED_CERT}} 17 | proxyURL: '' 18 | proxyPort: '' 19 | nonProxyHosts: '' 20 | proxyUser: '' 21 | proxyPassword: '' 22 | storage: 23 | pvcStrategy: 'per-workspace' 24 | pvcClaimSize: 1Gi 25 | database: 26 | externalDb: false 27 | chePostgresHostName: '' 28 | chePostgresPort: '' 29 | chePostgresUser: '' 30 | chePostgresPassword: '' 31 | chePostgresDb: '' 32 | auth: 33 | openShiftoAuth: ${{ENABLE_OPENSHIFT_OAUTH}} 34 | externalIdentityProvider: false 35 | identityProviderAdminUserName: 'admin' 36 | identityProviderPassword: 'admin' 37 | identityProviderURL: '' 38 | identityProviderRealm: '' 39 | identityProviderClientId: '' 40 | parameters: 41 | - name: SERVER_IMAGE_NAME 42 | displayName: Server image repo 43 | description: Server image repo 44 | - name: SERVER_IMAGE_TAG 45 | displayName: Server image tag 46 | description: Server image tag 47 | - name: TLS_SUPPORT 48 | displayName: TLS Support 49 | description: Secure routes for CodeReady Workspaces 50 | required: true 51 | - name: ENABLE_OPENSHIFT_OAUTH 52 | displayName: OpenShift oAuth 53 | description: Log in with OpenShift 54 | required: true 55 | - name: SELF_SIGNED_CERT 56 | displayName: Self signed cert 57 | description: Use of self signed router certs 58 | required: true 59 | -------------------------------------------------------------------------------- /apb/playbooks/codeready-workspaces-operator-installer/migrate_1.0_to_1.1.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | BASE_DIR=$(cd "$(dirname "$0")"; pwd) 3 | CRFILE=${BASE_DIR}/custom-resource.yaml 4 | 5 | DEFAULT_OPENSHIFT_PROJECT="workspaces" 6 | HELP=" 7 | 8 | How to use this script to migrate from CRW 1.0 to 1.1: 9 | -p=, --project= | project namespace to deploy CodeReady Workspaces, default: ${DEFAULT_OPENSHIFT_PROJECT} 10 | -c=, --custom-resource= | path to custom-resource.yaml file, default: ${CRFILE} 11 | -h, --help | show this help menu 12 | " 13 | if [[ $# -eq 0 ]] ; then 14 | echo -e "$HELP" 15 | exit 0 16 | fi 17 | for key in "$@" 18 | do 19 | case $key in 20 | -p=*| --project=*) 21 | OPENSHIFT_PROJECT="${key#*=}" 22 | shift 23 | ;; 24 | -c=*| --custom-resource=*) 25 | CRFILE="${key#*=}" 26 | shift 27 | ;; 28 | -h | --help) 29 | echo -e "$HELP" 30 | exit 1 31 | ;; 32 | *) 33 | echo "Unknown argument passed: '$key'." 34 | echo -e "$HELP" 35 | exit 1 36 | ;; 37 | esac 38 | done 39 | export OPENSHIFT_PROJECT=${OPENSHIFT_PROJECT:-${DEFAULT_OPENSHIFT_PROJECT}} 40 | 41 | if [[ ! -f ${CRFILE} ]]; then 42 | echo " 43 | [ERROR] Could not find file ${CRFILE}. Please copy into this directory to proceed. 44 | " && exit 1 45 | fi 46 | 47 | 48 | # check `oc status` for an error 49 | status="$(oc status 2>&1)" 50 | if [[ $status == *"Error"* ]]; then 51 | echo "$status" 52 | echo " 53 | [ERROR] You must log in to your cluster to use this script. For example, 54 | 55 | oc login --username developer --password developer 56 | 57 | " && exit 1 58 | fi 59 | # check `oc project` for a selected project 60 | status="$(oc project 2>&1)" 61 | if [[ $status == *"error"* ]]; then 62 | echo "$status" && exit 1 63 | fi 64 | 65 | POSTGRESQL_PASSWORD=$(oc get deployment postgres -o=jsonpath={'.spec.template.spec.containers[0].env[?(@.name=="POSTGRESQL_PASSWORD")].value'} -n=$OPENSHIFT_PROJECT) 66 | SSO_ADMIN_USERNAME=$(oc get deployment keycloak -o=jsonpath={'.spec.template.spec.containers[0].env[?(@.name=="SSO_ADMIN_USERNAME")].value'} -n=$OPENSHIFT_PROJECT) 67 | SSO_ADMIN_PASSWORD=$(oc get deployment keycloak -o=jsonpath={'.spec.template.spec.containers[0].env[?(@.name=="SSO_ADMIN_PASSWORD")].value'} -n=$OPENSHIFT_PROJECT) 68 | SECRET=$(oc get oauthclient/openshift-identity-provider-h2fh -o=jsonpath={'.secret'}) 69 | 70 | if [[ ${SECRET} == "" ]]; then echo " 71 | [WARNING] No secret found for oauthclient/openshift-identity-provider-h2fh !"; fi 72 | 73 | # replace values in custom resource yaml 74 | sed -i -e "s/chePostgresPassword: .\+/chePostgresPassword: '${POSTGRESQL_PASSWORD}'/g" \ 75 | -e "s/keycloakAdminUserName: .\+/keycloakAdminUserName: '${SSO_ADMIN_USERNAME}'/g" \ 76 | -e "s/keycloakAdminPassword: .\+/keycloakAdminPassword: '${SSO_ADMIN_PASSWORD}'/g" ${CRFILE} 77 | sed -i "/ \+\(oAuthClientName\|oAuthSecret\): .\+/d" ${CRFILE} 78 | sed -i "/auth:/a \ oAuthClientName: 'openshift-identity-provider-h2fh'\\n \ oAuthSecret: '${SECRET}'" ${CRFILE} 79 | 80 | echo " 81 | Successfully patched ${CRFILE} 82 | 83 | You can now run deploy.sh with arguments that suit your installation. 84 | " 85 | -------------------------------------------------------------------------------- /apb/playbooks/deprovision.yml: -------------------------------------------------------------------------------- 1 | - name: cloud-native-development-apb playbook to deprovision the application 2 | hosts: localhost 3 | gather_facts: false 4 | connection: local 5 | vars: 6 | openshift_user: 7 | openshift_password: 8 | openshift_token: 9 | 10 | roles: 11 | - role: ansible.kubernetes-modules 12 | install_python_requirements: no 13 | - role: ansibleplaybookbundle.asb-modules 14 | 15 | tasks: 16 | - name: login as super user with token 17 | shell: "oc login --token={{ openshift_token }} --insecure-skip-tls-verify=true" 18 | ignore_errors: true 19 | when: 20 | - openshift_token is defined 21 | - openshift_token is not none 22 | - openshift_token|trim() != "" 23 | 24 | - name: login as super user with pwd 25 | shell: "oc login -u {{ openshift_user }} -p {{ openshift_password }} --insecure-skip-tls-verify=true" 26 | ignore_errors: true 27 | when: > 28 | openshift_token is not defined or 29 | openshift_token is none or 30 | openshift_token|trim() == "" 31 | 32 | - name: Delete infrastructyre services from {{ namespace }} 33 | command: "oc delete all,cm,secret,pvc,sa -l app={{ item }} -n {{ namespace }}" 34 | ignore_errors: true 35 | with_items: 36 | - gogs 37 | - nexus 38 | - guides-codeready 39 | - codeready 40 | - etherpad 41 | 42 | - name: Delete configmap 'codeready-operator' 43 | command: "oc delete cm codeready-operator -n {{ namespace }}" 44 | ignore_errors: true 45 | 46 | - name: Delete CodeReady Workspaces additional resources from {{ namespace }} 47 | command: "oc delete {{ item }} codeready-operator -n {{ namespace }}" 48 | ignore_errors: true 49 | with_items: 50 | - serviceaccount 51 | - rolebinding 52 | - role 53 | 54 | - name: Delete projects if exists 55 | command: "oc delete project {{ infra_project_name }} {{ project_name }}" 56 | register: project_result 57 | ignore_errors: true 58 | vars: 59 | infra_project_name: "{{ 'infra%d' | format(item) }}" 60 | project_name: "{{ 'coolstore%d' | format(item) }}" 61 | loop: "{{ range(1, 100 )|list }}" 62 | -------------------------------------------------------------------------------- /apb/playbooks/provision.yml: -------------------------------------------------------------------------------- 1 | - name: cloud-native-workshop-apb playbook to provision the application 2 | hosts: localhost 3 | gather_facts: false 4 | connection: local 5 | vars: 6 | openshift_user: 7 | openshift_password: 8 | openshift_token: 9 | openshift_master_url: 10 | openshift_user_password: openshift 11 | git_repository_lab_path: openshift-labs/cloud-native-labs 12 | git_repository_lab_reference: ocp-3.11 13 | git_repository_guide_path: openshift-labs/cloud-native-guides 14 | git_repository_guide_reference: ocp-3.11 15 | git_repository_guide_context: 16 | guide_name: codeready 17 | gogs_dev_user: developer 18 | gogs_pwd: openshift 19 | infrasvcs_adm_user: adminuser 20 | infrasvcs_adm_pwd: adminpwd 21 | user_count: 5 22 | openshift_service_mesh_installation: true 23 | preconfigure_service_mesh_projects: true 24 | preconfigure_squash: false 25 | 26 | roles: 27 | - role: ansible.kubernetes-modules 28 | install_python_requirements: no 29 | - role: ansibleplaybookbundle.asb-modules 30 | 31 | tasks: 32 | - name: login as super user with token 33 | shell: "oc login --token={{ openshift_token }} --insecure-skip-tls-verify=true" 34 | when: 35 | - openshift_token is defined 36 | - openshift_token is not none 37 | - openshift_token|trim() != "" 38 | tags: always 39 | 40 | - name: login as super user with pwd 41 | shell: "oc login -u {{ openshift_user }} -p {{ openshift_password }} --insecure-skip-tls-verify=true" 42 | when: > 43 | openshift_token is not defined or 44 | openshift_token is none or 45 | openshift_token|trim() == "" 46 | tags: always 47 | 48 | - name: extract app route suffix from openshift-console 49 | block: 50 | - shell: "oc get route console -n openshift-console -o 'jsonpath={.spec.host}'" 51 | register: console_route 52 | - set_fact: 53 | apps_hostname_suffix: "{{ console_route.stdout |regex_replace('^console\\.(.*)$', '\\1') }}" 54 | tags: always 55 | 56 | - name: delete project quota 57 | shell: "oc delete limitrange --all -n {{ namespace }}" 58 | ignore_errors: true 59 | tags: always 60 | 61 | # Etherpad 62 | - name: install etherpad 63 | include: "{{ playbook_dir }}/tasks/install_etherpad.yml" 64 | tags: etherpad 65 | 66 | - import_role: 67 | name: openshift_sonatype_nexus 68 | vars: 69 | project_name: "{{ namespace }}" 70 | nexus_image_version: 3.12.1 71 | nexus_max_memory: 6Gi 72 | tags: nexus 73 | 74 | - import_role: 75 | name: openshift_gogs 76 | vars: 77 | project_name: "{{ namespace }}" 78 | gogs_route: "gogs-{{ namespace }}.{{ apps_hostname_suffix }}" 79 | gogs_image_version: 0.11.34 80 | gogs_admin_user: "{{ infrasvcs_adm_user }}" 81 | gogs_admin_password: "{{ infrasvcs_adm_pwd }}" 82 | gogs_user: "{{ gogs_dev_user }}" 83 | gogs_password: "{{ gogs_pwd }}" 84 | tags: gogs 85 | 86 | # install openjdk imagestream 87 | - name: get openjdk image stream 88 | shell: "oc get is java -n openshift" 89 | register: java_imagestream_result 90 | ignore_errors: true 91 | tags: jdk 92 | 93 | - name: install java image stream 94 | shell: "oc apply -n openshift -f https://raw.githubusercontent.com/jboss-openshift/application-templates/master/openjdk/openjdk18-image-stream.json" 95 | when: java_imagestream_result is failed 96 | tags: jdk 97 | 98 | # update jenkins templates 99 | - import_role: 100 | name: openshift_jenkins 101 | vars: 102 | update_jenkins_templates: true 103 | jenkins_template_disable_admin_monitors: true 104 | deploy_jenkins: false 105 | jenkins_max_cpu: 2 106 | jenkins_max_mem: 2Gi 107 | 108 | # install CodeReady Workspaces 109 | - name: Deploy CodeReady Workspaces 110 | command: "{{ playbook_dir }}/codeready-workspaces-operator-installer/deploy.sh --deploy --oauth --project={{ namespace }}" 111 | register: cmd_result 112 | changed_when: true 113 | 114 | - name: get CodeReady Workspaces URL 115 | command: "oc get routes codeready --template={% raw %}'{{ .spec.host }}'{% endraw %} -n {{ namespace }}" 116 | register: cmd_result 117 | changed_when: true 118 | 119 | - name: init 'codeready_url' variable 120 | set_fact: 121 | codeready_url: "{{ cmd_result.stdout }}" 122 | 123 | - name: get RHSSO URL 124 | command: "oc get routes keycloak --template={% raw %}'{{ .spec.host }}'{% endraw %} -n {{ namespace }}" 125 | register: cmd_result 126 | changed_when: true 127 | 128 | - name: init 'rhsso_url' variable 129 | set_fact: 130 | rhsso_url: "{{ cmd_result.stdout }}" 131 | 132 | - name: wait for CodeReady Workspaces to be running 133 | uri: 134 | url: "http://{{ codeready_url }}/api/system/state" 135 | status_code: 200 136 | register: result 137 | until: result.status == 200 138 | retries: 60 139 | delay: 30 140 | 141 | # Import custom stacks 142 | - name: Create Cloud-Native stack 143 | command: > 144 | oc import-image che-cloud-native:latest 145 | -n openshift 146 | --from=quay.io/mcouliba/che-cloud-native --confirm 147 | 148 | - name: Import custom stacks 149 | include: "{{ playbook_dir }}/tasks/add_custom_stack.yml" 150 | vars: 151 | stack_template: "{{ item }}" 152 | with_fileglob: 153 | - "{{ playbook_dir }}/templates/stacks/*-stack.json.j2" 154 | 155 | # Install Service Mesh 156 | - name: check if istio-system project exists 157 | command: "oc get project istio-system" 158 | register: istio_system_project_result 159 | ignore_errors: true 160 | changed_when: false 161 | - name: Openshift Service Mesh Installation 162 | block: 163 | - name: create istio-operator project 164 | command: "oc new-project istio-operator" 165 | - name: deploy istio operator 166 | command: > 167 | oc apply -n istio-operator 168 | -f https://raw.githubusercontent.com/Maistra/istio-operator/maistra-0.10/deploy/servicemesh-operator.yaml 169 | - name: create istio-system project 170 | command: "oc new-project istio-system" 171 | - name: delete project quota 172 | shell: "oc delete limitrange --all -n istio-system" 173 | ignore_errors: true 174 | - name: deploy istio 175 | command: > 176 | oc create -n istio-system 177 | -f https://raw.githubusercontent.com/Maistra/istio-operator/maistra-0.10/deploy/examples/istio_v1alpha3_controlplane_cr_basic.yaml 178 | when: 179 | - istio_system_project_result is failed 180 | - openshift_service_mesh_installation or preconfigure_service_mesh_projects 181 | 182 | # Get Jaeger and Grafana URL 183 | - name: get Jaeger URL 184 | command: "oc get route jaeger-query -o 'jsonpath={.spec.host}' -n istio-system" 185 | register: jaeger_host 186 | until: jaeger_host.rc == 0 187 | retries: 60 188 | delay: 30 189 | - name: init 'jaeger_url' variable 190 | set_fact: 191 | jaeger_url: "https://{{ jaeger_host.stdout }}" 192 | - name: get Grafana URL 193 | command: "oc get route grafana -o 'jsonpath={.spec.host}' -n istio-system" 194 | register: grafana_host 195 | until: grafana_host.rc == 0 196 | retries: 60 197 | delay: 30 198 | - name: init 'grafana_url' variable 199 | set_fact: 200 | grafana_url: "http://{{ grafana_host.stdout }}" 201 | 202 | # Preconfigure Projects for Service Mesh usage 203 | - name: preconfigure projects for service mesh 204 | include: "{{ playbook_dir }}/tasks/create_project_service_mesh.yml" 205 | vars: 206 | username: "{{ 'user%d' | format(item) }}" 207 | project_name: "{{ 'coolstore%d' | format(item) }}" 208 | infra_project_name: "{{ 'infra%d' | format(item) }}" 209 | loop: "{{ range(1, user_count|int + 1) | list }}" 210 | when: 211 | - preconfigure_service_mesh_projects 212 | 213 | # Preconfigure cluster for Squash 214 | - name: preconfigure cluster for Squash 215 | command: > 216 | oc create clusterrolebinding cluster-admin-binding-debug-1 \ 217 | --clusterrole=cluster-admin \ 218 | --user=system:serviceaccount:lab-infra:che-workspace 219 | when: 220 | - preconfigure_squash 221 | - name: preconfigure infra project for Squash 222 | command: > 223 | oc create clusterrolebinding cluster-admin-squash-plank-{{ infra_project_name }} \ 224 | --clusterrole=cluster-admin \ 225 | --user=system:serviceaccount:{{ infra_project_name }}:squash-plank 226 | vars: 227 | infra_project_name: "{{ 'infra%d' | format(item) }}" 228 | loop: "{{ range(1, user_count|int + 1) | list }}" 229 | when: 230 | - preconfigure_squash 231 | 232 | # track workshop deployment 233 | - import_role: 234 | name: workshop_deployment_tracker 235 | vars: 236 | apps_hostname_suffix: "{{ apps_hostname_suffix }}" 237 | workshop_type: cloud-native 238 | -------------------------------------------------------------------------------- /apb/playbooks/tasks/add_custom_stack.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: get auth token from RHSSO CodeReady realm 3 | uri: 4 | url: http://{{ rhsso_url }}/auth/realms/codeready/protocol/openid-connect/token 5 | method: POST 6 | body: "username=admin&password=admin&grant_type=password&client_id=admin-cli" 7 | status_code: 200 8 | headers: 9 | Content-Type: "application/x-www-form-urlencoded" 10 | register: codeready_access_token_result 11 | 12 | - name: init 'codeready_access_token_bearer' variable 13 | set_fact: 14 | codeready_access_token_bearer: "{{ codeready_access_token_result.json | json_query('access_token') }}" 15 | 16 | - name: add the cloud native stack 17 | uri: 18 | url: "http://{{ codeready_url }}/api/stack" 19 | method: POST 20 | body: "{{ lookup('template','{{ stack_template }}', convert_data=False) }}" 21 | status_code: 201 22 | body_format: json 23 | headers: 24 | Authorization: "Bearer {{ codeready_access_token_bearer }}" 25 | register: stack_json_result 26 | 27 | - name: init 'stack_id' variable 28 | set_fact: 29 | stack_id: "{{ stack_json_result.json|json_query('id') }}" 30 | 31 | - name: give all users access to the stack 32 | uri: 33 | url: "http://{{ codeready_url }}/api/permissions" 34 | method: POST 35 | body: "{{ lookup('template','{{ playbook_dir }}/templates/stacks/stack-permissions.json.j2', convert_data=False) }}" 36 | status_code: 204 37 | body_format: json 38 | headers: 39 | Authorization: "Bearer {{ codeready_access_token_bearer }}" 40 | vars: 41 | stack_id: "{{ stack_id }}" 42 | -------------------------------------------------------------------------------- /apb/playbooks/tasks/create_project_service_mesh.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Create and configuration application project 3 | - name: check if {{ project_name }} project exists 4 | command: "oc get project {{ project_name }}" 5 | register: project_result 6 | ignore_errors: true 7 | - name: delete {{ project_name }} project 8 | command: > 9 | oc delete project {{ project_name }} 10 | when: project_result is succeeded 11 | - name: create {{ project_name }} project 12 | command: > 13 | oc new-project {{ project_name }} 14 | - name: grant {{ username }} to edit the project 15 | command: "oc adm policy add-role-to-user admin {{ username }} -n {{ project_name }}" 16 | - name: grant applications in the the project to view Openshift API 17 | command: "oc policy add-role-to-user view -n {{ project_name }} -z default" 18 | - name: grant applications with privileged access (for Istio) 19 | command: "oc adm policy add-scc-to-user privileged -z default -n {{ project_name }}" 20 | - name: grant applications with anyuid access (for Istio) 21 | command: "oc adm policy add-scc-to-user anyuid -z default -n {{ project_name }}" 22 | - name: update limit range 23 | shell: "echo {{ lookup('template', '{{ playbook_dir }}/templates/project-limits.yaml.j2') | quote }} | oc replace -f -" 24 | 25 | # Create and configuration infra project 26 | - name: check if {{ infra_project_name }} project exists 27 | command: "oc get project {{ infra_project_name }}" 28 | register: infra_project_result 29 | ignore_errors: true 30 | - name: delete {{ infra_project_name }} project 31 | command: > 32 | oc delete project {{ infra_project_name }} 33 | when: infra_project_result is succeeded 34 | - name: create {{ infra_project_name }} project 35 | command: > 36 | oc new-project {{ infra_project_name }} 37 | - name: grant {{ username }} to edit the project {{ infra_project_name }} 38 | command: "oc adm policy add-role-to-user edit {{ username }} -n {{ infra_project_name }}" 39 | 40 | # Install local instance of Workshopper 41 | - name: Deploy Workshopper 42 | command: > 43 | oc new-app quay.io/osevg/workshopper --name=guides-codeready 44 | -e WORKSHOPS_URLS={{ workshopper_workshop_urls }} 45 | -e CONTENT_URL_PREFIX={{ workshopper_content_url_prefix }} 46 | -n {{ infra_project_name }} 47 | vars: 48 | workshopper_content_url_prefix: "https://raw.githubusercontent.com/{{ git_repository_guide_path }}/{{ git_repository_guide_reference }}/{{ git_repository_guide_context }}" 49 | workshopper_workshop_urls: "https://raw.githubusercontent.com/{{ git_repository_guide_path }}/{{ git_repository_guide_reference }}/{{ git_repository_guide_context }}/_cloud-native-workshop-{{ guide_name }}.yml" 50 | tags: guides 51 | - name: Expose Route 52 | command: > 53 | oc expose svc/guides-codeready -n {{ infra_project_name }} 54 | tags: guides 55 | - name: configure workshopper guide env vars 56 | command: > 57 | oc set env dc/guides-codeready -n {{ infra_project_name }} 58 | COOLSTORE_PROJECT="{{ project_name }}" 59 | INFRA_PROJECT="{{ infra_project_name }}" 60 | OPENSHIFT_CONSOLE_URL="{{ openshift_master_url }}" 61 | OPENSHIFT_USER="{{ username }}" 62 | OPENSHIFT_PASSWORD="{{ openshift_user_password }}" 63 | APPS_HOSTNAME_SUFFIX="{{ apps_hostname_suffix }}" 64 | LABS_GIT_REPO=https://github.com/{{ git_repository_lab_path }}.git#{{ git_repository_lab_reference }} 65 | LABS_DOWNLOAD_URL=https://github.com/{{ git_repository_lab_path }}/archive/{{ git_repository_lab_reference }}.zip 66 | WEB_NODEJS_GIT_REPO=https://github.com/{{ git_repository_lab_path }}/tree/{{ git_repository_lab_reference }}/web-nodejs 67 | CATALOG_GO_GIT_REPO=https://github.com/{{ git_repository_lab_path }}/tree/{{ git_repository_lab_reference }}/catalog-go 68 | CODEREADY_WORKSPACES_URL=http://codeready-{{ namespace }}.{{ apps_hostname_suffix }} 69 | GIT_URL=http://gogs-{{ namespace }}.{{ apps_hostname_suffix }} 70 | NEXUS_URL=http://nexus-{{ namespace }}.{{ apps_hostname_suffix }} 71 | KIALI_URL=https://kiali-{{ infra_project_name }}.{{ apps_hostname_suffix }} 72 | JAEGER_URL=https://jaeger-query-istio-system.{{ apps_hostname_suffix }} 73 | KIBANA_URL=https://kibana.{{ apps_hostname_suffix }} 74 | tags: guides 75 | 76 | # Install local instance of Kiali 77 | - name: Create kiali secret 78 | command: > 79 | oc create secret generic kiali -n {{ infra_project_name }} 80 | --from-literal=username={{ username }} 81 | --from-literal=passphrase={{ openshift_user_password }} 82 | - name: install kiali 83 | shell: "echo {{ lookup('template', '{{ playbook_dir }}/templates/kiali.yaml.j2') | quote }} | oc create -f -" 84 | - name: Check kiali route exists 85 | command: "oc get route kiali -n {{ infra_project_name }}" 86 | register: kiali_route 87 | ignore_errors: yes 88 | - name: Expose kiali service 89 | command: "oc create route reencrypt kiali --service=kiali -n {{ infra_project_name }}" 90 | when: kiali_route != 0 91 | - name: reducing kiali permissions to {{ project_name }} only 92 | command: > 93 | oc adm policy add-role-to-user kiali 94 | system:serviceaccount:{{ infra_project_name }}:kiali-service-account 95 | -n {{ project_name }} 96 | - name: grant kiali to view istio-system project 97 | command: > 98 | oc adm policy add-role-to-user view 99 | system:serviceaccount:{{ infra_project_name }}:kiali-service-account 100 | -n istio-system 101 | -------------------------------------------------------------------------------- /apb/playbooks/tasks/install_etherpad.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ##### 3 | # Etherpad 4 | ##### 5 | - name: etherpad_text 6 | set_fact: 7 | etherpad_text: "{{ lookup('file', '{{ playbook_dir }}/templates/etherpad/etherpad.txt') | replace('\n', '\\n') }}" 8 | 9 | - name: install etherpad 10 | shell: > 11 | echo {{ lookup('template', '{{ playbook_dir }}/templates/etherpad/etherpad.yaml.j2') | quote }} | \ 12 | oc process -f - | \ 13 | oc create -n {{ namespace }} -f - 14 | -------------------------------------------------------------------------------- /apb/playbooks/templates/codeready-user.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "username": "{{ username }}", 3 | "enabled": "true", 4 | "email": "{{ email }}", 5 | "credentials": [ 6 | { 7 | "type": "password", 8 | "value": "{{ password }}" 9 | } 10 | ], 11 | "clientRoles" : { 12 | "realm-management" : [ "user" ] 13 | } 14 | } -------------------------------------------------------------------------------- /apb/playbooks/templates/etherpad/etherpad.txt: -------------------------------------------------------------------------------- 1 | Welcome to the Cloud Native Workshop. 2 | 3 | If this is your first time using an Etherpad, it allows EVERYONE to edit 4 | documents collaboratively in real-time, much like a live multi-player editor 5 | that runs in your browser. To-do lists, notes, questions, follow ups; we can 6 | all work on the same document at the same time. 7 | 8 | To start using this collaboration tool, we are going to identify some logistics. 9 | 10 | Find an open user login and assign yourself one. Remember it, you will use it 11 | to login: 12 | 13 | {% for user_num in range(1, user_count|int + 1) %} 14 | You are user{{ user_num }} - http://guides-codeready-infra{{ user_num }}.{{ apps_hostname_suffix }} = 15 | {% endfor %} 16 | 17 | Parking Lot 18 | ----------- 19 | If there is anything we do not have time to cover, record it here. -------------------------------------------------------------------------------- /apb/playbooks/templates/etherpad/etherpad.yaml.j2: -------------------------------------------------------------------------------- 1 | kind: Template 2 | apiVersion: v1 3 | metadata: 4 | name: etherpad 5 | annotations: 6 | "openshift.io/display-name": Etherpad 7 | description: | 8 | A shared Notepad for an OpenShift Cluster. 9 | parameters: 10 | - name: NAME 11 | description: Name of the DC, service, route 12 | required: true 13 | value: etherpad 14 | - name: ETHERPAD_IMAGE 15 | description: Etherpad Image to be used 16 | value: "quay.io/wkulhanek/etherpad:1.7.0" 17 | required: true 18 | - description: Username for MySQL user that will be used for accessing the database. 19 | displayName: MySQL Connection Username 20 | from: user[A-Z0-9]{3} 21 | generate: expression 22 | name: MYSQL_USER 23 | required: true 24 | - description: Password for the MySQL connection user. 25 | displayName: MySQL Connection Password 26 | from: '[a-zA-Z0-9]{16}' 27 | generate: expression 28 | name: MYSQL_PASSWORD 29 | required: true 30 | - description: Password for the MySQL root user. 31 | displayName: MySQL root user Password 32 | from: '[a-zA-Z0-9]{16}' 33 | generate: expression 34 | name: MYSQL_ROOT_PASSWORD 35 | required: true 36 | - description: Name of the MySQL database accessed. 37 | displayName: MySQL Database Name 38 | name: MYSQL_DATABASE 39 | required: true 40 | value: sampledb 41 | - description: Volume space available for data, e.g. 512Mi, 2Gi. 42 | displayName: Volume Capacity 43 | name: VOLUME_CAPACITY 44 | required: true 45 | value: 1Gi 46 | - description: Maximum amount of memory the container can use. 47 | displayName: Memory Limit 48 | name: MEMORY_LIMIT 49 | required: true 50 | value: 512Mi 51 | - description: The OpenShift Namespace where the ImageStream resides. 52 | displayName: Namespace 53 | name: NAMESPACE 54 | value: openshift 55 | - description: Version of MySQL image to be used (5.5, 5.6, 5.7, or latest). 56 | displayName: Version of MySQL Image 57 | name: MYSQL_VERSION 58 | required: true 59 | value: "5.7" 60 | objects: 61 | 62 | - apiVersion: v1 63 | kind: Secret 64 | metadata: 65 | name: ${NAME}-mysql 66 | labels: 67 | app: ${NAME} 68 | stringData: 69 | database-name: ${MYSQL_DATABASE} 70 | database-password: ${MYSQL_PASSWORD} 71 | database-root-password: ${MYSQL_ROOT_PASSWORD} 72 | database-user: ${MYSQL_USER} 73 | 74 | - apiVersion: v1 75 | kind: PersistentVolumeClaim 76 | metadata: 77 | name: ${NAME}-mysql 78 | labels: 79 | app: ${NAME} 80 | spec: 81 | accessModes: 82 | - ReadWriteOnce 83 | resources: 84 | requests: 85 | storage: ${VOLUME_CAPACITY} 86 | 87 | - apiVersion: v1 88 | kind: ConfigMap 89 | metadata: 90 | name: ${NAME}-settings 91 | labels: 92 | app: ${NAME} 93 | data: 94 | settings.json: > 95 | { 96 | // Name your instance! 97 | "title": "OpenShift Workshop Etherpad", 98 | 99 | // favicon default name 100 | // alternatively, set up a fully specified Url to your own favicon 101 | "favicon": "favicon.ico", 102 | 103 | //IP and port which etherpad should bind at 104 | "ip": "0.0.0.0", 105 | "port" : 9001, 106 | 107 | "dbType" : "mysql", 108 | "dbSettings" : { 109 | "user" : "DB_USER", 110 | "host" : "DB_HOST", 111 | "port" : "DB_PORT", 112 | "password": "DB_PASS", 113 | "database": "DB_DBID" 114 | }, 115 | 116 | //the default text of a pad 117 | "defaultPadText" : "{{ etherpad_text }}", 118 | 119 | /* Default Pad behavior, users can override by changing */ 120 | "padOptions": { 121 | "noColors": false, 122 | "showControls": true, 123 | "showChat": true, 124 | "showLineNumbers": true, 125 | "useMonospaceFont": false, 126 | "userName": false, 127 | "userColor": false, 128 | "rtl": false, 129 | "alwaysShowChat": false, 130 | "chatAndUsers": false, 131 | "lang": "en-gb" 132 | }, 133 | 134 | /* Shoud we suppress errors from being visible in the default Pad Text? */ 135 | "suppressErrorsInPadText" : false, 136 | 137 | /* Users must have a session to access pads. This effectively allows only group pads to be accessed. */ 138 | "requireSession" : false, 139 | 140 | /* Users may edit pads but not create new ones. Pad creation is only via the API. This applies both to group pads and regular pads. */ 141 | "editOnly" : false, 142 | 143 | /* Users, who have a valid session, automatically get granted access to password protected pads */ 144 | "sessionNoPassword" : false, 145 | 146 | /* if true, all css & js will be minified before sending to the client. This will improve the loading performance massivly, 147 | but makes it impossible to debug the javascript/css */ 148 | "minify" : true, 149 | 150 | /* How long may clients use served javascript code (in seconds)? Without versioning this 151 | may cause problems during deployment. Set to 0 to disable caching */ 152 | "maxAge" : 21600, // 60 * 60 * 6 = 6 hours 153 | 154 | /* This is the path to the Abiword executable. Setting it to null, disables abiword. 155 | Abiword is needed to advanced import/export features of pads*/ 156 | "abiword" : null, 157 | 158 | /* This is the path to the Tidy executable. Setting it to null, disables Tidy. 159 | Tidy is used to improve the quality of exported pads*/ 160 | "tidyHtml" : null, 161 | 162 | /* Allow import of file types other than the supported types */ 163 | "allowUnknownFileEnds" : true, 164 | 165 | /* This setting is used if you require authentication of all users. 166 | Note: /admin always requires authentication. */ 167 | "requireAuthentication" : false, 168 | 169 | /* Require authorization by a module, or a user with is_admin set, see below. */ 170 | "requireAuthorization" : false, 171 | 172 | /*when you use NginX or another proxy/ load-balancer set this to true*/ 173 | "trustProxy" : false, 174 | 175 | /* Privacy= disable IP logging */ 176 | "disableIPlogging" : false, 177 | 178 | /* Users for basic authentication. is_admin = true gives access to /admin. 179 | If you do not uncomment this, /admin will not be available! */ 180 | 181 | "users": { 182 | "admin": { 183 | "password": "${MYSQL_ROOT_PASSWORD}", 184 | "is_admin": true 185 | } 186 | }, 187 | 188 | // restrict socket.io transport methods 189 | "socketTransportProtocols" : ["xhr-polling", "jsonp-polling", "htmlfile"], 190 | 191 | // Allow Load Testing tools to hit the Etherpad Instance. Warning this will disable security on the instance. 192 | "loadTest": false, 193 | 194 | /* The toolbar buttons configuration. 195 | "toolbar": { 196 | "left": [ 197 | ["bold", "italic", "underline", "strikethrough"], 198 | ["orderedlist", "unorderedlist", "indent", "outdent"], 199 | ["undo", "redo"], 200 | ["clearauthorship"] 201 | ], 202 | "right": [ 203 | ["importexport", "timeslider", "savedrevision"], 204 | ["settings", "embed"], 205 | ["showusers"] 206 | ], 207 | "timeslider": [ 208 | ["timeslider_export", "timeslider_returnToPad"] 209 | ] 210 | }, 211 | */ 212 | 213 | /* The log level we are using, can be: DEBUG, INFO, WARN, ERROR */ 214 | "loglevel": "INFO", 215 | 216 | //Logging configuration. See log4js documentation for further information 217 | // https://github.com/nomiddlename/log4js-node 218 | "logconfig" : 219 | { "appenders": [ 220 | { "type": "console" } 221 | ] 222 | } 223 | } 224 | 225 | - apiVersion: v1 226 | kind: DeploymentConfig 227 | metadata: 228 | annotations: 229 | template.alpha.openshift.io/wait-for-ready: "true" 230 | name: ${NAME}-mysql 231 | labels: 232 | app: ${NAME} 233 | spec: 234 | replicas: 1 235 | selector: 236 | name: ${NAME}-mysql 237 | strategy: 238 | type: Recreate 239 | template: 240 | metadata: 241 | labels: 242 | name: ${NAME}-mysql 243 | spec: 244 | containers: 245 | - env: 246 | - name: MYSQL_USER 247 | valueFrom: 248 | secretKeyRef: 249 | key: database-user 250 | name: ${NAME}-mysql 251 | - name: MYSQL_PASSWORD 252 | valueFrom: 253 | secretKeyRef: 254 | key: database-password 255 | name: ${NAME}-mysql 256 | - name: MYSQL_ROOT_PASSWORD 257 | valueFrom: 258 | secretKeyRef: 259 | key: database-root-password 260 | name: ${NAME}-mysql 261 | - name: MYSQL_DATABASE 262 | valueFrom: 263 | secretKeyRef: 264 | key: database-name 265 | name: ${NAME}-mysql 266 | image: ' ' 267 | imagePullPolicy: IfNotPresent 268 | livenessProbe: 269 | initialDelaySeconds: 30 270 | tcpSocket: 271 | port: 3306 272 | timeoutSeconds: 1 273 | name: mysql 274 | ports: 275 | - containerPort: 3306 276 | readinessProbe: 277 | exec: 278 | command: 279 | - /bin/sh 280 | - -i 281 | - -c 282 | - MYSQL_PWD="$MYSQL_PASSWORD" mysql -h 127.0.0.1 -u $MYSQL_USER -D $MYSQL_DATABASE 283 | -e 'SELECT 1' 284 | initialDelaySeconds: 5 285 | timeoutSeconds: 1 286 | resources: 287 | limits: 288 | memory: ${MEMORY_LIMIT} 289 | volumeMounts: 290 | - mountPath: /var/lib/mysql/data 291 | name: ${NAME}-mysql-data 292 | volumes: 293 | - name: ${NAME}-mysql-data 294 | persistentVolumeClaim: 295 | claimName: ${NAME}-mysql 296 | triggers: 297 | - imageChangeParams: 298 | automatic: true 299 | containerNames: 300 | - mysql 301 | from: 302 | kind: ImageStreamTag 303 | name: mysql:${MYSQL_VERSION} 304 | namespace: ${NAMESPACE} 305 | type: ImageChange 306 | - type: ConfigChange 307 | 308 | - apiVersion: v1 309 | kind: Service 310 | metadata: 311 | name: ${NAME}-mysql 312 | labels: 313 | app: ${NAME} 314 | spec: 315 | ports: 316 | - name: mysql 317 | port: 3306 318 | selector: 319 | name: ${NAME}-mysql 320 | 321 | - apiVersion: v1 322 | kind: DeploymentConfig 323 | metadata: 324 | labels: 325 | app: ${NAME} 326 | name: ${NAME} 327 | spec: 328 | replicas: 1 329 | selector: 330 | app: ${NAME} 331 | deploymentconfig: ${NAME} 332 | strategy: 333 | activeDeadlineSeconds: 21600 334 | resources: {} 335 | rollingParams: 336 | intervalSeconds: 1 337 | maxSurge: 25% 338 | maxUnavailable: 25% 339 | timeoutSeconds: 600 340 | updatePeriodSeconds: 1 341 | type: Rolling 342 | template: 343 | metadata: 344 | labels: 345 | app: ${NAME} 346 | deploymentconfig: ${NAME} 347 | spec: 348 | containers: 349 | - env: 350 | - name: DB_DBID 351 | valueFrom: 352 | secretKeyRef: 353 | key: database-name 354 | name: ${NAME}-mysql 355 | - name: DB_HOST 356 | value: ${NAME}-mysql 357 | - name: DB_PASS 358 | valueFrom: 359 | secretKeyRef: 360 | key: database-password 361 | name: ${NAME}-mysql 362 | - name: DB_PORT 363 | value: "3306" 364 | - name: DB_USER 365 | valueFrom: 366 | secretKeyRef: 367 | key: database-user 368 | name: ${NAME}-mysql 369 | - name: NODE_ENV 370 | value: production 371 | image: ${ETHERPAD_IMAGE} 372 | imagePullPolicy: Always 373 | name: ${NAME} 374 | ports: 375 | - containerPort: 9001 376 | protocol: TCP 377 | resources: {} 378 | terminationMessagePath: /dev/termination-log 379 | terminationMessagePolicy: File 380 | readinessProbe: 381 | failureThreshold: 5 382 | httpGet: 383 | path: / 384 | port: 9001 385 | scheme: HTTP 386 | initialDelaySeconds: 60 387 | periodSeconds: 10 388 | successThreshold: 1 389 | timeoutSeconds: 1 390 | livenessProbe: 391 | failureThreshold: 3 392 | httpGet: 393 | path: / 394 | port: 9001 395 | scheme: HTTP 396 | initialDelaySeconds: 120 397 | periodSeconds: 10 398 | successThreshold: 1 399 | timeoutSeconds: 1 400 | volumeMounts: 401 | - mountPath: /opt/etherpad/config 402 | name: ${NAME}-settings 403 | dnsPolicy: ClusterFirst 404 | restartPolicy: Always 405 | schedulerName: default-scheduler 406 | securityContext: {} 407 | terminationGracePeriodSeconds: 30 408 | volumes: 409 | - configMap: 410 | defaultMode: 420 411 | name: ${NAME}-settings 412 | name: ${NAME}-settings 413 | 414 | - apiVersion: v1 415 | kind: Service 416 | metadata: 417 | labels: 418 | app: ${NAME} 419 | name: ${NAME} 420 | spec: 421 | ports: 422 | - name: ${NAME} 423 | port: 9001 424 | protocol: TCP 425 | targetPort: 9001 426 | selector: 427 | app: ${NAME} 428 | deploymentconfig: ${NAME} 429 | 430 | - apiVersion: v1 431 | kind: Route 432 | metadata: 433 | labels: 434 | app: ${NAME} 435 | name: ${NAME} 436 | spec: 437 | to: 438 | name: ${NAME} 439 | -------------------------------------------------------------------------------- /apb/playbooks/templates/kiali.yaml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: kiali 6 | labels: 7 | app: kiali 8 | data: 9 | config.yaml: | 10 | istio_namespace: istio-system 11 | server: 12 | port: 20001 13 | static_content_root_directory: /opt/kiali/console 14 | external_services: 15 | jaeger: 16 | url: {{ jaeger_url }} 17 | grafana: 18 | url: {{ grafana_url }} 19 | identity: 20 | cert_file: /kiali-cert/tls.crt 21 | private_key_file: /kiali-cert/tls.key 22 | 23 | --- 24 | apiVersion: v1 25 | kind: ServiceAccount 26 | metadata: 27 | name: kiali-service-account 28 | labels: 29 | app: kiali 30 | 31 | --- 32 | apiVersion: v1 33 | kind: Service 34 | metadata: 35 | annotations: 36 | service.alpha.openshift.io/serving-cert-secret-name: kiali-cert-secret 37 | name: kiali 38 | labels: 39 | app: kiali 40 | spec: 41 | ports: 42 | - name: http-kiali 43 | protocol: TCP 44 | port: 20001 45 | selector: 46 | app: kiali 47 | 48 | --- 49 | apiVersion: extensions/v1beta1 50 | kind: Deployment 51 | metadata: 52 | name: kiali 53 | labels: 54 | app: kiali 55 | spec: 56 | replicas: 1 57 | selector: 58 | matchLabels: 59 | app: kiali 60 | template: 61 | metadata: 62 | name: kiali 63 | labels: 64 | app: kiali 65 | annotations: 66 | sidecar.istio.io/inject: "false" 67 | scheduler.alpha.kubernetes.io/critical-pod: "" 68 | spec: 69 | serviceAccountName: kiali-service-account 70 | containers: 71 | - image: "kiali/kiali:v0.15.0" 72 | name: kiali 73 | command: 74 | - "/opt/kiali/kiali" 75 | - "-config" 76 | - "/kiali-configuration/config.yaml" 77 | - "-v" 78 | - "4" 79 | env: 80 | - name: ACTIVE_NAMESPACE 81 | valueFrom: 82 | fieldRef: 83 | fieldPath: metadata.namespace 84 | - name: SERVER_CREDENTIALS_USERNAME 85 | valueFrom: 86 | secretKeyRef: 87 | name: kiali 88 | key: username 89 | - name: SERVER_CREDENTIALS_PASSWORD 90 | valueFrom: 91 | secretKeyRef: 92 | name: kiali 93 | key: passphrase 94 | volumeMounts: 95 | - name: kiali-configuration 96 | mountPath: "/kiali-configuration" 97 | - name: kiali-cert 98 | mountPath: "/kiali-cert" 99 | resources: 100 | requests: 101 | cpu: 10m 102 | 103 | volumes: 104 | - name: kiali-configuration 105 | configMap: 106 | name: kiali 107 | - name: kiali-cert 108 | secret: 109 | secretName: kiali-cert-secret 110 | affinity: 111 | nodeAffinity: 112 | requiredDuringSchedulingIgnoredDuringExecution: 113 | nodeSelectorTerms: 114 | - matchExpressions: 115 | - key: beta.kubernetes.io/arch 116 | operator: In 117 | values: 118 | - amd64 119 | - ppc64le 120 | - s390x 121 | preferredDuringSchedulingIgnoredDuringExecution: 122 | - weight: 2 123 | preference: 124 | matchExpressions: 125 | - key: beta.kubernetes.io/arch 126 | operator: In 127 | values: 128 | - amd64 129 | - weight: 2 130 | preference: 131 | matchExpressions: 132 | - key: beta.kubernetes.io/arch 133 | operator: In 134 | values: 135 | - ppc64le 136 | - weight: 2 137 | preference: 138 | matchExpressions: 139 | - key: beta.kubernetes.io/arch 140 | operator: In 141 | values: 142 | - s390x -------------------------------------------------------------------------------- /apb/playbooks/templates/project-limits.yaml.j2: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: LimitRange 4 | metadata: 5 | name: "{{ project_name }}-core-resource-limits" 6 | namespace: {{ project_name }} 7 | spec: 8 | limits: 9 | - default: 10 | cpu: 500m 11 | memory: 2Gi 12 | defaultRequest: 13 | cpu: 200m 14 | memory: 2Gi 15 | max: 16 | memory: 6Gi 17 | min: 18 | memory: 1Mi 19 | type: Container 20 | - max: 21 | memory: 12Gi 22 | min: 23 | memory: 6Mi 24 | type: Pod 25 | 26 | -------------------------------------------------------------------------------- /apb/playbooks/templates/stacks/cloud-native-stack.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "id": "cloud-native", 3 | "name": "Cloud-Native", 4 | "description": "Stack for Cloud-Native Development", 5 | "scope": "general", 6 | "workspaceConfig": { 7 | "environments": { 8 | "default": { 9 | "recipe": { 10 | "type": "dockerimage", 11 | "content": "docker-registry.default.svc:5000/openshift/che-cloud-native" 12 | }, 13 | "machines": { 14 | "dev-machine": { 15 | "env": { 16 | "MAVEN_OPTS" : "-Xmx512m", 17 | "MAVEN_MIRROR_URL": "http://nexus.{{ namespace }}.svc:8081/repository/maven-all-public" 18 | }, 19 | "servers": { 20 | "8080/tcp": { 21 | "attributes": {}, 22 | "protocol": "http", 23 | "port": "8080" 24 | }, 25 | "8000/tcp": { 26 | "attributes": {}, 27 | "protocol": "http", 28 | "port": "8000" 29 | }, 30 | "9000/tcp": { 31 | "attributes": {}, 32 | "protocol": "http", 33 | "port": "9000" 34 | }, 35 | "9001/tcp": { 36 | "attributes": {}, 37 | "protocol": "http", 38 | "port": "9001" 39 | } 40 | }, 41 | "volumes": {}, 42 | "installers": [ 43 | "org.eclipse.che.exec", 44 | "org.eclipse.che.terminal", 45 | "org.eclipse.che.ws-agent", 46 | "org.eclipse.che.ls.java" 47 | ], 48 | "attributes": { 49 | "memoryLimitBytes": "2147483648" 50 | } 51 | } 52 | } 53 | } 54 | }, 55 | "commands": [ 56 | { 57 | "commandLine": "mvn package -f ${current.project.path}", 58 | "name": "build", 59 | "type": "mvn", 60 | "attributes": { 61 | "goal": "Build", 62 | "previewUrl": "" 63 | } 64 | }, 65 | { 66 | "commandLine": "mvn clean package -f ${current.project.path}", 67 | "name": "clean build", 68 | "type": "mvn", 69 | "attributes": { 70 | "goal": "Build", 71 | "previewUrl": "" 72 | } 73 | }, 74 | { 75 | "commandLine": "mvn verify -f ${current.project.path}", 76 | "name": "test", 77 | "type": "mvn", 78 | "attributes": { 79 | "goal": "Test", 80 | "previewUrl": "" 81 | } 82 | }, 83 | { 84 | "commandLine": "mvn spring-boot:run -f ${current.project.path}", 85 | "name": "spring-boot:run", 86 | "type": "mvn", 87 | "attributes": { 88 | "goal": "Run", 89 | "previewUrl": "${server.9000/tcp}" 90 | } 91 | }, 92 | { 93 | "commandLine": "cd ${current.project.path} && java -Dswarm.http.port=9001 -jar target/*-thorntail.jar ", 94 | "name": "thorntail:run", 95 | "type": "mvn", 96 | "attributes": { 97 | "goal": "Run", 98 | "previewUrl": "${server.9001/tcp}" 99 | } 100 | }, 101 | { 102 | "commandLine": "mvn vertx:run -f ${current.project.path}", 103 | "name": "vertx:run", 104 | "type": "mvn", 105 | "attributes": { 106 | "goal": "Run", 107 | "previewUrl": "${server.9001/tcp}" 108 | } 109 | }, 110 | { 111 | "commandLine": "username=${workspace.namespace}\nprojectname=coolstore${username#user}\nchmod +x /projects/labs/scripts/runGatewayService.sh\n/projects/labs/scripts/runGatewayService.sh ${projectname}", 112 | "name": "runGatewayService", 113 | "attributes": { 114 | "goal": "Run", 115 | "previewUrl": "" 116 | }, 117 | "type": "custom" 118 | }, 119 | { 120 | "commandLine": "cd ${current.project.path} && mvn fabric8:deploy", 121 | "name": "fabric8:deploy", 122 | "type": "mvn", 123 | "attributes": { 124 | "goal": "Deploy", 125 | "previewUrl": "" 126 | } 127 | }, 128 | { 129 | "commandLine": "oc rollout pause dc/cart\noc set probe dc/cart --readiness --liveness --remove\noc patch dc/cart --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"true\"}}}}}'\noc rollout resume dc/cart", 130 | "name": "Cart Service: Inject Istio Sidecar", 131 | "attributes": { 132 | "goal":"Service Mesh", 133 | "previewUrl":"" 134 | }, 135 | "type": "custom" 136 | }, 137 | { 138 | "commandLine": "oc rollout pause dc/cart\noc set probe dc/cart --readiness --liveness --remove\noc patch dc/cart --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"false\"}}}}}'\noc rollout resume dc/cart", 139 | "name": "Cart Service: Remove Istio Sidecar", 140 | "attributes": { 141 | "goal":"Service Mesh", 142 | "previewUrl":"" 143 | }, 144 | "type": "custom" 145 | }, 146 | { 147 | "commandLine": "oc rollout pause dc/catalog\noc set probe dc/catalog --readiness --liveness --remove\noc patch dc/catalog --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"true\"}}}}}'\noc patch dc/catalog --patch '{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"spring-boot\", \"command\" : [\"/bin/bash\"], \"args\": [\"-c\", \"until $(curl -o /dev/null -s -I -f http://localhost:15000); do echo \\\"Waiting for Istio Sidecar...\\\"; sleep 1; done; sleep 10; /usr/local/s2i/run\"]}]}}}}'\noc rollout resume dc/catalog", 148 | "name": "Catalog Service: Inject Istio Sidecar", 149 | "attributes": { 150 | "goal":"Service Mesh", 151 | "previewUrl":"" 152 | }, 153 | "type": "custom" 154 | }, 155 | { 156 | "commandLine": "oc rollout pause dc/catalog\noc set probe dc/catalog --readiness --liveness --remove\noc patch dc/catalog --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"false\"}}}}}'\noc patch dc/catalog --patch '{ \"op\": \"remove\", \"path\": \"/spec/template/spec/containers/command\" }'\noc patch dc/catalog --patch '{ \"op\": \"remove\", \"path\": \"/spec/template/spec/containers/args\" }'\noc rollout resume dc/catalog", 157 | "name": "Catalog Service: Remove Istio Sidecar", 158 | "attributes": { 159 | "goal":"Service Mesh", 160 | "previewUrl":"" 161 | }, 162 | "type": "custom" 163 | }, 164 | { 165 | "commandLine": "oc rollout pause dc/catalog-v2\noc set probe dc/catalog-v2 --readiness --liveness --remove\noc patch dc/catalog-v2 --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"true\"}}}}}'\noc rollout resume dc/catalog-v2", 166 | "name": "Catalog-v2 Service: Inject Istio Sidecar", 167 | "attributes": { 168 | "goal":"Service Mesh", 169 | "previewUrl":"" 170 | }, 171 | "type": "custom" 172 | }, 173 | { 174 | "commandLine": "oc rollout pause dc/catalog-v2\noc set probe dc/catalog-v2 --readiness --liveness --remove\noc patch dc/catalog-v2 --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"false\"}}}}}'\noc rollout resume dc/catalog-v2", 175 | "name": "Catalog-v2 Service: Remove Istio Sidecar", 176 | "attributes": { 177 | "goal":"Service Mesh", 178 | "previewUrl":"" 179 | }, 180 | "type": "custom" 181 | }, 182 | { 183 | "commandLine": "oc rollout pause dc/inventory\noc set probe dc/inventory --readiness --liveness --remove\noc patch dc/inventory --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"true\"}}}}}'\noc patch dc/inventory --patch '{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"thorntail-v2\", \"command\" : [\"/bin/bash\"], \"args\": [\"-c\", \"until $(curl -o /dev/null -s -I -f http://localhost:15000); do echo \\\"Waiting for Istio Sidecar...\\\"; sleep 1; done; sleep 10; /usr/local/s2i/run\"]}]}}}}'\noc rollout resume dc/inventory", 184 | "name": "Inventory Service: Inject Istio Sidecar", 185 | "attributes": { 186 | "goal":"Service Mesh", 187 | "previewUrl":"" 188 | }, 189 | "type": "custom" 190 | }, 191 | { 192 | "commandLine": "oc rollout pause dc/inventory\noc set probe dc/inventory --readiness --liveness --remove\noc patch dc/inventory --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"false\"}}}}}'\noc patch dc/inventory --patch '{ \"op\": \"remove\", \"path\": \"/spec/template/spec/containers/command\" }'\noc patch dc/inventory --patch '{ \"op\": \"remove\", \"path\": \"/spec/template/spec/containers/args\" }'\noc rollout resume dc/inventory", 193 | "name": "Inventory Service: Remove Istio Sidecar", 194 | "attributes": { 195 | "goal":"Service Mesh", 196 | "previewUrl":"" 197 | }, 198 | "type": "custom" 199 | }, 200 | { 201 | "commandLine": "oc rollout pause dc/gateway\noc set probe dc/gateway --readiness --liveness --remove\noc patch dc/gateway --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"true\"}}}}}'\noc patch dc/gateway --patch '{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"vertx\", \"command\" : [\"/bin/bash\"], \"args\": [\"-c\", \"until $(curl -o /dev/null -s -I -f http://localhost:15000); do echo \\\"Waiting for Istio Sidecar...\\\"; sleep 1; done; sleep 10; /usr/local/s2i/run\"]}]}}}}'\noc rollout resume dc/gateway", 202 | "name": "Gateway Service: Inject Istio Sidecar", 203 | "attributes": { 204 | "goal":"Service Mesh", 205 | "previewUrl":"" 206 | }, 207 | "type":"custom" 208 | }, 209 | { 210 | "commandLine": "oc rollout pause dc/gateway\noc set probe dc/gateway --readiness --liveness --remove\noc patch dc/gateway --patch '{\"spec\": {\"template\": {\"metadata\": {\"annotations\": {\"sidecar.istio.io/inject\": \"false\"}}}}}'\noc patch dc/gateway --patch '{ \"op\": \"remove\", \"path\": \"/spec/template/spec/containers/command\" }'\noc patch dc/gateway --patch '{ \"op\": \"remove\", \"path\": \"/spec/template/spec/containers/args\" }'\noc rollout resume dc/gateway", 211 | "name": "Gateway Service: Remove Istio Sidecar", 212 | "attributes": { 213 | "goal":"Service Mesh", 214 | "previewUrl":"" 215 | }, 216 | "type": "custom" 217 | } 218 | ], 219 | "projects": [], 220 | "defaultEnv": "default", 221 | "name": "default", 222 | "links": [] 223 | }, 224 | "components": [ 225 | { 226 | "version": "---", 227 | "name": "CentOS" 228 | }, 229 | { 230 | "version": "1.8.0_45", 231 | "name": "JDK" 232 | }, 233 | { 234 | "version": "3.2.2", 235 | "name": "Maven" 236 | }, 237 | { 238 | "version": "2.6", 239 | "name": "Ansible" 240 | }, 241 | { 242 | "version": "3.11", 243 | "name": "OpenShift CLI" 244 | }, 245 | { 246 | "version": "0.0.19", 247 | "name": "OpenShift DO" 248 | } 249 | ], 250 | "creator": "ide", 251 | "tags": [ 252 | "Java", 253 | "JDK", 254 | "Maven", 255 | "CentOS", 256 | "Git" 257 | ] 258 | } -------------------------------------------------------------------------------- /apb/playbooks/templates/stacks/stack-permissions.json.j2: -------------------------------------------------------------------------------- 1 | { 2 | "userId": "*", 3 | "domainId": "stack", 4 | "instanceId": "{{ stack_id }}", 5 | "actions": [ 6 | "read", 7 | "search" 8 | ] 9 | } -------------------------------------------------------------------------------- /apb/requirements-travis.yml: -------------------------------------------------------------------------------- 1 | - src: siamaksade.openshift_sonatype_nexus 2 | version: 1.1.0 3 | name: openshift_sonatype_nexus 4 | 5 | - src: siamaksade.openshift_gogs 6 | version: 1.1.0 7 | name: openshift_gogs 8 | 9 | - src: siamaksade.openshift_workshopper 10 | version: 1.2.0 11 | name: openshift_workshopper 12 | 13 | - src: siamaksade.openshift_jenkins 14 | version: 1.4.1 15 | name: openshift_jenkins 16 | 17 | - src: openshift_labs.workshop_deployment_tracker 18 | version: 1.0.1 19 | name: workshop_deployment_tracker 20 | 21 | - src: ansible.kubernetes-modules 22 | 23 | - src: ansibleplaybookbundle.asb-modules 24 | -------------------------------------------------------------------------------- /apb/requirements.yml: -------------------------------------------------------------------------------- 1 | - src: siamaksade.openshift_sonatype_nexus 2 | version: 1.1.0 3 | name: openshift_sonatype_nexus 4 | 5 | - src: siamaksade.openshift_gogs 6 | version: 1.1.0 7 | name: openshift_gogs 8 | 9 | - src: siamaksade.openshift_workshopper 10 | version: 1.2.0 11 | name: openshift_workshopper 12 | 13 | - src: siamaksade.openshift_jenkins 14 | version: 1.4.1 15 | name: openshift_jenkins 16 | 17 | - src: openshift_labs.workshop_deployment_tracker 18 | version: 1.0.1 19 | name: workshop_deployment_tracker -------------------------------------------------------------------------------- /catalog-deployment.adoc: -------------------------------------------------------------------------------- 1 | == Deploying the Catalog Service 2 | 3 | _10 MINUTE EXERCISE_ 4 | 5 | In this lab you will learn about building and deploying a microservice based on Java/Maven on OpenShift. 6 | The **Catalog Service** is part of the Cool Store architecture to provide a list of products for the CoolStore online shop. 7 | 8 | image:{% image_path coolstore-arch-catalog-spring-boot.png %}[CoolStore Architecture,400] 9 | 10 | === What is Spring Boot? 11 | 12 | [sidebar] 13 | -- 14 | image:{% image_path spring-boot-logo.png %}[Spring Boot, 400] 15 | 16 | Spring Boot is an opinionated framework that makes it easy to create stand-alone Spring based 17 | applications with embedded web containers such as Tomcat (or JBoss Web Server), Jetty and Undertow 18 | that you can run directly on the JVM using **java -jar**. Spring Boot also allows producing a war 19 | file that can be deployed on stand-alone web containers. 20 | 21 | The opinionated approach means many choices about Spring platform and third-party libraries 22 | are already made by Spring Boot so that you can get started with minimum effort and configuration. 23 | -- 24 | 25 | === Spring Boot Maven Project 26 | 27 | The **catalog-spring-boot** project has the following structure which shows the components of 28 | the Spring Boot project laid out in different subdirectories according to Maven best practices: 29 | 30 | 31 | Once loaded, you should see the following files and be able to navigate amongst the files. The 32 | components of the Spring Boot project are laid out in different subdirectories according to Maven best practices: 33 | 34 | image:{% image_path springboot-catalog-project.png %}[Catalog Project,300] 35 | 36 | === Deploy Catalog Service on OpenShift 37 | 38 | Now it’s time to build and deploy our service on OpenShift. 39 | 40 | OpenShift {{OPENSHIFT_DOCS_BASE}}/architecture/core_concepts/builds_and_image_streams.html#source-build[Source-to-Image (S2I)^] 41 | feature can be used to build a container image from your project. OpenShift 42 | S2I uses the https://access.redhat.com/documentation/en-us/red_hat_jboss_middleware_for_openshift/3/html/red_hat_java_s2i_for_openshift[supported OpenJDK container image^] to build the final container image 43 | of the **Catalog Service** by uploading the Spring Boot uber-jar from the **target/** 44 | folder to the OpenShift platform. 45 | 46 | Maven projects can use the https://maven.fabric8.io[Fabric8 Maven Plugin^] in order to use OpenShift S2I for building 47 | the container image of the application from within the project. This maven plugin is a Kubernetes/OpenShift client 48 | able to communicate with the OpenShift platform using the REST endpoints in order to issue the commands 49 | allowing to build a project, deploy it and finally launch a docker process as a pod. 50 | 51 | To build and deploy the **Catalog Service** on OpenShift using the *fabric8* maven plugin, 52 | which is already configured in CodeReady Workspaces, `*right click on catalog-spring-boot*` project in the project explorer then, `*click on Commands > Deploy > fabric8:deploy*` 53 | 54 | image:{% image_path codeready-commands-deploy.png %}[Fabric8 Deploy,600] 55 | 56 | [TIP] 57 | .fabric8:deploy 58 | ==== 59 | It will cause the following to happen: 60 | 61 | * The Catalog uber-jar is built using Spring Boot 62 | * A container image is built on OpenShift containing the Catalog uber-jar and JDK 63 | * All necessary objects are created within the OpenShift project to deploy the Catalog service 64 | ==== 65 | 66 | Once this completes, your project should be up and running. You can see the expose DNS url for the **Catalog Service** in the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^] or using OpenShift CLI. 67 | 68 | ---- 69 | $ oc get routes 70 | 71 | NAME HOST/PORT PATH SERVICES PORT TERMINATION 72 | catalog catalog-{{COOLSTORE_PROJECT}}.{{APPS_HOSTNAME_SUFFIX}} catalog 8080 None 73 | inventory inventory-{{COOLSTORE_PROJECT}}.{{APPS_HOSTNAME_SUFFIX}} inventory 8080 None 74 | ---- 75 | 76 | `*Click on the OpenShift Route of _'Catalog Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]. 77 | 78 | image:{% image_path catalog-service.png %}[Catalog Service,500] 79 | 80 | Then `*click on 'Test it'*`. You should have the following output: 81 | 82 | [source,json] 83 | ---- 84 | [{"itemId":"329299","name":"Red Fedora","desc":"Official Red Hat Fedora","price":34.99},...] 85 | ---- 86 | 87 | Well done! You are ready to move on to the next lab. 88 | -------------------------------------------------------------------------------- /continuous-delivery.adoc: -------------------------------------------------------------------------------- 1 | == Automating Deployments Using Pipelines 2 | 3 | _20 MINUTE EXERCISE_ 4 | 5 | In this lab you will learn about deployment pipelines and you will create a pipeline to 6 | automate build and deployment of the Inventory service. 7 | 8 | [sidebar] 9 | .Continuous Delivery 10 | -- 11 | So far you have been building and deploying each service manually to OpenShift. Although 12 | it's convenient for local development, it's an error-prone way of delivering software if 13 | extended to test and production environments. 14 | 15 | Continuous Delivery (CD) refers to a set of practices with the intention of automating 16 | various aspects of delivery software. One of these practices is called **Delivery Pipeline** 17 | which is an automated process to define the steps a change in code or configuration has 18 | to go through in order to reach upper environments and eventually to production. 19 | 20 | OpenShift simplifies building CI/CD Pipelines by integrating 21 | the popular https://jenkins.io/doc/book/pipeline/overview/[Jenkins Pipelines^] into 22 | the platform and enables defining truly complex workflows directly from within OpenShift. 23 | -- 24 | 25 | ==== Create a Git Repository for Inventory 26 | 27 | The first step for any deployment pipeline is to store all code and configurations in 28 | a source code repository. You can use any Git server (e.g. GitHub, BitBucket, etc) for this lab but we have prepared a 29 | Gogs git server which you can access here: 30 | 31 | {{ GIT_URL }}[{{ GIT_URL }}^] 32 | 33 | `*Click on 'Register'*` to register a new user with the following details and then click on 34 | **Create New Account**: 35 | 36 | * Username: *_{{OPENSHIFT_USER}}_* 37 | * Email: *_your email_* (Don't worry! Gogs won't send you any emails) 38 | * Password: *_{{OPENSHIFT_PASSWORD}}_* 39 | * Re-Type: *_{{OPENSHIFT_PASSWORD}}_* 40 | 41 | image:{% image_path cd-gogs-signup.png %}[Sign Up Gogs,900] 42 | 43 | You will be redirected to the sign in page. Sign in using the above username and password. 44 | 45 | `*Click on the plus icon*` on the top navigation bar and then on **New Repository**. 46 | 47 | image:{% image_path cd-gogs-plus-icon.png %}[Create New Repository,900] 48 | 49 | Give **inventory-thorntail** as **Repository Name** and `*click on 'Create Repository'*` 50 | button, leaving the rest with default values. 51 | 52 | image:{% image_path cd-gogs-new-repo.png %}[Create New Repository,700] 53 | 54 | The Git repository is created now. 55 | 56 | `*Click on the copy-to-clipboard icon*` to near the 57 | HTTP Git url to copy it to the clipboard which you will need in a few minutes. 58 | 59 | image:{% image_path cd-gogs-empty-repo.png %}[Empty Repository,900] 60 | 61 | ==== Push Inventory Code to the Git Repository 62 | 63 | Now that you have a Git repository for the Inventory service, you should push the 64 | source code into this Git repository. 65 | 66 | Go the **inventory-thorntail** folder, initialize it as a Git working copy and add 67 | the GitHub repository as the remote repository for your working copy. 68 | 69 | IMPORTANT: Replace **GIT-REPO-URL** with the Git repository url copied in the previous steps 70 | 71 | ---- 72 | $ cd /projects/labs/inventory-thorntail 73 | $ git init 74 | $ git remote add origin GIT-REPO-URL 75 | ---- 76 | 77 | 78 | Before you commit the source code to the Git repository, configure your name and 79 | email so that the commit owner can be seen on the repository. If you want, you can 80 | replace the name and the email with your own in the following commands: 81 | 82 | ---- 83 | $ git config --global user.name "Developer" 84 | $ git config --global user.email "developer@me.com" 85 | ---- 86 | 87 | Commit and push the existing code to the GitHub repository. 88 | 89 | ---- 90 | $ git add . --all 91 | $ git commit -m "initial add" 92 | $ git push -u origin master 93 | ---- 94 | 95 | `*Enter your Git repository credentials*` if you get asked to. 96 | `*Refresh the page of your 'inventory-thorntail' repository*`. You should 97 | see the project files in the repository. 98 | 99 | image:{% image_path cd-gogs-inventory-repo.png %}[Inventory Repository,900] 100 | 101 | ==== Define the Deployment Pipeline 102 | 103 | OpenShift has built-in support for CI/CD pipelines by allowing developers to define 104 | a https://jenkins.io/solutions/pipeline/[Jenkins pipeline^] for execution by a Jenkins 105 | automation engine, which is automatically provisioned on-demand by OpenShift when needed. 106 | 107 | The build can get started, monitored, and managed by OpenShift in 108 | the same way as any other build types e.g. S2I. Pipeline workflows are defined in 109 | a Jenkinsfile, either embedded directly in the build configuration, or supplied in 110 | a Git repository and referenced by the build configuration. 111 | 112 | Jenkinsfile is a text file that contains the definition of a Jenkins Pipeline 113 | and is created using a https://jenkins.io/doc/book/pipeline/syntax/[scripted or declarative syntax^]. 114 | 115 | In the project explorer in CodeReady Workspaces, `*right-click 'inventory-thorntail' project and then 116 | on 'New > File' and name it 'Jenkinsfile'*`. 117 | 118 | `*Copy the following pipeline definition*` into *_Jenkinsfile_*. 119 | 120 | [source,groovy] 121 | .Jenkinsfile 122 | ---- 123 | pipeline { 124 | agent { 125 | label 'maven' 126 | } 127 | stages { 128 | stage('Build JAR') { #<1> 129 | steps { 130 | sh "mvn package" 131 | stash name:"jar", includes:"target/inventory-1.0-SNAPSHOT-thorntail.jar" 132 | } 133 | } 134 | stage('Build Image') { #<2> 135 | steps { 136 | unstash name:"jar" 137 | script { 138 | openshift.withCluster() { 139 | openshift.startBuild("inventory-s2i", "--from-file=target/inventory-1.0-SNAPSHOT-thorntail.jar", "--wait") 140 | } 141 | } 142 | } 143 | } 144 | stage('Deploy') { #<3> 145 | steps { 146 | script { 147 | openshift.withCluster() { 148 | def dc = openshift.selector("dc", "inventory") 149 | dc.rollout().latest() 150 | dc.rollout().status() 151 | } 152 | } 153 | } 154 | } 155 | } 156 | } 157 | ---- 158 | This pipeline has three stages 159 | <1> **Build JAR**: to build and test the jar file using Maven 160 | <2> **Build Image**: to build a container image from the Inventory JAR archive using OpenShift S2I 161 | <3> **Deploy**: to deploy the Inventory container image in the current project 162 | 163 | TIP: The pipeline definition is fully integrated with OpenShift and you can 164 | perform operations like image build, image deploy, etc directly from within the *_Jenkinsfile_*. 165 | 166 | TIP: When building deployment pipelines, it's important to treat your https://martinfowler.com/bliki/InfrastructureAsCode.html[infrastructure and everything else that needs to be configured (including the pipeline definition) as code^] 167 | and store them in a source repository for version control. 168 | 169 | `*Commit and push*` the *_Jenkinsfile_* to the Git repository. 170 | 171 | ---- 172 | $ git add Jenkinsfile 173 | $ git commit -m "pipeline added" 174 | $ git push origin master 175 | ---- 176 | 177 | The pipeline definition is ready and now you can create a deployment pipeline using 178 | this *_Jenkinsfile_*. 179 | 180 | ==== Create an OpenShift Pipeline 181 | 182 | Like mentioned, {{OPENSHIFT_DOCS_BASE}}/architecture/core_concepts/builds_and_image_streams.html#pipeline-build[OpenShift Pipelines^] enable creating deployment pipelines using the widely popular *_Jenkinsfile_* format. 183 | 184 | OpenShift automates deployments using {{OPENSHIFT_DOCS_BASE}}/dev_guide/deployments/basic_deployment_operations.html#triggers[deployment triggers^] that react to changes to the container image or configuration. Since you want to control the deployments instead 185 | from the pipeline, you should remove the Inventory deploy triggers so that building a new 186 | Inventory container image wouldn't automatically result in a new deployment. That would 187 | allow the pipeline to decide when a deployment should occur. 188 | 189 | `*Set triggers of _Inventory Deployment_ to manual*` and `*switch off Prometheus Agent*`: 190 | 191 | ---- 192 | $ oc set triggers dc/inventory --manual 193 | $ oc set env dc/inventory AB_PROMETHEUS_OFF=true 194 | ---- 195 | 196 | `*Deploy a Jenkins server*` using the provided template and container image that 197 | comes out-of-the-box with OpenShift: 198 | 199 | ---- 200 | $ oc new-app jenkins-ephemeral --param=MEMORY_LIMIT="2Gi" 201 | ---- 202 | 203 | CAUTION: Please modify the **'Resource Limits: jenkins'** 204 | from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^] to define **'CPU Limit = 2'** 205 | 206 | After Jenkins is deployed and is running (verify in web console), then `*create a 207 | deployment pipeline*` by running the following command within the **inventory-thorntail** folder: 208 | 209 | ---- 210 | $ oc new-app . --name=inventory-pipeline --strategy=pipeline 211 | ---- 212 | 213 | The above command creates a new build config of type pipeline which is automatically 214 | configured to fetch the *_Jenkinsfile_* from the Git repository of the current folder 215 | (**inventory-thorntail** Git repository) and execute it on Jenkins. 216 | 217 | `*Go to the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]*` inside the **{{COOLSTORE_PROJECT}}** project and from the left sidebar 218 | `*click on 'Builds >> Pipelines'*` 219 | 220 | image:{% image_path cd-pipeline-inprogress.png %}[OpenShift Pipeline,900] 221 | 222 | 223 | TIP: Pipeline syntax allows creating complex deployment scenarios with the possibility of defining 224 | checkpoint for manual interaction and approval process using 225 | https://jenkins.io/doc/pipeline/steps/[the large set of steps and plugins that Jenkins provide^] in 226 | order to adapt the pipeline to the process used in your team. You can see a few examples of 227 | advanced pipelines in the 228 | https://github.com/openshift/origin/tree/master/examples/jenkins/pipeline[OpenShift GitHub Repository^]. 229 | 230 | TIP: In order to update the deployment pipeline, all you need to do is to update the *_Jenkinsfile_* 231 | in the *_inventory-thorntail_* Git repository. OpenShift pipeline automatically executes the 232 | updated pipeline next time it runs. 233 | 234 | ==== Run the Pipeline on Every Code Change 235 | 236 | Manually triggering the deployment pipeline to run is useful but the real goal is to be able 237 | to build and deploy every change in code or configuration at least to lower environments 238 | (e.g. dev and test) and ideally all the way to production with some manual approvals in-place. 239 | 240 | In order to automate triggering the pipeline, you can define a *_Webhook_* on your Git repository 241 | to notify OpenShift on every commit that is made to the Git repository and trigger a pipeline 242 | execution. 243 | 244 | You can get see the webhook links in the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]. 245 | `*Select 'Build >> Pipelines' menu*`, then `*click on your _pipeline_*` and `*go to the _Configuration_ tab*`. 246 | 247 | WARNING: Copy the *_Generic Webhook URL_* which you will need in the next steps. 248 | 249 | `*Go to your 'inventory-thorntail' repository in {{ GIT_URL }}[Gogs^]`* and `*click on 'Settings'*`. 250 | 251 | image:{% image_path cd-gogs-settings-link.png %}[Repository Settings,900] 252 | 253 | On the left menu, `*click on 'Webhooks >> Add Webhook >> Gogs'*`. 254 | 255 | Create a webhook with the following details: 256 | 257 | * **Payload URL**: paste the Generic webhook url you copied from the *_inventory-pipeline_* 258 | * **Content type**: *_application/json_* 259 | 260 | `*Click on 'Add Webhook'*`. 261 | 262 | image:{% image_path cd-gogs-webhook-add.png %}[Repository Webhook,660] 263 | 264 | All done. You can click on the newly defined webhook to see the list of *Recent Delivery*. 265 | Clicking on the **Test Delivery** button allows you to manually trigger the webhook for 266 | testing purposes. Click on it and verify that the *_inventory-pipeline_* starts running 267 | immediately. 268 | 269 | Well done! You are ready for the next lab. 270 | -------------------------------------------------------------------------------- /debug-codeready.adoc: -------------------------------------------------------------------------------- 1 | ## Debugging Applications 2 | 3 | *20 MINUTE EXERCISE* 4 | 5 | In this lab you will debug the CoolStore application using Java remote debugging and 6 | look into line-by-line code execution as the code runs inside a container on OpenShift. 7 | 8 | #### Investigate The Bug 9 | 10 | CoolStore application seems to have a bug that causes the inventory status for one of the 11 | products not to be displayed in the web interface. 12 | 13 | image:{% image_path debug-coolstore-bug.png %}[Inventory Status Bug,800] 14 | 15 | This is not an expected behavior! In previous labs, you added a circuit breaker to 16 | protect the CoolStore application from failures and in case the Inventory API is not 17 | available, to skip it and show the products without the inventory status. However, right 18 | now the inventory status is available for all products but one which is not how we 19 | expect to see the products. 20 | 21 | Since the product list is provided by the API Gateway, take a look into the API Gateway 22 | logs to see if there are any errors: 23 | 24 | ---- 25 | $ oc logs dc/gateway -c vertx | grep -i "inventory error" 26 | 27 | ... 28 | WARNING: Inventory error for 444436: status code 204 29 | WARNING: Inventory error for 444436: status code 204 30 | ... 31 | ---- 32 | 33 | Oh! Something seems to be wrong with the response the API Gateway has received from the 34 | Inventory API for the product id **444436**. 35 | 36 | Look into the Inventory pod logs to investigate further and see if you can find more 37 | information about this bug: 38 | 39 | 40 | ---- 41 | $ oc logs dc/inventory -c thorntail-v2 | grep ERROR 42 | ---- 43 | 44 | There doesn't seem to be anything relevant to the **invalid response** error that the 45 | API Gateway received either! 46 | 47 | Invoke the Inventory API using `*curl*` for the suspect product id to see what actually 48 | happens when API Gateway makes this call: 49 | 50 | IMPORTANT: You can find out the Inventory route url using `*oc get route inventory`. Replace 51 | IMPORTANT: **{{INVENTORY_ROUTE_HOST}}** with the Inventory route url from your project. 52 | 53 | ---- 54 | $ curl -v http://{{INVENTORY_ROUTE_HOST}}/api/inventory/444436 55 | ---- 56 | 57 | You received a ***HTTP/1.1 204 No Content*** response for the above request. Indeed, no response came back and that seems to be the reason the inventory status is not displayed on the web interface. 58 | 59 | Let's debug the Inventory service to get to the bottom of this! 60 | 61 | #### Enable Remote Debugging 62 | 63 | Remote debugging is a useful debugging technique for application development which allows 64 | looking into the code that is being executed somewhere else on a different machine and 65 | execute the code line-by-line to help investigate bugs and issues. Remote debugging is 66 | part of Java SE standard debugging architecture which you can learn more about it in https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/architecture.html[Java SE docs^]. 67 | 68 | 69 | The Java image on OpenShift has built-in support for remote debugging and it can be enabled 70 | by setting the ***JAVA_DEBUG=true*** environment variables on the deployment config for the pod 71 | that you want to remotely debug. 72 | 73 | An easier approach would be to use the fabric8 maven plugin to enable remote debugging on 74 | the Inventory pod. It also forwards the default remote debugging port, 5005, from the 75 | Inventory pod to your workstation so simplify connectivity. 76 | 77 | Enable remote debugging on Inventory by running the following command in the CodeReady Workspaces **Terminal** window: 78 | 79 | ---- 80 | $ oc rollout pause dc/inventory 81 | $ oc set env dc/inventory JAVA_DEBUG=true 82 | $ oc set env dc/inventory AB_PROMETHEUS_OFF- 83 | $ oc set probe dc/inventory --readiness --liveness --remove 84 | $ oc rollout resume dc/inventory 85 | $ oc rollout latest dc/inventory 86 | $ oc get pods -lapp=inventory,deploymentconfig=inventory 87 | NAME READY STATUS RESTARTS AGE 88 | inventory-19-k54lj 1/1 Running 0 3m 89 | ---- 90 | 91 | Wait until the service is **Running** with **1/1** in the **READY** column. 92 | 93 | IMPORTANT: The default port for remoting debugging is **5005** but you can change the default port 94 | IMPORTANT: via environment variables (JAVA_DEBUG_PORT). Read more in the https://access.redhat.com/documentation/en-us/red_hat_jboss_middleware_for_openshift/3/html/red_hat_java_s2i_for_openshift/reference#configuration_environment_variables[Java S2I Image docs^]. 95 | 96 | You are all set now to start debugging using the tools of you choice. 97 | 98 | Forward the remote debugging port of the Inventory service locally by executing the following command: 99 | 100 | ---- 101 | $ oc port-forward dc/inventory 5005 102 | Forwarding from 127.0.0.1:5005 -> 5005 103 | Forwarding from [::1]:5005 -> 5005 104 | ---- 105 | 106 | Do not wait for the command to return! It keeps the forwarded 107 | port open so that you can start debugging remotely. 108 | 109 | #### Remote Debug with CodeReady Workspaces 110 | 111 | CodeReady Workspaces provides a convenient way to remotely connect to Java applications running 112 | inside containers and debug while following the code execution in the IDE. 113 | 114 | From the **Run** menu, click on **Edit Debug Configurations...**. 115 | 116 | image:{% image_path debug-che-debug-config-1.png %}[Remote Debug,600] 117 | 118 | The window shows the debuggers available in CodeReady Workspaces. Click on the plus sign near the 119 | Java debugger. 120 | 121 | image:{% image_path debug-che-debug-config-2.png %}[Remote Debug,700] 122 | 123 | Configure the remote debugger and click on the **Save** button: 124 | 125 | * Check **Connect to process on workspace machine** 126 | * Port: **5005** 127 | 128 | image:{% image_path debug-che-debug-config-3.png %}[Remote Debug,700] 129 | 130 | You can now click on the **Debug** button to make CodeReady Workspaces connect to the 131 | Inventory service running on OpenShift. 132 | 133 | You should see a confirmation that the remote debugger is successfully connected. 134 | 135 | image:{% image_path debug-che-debug-config-4.png %}[Remote Debug,360] 136 | 137 | Open ***com.redhat.cloudnative.inventory.InventoryResource*** and `*click once 138 | on the editor sidebar on the line number of the first line of the getAvailability() 139 | method*` to add a breakpoint to that line. A start appears near the line to show a breakpoint 140 | is set. 141 | 142 | image:{% image_path debug-che-breakpoint.png %}[Add Breakpoint,600] 143 | 144 | Open a new **Terminal** window and use `*curl*` to invoke the Inventory API with the 145 | suspect product id in order to pause the code execution at the defined breakpoint. 146 | 147 | Note that you can use the the following icons to switch between debug and terminal windows. 148 | 149 | 150 | image:{% image_path debug-che-window-guide.png %}[Icons,700] 151 | 152 | IMPORTANT: You can find out the Inventory route url using `*oc get routes`. Replace 153 | IMPORTANT: **{{INVENTORY_ROUTE_HOST}}** with the Inventory route url from your project. 154 | 155 | ---- 156 | $ curl -v http://{{INVENTORY_ROUTE_HOST}}/api/inventory/444436 157 | ---- 158 | 159 | Switch back to the debug panel and notice that the code execution is paused at the 160 | breakpoint on ***InventoryResource*** class. 161 | 162 | image:{% image_path debug-che-breakpoint-stop.png %}[Icons,900] 163 | 164 | Click on the _Step Over_ icon to execute one line and retrieve the inventory object for the 165 | given product id from the database. 166 | 167 | image:{% image_path debug-che-step-over.png %}[Step Over,340] 168 | 169 | Click on the the plus icon in the **Variables** panel to add the ***inventory*** variable 170 | to the list of watch variables. This would allow you to see the value of ***inventory*** variable 171 | during execution. 172 | 173 | image:{% image_path debug-che-variables.png %}[Watch Variables,500] 174 | 175 | image:{% image_path debug-che-breakpoint-values.png %}[Debug,900] 176 | 177 | Can you spot the bug now? 178 | 179 | Look at the **Variables** window. The retrieved inventory object is ***null***! 180 | 181 | The non-existing product id is not a problem on its own because it simply could mean 182 | this product is discontinued and removed from the Inventory database but it's not 183 | removed from the product catalog database yet. The bug is however caused because 184 | the code returns this ***null*** value instead of a sensible REST response. If the product 185 | id does not exist, a proper JSON response stating a zero inventory should be 186 | returned instead of ***null***. 187 | 188 | `Click on the _Resume_ icon*` to continue the code execution and then on the stop icon to 189 | end the debug session. 190 | 191 | #### Fix the Inventory Bug 192 | 193 | Edit the ***InventoryResource.java*** and update the ***getAvailability()*** to make it look like the following 194 | code in order to return a zero inventory for products that don't exist in the inventory 195 | database: 196 | 197 | ---- 198 | @GET 199 | @Path("/{itemId}") 200 | @Produces(MediaType.APPLICATION_JSON) 201 | public Inventory getAvailability(@PathParam("itemId") String itemId) { 202 | Inventory inventory = em.find(Inventory.class, itemId); 203 | 204 | if (inventory == null) { 205 | inventory = new Inventory(); 206 | inventory.setItemId(itemId); 207 | inventory.setQuantity(0); 208 | } 209 | 210 | return inventory; 211 | } 212 | ---- 213 | 214 | Go back to the **Terminal** window where `*oc port-forward*` was running. Press 215 | `Ctrl+C*` to stop the debug and port-forward and then run the following commands 216 | to commit the changes to the Git repository. 217 | 218 | ---- 219 | $ git add src/main/java/com/redhat/cloudnative/inventory/InventoryResource.java 220 | $ git commit -m "inventory returns zero for non-existing product id" 221 | $ git push origin master 222 | ---- 223 | 224 | As soon as you commit the changes to the Git repository, the ***inventory-pipeline*** gets 225 | triggered to build and deploy a new Inventory container with the fix. Go to the 226 | OpenShift Web Console and inside the **{{COOLSTORE_PROJECT}}** project. On the sidebar 227 | menu, `*click on 'Builds >> Pipelines'*` to see its progress. 228 | 229 | When the pipeline completes successfully, point your browser at the Web route and verify 230 | that the inventory status is visible for all products. The suspect product should show 231 | the inventory status as _Not in Stock_. 232 | 233 | image:{% image_path debug-coolstore-bug-fixed.png %}[Inventory Status Bug Fixed,800] 234 | 235 | Well done and congratulations for completing all the labs. 236 | -------------------------------------------------------------------------------- /env-info.adoc: -------------------------------------------------------------------------------- 1 | == Appendix: Environment Info 2 | 3 | You find all urls, hostnames, usernames and passwords that are needed during the 4 | labs in this page. Note that the urls are also embedded inside each lab instructions. 5 | 6 | OPENSHIFT:: 7 | {{ OPENSHIFT_CONSOLE_URL }} 8 | 9 | GIT SERVER:: 10 | {{ GIT_URL }} 11 | 12 | NEXUS MAVEN REPOSITORY:: 13 | {{ NEXUS_URL }} 14 | 15 | CODEREADY WORKSPACES:: 16 | {{ CODEREADY_WORKSPACES_URL }} 17 | 18 | KIALI:: 19 | {{ KIALI_URL }} 20 | 21 | JAEGER:: 22 | {{ JAEGER_URL }} 23 | 24 | OPENSHIFT DOCS:: 25 | {{ OPENSHIFT_DOCS_BASE }} 26 | -------------------------------------------------------------------------------- /gateway-deployment.adoc: -------------------------------------------------------------------------------- 1 | == Deploying the API Gateway 2 | 3 | _10 MINUTE EXERCISE_ 4 | 5 | As explained in the introduction at the core of the Cool Store Portal architecture there is a Gateway component. 6 | 7 | As we have done previously for the sake of saving time we're going to deploy our 'Gateway' service instead of coding it. But before we actually deploy the service we're going to explain briefly some concepts. 8 | 9 | image:{% image_path coolstore-arch-gateway-vertx.png %}[CoolStore Architecture,400] 10 | 11 | === Technology 12 | 13 | Our **'API Gateway'** service needed to be easy to scale, light and responsive, these are some of the reasons why we have implemented it as a Vert.x verticle. 14 | 15 | === What is Eclipse Vert.x? 16 | 17 | [sidebar] 18 | -- 19 | image:{% image_path vertx-logo.png %}[Vertx, 400] 20 | 21 | http://vertx.io/[Eclipse Vert.x^] is a toolkit for building reactive applications on the Java Virtual Machine (JVM). Vert.x does not 22 | impose a specific framework or packaging model and can be used within your existing applications and frameworks 23 | in order to add reactive functionality by just adding the Vert.x jar files to the application classpath. 24 | 25 | http://vertx.io/[Eclipse Vert.x^] enables building reactive systems as defined by http://www.reactivemanifesto.org[The Reactive Manifesto^] and build 26 | services that are: 27 | 28 | * *Responsive*: to handle requests in a reasonable time 29 | * *Resilient*: to stay responsive in the face of failures 30 | * *Elastic*: to stay responsive under various loads and be able to scale up and down 31 | * *Message driven*: components interact using asynchronous message-passing 32 | 33 | http://vertx.io/[Eclipse Vert.x^] is designed to be event-driven and non-blocking. Events are delivered in an event loop that must never be blocked. Unlike traditional applications, Vert.x uses a very small number of threads responsible for dispatching the events to event handlers. If the event loop is blocked, the events won’t be delivered anymore and therefore the code needs to be mindful of this execution model. 34 | -- 35 | 36 | === Vert.x Maven Project 37 | 38 | The `*gateway-vertx*` project has the following structure which shows the components of the Vert.x project laid out in different subdirectories according to Maven best practices: 39 | 40 | image:{% image_path vertx-gateway-project.png %}[Gateway Project,340] 41 | 42 | This is a minimal Vert.x project with support for RESTful services. This project currently contains no code other than the main class, `*GatewayVerticle.java*` which is there to bootstrap the Vert.x application. Verticles are encapsulated parts of the application that can run completely independently and communicate with each other via the built-in event bus in Vert.x. Verticles get deployed and run by Vert.x in an event loop and therefore it is important that the code in a Verticle does not block. This asynchronous architecture allows Vert.x applications to easily scale and handle large amounts of throughput with few threads.All API calls in Vert.x by default are non-blocking and support this concurrency model. 43 | 44 | image:{% image_path vertx-event-loop.png %}[Vert.x Event Loop,600] 45 | 46 | Although you can have multiple, there is currently only one Verticle created in the `*gateway-vertx*` project. 47 | 48 | === Deploying our API Gateway on OpenShift 49 | 50 | It’s time to deploy our service on OpenShift. 51 | 52 | The API Gateway is using http://vertx.io/docs/vertx-service-discovery/java[Vert.x service discovery^] for finding where dependent services are deployed 53 | and accessing their endpoints. This service discovery can seamlessly integrated with external 54 | service discovery mechanisms provided by OpenShift, Kubernetes, Consul, Redis, etc. 55 | 56 | http://vertx.io/docs/vertx-service-discovery/java[Vert.x service discovery^] integrates into OpenShift service discovery via OpenShift 57 | REST API and imports available services to make them available to the Vert.x application. 58 | 59 | Next commands are going to deploy our API Gateway service. 60 | 61 | * **Name:** gateway 62 | * **S2I runtime:** redhat-openjdk18-openshift 63 | * **Image tag:** 1.4 64 | * **Repository:** {{LABS_GIT_REPO}} 65 | * **Context Directory:** gateway-vertx 66 | 67 | ---- 68 | $ oc new-app redhat-openjdk18-openshift:1.4~{{LABS_GIT_REPO}} \ 69 | --context-dir=gateway-vertx \ 70 | --name=gateway 71 | 72 | $ oc expose svc/gateway 73 | ---- 74 | 75 | Once this completes, your project should be up and running. You can see the expose DNS url for the Gateway service in the OpenShift Web Console or using OpenShift CLI. 76 | 77 | ---- 78 | $ oc get routes 79 | 80 | NAME HOST/PORT PATH SERVICES PORT TERMINATION 81 | catalog catalog-{{COOLSTORE_PROJECT}}-{{OPENSHIFT_USER}}.roadshow.openshiftapps.com catalog 8080 None 82 | inventory inventory-{{COOLSTORE_PROJECT}}-{{OPENSHIFT_USER}}.roadshow.openshiftapps.com inventory 8080 None 83 | gateway gateway-{{COOLSTORE_PROJECT}}-{{OPENSHIFT_USER}}.roadshow.openshiftapps.com gateway 8080 None 84 | ---- 85 | 86 | 87 | `*Click on the OpenShift Route of _'Gateway Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]. 88 | 89 | image:{% image_path gateway-service.png %}[Gateway Service,500] 90 | 91 | Then `*click on 'Test it'*`. You should have the following output: 92 | 93 | [source,json] 94 | ---- 95 | [ { 96 | "itemId" : "329299", 97 | "name" : "Red Fedora", 98 | "desc" : "Official Red Hat Fedora", 99 | "price" : 34.99, 100 | "availability" : { 101 | "quantity" : 35 102 | } 103 | }, 104 | ... 105 | ] 106 | ---- 107 | 108 | As mentioned earlier, Vert.x built-in service discovery is integrated with OpenShift service 109 | discovery to lookup the Catalog and Inventory APIs. 110 | 111 | Well done! You are ready to move on to the next lab. 112 | -------------------------------------------------------------------------------- /getting-started-codeready.adoc: -------------------------------------------------------------------------------- 1 | == Getting Started with OpenShift 2 | 3 | _5 MINUTE EXERCISE_ 4 | 5 | In this lab you will learn about providing your Developer Workspace with a Kubernetes-native development platform 6 | and getting familiar with the OpenShift CLI and OpenShift Web Console. 7 | 8 | === What is CodeReady Workspaces? 9 | 10 | [sidebar] 11 | -- 12 | image:{% image_path codeready.png %}[CodeReady, 400] 13 | 14 | https://developers.redhat.com/products/codeready-workspaces/overview/[Red Hat CodeReady Workspaces^] is a collaborative Kubernetes-native development platform that delivers OpenShift workspaces and an IDE for rapid cloud application development. 15 | 16 | Built on the open Eclipse Che project, https://developers.redhat.com/products/codeready-workspaces/overview/[Red Hat CodeReady Workspaces^] provides developer workspaces on OpenShift with all the tools and the dependencies that are needed to code, build, test, run, and debug containerized applications. The entire product runs in the cloud and eliminates the need to install anything on a local machine. 17 | 18 | * It offers fast onboarding capabilities for teams with powerful collaboration, workspace automation, and management at scale 19 | * It removes inconsistencies and the “works on my machine” syndrome 20 | * It protects source code from the hard-to-secure developer and personal laptops 21 | -- 22 | 23 | === Logging in to CodeReady Workspaces 24 | 25 | `*Go to {{ CODEREADY_WORKSPACES_URL }}[CodeReady Workspaces^]*` then `*click on 'Openshift v3'*` to log in through 26 | https://docs.openshift.com/container-platform/3.11/architecture/additional_concepts/authentication.html#oauth[OpenShift OAuth^]. 27 | 28 | image:{% image_path codeready-oauth.png %}[CodeReady Workspaces - Log in,500] 29 | 30 | Log in as `*{{OPENSHIFT_USER}}/{{OPENSHIFT_PASSWORD}}*` and `*click on 'Allow selected permissions'*` 31 | 32 | image:{% image_path codeready-login.png %}[CodeReady Workspaces - Log in,500] 33 | 34 | image:{% image_path codeready-authorize-access.png %}[CodeReady Workspaces - Log in,500] 35 | 36 | Finally, `*enter your account information*` and `*click on 'Submit'*` 37 | 38 | image:{% image_path codeready-account-information.png %}[CodeReady Workspaces - Log in,300] 39 | 40 | === Creating a Workspace 41 | Once logged into CodeReady Workspaces, you can now create your workspace based on the **Cloud-Native Stack**. 42 | 43 | [TIP] 44 | ==== 45 | A **Stack** is a template for workspace configuration. 46 | It includes the programming language and tools needed in your workspace to create applications. 47 | Stacks make it possible to deploy identical workspaces for all users on demand. 48 | ==== 49 | 50 | `*Select the stack called 'Cloud-Native'*` and then `*click on 'CREATE & OPEN'*`. 51 | 52 | image:{% image_path codeready-create-workspace.png %}[CodeReady Workspaces - Workspace,1000] 53 | 54 | [CAUTION] 55 | ==== 56 | *Make sure to select the stack called 'Cloud-Native' otherwise, you will not be able to complete the lab!* 57 | ==== 58 | 59 | It takes a little while for the workspace to be ready. When it's ready, you will see a fully functional CodeReady Workspaces IDE running in your browser. 60 | 61 | image:{% image_path codeready-workspace.png %}[CodeReady Workspaces - Workspace,1000] 62 | 63 | === Importing the lab project 64 | Now you can import the project skeletons into your workspace. 65 | 66 | In the Project Explorer pane, `*click on 'Import Project...'*` and enter the following: 67 | 68 | * Type: **ZIP** 69 | * URL: **{{LABS_DOWNLOAD_URL}}** 70 | * Name: **labs** 71 | * Check **Skip the root folder of the archive** 72 | 73 | image:{% image_path codeready-import.png %}[CodeReady Workspaces - Import Project,700] 74 | 75 | `*Click on 'Import'*`. Make sure you choose the **Blank** project configuration since the zip file contains multiple 76 | project skeletons. `*Click on 'Save'*` 77 | 78 | image:{% image_path codeready-import-save.png %}[CodeReady Workspaces - Import Project,500] 79 | 80 | === Converting your project skeletons 81 | The projects are imported now into your workspace and is visible in the project explorer. 82 | 83 | CodeReady Workspaces is a full featured IDE and provides language specific capabilities for various project types. In order to 84 | enable these capabilities, let's convert the imported project skeletons to Maven projects. 85 | 86 | In the Project Explorer, `*right-click on 'catalog-spring-boot'*` then, `*click on 'Convert to Project'*`. 87 | 88 | image:{% image_path codeready-convert.png %}[CodeReady Workspaces - Convert to Project,500] 89 | 90 | `*Choose 'JAVA > Maven'*` from the project configurations and then `*click on 'Save'*` 91 | 92 | image:{% image_path codeready-maven.png %}[CodeReady Workspaces - Convert to Project,500] 93 | 94 | [WARNING] 95 | .Project Conversion 96 | ==== 97 | Repeat the above for **inventory-thorntail** and **gateway-vertx** projects. 98 | ==== 99 | 100 | [IMPORTANT] 101 | .Terminal Window of CodeReady Workspaces 102 | ==== 103 | For the rest of these labs, anytime you need to run a command in a terminal, you can use the CodeReady Workspaces **Terminal** window. 104 | 105 | image:{% image_path codeready-terminal.png %}[CodeReady Workspaces - Terminal, 700] 106 | ==== 107 | 108 | == Explore OpenShift with OpenShift CLI 109 | 110 | In order to login, `*issue the following command*` and log in as `*{{OPENSHIFT_USER}}/{{OPENSHIFT_PASSWORD}}*` 111 | 112 | [source,shell] 113 | ---- 114 | $ oc login {{OPENSHIFT_CONSOLE_URL}} 115 | ---- 116 | 117 | [TIP] 118 | ==== 119 | You may see the following output: 120 | 121 | ---- 122 | The server uses a certificate signed by an unknown authority. 123 | You can bypass the certificate check, but any data you send to the server could be intercepted by others. 124 | Use insecure connections? (y/n): 125 | ---- 126 | 127 | Enter in `*Y*` to use a potentially insecure connection. The reason you received 128 | this message is because we are using a self-signed certificate for this 129 | workshop, but we did not provide you with the CA certificate that was generated 130 | by OpenShift. In a real-world scenario, either OpenShift's certificate would be 131 | signed by a standard CA (eg: Thawte, Verisign, StartSSL, etc.) or signed by a 132 | corporate-standard CA that you already have installed on your system. 133 | ==== 134 | 135 | Congratulations, you are now authenticated to the OpenShift server. 136 | 137 | {{OPENSHIFT_DOCS_BASE}}/architecture/core_concepts/projects_and_users.html#projects[Projects^] 138 | are a top level concept to help you organize your deployments. An 139 | OpenShift project allows a community of users (or a user) to organize and manage 140 | their content in isolation from other communities. Each project has its own 141 | resources, policies (who can or cannot perform actions), and constraints (quotas 142 | and limits on resources, etc). Projects act as a "wrapper" around all the 143 | application services and endpoints you (or your teams) are using for your work. 144 | 145 | [WARNING] 146 | ==== 147 | 148 | Make sure to use your dedicated project {{COOLSTORE_PROJECT}} by running the following command: 149 | 150 | [source,shell] 151 | ---- 152 | $ oc project {{COOLSTORE_PROJECT}} 153 | ---- 154 | 155 | ==== 156 | 157 | OpenShift ships with a web-based console that will allow users to 158 | perform various tasks via a browser. To get a feel for how the web console 159 | works, open your browser and `*go to {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]*`. 160 | 161 | The first screen you will see is the authentication screen. Enter your username and password (`*{{OPENSHIFT_USER}}/{{OPENSHIFT_PASSWORD}}*`) and 162 | then log in. After you have authenticated to the web console, you will be presented with a 163 | list of projects that your user has permission to work with. 164 | 165 | `*Click on '{{COOLSTORE_PROJECT}}'*` project to be taken to the project overview page 166 | which will list all of the routes, services, deployments, and pods that you have 167 | running as part of your project. There's nothing there now, but that's about to 168 | change. 169 | 170 | Now you are ready to get started with the labs! 171 | -------------------------------------------------------------------------------- /health.adoc: -------------------------------------------------------------------------------- 1 | == Monitoring Application Health 2 | 3 | _15 MINUTE EXERCISE_ 4 | 5 | In this lab we will learn how to monitor application health using OpenShift 6 | health probes and how you can see container resource consumption using metrics. 7 | 8 | [sidebar] 9 | .Health Probes 10 | -- 11 | 12 | When building microservices, monitoring becomes of extreme importance to make sure all services 13 | are running at all times, and when they don't there are automatic actions triggered to rectify 14 | the issues. 15 | 16 | OpenShift, using Kubernetes health probes, offers a solution for monitoring application 17 | health and trying to automatically heal faulty containers through restarting them to fix issues such as 18 | a deadlock in the application which can be resolved by restarting the container. Restarting a container 19 | in such a state can help to make the application more available despite bugs. 20 | 21 | Furthermore, there are of course a category of issues that can't be resolved by restarting the container. 22 | In those scenarios, OpenShift would remove the faulty container from the built-in load-balancer and send traffic 23 | only to the healthy containers that remain. 24 | 25 | There are two types of health probes available in OpenShift: {{OPENSHIFT_DOCS_BASE}}/dev_guide/application_health.html#container-health-checks-using-probes[liveness probes and readiness probes^]. 26 | *Liveness probes* are to know when to restart a container and *readiness probes* to know when a 27 | Container is ready to start accepting traffic. 28 | 29 | Health probes also provide crucial benefits when automating deployments with practices like rolling updates in 30 | order to remove downtime during deployments. A readiness health probe would signal OpenShift when to switch 31 | traffic from the old version of the container to the new version so that the users don't get affected during 32 | deployments. 33 | 34 | There are {{OPENSHIFT_DOCS_BASE}}/dev_guide/application_health.html#container-health-checks-using-probes[three ways to define a health probe^] for a container: 35 | 36 | * **HTTP Checks:** healthiness of the container is determined based on the response code of an HTTP 37 | endpoint. Anything between 200 and 399 is considered success. A HTTP check is ideal for applications 38 | that return HTTP status codes when completely initialized. 39 | 40 | * **Container Execution Checks:** a specified command is executed inside the container and the healthiness is 41 | determined based on the return value (0 is success). 42 | 43 | * **TCP Socket Checks:** a socket is opened on a specified port to the container and it's considered healthy 44 | only if the check can establish a connection. TCP socket check is ideal for applications that do not 45 | start listening until initialization is complete. 46 | -- 47 | 48 | === Explore Health REST Endpoints 49 | 50 | Let's add health probes to the microservices deployed so far. 51 | Spring Boot, Thorntail and Vert.x all provide out-of-the-box support for creating RESTful endpoints that 52 | provide details on the health of the application. These endpoints by default provide basic data about the 53 | service however they all provide a way to customize the health data and add more meaningful information (e.g. 54 | database connection health, backoffice system availability, etc). 55 | 56 | http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready[Spring Boot Actuator^] is a 57 | sub-project of Spring Boot which adds health and management HTTP endpoints to the application. Enabling Spring Boot 58 | Actuator is done via adding **org.springframework.boot:spring-boot-starter-actuator** dependency to the Maven project 59 | dependencies which is already done for the **Catalog Service**. 60 | 61 | Verify that the health endpoint works for the **Catalog Service** using `*curl*` 62 | 63 | ---- 64 | $ curl http://catalog.{{COOLSTORE_PROJECT}}.svc:8080/health 65 | 66 | {"status":"UP"} 67 | ---- 68 | 69 | https://docs.thorntail.io/2.2.0.Final/#_microprofile_health[Thorntail health endpoints^] function in a similar fashion and are enabled by adding **io.thorntail:microprofile-health** 70 | to the Maven project dependencies. 71 | This is also already done for the **Inventory Service**. 72 | 73 | Verify that the health endpoint works for the **Inventory Service** using `*curl*` 74 | 75 | ---- 76 | $ curl http://inventory.{{COOLSTORE_PROJECT}}.svc:8080/node 77 | 78 | { 79 | "name" : "localhost", 80 | "server-state" : "running", 81 | "suspend-state" : "RUNNING", 82 | "running-mode" : "NORMAL", 83 | "uuid" : "79b3ffc5-d98c-4b8e-ae5c-9756ed13944a", 84 | "swarm-version" : "2.2.0.Final-redhat-00021" 85 | } 86 | ---- 87 | 88 | Expectedly, Eclipse Vert.x also provides a http://vertx.io/docs/vertx-health-check/java[health check module^] 89 | which is enabled by adding **io.vertx:vertx-health-check** as a dependency to the Maven project. 90 | 91 | Verify that the health endpoint works for the **Gateway Service** using `*curl*` 92 | 93 | ---- 94 | $ curl http://gateway.{{COOLSTORE_PROJECT}}.svc:8080/health 95 | 96 | {"status":"UP"} 97 | ---- 98 | 99 | Last but not least, although you can build more sophisticated health endpoints for the Web UI as well, you 100 | can use the root context ("/") of the Web UI in this lab to verify it's up and running. 101 | 102 | === Monitoring Catalog Service Health 103 | 104 | Health probes are defined on the deployment config for each pod and can be added using OpenShift Web 105 | Console or OpenShift CLI. You will try both in this lab. 106 | 107 | Like mentioned, health probes are defined on a deployment config for each pod. Review the available 108 | deployment configs in the project. 109 | 110 | ---- 111 | $ oc get dc 112 | 113 | NAME REVISION DESIRED CURRENT TRIGGERED BY 114 | catalog 1 1 1 config,image(catalog:latest) 115 | gateway 1 1 1 config,image(gateway:latest) 116 | inventory 1 1 1 config,image(inventory:latest) 117 | web 1 1 1 config,image(web:latest) 118 | ---- 119 | 120 | TIP: **dc** stands for deployment config 121 | 122 | `*Add a Liveness Probe on the Catalog Deployment Config*`: 123 | 124 | ---- 125 | $ oc set probe dc/catalog --liveness --initial-delay-seconds=30 --failure-threshold=3 --get-url=http://:8080/health 126 | ---- 127 | 128 | TIP: OpenShift automates deployments using 129 | {{OPENSHIFT_DOCS_BASE}}/dev_guide/deployments/basic_deployment_operations.html#triggers[deployment triggers^] 130 | that react to changes to the container image or configuration. 131 | Therefore, as soon as you define the probe, OpenShift automatically redeploys the 132 | Catalog pod using the new configuration including the liveness probe. 133 | 134 | The `*--get-url*` defines the HTTP endpoint to use for check the liveness of the container. The ***http://:8080*** 135 | syntax is a convenient way to define the endpoint without having to worry about the hostname for the running 136 | container. 137 | 138 | TIP: It is possible to customize the probes even further using for example `*--initial-delay-seconds*` to specify how long 139 | to wait after the container starts and before to begin checking the probes. Run `*oc set probe --help*` to get 140 | a list of all available options. 141 | 142 | `*Add a Readiness Probe on the Catalog Deployment Config*` using the same **/health** endpoint that you used for 143 | the liveness probe. 144 | 145 | TIP: It's recommended to have separate endpoints for readiness and liveness to indicate to OpenShift when 146 | to restart the container and when to leave it alone and remove it from the load-balancer so that an administrator 147 | would manually investigate the issue. 148 | 149 | ---- 150 | $ oc set probe dc/catalog --readiness --initial-delay-seconds=30 --failure-threshold=3 --get-url=http://:8080/health 151 | ---- 152 | 153 | Voilà! OpenShift automatically restarts the Catalog pod and as soon as the 154 | health probes succeed, it is ready to receive traffic. 155 | 156 | TIP: Fabric8 Maven Plugin can also be configured to automatically set the health probes when running **fabric8:deploy** 157 | goal. Read more on https://maven.fabric8.io/#enrichers[Fabric8 docs^] under 158 | https://maven.fabric8.io/#f8-spring-boot-health-check[Spring Boot^], 159 | https://maven.fabric8.io/#f8-healthcheck-thorntail-v2[Thorntail^] and 160 | https://maven.fabric8.io/#f8-vertx-health-check[Eclipse Vert.x^]. 161 | 162 | === Monitoring Inventory Service Health 163 | 164 | Adding liveness and readiness probes can be done at the same time if you want to define the same health endpoint 165 | and parameters for both liveness and readiness probes. 166 | 167 | `*Add the Liveness and Readiness Probes to the Inventory Service*` 168 | 169 | ---- 170 | $ oc set probe dc/inventory --liveness --readiness --initial-delay-seconds=30 --failure-threshold=3 --get-url=http://:8080/node 171 | ---- 172 | 173 | OpenShift automatically restarts the Inventory pod and as soon as the health probes succeed, it is ready to receive traffic. 174 | 175 | Using the `*oc describe*` command, you can get a detailed look into the deployment config and verify that the health probes are in fact 176 | configured as you wanted: 177 | 178 | ---- 179 | $ oc describe dc/inventory 180 | 181 | Name: inventory 182 | Namespace: {{COOLSTORE_PROJECT}} 183 | ... 184 | Containers: 185 | thorntail-v2: 186 | ... 187 | Liveness: http-get http://:8080/node delay=180s timeout=1s period=10s #success=1 #failure=3 188 | Readiness: http-get http://:8080/node delay=10s timeout=1s period=10s #success=1 #failure=3 189 | ... 190 | ---- 191 | 192 | === Monitoring API Gateway Health 193 | 194 | You are an expert in health probes by now! `*Add Liveness and Readiness Probes to the API Gateway Service`* 195 | 196 | ---- 197 | $ oc set probe dc/gateway --liveness --readiness --initial-delay-seconds=15 --failure-threshold=3 --get-url=http://:8080/health 198 | ---- 199 | 200 | OpenShift automatically restarts the Inventory pod and as soon as the health probes succeed, it is 201 | ready to receive traffic. 202 | 203 | === Monitoring Web UI Health 204 | 205 | Although you can add the liveness and health probes to the Web UI using a single CLI command, let's 206 | give the OpenShift Web Console a try this time. 207 | 208 | `*Go to {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]*` in your browser and in the **{{COOLSTORE_PROJECT}}** project. 209 | `*Click on 'Applications > Deployments'*` on the left-side bar. `*Click on 'web > Configuration tab'*`. 210 | You will see the warning about health checks, with a link to 211 | click in order to add them. `*Click on 'Add health checks'*` now. 212 | 213 | TIP: Instead of **Configuration** tab, you can directly click on **Actions** button on the top-right 214 | and then **Edit Health Checks** 215 | 216 | image:{% image_path health-web-details.png %}[Health Probes,900] 217 | 218 | You will want to `*click on both 'Add Readiness Probe' and 'Add Liveness Probe'*` and 219 | then fill them out as follows: 220 | 221 | Readiness Probe:: 222 | * Path: **/** 223 | * Initial Delay: **10** 224 | * Timeout: **1** 225 | 226 | Liveness Probe:: 227 | * Path: **/** 228 | * Initial Delay: **180** 229 | * Timeout: **1** 230 | 231 | image:{% image_path health-readiness.png %}[Readiness Probe,700] 232 | 233 | image:{% image_path health-liveness.png %}[Readiness Probe,700] 234 | 235 | `*Click on 'Save'*` and then `*click the 'Overview' button*` in the left navigation. You 236 | will notice that Web UI pod is getting restarted and it stays light blue 237 | for a while. This is a sign that the pod(s) have not yet passed their readiness 238 | checks and it turns blue when it's ready! 239 | 240 | image:{% image_path health-web-redeploy.png %}[Web Redeploy,740] 241 | 242 | === Monitoring Metrics 243 | 244 | Metrics are another important aspect of monitoring applications which is required in order to 245 | gain visibility into how the application behaves and particularly in identifying issues. 246 | 247 | OpenShift provides container metrics out-of-the-box and displays how much memory, cpu and network 248 | each container has been consuming over time. In the project overview, you can see three charts 249 | near each pod that shows the resource consumption by that pod. 250 | 251 | image:{% image_path health-metrics-brief.png %}[Container Metrics,740] 252 | 253 | `*Click on any of the pods*` (blue circle) which takes you to the pod details. `*Click on the 'Metrics' tab*` 254 | to see a more detailed view of the metrics charts. 255 | 256 | image:{% image_path health-metrics-detailed.png %}[Container Metrics,900] 257 | 258 | Well done! You are ready to move on to the next lab. 259 | -------------------------------------------------------------------------------- /images/Screen Shot 2018-07-25 at 09.55.19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/Screen Shot 2018-07-25 at 09.55.19.png -------------------------------------------------------------------------------- /images/bootstrap-che-build-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-build-palette.png -------------------------------------------------------------------------------- /images/bootstrap-che-convert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-convert.png -------------------------------------------------------------------------------- /images/bootstrap-che-create-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-create-workspace.png -------------------------------------------------------------------------------- /images/bootstrap-che-git-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-git-commit.png -------------------------------------------------------------------------------- /images/bootstrap-che-git-profile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-git-profile.png -------------------------------------------------------------------------------- /images/bootstrap-che-import-save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-import-save.png -------------------------------------------------------------------------------- /images/bootstrap-che-import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-import.png -------------------------------------------------------------------------------- /images/bootstrap-che-maven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-maven.png -------------------------------------------------------------------------------- /images/bootstrap-che-register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-register.png -------------------------------------------------------------------------------- /images/bootstrap-che-start-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-start-workspace.png -------------------------------------------------------------------------------- /images/bootstrap-che-terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-terminal.png -------------------------------------------------------------------------------- /images/bootstrap-che-wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-wide.png -------------------------------------------------------------------------------- /images/bootstrap-che-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/bootstrap-che-workspace.png -------------------------------------------------------------------------------- /images/catalog-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/catalog-service.png -------------------------------------------------------------------------------- /images/cd-github-empty-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-github-empty-repo.png -------------------------------------------------------------------------------- /images/cd-github-inventory-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-github-inventory-repo.png -------------------------------------------------------------------------------- /images/cd-github-new-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-github-new-repo.png -------------------------------------------------------------------------------- /images/cd-github-plus-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-github-plus-icon.png -------------------------------------------------------------------------------- /images/cd-github-settings-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-github-settings-link.png -------------------------------------------------------------------------------- /images/cd-github-webhook-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-github-webhook-add.png -------------------------------------------------------------------------------- /images/cd-gogs-empty-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-empty-repo.png -------------------------------------------------------------------------------- /images/cd-gogs-inventory-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-inventory-repo.png -------------------------------------------------------------------------------- /images/cd-gogs-new-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-new-repo.png -------------------------------------------------------------------------------- /images/cd-gogs-plus-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-plus-icon.png -------------------------------------------------------------------------------- /images/cd-gogs-settings-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-settings-link.png -------------------------------------------------------------------------------- /images/cd-gogs-signup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-signup.png -------------------------------------------------------------------------------- /images/cd-gogs-webhook-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-gogs-webhook-add.png -------------------------------------------------------------------------------- /images/cd-pipeline-inprogress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/cd-pipeline-inprogress.png -------------------------------------------------------------------------------- /images/codeready-account-information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-account-information.png -------------------------------------------------------------------------------- /images/codeready-authorize-access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-authorize-access.png -------------------------------------------------------------------------------- /images/codeready-command-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-command-build.png -------------------------------------------------------------------------------- /images/codeready-command-inject-catalog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-command-inject-catalog.png -------------------------------------------------------------------------------- /images/codeready-command-inject-gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-command-inject-gateway.png -------------------------------------------------------------------------------- /images/codeready-command-inject-inventory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-command-inject-inventory.png -------------------------------------------------------------------------------- /images/codeready-command-run-gateway-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-command-run-gateway-service.png -------------------------------------------------------------------------------- /images/codeready-commands-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-commands-build.png -------------------------------------------------------------------------------- /images/codeready-commands-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-commands-deploy.png -------------------------------------------------------------------------------- /images/codeready-convert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-convert.png -------------------------------------------------------------------------------- /images/codeready-create-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-create-workspace.png -------------------------------------------------------------------------------- /images/codeready-import-save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-import-save.png -------------------------------------------------------------------------------- /images/codeready-import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-import.png -------------------------------------------------------------------------------- /images/codeready-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-login.png -------------------------------------------------------------------------------- /images/codeready-maven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-maven.png -------------------------------------------------------------------------------- /images/codeready-oauth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-oauth.png -------------------------------------------------------------------------------- /images/codeready-register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-register.png -------------------------------------------------------------------------------- /images/codeready-run-gateway-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-run-gateway-100.png -------------------------------------------------------------------------------- /images/codeready-run-gateway-50-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-run-gateway-50-50.png -------------------------------------------------------------------------------- /images/codeready-run-gateway-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-run-gateway-service.png -------------------------------------------------------------------------------- /images/codeready-start-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-start-workspace.png -------------------------------------------------------------------------------- /images/codeready-terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-terminal.png -------------------------------------------------------------------------------- /images/codeready-workspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready-workspace.png -------------------------------------------------------------------------------- /images/codeready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/codeready.png -------------------------------------------------------------------------------- /images/config-psql-secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/config-psql-secret.png -------------------------------------------------------------------------------- /images/coolstore-arch-catalog-spring-boot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-catalog-spring-boot.png -------------------------------------------------------------------------------- /images/coolstore-arch-catalog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-catalog.png -------------------------------------------------------------------------------- /images/coolstore-arch-gateway-vertx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-gateway-vertx.png -------------------------------------------------------------------------------- /images/coolstore-arch-gateway.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-gateway.png -------------------------------------------------------------------------------- /images/coolstore-arch-inventory-thorntail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-inventory-thorntail.png -------------------------------------------------------------------------------- /images/coolstore-arch-inventory-vertx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-inventory-vertx.png -------------------------------------------------------------------------------- /images/coolstore-arch-inventory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-inventory.png -------------------------------------------------------------------------------- /images/coolstore-arch-webui-nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch-webui-nodejs.png -------------------------------------------------------------------------------- /images/coolstore-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-arch.png -------------------------------------------------------------------------------- /images/coolstore-pods-nodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-pods-nodb.png -------------------------------------------------------------------------------- /images/coolstore-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/coolstore-web.png -------------------------------------------------------------------------------- /images/debug-che-breakpoint-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-breakpoint-stop.png -------------------------------------------------------------------------------- /images/debug-che-breakpoint-values.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-breakpoint-values.png -------------------------------------------------------------------------------- /images/debug-che-breakpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-breakpoint.png -------------------------------------------------------------------------------- /images/debug-che-debug-config-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-debug-config-1.png -------------------------------------------------------------------------------- /images/debug-che-debug-config-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-debug-config-2.png -------------------------------------------------------------------------------- /images/debug-che-debug-config-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-debug-config-3.png -------------------------------------------------------------------------------- /images/debug-che-debug-config-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-debug-config-4.png -------------------------------------------------------------------------------- /images/debug-che-fabric8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-fabric8.png -------------------------------------------------------------------------------- /images/debug-che-resume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-resume.png -------------------------------------------------------------------------------- /images/debug-che-step-over.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-step-over.png -------------------------------------------------------------------------------- /images/debug-che-variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-variables.png -------------------------------------------------------------------------------- /images/debug-che-window-guide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-che-window-guide.png -------------------------------------------------------------------------------- /images/debug-coolstore-bug-fixed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-coolstore-bug-fixed.png -------------------------------------------------------------------------------- /images/debug-coolstore-bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-coolstore-bug.png -------------------------------------------------------------------------------- /images/debug-idea-add-breakpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-idea-add-breakpoint.png -------------------------------------------------------------------------------- /images/debug-idea-debug-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-idea-debug-config.png -------------------------------------------------------------------------------- /images/debug-idea-debug-vars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-idea-debug-vars.png -------------------------------------------------------------------------------- /images/debug-idea-debug-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-idea-debug-view.png -------------------------------------------------------------------------------- /images/debug-idea-edit-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-idea-edit-config.png -------------------------------------------------------------------------------- /images/debug-jbds-add-breakpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-jbds-add-breakpoint.png -------------------------------------------------------------------------------- /images/debug-jbds-debug-config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-jbds-debug-config.png -------------------------------------------------------------------------------- /images/debug-jbds-debug-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-jbds-debug-hover.png -------------------------------------------------------------------------------- /images/debug-jbds-debug-vars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-jbds-debug-vars.png -------------------------------------------------------------------------------- /images/debug-jbds-debug-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-jbds-debug-view.png -------------------------------------------------------------------------------- /images/debug-jbds-import-maven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/debug-jbds-import-maven.png -------------------------------------------------------------------------------- /images/eclipse-che-commands-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/eclipse-che-commands-build.png -------------------------------------------------------------------------------- /images/eclipse-che-commands-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/eclipse-che-commands-deploy.png -------------------------------------------------------------------------------- /images/eclipse-che-commands-run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/eclipse-che-commands-run.png -------------------------------------------------------------------------------- /images/fault-autoscale-metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-autoscale-metrics.png -------------------------------------------------------------------------------- /images/fault-autoscale-web.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-autoscale-web.gif -------------------------------------------------------------------------------- /images/fault-autoscale-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-autoscale-web.png -------------------------------------------------------------------------------- /images/fault-circuit-breaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-circuit-breaker.png -------------------------------------------------------------------------------- /images/fault-coolstore-no-cb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-coolstore-no-cb.png -------------------------------------------------------------------------------- /images/fault-coolstore-with-cb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-coolstore-with-cb.png -------------------------------------------------------------------------------- /images/fault-scale-up-vs-out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-scale-up-vs-out.png -------------------------------------------------------------------------------- /images/fault-scale-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/fault-scale-up.png -------------------------------------------------------------------------------- /images/gateway-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/gateway-service.png -------------------------------------------------------------------------------- /images/health-liveness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/health-liveness.png -------------------------------------------------------------------------------- /images/health-metrics-brief.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/health-metrics-brief.png -------------------------------------------------------------------------------- /images/health-metrics-detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/health-metrics-detailed.png -------------------------------------------------------------------------------- /images/health-readiness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/health-readiness.png -------------------------------------------------------------------------------- /images/health-web-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/health-web-details.png -------------------------------------------------------------------------------- /images/health-web-redeploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/health-web-redeploy.png -------------------------------------------------------------------------------- /images/inventory-service-test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/inventory-service-test.png -------------------------------------------------------------------------------- /images/inventory-service-vertx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/inventory-service-vertx.png -------------------------------------------------------------------------------- /images/inventory-service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/inventory-service.png -------------------------------------------------------------------------------- /images/inventory-thorntail-new-class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/inventory-thorntail-new-class.png -------------------------------------------------------------------------------- /images/kiali-abtesting-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-abtesting-100.png -------------------------------------------------------------------------------- /images/kiali-abtesting-50-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-abtesting-50-50.png -------------------------------------------------------------------------------- /images/kiali-graph-param.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-graph-param.png -------------------------------------------------------------------------------- /images/kiali-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-graph.png -------------------------------------------------------------------------------- /images/kiali-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-login.png -------------------------------------------------------------------------------- /images/kiali-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-logo.png -------------------------------------------------------------------------------- /images/kiali-trace-detail-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-trace-detail-view.png -------------------------------------------------------------------------------- /images/kiali-traces-param.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-traces-param.png -------------------------------------------------------------------------------- /images/kiali-traces-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/kiali-traces-view.png -------------------------------------------------------------------------------- /images/microprofile-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/microprofile-logo.png -------------------------------------------------------------------------------- /images/nodejs-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/nodejs-logo.png -------------------------------------------------------------------------------- /images/nodejs-webui-component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/nodejs-webui-component.png -------------------------------------------------------------------------------- /images/run-icon-springboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/run-icon-springboot.png -------------------------------------------------------------------------------- /images/run-icon-thorntail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/run-icon-thorntail.png -------------------------------------------------------------------------------- /images/service-catalog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/service-catalog.png -------------------------------------------------------------------------------- /images/servicemesh-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/servicemesh-architecture.png -------------------------------------------------------------------------------- /images/spring-boot-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/spring-boot-logo.png -------------------------------------------------------------------------------- /images/springboot-catalog-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/springboot-catalog-arch.png -------------------------------------------------------------------------------- /images/springboot-catalog-component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/springboot-catalog-component.png -------------------------------------------------------------------------------- /images/springboot-catalog-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/springboot-catalog-project.png -------------------------------------------------------------------------------- /images/springboot-catalog-service-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/springboot-catalog-service-root.png -------------------------------------------------------------------------------- /images/springboot-che-preview-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/springboot-che-preview-browser.png -------------------------------------------------------------------------------- /images/springboot-che-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/springboot-che-stop.png -------------------------------------------------------------------------------- /images/thorntail-inventory-codeready-preview-url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-inventory-codeready-preview-url.png -------------------------------------------------------------------------------- /images/thorntail-inventory-codeready-run-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-inventory-codeready-run-palette.png -------------------------------------------------------------------------------- /images/thorntail-inventory-codeready-run-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-inventory-codeready-run-stop.png -------------------------------------------------------------------------------- /images/thorntail-inventory-component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-inventory-component.png -------------------------------------------------------------------------------- /images/thorntail-inventory-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-inventory-project.png -------------------------------------------------------------------------------- /images/thorntail-inventory-service-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-inventory-service-root.png -------------------------------------------------------------------------------- /images/thorntail-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/thorntail-logo.png -------------------------------------------------------------------------------- /images/vertx-event-loop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-event-loop.jpg -------------------------------------------------------------------------------- /images/vertx-event-loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-event-loop.png -------------------------------------------------------------------------------- /images/vertx-gateway-component.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-gateway-component.png -------------------------------------------------------------------------------- /images/vertx-gateway-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-gateway-project.png -------------------------------------------------------------------------------- /images/vertx-gateway-service-root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-gateway-service-root.png -------------------------------------------------------------------------------- /images/vertx-inventory-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-inventory-project.png -------------------------------------------------------------------------------- /images/vertx-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/vertx-logo.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-arch.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-build.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-deployed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-deployed.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-new-class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-new-class.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-preview-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-preview-browser.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-preview-url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-preview-url.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-run-palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-run-palette.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-che-run-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-che-run-stop.png -------------------------------------------------------------------------------- /images/wfswarm-inventory-project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openshift-labs/cloud-native-guides/6cd1585cb436834d657912a1f7a9313ad9974eae/images/wfswarm-inventory-project.png -------------------------------------------------------------------------------- /introduction.adoc: -------------------------------------------------------------------------------- 1 | == Introduction 2 | 3 | _2 MINUTE EXERCISE_ 4 | 5 | In this workshop you will learn how to develop and deploy a microservices based application. 6 | 7 | The overall architecture of the application that you will deploy is the following: 8 | 9 | image:{% image_path coolstore-arch.png %}[API Gateway Pattern, 400] 10 | 11 | During the various steps of the the workshop you will use CodeReady Workspaces, an online IDE that is running on Red Hat OpenShift to write, test and deploy these services: 12 | 13 | * **Catalog Service** exposes using a REST API content of a catalog stored in a relational database 14 | * **Inventory Service** exposes using a REST API the inventory stored in a relational database 15 | * **Gateway Service** calls the **Catalog Service** and **Inventory Service** in an efficient way 16 | * **WebUI Service** calls **Gateway Service** to retrieve all the informations. 17 | 18 | The outcome is an online store with a catalog of product items and an inventory of stock: 19 | 20 | image:{% image_path coolstore-web.png %}[CoolStore Shop,840] 21 | 22 | In addition to the application code, you will learn how to deploy the various services to OpenShift and how to use it to route the trafic to these services and monitor them. 23 | 24 | You will also have the opportunity to look at some optional steps such as debugging, continuous delivery, externalized configuration and more. 25 | 26 | Let's start the workshop with the discovery of OpenShift and CodeReady Workspaces. 27 | -------------------------------------------------------------------------------- /inventory-deployment.adoc: -------------------------------------------------------------------------------- 1 | == Deploying the Inventory Service 2 | 3 | _10 MINUTE EXERCISE_ 4 | 5 | In this lab you will learn about building and deploying a microservice based on Java/Maven on OpenShift. 6 | The **Inventory Service** is part of the Cool Store architecture to provide the quantity (hence the availability too) of a given product by ID. 7 | 8 | image:{% image_path coolstore-arch-inventory-thorntail.png %}[CoolStore Architecture,400] 9 | 10 | === What is Thorntail? 11 | 12 | [sidebar] 13 | -- 14 | image:{% image_path thorntail-logo.png %}[Thorntail, 300] 15 | image:{% image_path microprofile-logo.png %}[Microprofile, 400] 16 | 17 | Java EE applications are traditionally created as an *ear* or *war* archive including all 18 | dependencies and deployed in an application server. Multiple Java EE applications can and 19 | were typically deployed in the same application server. This model is well understood in 20 | development teams and has been used over the past several years. 21 | 22 | https://thorntail.io/[Thorntail^] offers an innovative approach to packaging and running Java EE applications by 23 | packaging them with just enough of the Java EE server runtime to be able to run them directly 24 | on the JVM using `*java -jar`. For more details on various approaches to packaging Java 25 | applications, read https://developers.redhat.com/blog/2017/08/24/the-skinny-on-fat-thin-hollow-and-uber[this blog post^]. 26 | 27 | https://thorntail.io/[Thorntail^] is based on WildFly and it's compatible with 28 | https://microprofile.io/[MicroProfile^], which is a community effort to standardize the subset of Java EE standards 29 | such as JAX-RS, CDI and JSON-P that are useful for building microservices applications. 30 | 31 | Since https://thorntail.io/[Thorntail^] is based on Java EE standards, it significantly simplifies refactoring 32 | existing Java EE applications to microservices and allows much of the existing code-base to be 33 | reused in the new services. 34 | -- 35 | 36 | === Thorntail Maven Project 37 | 38 | The **inventory-thorntail** project has the following structure which shows the components of 39 | the Thorntail project laid out in different subdirectories according to Maven best practices: 40 | 41 | image:{% image_path thorntail-inventory-project.png %}[Inventory Project,300] 42 | 43 | === Deploy Inventory Service on OpenShift 44 | 45 | Now it’s time to build and deploy our service on OpenShift. 46 | 47 | OpenShift {{OPENSHIFT_DOCS_BASE}}/architecture/core_concepts/builds_and_image_streams.html#source-build[Source-to-Image (S2I)^] 48 | feature can be used to build a container image from a git repository. OpenShift S2I uses the https://access.redhat.com/documentation/en-us/red_hat_jboss_middleware_for_openshift/3/html/red_hat_java_s2i_for_openshift[supported OpenJDK container image^] to build the final container image of the 49 | **Inventory Service** by building the Thorntail uber-jar from source code (build strategy **'Source'**), using Maven, to the OpenShift platform. 50 | 51 | To build and deploy the **Inventory Service** on OpenShift using the *fabric8* maven plugin, 52 | which is already configured in CodeReady Workspaces, `*right click on 'inventory-thorntail'*` project in the project explorer 53 | then, `*click on 'Commands > Deploy > fabric8:deploy'*` 54 | 55 | image:{% image_path codeready-commands-deploy.png %}[Fabric8 Deploy,600] 56 | 57 | [TIP] 58 | .fabric8:deploy 59 | ==== 60 | It will cause the following to happen: 61 | 62 | * The Inventory uber-jar is built using Thorntail 63 | * A container image is built on OpenShift containing the Inventory uber-jar and JDK 64 | * All necessary objects are created within the OpenShift project to deploy the Inventory service 65 | ==== 66 | 67 | Once this completes, your project should be up and running. You can see the expose DNS url for the **Inventory Service** in the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^] or using OpenShift CLI. 68 | 69 | ---- 70 | $ oc get routes 71 | 72 | NAME HOST/PORT PATH SERVICES PORT TERMINATION 73 | inventory inventory-{{COOLSTORE_PROJECT}}.{{APPS_HOSTNAME_SUFFIX}} inventory 8080 None 74 | ---- 75 | 76 | `*Click on the OpenShift Route of _'Inventory Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]. 77 | 78 | image:{% image_path inventory-service.png %}[Inventory Service,500] 79 | 80 | Then `*click on 'Test it'*`. You should have the following output: 81 | 82 | [source,json] 83 | ---- 84 | {"itemId":"329299","quantity":35} 85 | ---- 86 | 87 | Well done! You are ready to move on to the next lab. 88 | -------------------------------------------------------------------------------- /service-mesh.adoc: -------------------------------------------------------------------------------- 1 | == Microservice Tracing with Service Mesh 2 | 3 | _20 MINUTE EXERCISE_ 4 | 5 | In this lab you will enable tracing and monitoring of your backend services using Service Mesh. 6 | 7 | [sidebar] 8 | .OpenShift Service Mesh 9 | -- 10 | The term **Service Mesh** describes the network of microservices that make up applications in a distributed microservice architecture and the interactions between those microservices. As a service mesh grows in size and complexity, it can become harder to understand and manage. 11 | 12 | **Red Hat OpenShift Service Mesh** is a platform that provides behavioral insight and operational control over the **Service Mesh**, providing a uniform way to connect, secure, and monitor microservice applications. 13 | 14 | Based on the open source https://istio.io/[Istio^] project, **Red Hat OpenShift Service Mesh** adds a transparent layer on existing distributed applications without requiring any changes to the service code. You add Red Hat OpenShift Service Mesh support to services by deploying a special sidecar proxy throughout your environment that intercepts all network communication between microservices. You configure and manage the service mesh using the control plane features. 15 | 16 | Red Hat OpenShift Service Mesh provides an easy way to create a network of deployed services that provides discovery, load balancing, service-to-service authentication, failure recovery, metrics, and monitoring. A service mesh also provides more complex operational functionality, including A/B testing, canary releases, rate limiting, access control, and end-to-end authentication. 17 | 18 | Red Hat OpenShift Service Mesh is logically split into a data plane and a control plane: 19 | 20 | * The **data plane** is composed of a set of intelligent proxies deployed as sidecars. These proxies intercept and control all inbound and outbound network communication between microservices in the service mesh; sidecar proxies also communicate with Mixer, the general-purpose policy and telemetry hub. 21 | 22 | * The **control plane** is responsible for managing and configuring proxies to route traffic, and configuring Mixers to enforce policies and collect telemetry. 23 | 24 | image:{% image_path servicemesh-architecture.png %}[Service Mesh Architecture,400] 25 | 26 | The components that make up the data plane and the control plane are: 27 | 28 | * **Envoy proxy** - is the data plane component that intercepts all inbound and outbound traffic for all services in the service mesh. Envoy is deployed as a sidecar to the relevant service in the same pod. 29 | * **Mixer** - is the control plane component responsible responsible for enforcing access control and usage policies (such as authorization, rate limits, quotas, authentication, request tracing) and collecting telemetry data from the Envoy proxy and other services. 30 | * **Pilot** - is the control plane component responsible for configuring the proxies at runtime. Pilot provides service discovery for the Envoy sidecars, traffic management capabilities for intelligent routing (for example, A/B tests or canary deployments), and resiliency (timeouts, retries, and circuit breakers). 31 | * **Citadel** - is the control plane component responsible for certificate issuance and rotation. Citadel provides strong service-to-service and end-user authentication with built-in identity and credential management. You can use Citadel to upgrade unencrypted traffic in the service mesh. Using Citadel, operators can enforce policies based on service identity rather than on network controls. 32 | 33 | -- 34 | 35 | === Enabling Service Mesh to Catalog Service 36 | 37 | OpenShift Service Mesh automatically injects the sidecar into the Pod by specifying *_sidecar.istio.io/inject:true_* annotation in the DeploymentConfig. 38 | 39 | From the Terminal console, `*execute the following commands*`: 40 | 41 | ---- 42 | oc rollout pause dc/catalog # <1> 43 | oc set probe dc/catalog --readiness --liveness --remove # <2> 44 | oc patch dc/catalog --patch '{"spec": {"template": {"metadata": {"annotations": {"sidecar.istio.io/inject": "true"}}}}}' # <3> 45 | oc patch dc/catalog --patch '{"spec": {"template": {"spec": {"containers": [{"name": "spring-boot", "command" : ["/bin/bash"], "args": ["-c", "until $(curl -o /dev/null -s -I -f http://localhost:15000); do echo \"Waiting for Istio Sidecar...\"; sleep 1; done; sleep 10; /usr/local/s2i/run"]}]}}}}' # <4> 46 | oc rollout resume dc/catalog # <5> 47 | ---- 48 | <1> Pause the deployment 49 | <2> Remove all existing probes 50 | <3> Define the annotation to automatically inject an Istio sidecar 51 | <4> Wait for the proxy to be up and running before starting the application 52 | <5> Resume the deployment 53 | 54 | [TIP] 55 | .Other Option 56 | ==== 57 | As an alternative way, you can use the *_Commands Palette_* to enable Service Mesh capability. 58 | In CodeReady Workspaces, click on *_'Commands Palette'_* and click on **'SERVICE MESH > Catalog Service: Inject Istio Sidecar'** 59 | 60 | image:{% image_path codeready-command-inject-catalog.png %}[Inject Sidecar^,200] 61 | ==== 62 | 63 | To confirm that the application is successfully deployed, `*run this following command*`: 64 | 65 | ---- 66 | $ oc get pods -lapp=catalog,deploymentconfig=catalog 67 | NAME READY STATUS RESTARTS AGE 68 | catalog-3-ppj47 2/2 Running 1 8m 69 | ---- 70 | 71 | The status should be **Running** and there should be **2/2** pods in the **Ready** column. 72 | Wait few seconds that the application restarts then `*Click on the OpenShift Route of _'Catalog Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^] 73 | and ensure the proper functioning of the service. 74 | 75 | === Enabling Service Mesh to Inventory Service 76 | 77 | Repeat the above step to enable Service Mesh to Inventory Service. 78 | 79 | ---- 80 | oc rollout pause dc/inventory 81 | oc set probe dc/inventory --readiness --liveness --remove 82 | oc patch dc/inventory --patch '{"spec": {"template": {"metadata": {"annotations": {"sidecar.istio.io/inject": "true"}}}}}' 83 | oc patch dc/inventory --patch '{"spec": {"template": {"spec": {"containers": [{"name": "thorntail-v2", "command" : ["/bin/bash"], "args": ["-c", "until $(curl -o /dev/null -s -I -f http://localhost:15000); do echo \"Waiting for Istio Sidecar...\"; sleep 1; done; sleep 10; /usr/local/s2i/run"]}]}}}}' 84 | oc rollout resume dc/inventory 85 | ---- 86 | 87 | [TIP] 88 | .Other Option 89 | ==== 90 | As an alternative way, you can use the *_Commands Palette_* to enable Service Mesh capability. 91 | In CodeReady Workspaces, click on *_'Commands Palette'_* and click on **'SERVICE MESH > Inventory Service: Inject Istio Sidecar'** 92 | 93 | image:{% image_path codeready-command-inject-inventory.png %}[Inject Sidecar^,200] 94 | ==== 95 | 96 | To confirm that the application is successfully deployed, `*run this following command*`: 97 | 98 | ---- 99 | $ oc get pods -lapp=inventory,deploymentconfig=inventory 100 | NAME READY STATUS RESTARTS AGE 101 | inventory-2-k6ftf 2/2 Running 1 3m 102 | ---- 103 | 104 | The status should be **Running** and there should be **2/2** pods in the **Ready** column. 105 | Wait few seconds that the application restarts then `*Click on the OpenShift Route of _'Inventory Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^] 106 | and ensure the proper functioning of the service. 107 | 108 | === Enabling Service Mesh to Gateway Service 109 | 110 | Repeat the above step to enable Service Mesh to Gateway Service. 111 | 112 | ---- 113 | oc rollout pause dc/gateway 114 | oc set probe dc/gateway --readiness --liveness --remove 115 | oc patch dc/gateway --patch '{"spec": {"template": {"metadata": {"annotations": {"sidecar.istio.io/inject": "true"}}}}}' 116 | oc patch dc/gateway --patch '{"spec": {"template": {"spec": {"containers": [{"name": "vertx", "command" : ["/bin/bash"], "args": ["-c", "until $(curl -o /dev/null -s -I -f http://localhost:15000); do echo \"Waiting for Istio Sidecar...\"; sleep 1; done; sleep 10; /usr/local/s2i/run"]}]}}}}' 117 | oc rollout resume dc/gateway 118 | ---- 119 | 120 | [TIP] 121 | .Other Option 122 | ==== 123 | As an alternative way, you can use the *_Commands Palette_* to enable Service Mesh capability. 124 | In CodeReady Workspaces, click on *_'Commands Palette'_* and click on **'SERVICE MESH > Gateway Service: Inject Istio Sidecar'** 125 | 126 | image:{% image_path codeready-command-inject-gateway.png %}[Inject Sidecar^,200] 127 | ==== 128 | 129 | To confirm that the application is successfully deployed, `*run this following command*`: 130 | 131 | ---- 132 | $ oc get pods -lapp=gateway,deploymentconfig=gateway 133 | NAME READY STATUS RESTARTS AGE 134 | gateway-2-zqsmn 2/2 Running 1 1m 135 | ---- 136 | 137 | The status should be **Running** and there should be **2/2** pods in the **Ready** column. 138 | Wait few seconds that the application restarts then `*Click on the OpenShift Route of _'Gateway Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^] 139 | and ensure the proper functioning of the service. 140 | 141 | === Controlling Ingress Traffic 142 | 143 | In a OpenShift environment, the OpenShift Route is used to specify services that should be exposed outside the cluster. In an Istio service mesh, a better approachis to use a different configuration model, namely *_Istio Gateway_*. 144 | 145 | * A **Gateway** describes a load balancer operating at the edge of the mesh receiving incoming or outgoing HTTP/TCP connections. The specification describes a set of ports that should be exposed, the type of protocol to use, SNI configuration for the load balancer, etc. 146 | * A **VirtualService** defines a set of traffic routing rules to apply when a host is addressed. Each routing rule defines matching criteria for traffic of a specific protocol. If the traffic is matched, then it is sent to a named destination service (or subset/version of it) defined in the registry. 147 | 148 | In the Terminal, `*execute the following command*` to create an *_Istio Gateway_* and a *_VirtualService_* for the *_Gateway Service_* 149 | 150 | ---- 151 | oc create -f /projects/labs/gateway-vertx/openshift/istio-gateway.yml 152 | sed s/COOLSTORE_PROJECT/{{COOLSTORE_PROJECT}}/g /projects/labs/gateway-vertx/openshift/virtualservice.yml | oc create -f - 153 | ---- 154 | 155 | To confirm that the *_Istio Gateway_* is properly configured, 156 | 157 | ---- 158 | $ curl -o /dev/null -s -w "%{http_code}\n" http://istio-ingressgateway-istio-system.{{APPS_HOSTNAME_SUFFIX}}/{{COOLSTORE_PROJECT}}/api/products 159 | 200 160 | ---- 161 | 162 | The result should be *_200_* (Successful). 163 | 164 | === Updating the WebUI to use the Istio Gateway 165 | 166 | `*Issue the following command*` to configure the *_WebUI Service_* to use the *_Istio Gateway_* instead of the *_OpenShift Route_*: 167 | 168 | ---- 169 | $ oc set env dc/web COOLSTORE_GW_ENDPOINT=http://istio-ingressgateway-istio-system.{{APPS_HOSTNAME_SUFFIX}}/{{COOLSTORE_PROJECT}} 170 | ---- 171 | 172 | === Testing the application 173 | 174 | Point your browser at the Web UI route url. You should be able to see the CoolStore with all products and their inventory status. 175 | 176 | IMPORTANT: Refresh your browser several times to generate traffic. 177 | 178 | [sidebar] 179 | -- 180 | image:{% image_path kiali-logo.png %}[Kiali,400] 181 | 182 | A Microservice Architecture breaks up the monolith into many smaller pieces that are composed together. Patterns to secure the communication between services like fault tolerance (via timeout, retry, circuit breaking, etc.) have come up as well as distributed tracing to be able to see where calls are going. 183 | 184 | A service mesh can now provide these services on a platform level and frees the application writers from those tasks. Routing decisions are done at the mesh level. 185 | 186 | https://www.kiali.io[Kiali^] works with Istio, in OpenShift or Kubernetes, to visualize the service mesh topology, to provide visibility into features like circuit breakers, request rates and more. It offers insights about the mesh components at different levels, from abstract Applications to Services and Workloads. 187 | -- 188 | 189 | === Observability with Kiali 190 | 191 | Kiali provides an interactive graph view of your namespace in real time, being able to display the interactions at several levels (applications, versions, workloads), with contextual information and charts on the selected graph node or edge. 192 | 193 | First, you need to access to Kiali. 194 | `*Launch a browser and navigate to {{ KIALI_URL }}[Kiali Console^]*`. 195 | You should see the Kiali console login screen. 196 | 197 | image:{% image_path kiali-login.png %}[Kiali- Log In,500] 198 | 199 | Log in to the Kiali console as `*{{OPENSHIFT_USER}}/{{OPENSHIFT_PASSWORD}}*` 200 | 201 | After you log in, `*click on the 'Graph' link*` in the left navigation and enter the following configuration in the drop down menus: 202 | 203 | * Namespace: **{{COOLSTORE_PROJECT}}** 204 | * Display: **'Traffic Animation'** check 205 | 206 | image:{% image_path kiali-graph-param.png %}[Kiali- Graph,300] 207 | 208 | The outcome is a graph with all the microservices, connected by the requests going through them. You can see how the services interact with each other. 209 | 210 | image:{% image_path kiali-graph.png %}[Kiali- Graph,700] 211 | 212 | WARNING: Please ignore the error for the *_Gateway Service_*. 213 | It is because the *_Cart Service_* is missing and its deployment is not a part of this lab. 214 | 215 | === Tracing with Kiali and Jaeger 216 | 217 | [sidebar] 218 | .Jaeger, Distributed Tracing 219 | -- 220 | Jaeger, inspired by Dapper and OpenZipkin, is a distributed tracing system released as open source by Uber Technologies. It is used for monitoring and troubleshooting microservices-based distributed systems, including: 221 | 222 | * Distributed context propagation 223 | * Distributed transaction monitoring 224 | * Root cause analysis 225 | * Service dependency analysis 226 | * Performance / latency optimization 227 | 228 | https://www.kiali.io/[Kiali^] includes https://www.jaegertracing.io/[Jaeger Tracing^] to provide distributed tracing out of the box. 229 | -- 230 | 231 | IMPORTANT: Because of certificates issues, you need first to access the main {{ JAEGER_URL }}[Jaeger Console^] to use it through Kiali. 232 | 233 | From the {{ KIALI_URL }}[Kiali Console^], `*click on the _Distributed Tracing_ link*` in the left navigation and enter the following configuration in the drop down menus: 234 | 235 | * Select a Namespace: *_{{COOLSTORE_PROJECT}}_* 236 | * Select a Service: *_gateway_* 237 | 238 | image:{% image_path kiali-traces-param.png %}[Kiali- Traces View,500] 239 | 240 | Then `*click on the 'Search' button*` on the right corner. 241 | 242 | image:{% image_path kiali-traces-view.png %}[Kiali- Traces View,700] 243 | 244 | Let’s `*click on one of trace title bar*`. 245 | 246 | image:{% image_path kiali-trace-detail-view.png %}[Kiali- Trace Detail View,700] 247 | 248 | That's all for this lab! You are ready to move on to the next lab. 249 | -------------------------------------------------------------------------------- /webui-deployment.adoc: -------------------------------------------------------------------------------- 1 | == Web UI with Node.js and AngularJS 2 | 3 | _10 MINUTE EXERCISE_ 4 | 5 | In this lab you will learn about Node.js and will deploy the Node.js and Angular-based 6 | web frontend for the CoolStore online shop which uses the API Gateway services you deployed 7 | in previous labs. 8 | 9 | image:{% image_path coolstore-arch-webui-nodejs.png %}[API Gateway Pattern,400] 10 | 11 | === What is Node.js? 12 | 13 | [sidebar] 14 | -- 15 | image:{% image_path nodejs-logo.png %}[Node.js, 400] 16 | 17 | https://nodejs.org/[Node.js^] is an open source, cross-platform runtime environment for developing server-side 18 | applications using JavaScript. https://nodejs.org/[Node.js^] has an event-driven architecture capable of 19 | non-blocking I/O. These design choices aim to optimize throughput and scalability in 20 | Web applications with many input/output operations, as well as for real-time web applications. 21 | 22 | https://nodejs.org/[Node.js^] non-blocking architecture allows applications to process large number of 23 | requests (tens of thousands) using a single thread which makes it desirable choice for building 24 | scalable web applications. 25 | -- 26 | 27 | === Deploy Web UI on OpenShift 28 | 29 | The Web UI is built using Node.js for server-side JavaScript and AngularJS for client-side 30 | JavaScript. Let's deploy it on OpenShift using the certified Node.js container image available 31 | in OpenShift. 32 | 33 | In the previous labs, you used the OpenShift 34 | {{OPENSHIFT_DOCS_BASE}}/architecture/core_concepts/builds_and_image_streams.html#source-build[Source-to-Image (S2I)^] 35 | feature via the https://maven.fabric8.io[Fabric8 Maven Plugin^] to build a container image from the 36 | source code on your laptop. In this lab, you will still use S2I but instead instruct OpenShift 37 | to obtain the application code directly from the source repository and build and deploy a 38 | container image of it. 39 | 40 | The source code for the Node.js Web front-end is available in this Git repository: 41 | 42 | <{{WEB_NODEJS_GIT_REPO}}> 43 | 44 | Use the OpenShift CLI command to create a new build and deployment for the Web component: 45 | 46 | * Name: **web** 47 | * Version: **Nodejs 8** 48 | * Git Repository URL: **{{LABS_GIT_REPO}}** 49 | * Context Dir: **web-nodejs** 50 | * Labels: **app=web,version=1.0** 51 | 52 | TIP: Feeling adventurous? Build and deploy the Web front-end via the OpenShift Web Console 53 | instead. To give you a hint, start by clicking on **Add to project** within the 54 | **{{COOLSTORE_PROJECT}}** project and pick **JavaScript** and then **Node.js** in the service 55 | catalog. Don't forget to click on **advanced options** and set **Context Dir** to **web-nodejs** 56 | which is the sub-folder of the Git repository where the source code for Web resides. 57 | 58 | ---- 59 | $ oc new-app nodejs:8~{{LABS_GIT_REPO}} \ 60 | --context-dir=web-nodejs \ 61 | --name=web \ 62 | --labels=app=web,version=1.0 63 | ---- 64 | 65 | The ***--context-dir*** option specifies the sub-directly of the Git repository which contains 66 | the source code for the application to be built and deployed. The ***--labels*** allows 67 | assigning arbitrary key-value labels to the application objects in order to make it easier to 68 | find them later on when you have many applications in the same project. 69 | 70 | A build gets created and starts building the Node.js Web UI container image. You can see the build 71 | logs using OpenShift Web Console or OpenShift CLI: 72 | 73 | ---- 74 | $ oc logs -f bc/web 75 | ---- 76 | 77 | The ***-f*** option is to follow the logs as the build progresses. After the building the Node.js Web UI 78 | completes, it gets pushed into the internal image registry in OpenShift and then deployed within 79 | your project. 80 | 81 | In order to access the Web UI from outside (e.g. from a browser), it needs to get added to the load 82 | balancer. Run the following command to add the Web UI service to the built-in HAProxy load balancer 83 | in OpenShift. 84 | 85 | ---- 86 | $ oc expose svc/web 87 | $ oc get route web 88 | ---- 89 | 90 | `*Click on the OpenShift Route of _'Web Service'_*` from the {{OPENSHIFT_CONSOLE_URL}}[OpenShift Web Console^]. 91 | You should be able to see the CoolStore with all products and their inventory status. 92 | 93 | image:{% image_path coolstore-web.png %}[CoolStore Shop,840] 94 | 95 | Well done! You are ready to move on to the next lab. 96 | --------------------------------------------------------------------------------