From 1701e700b08c4c850663ed1c43ca16697e291f18 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 09:17:09 +0000 Subject: [PATCH 01/19] TELCODOCS-2229 updating retail pattern docs --- content/patterns/retail/_index.adoc | 33 +++ content/patterns/retail/application.adoc | 59 ++++++ content/patterns/retail/cluster-sizing.adoc | 199 ++++++++++++++++++ content/patterns/retail/components.adoc | 99 +++++++++ content/patterns/retail/getting-started.adoc | 14 ++ .../retail/ideas-for-customization.adoc | 1 + content/patterns/retail/store.adoc | 76 +++++++ content/patterns/retail/troubleshooting.adoc | 3 + 8 files changed, 484 insertions(+) create mode 100644 content/patterns/retail/_index.adoc create mode 100644 content/patterns/retail/application.adoc create mode 100644 content/patterns/retail/cluster-sizing.adoc create mode 100644 content/patterns/retail/components.adoc create mode 100644 content/patterns/retail/getting-started.adoc create mode 100644 content/patterns/retail/ideas-for-customization.adoc create mode 100644 content/patterns/retail/store.adoc create mode 100644 content/patterns/retail/troubleshooting.adoc diff --git a/content/patterns/retail/_index.adoc b/content/patterns/retail/_index.adoc new file mode 100644 index 000000000..7dcaa84f7 --- /dev/null +++ b/content/patterns/retail/_index.adoc @@ -0,0 +1,33 @@ +--- +title: Retail +date: 2022-12-08 +tier: tested +summary: This pattern demonstrates a pattern that models the store side of a retail application. +rh_products: +- Red Hat OpenShift Container Platform +- Red Hat Advanced Cluster Management +- Red Hat AMQ +industries: +- Retail +aliases: /retail/ +# uncomment once this exists +# pattern_logo: retail.png +links: + install: getting-started + help: https://groups.google.com/g/validatedpatterns + bugs: https://github.com/validatedpatterns/retail/issues +# uncomment once this exists +ci: retail +--- + +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY +include::modules/comm-attributes.adoc[] + +include::modules/retail-about.adoc[leveloffset=+1] + +include::modules/retail-architecture.adoc[leveloffset=+1] + + + diff --git a/content/patterns/retail/application.adoc b/content/patterns/retail/application.adoc new file mode 100644 index 000000000..02b287d09 --- /dev/null +++ b/content/patterns/retail/application.adoc @@ -0,0 +1,59 @@ +== Demonstrating Retail example applications + +=== Background + +Up until now the Retail validated pattern has focused primarily on +successfully deploying the architectural pattern. Now it is time to see +the actual applications running as we have deployed them. + +If you have already deployed the hub cluster, then you have already seen +several applications deployed in the OpenShift GitOps console. If you +haven’t done this then we recommend you deploy the hub after you have +setup the Quay repositories described below. + +=== Ordering Items at the Coffeeshop + +The easiest way to get to the coffeeshop store page is from the +OpenShift Console Menu Landing Page entry: + +link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu]] + +Clicking on the Quarkus Coffeeshop Landing Page link will bring you to +this page: + +link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page]] + +And clicking on either the "`Store Web Page`" or "`TEST Store Web Page`" +links will bring you to a screen that looks like this: + +link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page]] + +_NOTE_: The applications are initially identical. The "`TEST`" site is +deployed to the `+quarkuscoffeeshop-demo+` namespace; the regular Store +site is deployed to the `+quarkuscoffeeshop-store+` namespace. + +Each store requires supporting services, in PostgreSQL and Kafka. In our +pattern, PostgreSQL is provided by the Crunchy PostgreSQL operator, and +Kafka is provided by the Red Hat AMQ Streams operator. Each instance, +the regular instance and the TEST instance, has its own instance of each +of these supporting services it uses. + +To order, click on the "`Place an Order`" button on the front page. The +menu should look like this: + +link:/images/retail/retail-v1-store-web-menu.png[image:/images/retail/retail-v1-store-web-menu.png[retail-v1-store-web-menu]] + +Click the "`Add`" button next to a menu item; the item name will appear. +Add a name for the order: + +link:/images/retail/retail-v1-order-p1.png[image:/images/retail/retail-v1-order-p1.png[retail-v1-order-p1]] + +You can add as many orders as you want. On your last item, click the +"`Place Order`" button on the item dialog: + +link:/images/retail/retail-v1-place-order.png[image:/images/retail/retail-v1-place-order.png[retail-v1-place-order]] + +As the orders are serviced by the barista and kitchen services, you can +see their status in the "`Orders`" section of the page: + +link:/images/retail/retail-v1-orders-status.png[image:/images/retail/retail-v1-orders-status.png[retail-v1-orders-status]] diff --git a/content/patterns/retail/cluster-sizing.adoc b/content/patterns/retail/cluster-sizing.adoc new file mode 100644 index 000000000..f89eef60e --- /dev/null +++ b/content/patterns/retail/cluster-sizing.adoc @@ -0,0 +1,199 @@ +== OpenShift Cluster Sizing for the Retail Pattern + +=== Tested Platforms + +The *retail* pattern has been tested in the following Certified Cloud +Providers. + +[cols="<,<",options="header",] +|=== +|*Certified Cloud Providers* |4.10 +|Amazon Web Services |:heavy_check_mark: +|Microsoft Azure | +|Google Cloud Platform | +|=== + +=== General OpenShift Minimum Requirements + +OpenShift 4 has the following minimum requirements for sizing of nodes: + +* *Minimum 4 vCPU* (additional are strongly recommended). +* *Minimum 16 GB RAM* (additional memory is strongly recommended, +especially if etcd is colocated on masters). +* *Minimum 40 GB* hard disk space for the file system containing /var/. +* *Minimum 1 GB* hard disk space for the file system containing +/usr/local/bin/. + +There are several applications that comprise the *retail* pattern. In +addition, the *retail* pattern also includes a number of supporting +operators that are installed by *OpenShift GitOps* using ArgoCD. + +==== Retail Pattern OpenShift Datacenter HUB Cluster Size + +The retail pattern has been tested with a defined set of specifically +tested configurations that represent the most common combinations that +Red Hat OpenShift Container Platform (OCP) customers are using or +deploying for the x86_64 architecture. + +The Datacenter HUB OpenShift Cluster is made up of the the following on +the AWS deployment tested: + +[cols="<,^,<,<",options="header",] +|=== +|Node Type |Number of nodes |Cloud Provider |Instance Type +|Master |3 |Amazon Web Services |m5.xlarge +|Worker |3 |Amazon Web Services |m5.xlarge +|=== + +The Datacenter HUB OpenShift cluster needs to be a bit bigger than the +Factory/Edge clusters because this is where the developers will be +running pipelines to build and deploy the *Industrial Edge* pattern on +the cluster. The above cluster sizing is close to a *minimum* size for a +Datacenter HUB cluster. In the next few sections we take some snapshots +of the cluster utilization while the *Industrial Edge* pattern is +running. Keep in mind that resources will have to be added as more +developers are working building their applications. + +==== Retail Pattern OpenShift Store Edge Cluster Size + +The OpenShift cluster is made of 3 Nodes combining Master/Workers for +the Edge/Factory cluster. + +[cols="^,^,^,^",options="header",] +|=== +|Node Type |Number of nodes |Cloud Provider |Instance Type +|Master/Worker |3 |Google Cloud |n1-standard-8 +|Master/Worker |3 |Amazon Cloud Services |m5.2xlarge +|Master/Worker |3 |Microsoft Azure |Standard_D8s_v3 +|=== + +==== AWS Instance Types + +The *retail* pattern was tested with the highlighted AWS instances in +*bold*. The OpenShift installer will let you know if the instance type +meets the minimum requirements for a cluster. + +The message that the openshift installer will give you will be similar +to this message + +[source,text] +---- +INFO Credentials loaded from default AWS environment variables +FATAL failed to fetch Metadata: failed to load asset "Install Config": [controlPlane.platform.aws.type: Invalid value: "m4.large": instance type does not meet minimum resource requirements of 4 vCPUs, controlPlane.platform.aws.type: Invalid value: "m4.large": instance type does not meet minimum resource requirements of 16384 MiB Memory] +---- + +Below you can find a list of the AWS instance types that can be used to +deploy the *retail* pattern. + +[width="100%",cols="^26%,^20%,^20%,^17%,^17%",options="header",] +|=== +|Instance type |Default vCPUs |Memory (GiB) |Datacenter |Factory/Edge +| | | |3x3 OCP Cluster |3 Node OCP Cluster +|m4.xlarge |4 |16 |N |N +|m4.2xlarge |8 |32 |Y |Y +|m4.4xlarge |16 |64 |Y |Y +|m4.10xlarge |40 |160 |Y |Y +|m4.16xlarge |64 |256 |Y |Y +|*m5.xlarge* |4 |16 |Y |N +|m5.2xlarge |8 |32 |Y |Y +|m5.4xlarge |16 |64 |Y |Y +|m5.8xlarge |32 |128 |Y |Y +|m5.12xlarge |48 |192 |Y |Y +|m5.16xlarge |64 |256 |Y |Y +|m5.24xlarge |96 |384 |Y |Y +|=== + +The OpenShift cluster is made of 3 Masters and 3 Workers for the +Datacenter and the Edge/Factory cluster are made of 3 Master/Worker +nodes. For the node sizes we used the *m5.xlarge* on AWS and this +instance type met the minimum requirements to deploy the *retail* +pattern successfully on the Datacenter hub. On the Factory/Edge cluster +we used the *m5.2xlarge* since the minimum cluster was comprised of 3 +nodes. . + +To understand better what types of nodes you can use on other Cloud +Providers we provide some of the details below. + +==== Azure Instance Types + +The *retail* pattern was also deployed on Azure using the +*Standard_D8s_v3* VM size. Below is a table of different VM sizes +available for Azure. Keep in mind that due to limited access to Azure we +only used the *Standard_D8s_v3* VM size. + +The OpenShift cluster is made of 3 Master and 3 Workers for the +Datacenter cluster. + +The OpenShift cluster is made of 3 Nodes combining Master/Workers for +the Edge/Factory cluster. + +[width="100%",cols="<34%,<33%,<33%",options="header",] +|=== +|Type |Sizes |Description +|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-general[General +purpose] |B, Dsv3, Dv3, Dasv4, Dav4, DSv2, Dv2, Av2, DC, DCv2, Dv4, +Dsv4, Ddv4, Ddsv4 |Balanced CPU-to-memory ratio. Ideal for testing and +development, small to medium databases, and low to medium traffic web +servers. + +|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-compute[Compute +optimized] |F, Fs, Fsv2, FX |High CPU-to-memory ratio. Good for medium +traffic web servers, network appliances, batch processes, and +application servers. + +|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-memory[Memory +optimized] |Esv3, Ev3, Easv4, Eav4, Ev4, Esv4, Edv4, Edsv4, Mv2, M, +DSv2, Dv2 |High memory-to-CPU ratio. Great for relational database +servers, medium to large caches, and in-memory analytics. + +|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-storage[Storage +optimized] |Lsv2 |High disk throughput and IO ideal for Big Data, SQL, +NoSQL databases, data warehousing and large transactional databases. + +|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-gpu[GPU] +|NC, NCv2, NCv3, NCasT4_v3, ND, NDv2, NV, NVv3, NVv4 |Specialized +virtual machines targeted for heavy graphic rendering and video editing, +as well as model training and inferencing (ND) with deep learning. +Available with single or multiple GPUs. + +|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-hpc[High +performance compute] |HB, HBv2, HBv3, HC, H |Our fastest and most +powerful CPU virtual machines with optional high-throughput network +interfaces (RDMA). +|=== + +For more information please refer to the +https://docs.microsoft.com/en-us/azure/virtual-machines/sizes[Azure VM +Size Page]. + +==== Google Cloud (GCP) Instance Types + +The *retail* pattern was also deployed on GCP using the *n1-standard-8* +VM size. Below is a table of different VM sizes available for GCP. Keep +in mind that due to limited access to GCP we only used the +*n1-standard-8* VM size. + +The OpenShift cluster is made of 3 Master and 3 Workers for the +Datacenter cluster. + +The OpenShift cluster is made of 3 Nodes combining Master/Workers for +the Edge/Factory cluster. + +The following table provides VM recommendations for different workloads. + +[verse] +-- +*General purpose* | *Workload optimized* +Cost-optimized | Balanced | Scale-out optimized | Memory-optimized |Compute-optimized | Accelerator-optimized +:—- | :—- | :—- | :—- | :—- | :—- +E2 | N2, N2D, N1 | T2D | M2, M1 | C2 | A2 +-- + +Day-to-day computing at a lower cost | Balanced price/performance across +a wide range of VM shapes | Best performance/cost for scale-out +workloads | Ultra high-memory workloads | Ultra high performance for +compute-intensive workloads | Optimized for high performance computing +workloads + +For more information please refer to the +https://cloud.google.com/compute/docs/machine-types[GCP VM Size Page]. diff --git a/content/patterns/retail/components.adoc b/content/patterns/retail/components.adoc new file mode 100644 index 000000000..9a2c35e97 --- /dev/null +++ b/content/patterns/retail/components.adoc @@ -0,0 +1,99 @@ +== Component Details + +=== The Quarkus Coffeeshop Store https://github.com/validatedpatterns/retail/tree/main/charts/store/quarkuscoffeeshop-charts[Chart] + +This chart is responsible for deploying the applications, services and +routes for the Quarkus Coffeeshop demo. It models a set of microservices +that would make sense for a coffeeshop retail operation. The detail of +what the microservices do is +https://quarkuscoffeeshop.github.io/coffeeshop/[here]. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-web[quarkuscoffeeshop-web] + +Serves as the "`front end`" for ordering food and drinks. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-counter[quarkuscoffeeshop-counter] + +The counter service receives the orders, persists them in the database, +and notifies when they are ready. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-barista[quarkuscoffeeshop-barista] + +The barista service is responsible for preparing items from the +"`drink`" side of the menu. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-kitchen[quarkuscoffeeshop-kitchen] + +The kitchen service is responsible for preparing items from the "`food`" +side of the menu. + +* https://github.com/quarkuscoffeeshop/customerloyalty[quarkuscoffeeshop-customerloyalty] + +The customerloyalty service is responsible for generating customer +loyalty events, when a customer enters the "`rewards`" email. This data +is not persisted or tracked anywhere. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-inventory[quarkuscoffeeshop-inventory] + +The inventory service is responsible for tracking food and drink +inventory. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-customermocker[quarkuscoffeeshop-customermocker] + +The customermocker can be used to generate test traffic. + +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-majestic-monolith[quarkuscoffeeshop-majestic-monolith] + +The "`majestic monolith`" builds all the apps into a single bundle, to +simplify the process of deploying this app on single node systems. + +All the components look like this in ArgoCD when deployed: + +link:/images/retail/retail-v1-argo-coffeeshop-store.png[image:/images/retail/retail-v1-argo-coffeeshop-store.png[retail-v1-argo-coffeeshop-store]] + +The chart is designed such that the same chart can be deployed in the +hub cluster as the "`production`" store, the "`demo`" or TEST store, and +on a remote cluster. + +=== The Quarkus Coffeeshop Database https://github.com/validatedpatterns/retail/tree/main/charts/all/crunchy-pgcluster[Chart] + +This installs a database instance suitable for use in the Retail +pattern. It uses the Crunchy PostgreSQL +https://github.com/CrunchyData/postgres-operator[Operator] to provide +PostgreSQL services, which includes high availability and backup +services by default, and other features available. + +Like the store chart, the Database chart can be deployed in the same +different scenarios. + +In ArgoCD, it looks like this: + +link:/images/retail/retail-v1-argo-coffeeshopdb.png[image:/images/retail/retail-v1-argo-coffeeshopdb.png[retail-v1-argo-coffeeshopdb]] + +=== The Quarkus Coffeeshop Kafka https://github.com/validatedpatterns/retail/tree/main/charts/all/quarkuscoffeeshop-kafka[Chart] + +This chart installs Kafka for use in the Retail pattern. It uses the Red +Hat AMQ Streams +https://access.redhat.com/documentation/en-us/red_hat_amq/7.2/html/using_amq_streams_on_openshift_container_platform/index[operator]. + +=== The Quarkus Coffeeshop Pipelines https://github.com/validatedpatterns/retail/tree/main/charts/hub/quarkuscoffeeshop-pipelines[Chart] + +The pipelines chart defines build pipelines using the Red Hat OpenShift +Pipelines +https://catalog.redhat.com/software/operators/detail/5ec54a4628834587a6b85ca5[Operator] +(tektoncd). Pipelines are provided for all of the application images +that ship with the pattern; the pipelines all build the app from source, +deploy them to the "`demo`" namespace, and push them to the configured +image registry. + +Like the store and database charts, the kafka chart supports all three +modes of deployment. + +link:/images/retail/retail-v1-argo-pipelines.png[image:/images/retail/retail-v1-argo-pipelines.png[retail-v1-argo-pipelines]] + +=== The Quarkus Coffeeshop Landing Page https://github.com/validatedpatterns/retail/tree/main/charts/all/landing-page[Chart] + +The Landing Page chart builds the page that presents the links for the +demos in the pattern. + +link:/images/retail/retail-v1-argo-landing-page.png[image:/images/retail/retail-v1-argo-landing-page.png[retail-v1-landing-page]] diff --git a/content/patterns/retail/getting-started.adoc b/content/patterns/retail/getting-started.adoc new file mode 100644 index 000000000..a18d6f851 --- /dev/null +++ b/content/patterns/retail/getting-started.adoc @@ -0,0 +1,14 @@ +--- +title: Getting Started +weight: 10 +aliases: /travelops/getting-started/ +--- + +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY +include::modules/comm-attributes.adoc[] + +include::modules/retail-deploying.adoc[leveloffset=1] + + diff --git a/content/patterns/retail/ideas-for-customization.adoc b/content/patterns/retail/ideas-for-customization.adoc new file mode 100644 index 000000000..cc68c9e5b --- /dev/null +++ b/content/patterns/retail/ideas-for-customization.adoc @@ -0,0 +1 @@ +== Ideas for Customization diff --git a/content/patterns/retail/store.adoc b/content/patterns/retail/store.adoc new file mode 100644 index 000000000..47eecdeb5 --- /dev/null +++ b/content/patterns/retail/store.adoc @@ -0,0 +1,76 @@ +--- +title: Managed cluster sites +weight: 30 +aliases: /retail/retail-managed-cluster/ +--- + +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY +include::modules/comm-attributes.adoc[] + +== Having a store (edge) cluster join the datacenter (hub) + +=== Allow ACM to deploy the store application to a subset of clusters + +A store ("`ATLANTA`") is installed on the hub cluster by default. This feature is interesting if you want to see how ACM can manage a remote +cluster to install the same application on a different cluster. + +The way we apply this is through the managedClusterGroups block in `values-hub.yaml`: ++ +[source,yaml] +---- + managedClusterGroups: + raleigh: + name: store-raleigh + helmOverrides: + # Values must be strings! + - name: clusterGroup.isHubCluster + value: "false" + clusterSelector: + matchLabels: + clusterGroup: store-raleigh + matchExpressions: + - key: vendor + operator: In + values: + - OpenShift +---- + +Any cluster joined with the label `clusterGroup=store-raleigh` will be assigned the policies that deploy the store app to them. + +[id="attach-managed-cluster"] += Attach a managed cluster (edge) to the management hub + +The use of this Multicloud GitOps pattern depends on having at least one running Red Hat OpenShift cluster. + +When you install the multi-cloud GitOps pattern, a hub cluster is setup. The hub cluster serves as the central point for managing and deploying applications across multiple clusters. + +include::modules/mcg-understanding-rhacm-requirements.adoc[leveloffset=+1] + +include::modules/mcg-deploying-managed-cluster-using-rhacm.adoc[leveloffset=+1] + +include::modules/comm-deploying-managed-cluster-using-cm-cli-tool.adoc[leveloffset=+1] + +include::modules/comm-deploying-managed-cluster-using-clusteradm-tool.adoc[leveloffset=+1] + +include::modules/comm-designate-cluster-as-managed-cluster-site.adoc[leveloffset=+2] + + +== Verification + +. Go to your managed cluster (edge) OpenShift console and check for the `open-cluster-management-agent` pod being launched. + +[NOTE] +==== +It might take a while for the RHACM agent and `agent-addons` to launch. +==== + +=== Store is joined + +==== You’re done + +That’s it! Go to your store (edge) OpenShift console and check for the open-cluster-management-agent pod being launched. Be patient, it will +take a while for the ACM agent and agent-addons to launch. After that, the operator OpenShift GitOps will run. When it’s finished coming up +launch the OpenShift GitOps (ArgoCD) console from the top right of the +OpenShift console. diff --git a/content/patterns/retail/troubleshooting.adoc b/content/patterns/retail/troubleshooting.adoc new file mode 100644 index 000000000..37819b535 --- /dev/null +++ b/content/patterns/retail/troubleshooting.adoc @@ -0,0 +1,3 @@ +== Troubleshooting + +=== Our https://github.com/validatedpatterns/industrial-edge/issues[Issue Tracker] From ea0757ab7ac283fbbd478e53244f00b6a274c265 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 09:17:33 +0000 Subject: [PATCH 02/19] TELCODOCS-2229 updating retail pattern docs 2 --- .../retail-managed-cluster.adoc | 73 ++++++++ modules/retail-about.adoc | 34 ++++ modules/retail-architecture.adoc | 29 +++ modules/retail-deploying.adoc | 169 ++++++++++++++++++ 4 files changed, 305 insertions(+) create mode 100644 content/patterns/multicloud-gitops/retail-managed-cluster.adoc create mode 100644 modules/retail-about.adoc create mode 100644 modules/retail-architecture.adoc create mode 100644 modules/retail-deploying.adoc diff --git a/content/patterns/multicloud-gitops/retail-managed-cluster.adoc b/content/patterns/multicloud-gitops/retail-managed-cluster.adoc new file mode 100644 index 000000000..90821ab29 --- /dev/null +++ b/content/patterns/multicloud-gitops/retail-managed-cluster.adoc @@ -0,0 +1,73 @@ +--- +title: Managed cluster sites +weight: 30 +aliases: /retail/retail-managed-cluster/ +--- + +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY +include::modules/comm-attributes.adoc[] + +//leaving this here on purpose to test H1 headings (with ID) in assemblies and it's impact of TOC +[id="attach-managed-cluster"] += Attach a managed cluster (edge) to the management hub + +The use of this Multicloud GitOps pattern depends on having at least one running Red Hat OpenShift cluster. + +When you install the multi-cloud GitOps pattern, a hub cluster is setup. The hub cluster serves as the central point for managing and deploying applications across multiple clusters. + +include::modules/mcg-understanding-rhacm-requirements.adoc[leveloffset=+1] + +include::modules/mcg-deploying-managed-cluster-using-rhacm.adoc[leveloffset=+1] + +include::modules/comm-deploying-managed-cluster-using-cm-cli-tool.adoc[leveloffset=+1] + +include::modules/comm-deploying-managed-cluster-using-clusteradm-tool.adoc[leveloffset=+1] + +include::modules/comm-designate-cluster-as-managed-cluster-site.adoc[leveloffset=+2] + + +== Verification + +. Go to your managed cluster (edge) OpenShift console and check for the `open-cluster-management-agent` pod being launched. + +[NOTE] +==== +It might take a while for the RHACM agent and `agent-addons` to launch. +==== + +. Check the *Red Hat OpenShift GitOps Operator* is installed. + +. Launch the *Group-One OpenShift ArgoCD* console from nines menu in the top right of the OpenShift console. Verify the applications report the status `Healthy` and `Synched`. + +Verify that the *hello-world* application deployed successfully as follows: + +. Navigate to the *Networking* -> *Routes* menu options on your managed cluster (edge) OpenShift. + +. From the *Project:* drop down select the *hello-world* project. + +. Click the *Location URL*. This should reveal the following: ++ +[source,terminal] +---- +Hello World! + +Hub Cluster domain is 'apps.aws-hub-cluster.openshift.org' +Pod is running on Local Cluster Domain 'apps.aws-hub-cluster.openshift.org' +---- + +Verify that the *config-demo* application deployed successfully as follows: + +. Navigate to the *Networking* -> *Routes* menu options on your managed cluster (edge) OpenShift. + +. Select the *config-demo* *Project*. + +. Click the *Location URL*. This should reveal the following: ++ +[source,terminal] +---- +Hub Cluster domain is 'apps.aws-hub-cluster.openshift.org' +Pod is running on Local Cluster Domain 'apps.aws-hub-cluster.openshift.org' +The secret is `secret` +---- diff --git a/modules/retail-about.adoc b/modules/retail-about.adoc new file mode 100644 index 000000000..001a51eb6 --- /dev/null +++ b/modules/retail-about.adoc @@ -0,0 +1,34 @@ +:_content-type: CONCEPT +:imagesdir: ../../images + +[id="about-retail-pattern"] += About the retail pattern + +This pattern demonstrates a pattern that models the store side of a retail application. + +It is derived from the https://quarkuscoffeeshop.github.io[Quarkus Coffeeshop Demo] created by Red Hat Solution Architects. The demo showcases the use of multiple microservices that interact through Kafka messaging and persist data in a PostgreSQL database. + +This demo pulls together several different strands of the demo and allows for multiple stores to be installed on remote clusters via ACM if the user desires. + +The demo allows users to go to the store’s web page, order drinks and food items, and see those items `made` and served by the microservices in real time. + +The pattern includes build pipelines and a demo space, so that changes to the applications can be tested prior to `production` deployments. + +[id="solution-elements"] +== Solution elements + +* How to use a GitOps approach to keep in control of configuration and +operations +* How to centrally manage multiple clusters, including workloads +* How to build and deploy workloads across clusters using modern CI/CD +* How to architect a modern application using microservices and Kafka in Java + + +[id="rhel-technologies"] +== Red Hat Technologies + +* Red Hat OpenShift Container Platform (Kubernetes) +* Red Hat Advanced Cluster Management (Open Cluster Management) +* Red Hat OpenShift GitOps (ArgoCD) +* Red Hat OpenShift Pipelines (Tekton) +* Red Hat AMQ Streams (Apache Kafka Event Broker) diff --git a/modules/retail-architecture.adoc b/modules/retail-architecture.adoc new file mode 100644 index 000000000..a44fbf99d --- /dev/null +++ b/modules/retail-architecture.adoc @@ -0,0 +1,29 @@ +:_content-type: CONCEPT +:imagesdir: ../../images + +[id="overview-architecture"] += Architecture + +The following diagram shows the relationship between the microservices, +messaging, and database components: + +link:/images/retail/retail-architecture.png[image:/images/retail/retail-architecture.png[Retail Pattern Architecture]] + +* The hub. This cluster hosts the CI/CD pipelines, a test instance of the applications and messaging/database services for testing purposes, and a single functional store. +* Optional remote clusters. Each remote site can support a complete store environment. The default one modelled is a "`RALEIGH`" store location. + +[id="demo-scenario"] +== Demo Scenario + +The Retail Validated Pattern/Demo Scenario showcases the Quarkus Coffeeshop retail experience. Rather than modeling the complexities of a full retail environment—such as item files, tax tables, and inventory management—it focuses on a subset of services to illustrate data flow, microservice interaction through APIs, messaging, and data persistence. + +* Web Service - the point of sale within the store. Shows the menu, and allows the user to order food and drinks, and shows when orders are ready. +* Counter service - the "`heart`" of the store operation - receives orders and dispatches them to the barista and kitchen services, as appropriate. Users may order as many food and drink items in one order as they wish. +* Barista - the service responsible for providing items from the +"`drinks`" side of the menu. +* Kitchen - the service responsible for providing items from the +"`food`" side of the menu. + +Further documentation on the individual services is available at the upstream https://quarkuscoffeeshop.github.io/[Quarkus Coffeeshop] documentation site. + +link:/images/retail/retail-highlevel.png[image:/images/retail/retail-highlevel.png[Demo Scenario]] \ No newline at end of file diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc new file mode 100644 index 000000000..6c712a4aa --- /dev/null +++ b/modules/retail-deploying.adoc @@ -0,0 +1,169 @@ +:_content-type: PROCEDURE +:imagesdir: ../../../images + +[id="deploying-retail-pattern"] += Deploying the retail pattern + +.Prerequisites + +* An OpenShift cluster + ** To create an OpenShift cluster, go to the https://console.redhat.com/[Red Hat Hybrid Cloud console]. + ** Select *Services \-> Containers \-> Create cluster*. + ** The cluster must have a dynamic `StorageClass` to provision `PersistentVolumes`. See link:../../multicloud-gitops/mcg-cluster-sizing[sizing your cluster]. +* Optional: A second OpenShift cluster for multicloud demonstration. +//Replaced git and podman prereqs with the tooling dependencies page +* https://validatedpatterns.io/learn/quickstart/[Install the tooling dependencies]. + +The use of this pattern depends on having at least one running Red Hat OpenShift cluster. However, consider creating a cluster for deploying the GitOps management hub assets and a separate cluster for the managed cluster. + +If you do not have a running Red Hat OpenShift cluster, you can start one on a public or private cloud by using https://console.redhat.com/openshift/create[Red Hat Hybrid Cloud Console]. + +.Procedure + +. Fork the https://github.com/validatedpatterns/retail[retail] repository on GitHub. + +. Clone the forked copy of this repository. ++ +[source,terminal] +---- +git clone git@github.com:your-username/retail.git +---- + +. Create a local copy of the secret values file that can safely include credentials. Run the following commands: ++ +[source,terminal] +---- +cp values-secret.yaml.template ~/values-secret.yaml +---- + +. Edit `values-secret.yaml` populating with your quay `username` and `password`. ++ +[source,yaml] +--- +# NEVER COMMIT THESE VALUES TO GIT +version: "2.0" +secrets: + # These are credentials to allow you to push to your image registry (quay.io) for application images + - name: imageregistry + fields: + # eg. Quay -> Robot Accounts -> Robot Login + - name: username + value: "my-quay-username" + - name: password + value: "my-quay-password" +---- ++ +[WARNING] +==== +Do not commit this file. You do not want to push personal credentials to GitHub. +==== + +. Customize the deployment for your cluster by following these steps: + +.. Create a new branch named my-branch and switch to it by running the following command: ++ +[source,terminal] +---- +$ git switch -c my-branch +---- + +.. Edit the `values-hub.yaml` file to customize the deployment for your cluster by running the following command: ++ +[source,terminal] +---- +$ vi values-global.yaml +---- ++ +The values that you need to change are under the `imageregistry` key, to use your own account and hostname. If you like, you can change the `git` settings of `account`, `email` and `hostname` to reflect your own account settings. + +If you plan to customize the build of the applications themselves, there are `revision` and `imageTag` settings for each of them. The defaults should suffice if you just want to see the apps running. + +.. Stage the changes to the `values-hub.yaml` file by running the following commands: ++ +[source,terminal] +---- +$ git add values-global.yaml +---- + +.. Commit the changes to the `values-hub.yaml` file by running the following commands: ++ +[source,terminal] +---- +$ git commit -m "update deployment for my-branch" +---- + +.. Push the changes to the `values-global.yaml` file by running the following command: ++ +[source,terminal] +---- +$ git push origin my-branch +---- + +. Deploy the pattern by running `./pattern.sh make install` or by using the link:/infrastructure/using-validated-pattern-operator/[Validated Patterns Operator]. + +[id="deploying-cluster-using-patternsh-file"] +== Deploying the pattern by using the pattern.sh script + +To deploy the pattern by using the `pattern.sh` script, complete the following steps: + +. Log in to your cluster by running the following: + +.. Obtain an API token by visiting https://oauth-openshift.apps../oauth/token/request + +.. Log in with this retrieved token by running the following command: ++ +[source,terminal] +---- +$ oc login --token= --server=https://api..:6443 +---- + +. Alternatively log in by running the following command: ++ +[source,terminal] +---- +$ export KUBECONFIG=~/ +---- + +. Deploy the pattern to your cluster by running the following command: ++ +[source,terminal] +---- +$ ./pattern.sh make install +---- + +[id="verify-trvlops-pattern-install"] +== Verify the retail pattern installation + +. Verify that the Operators have been installed. + + .. To verify, in the OpenShift Container Platform web console, navigate to *Operators → Installed Operators* page. + + .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. + + + link:/images/retail/retail-v1-operators.png[image:/images/retail/retail-v1-operators.png[retail-v1-operators]] + +. Track the progress through the Hub ArgoCD UI from the nines menu.: ++ +link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu]] + +Ensure that the Hub ArgoCD instance shows all of its apps in Healthy and Synced status once all of the images have been built: ++ +link:/images/retail/retail-v1-argo-apps-p1.png[image:/images/retail/retail-v1-argo-apps-p1.png[retail-v1-argo-apps-p1]] + +. Check on the pipelines, if you chose to run them. They should all complete successfully: ++ +link:/images/retail/retail-v1-pipelines.png[image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines]] + +. Go to the *Quarkus Coffeeshop Landing Page* where you are presented with the applications in the pattern: ++ +link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page]] + +. Click the *Store Web Page* to open the Quarkus Coffeeshop Demo: ++ +link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page]] + +. Click the *TEST Store Web Page* to open a separate copy of the same demo. + +. Clicking the respective *Kafdrop* links to go to a Kafdrop instance that allows inspection of each of the respective environments. ++ +link:/images/retail/retail-v1-kafdrop.png[image:/images/retail/retail-v1-kafdrop.png[retail-v1-kafdrop]] From b80719586ffc34f68cb3b9f63b8b890da37d4d53 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 12:23:13 +0000 Subject: [PATCH 03/19] More updates --- content/patterns/retail/application.adoc | 66 +++---------------- content/patterns/retail/getting-started.adoc | 2 +- content/patterns/retail/store.adoc | 16 ++--- modules/retail-about.adoc | 7 +- modules/retail-deploying.adoc | 69 +++++++++++++++----- 5 files changed, 71 insertions(+), 89 deletions(-) diff --git a/content/patterns/retail/application.adoc b/content/patterns/retail/application.adoc index 02b287d09..572d9c2ac 100644 --- a/content/patterns/retail/application.adoc +++ b/content/patterns/retail/application.adoc @@ -1,59 +1,11 @@ -== Demonstrating Retail example applications +--- +title: Demonstrating Retail example applications +weight: 10 +aliases: /retail/application-demos/ +--- -=== Background +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY +include::modules/comm-attributes.adoc[] -Up until now the Retail validated pattern has focused primarily on -successfully deploying the architectural pattern. Now it is time to see -the actual applications running as we have deployed them. - -If you have already deployed the hub cluster, then you have already seen -several applications deployed in the OpenShift GitOps console. If you -haven’t done this then we recommend you deploy the hub after you have -setup the Quay repositories described below. - -=== Ordering Items at the Coffeeshop - -The easiest way to get to the coffeeshop store page is from the -OpenShift Console Menu Landing Page entry: - -link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu]] - -Clicking on the Quarkus Coffeeshop Landing Page link will bring you to -this page: - -link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page]] - -And clicking on either the "`Store Web Page`" or "`TEST Store Web Page`" -links will bring you to a screen that looks like this: - -link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page]] - -_NOTE_: The applications are initially identical. The "`TEST`" site is -deployed to the `+quarkuscoffeeshop-demo+` namespace; the regular Store -site is deployed to the `+quarkuscoffeeshop-store+` namespace. - -Each store requires supporting services, in PostgreSQL and Kafka. In our -pattern, PostgreSQL is provided by the Crunchy PostgreSQL operator, and -Kafka is provided by the Red Hat AMQ Streams operator. Each instance, -the regular instance and the TEST instance, has its own instance of each -of these supporting services it uses. - -To order, click on the "`Place an Order`" button on the front page. The -menu should look like this: - -link:/images/retail/retail-v1-store-web-menu.png[image:/images/retail/retail-v1-store-web-menu.png[retail-v1-store-web-menu]] - -Click the "`Add`" button next to a menu item; the item name will appear. -Add a name for the order: - -link:/images/retail/retail-v1-order-p1.png[image:/images/retail/retail-v1-order-p1.png[retail-v1-order-p1]] - -You can add as many orders as you want. On your last item, click the -"`Place Order`" button on the item dialog: - -link:/images/retail/retail-v1-place-order.png[image:/images/retail/retail-v1-place-order.png[retail-v1-place-order]] - -As the orders are serviced by the barista and kitchen services, you can -see their status in the "`Orders`" section of the page: - -link:/images/retail/retail-v1-orders-status.png[image:/images/retail/retail-v1-orders-status.png[retail-v1-orders-status]] diff --git a/content/patterns/retail/getting-started.adoc b/content/patterns/retail/getting-started.adoc index a18d6f851..35dfb6049 100644 --- a/content/patterns/retail/getting-started.adoc +++ b/content/patterns/retail/getting-started.adoc @@ -1,7 +1,7 @@ --- title: Getting Started weight: 10 -aliases: /travelops/getting-started/ +aliases: /retail/getting-started/ --- :toc: diff --git a/content/patterns/retail/store.adoc b/content/patterns/retail/store.adoc index 47eecdeb5..1602b2e3b 100644 --- a/content/patterns/retail/store.adoc +++ b/content/patterns/retail/store.adoc @@ -16,7 +16,7 @@ include::modules/comm-attributes.adoc[] A store ("`ATLANTA`") is installed on the hub cluster by default. This feature is interesting if you want to see how ACM can manage a remote cluster to install the same application on a different cluster. -The way we apply this is through the managedClusterGroups block in `values-hub.yaml`: +The way we apply this is through the `managedClusterGroups` block in `values-hub.yaml`: + [source,yaml] ---- @@ -37,16 +37,16 @@ The way we apply this is through the managedClusterGroups block in `values-hub.y - OpenShift ---- -Any cluster joined with the label `clusterGroup=store-raleigh` will be assigned the policies that deploy the store app to them. +Any cluster joined with the label `clusterGroup=store-raleigh` is assigned the policies that deploy the store app to them. [id="attach-managed-cluster"] -= Attach a managed cluster (edge) to the management hub +=== Attaching a managed cluster (edge) to the management hub -The use of this Multicloud GitOps pattern depends on having at least one running Red Hat OpenShift cluster. +The use of this pattern depends on having at least one running Red Hat OpenShift cluster. -When you install the multi-cloud GitOps pattern, a hub cluster is setup. The hub cluster serves as the central point for managing and deploying applications across multiple clusters. +When you install the retail GitOps pattern, a hub cluster is setup. The hub cluster serves as the central point for managing and deploying applications across multiple clusters. -include::modules/mcg-understanding-rhacm-requirements.adoc[leveloffset=+1] +include::modules/retail-understanding-rhacm-requirements.adoc[leveloffset=+1] include::modules/mcg-deploying-managed-cluster-using-rhacm.adoc[leveloffset=+1] @@ -70,7 +70,7 @@ It might take a while for the RHACM agent and `agent-addons` to launch. ==== You’re done -That’s it! Go to your store (edge) OpenShift console and check for the open-cluster-management-agent pod being launched. Be patient, it will -take a while for the ACM agent and agent-addons to launch. After that, the operator OpenShift GitOps will run. When it’s finished coming up +That is it! Go to your store (edge) OpenShift console and check for the open-cluster-management-agent pod being launched. Be patient, it will +take a while for the ACM agent and agent-addons to launch. After that, the operator OpenShift GitOps will run. When it is finished coming up launch the OpenShift GitOps (ArgoCD) console from the top right of the OpenShift console. diff --git a/modules/retail-about.adoc b/modules/retail-about.adoc index 001a51eb6..abdace095 100644 --- a/modules/retail-about.adoc +++ b/modules/retail-about.adoc @@ -10,15 +10,12 @@ It is derived from the https://quarkuscoffeeshop.github.io[Quarkus Coffeeshop De This demo pulls together several different strands of the demo and allows for multiple stores to be installed on remote clusters via ACM if the user desires. -The demo allows users to go to the store’s web page, order drinks and food items, and see those items `made` and served by the microservices in real time. - -The pattern includes build pipelines and a demo space, so that changes to the applications can be tested prior to `production` deployments. +The demo allows users to go to the store’s web page, order drinks and food items, and see those items `made` and served by the microservices in real time. The pattern includes build pipelines and a demo space, so that changes to the applications can be tested prior to `production` deployments. [id="solution-elements"] == Solution elements -* How to use a GitOps approach to keep in control of configuration and -operations +* How to use a GitOps approach to keep in control of configuration and operations * How to centrally manage multiple clusters, including workloads * How to build and deploy workloads across clusters using modern CI/CD * How to architect a modern application using microservices and Kafka in Java diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 6c712a4aa..6edea7d43 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -8,10 +8,43 @@ * An OpenShift cluster ** To create an OpenShift cluster, go to the https://console.redhat.com/[Red Hat Hybrid Cloud console]. - ** Select *Services \-> Containers \-> Create cluster*. - ** The cluster must have a dynamic `StorageClass` to provision `PersistentVolumes`. See link:../../multicloud-gitops/mcg-cluster-sizing[sizing your cluster]. + ** Select *OpenShift \-> Red Hat OpenShift Container Platform \-> Create cluster*. + ** The cluster must have a dynamic `StorageClass` to provision `PersistentVolumes`. Verify that a dynamic StorageClass exists before creating one by running the following command: ++ +[source,terminal] +---- +$ oc get storageclass -o custom-columns=NAME:.metadata.name,PROVISIONER:.provisioner,DEFAULT:.metadata.annotations."storageclass\.kubernetes\.io/is-default-class" +---- ++ +.Example output ++ +[source,terminal] +---- +NAME PROVISIONER DEFAULT +gp2-csi ebs.csi.aws.com +gp3-csi ebs.csi.aws.com true +---- ++ +For more information about creating a dynamic `StorageClass`, see the https://docs.openshift.com/container-platform/latest/storage/dynamic-provisioning.html[Dynamic provisioning] documentation. + * Optional: A second OpenShift cluster for multicloud demonstration. //Replaced git and podman prereqs with the tooling dependencies page +* Optional: A quay account that can update images; this is if you want to use the pipelines to customize the applications. +* Optional: A quay account with the following repositories set as public, and which you can write to: +** quay.io/your-quay-username/quarkuscoffeeshop-barista +** quay.io/your-quay-username/quarkuscoffeeshop-counter +** quay.io/your-quay-username/quarkuscoffeeshop-inventory +** quay.io/your-quay-username/quarkuscoffeeshop-web +** quay.io/your-quay-username/quarkuscoffeeshop-customerloyalty +** quay.io/your-quay-username/quarkuscoffeeshop-kitchen +** quay.io/your-quay-username/quarkuscoffeeshop-majestic-monolith +** quay.io/your-quay-username/quarkuscoffeeshop-monolith ++ +[NOTE] +==== +These repos contain the demo's microservices. The public repos (`quay.io/hybridcloudpatterns/*`) provide pre-built images used by default, allowing the demo to run without rebuilding the apps. Creating your own quay copies offers transparency and lets you reproduce results or customize the apps. +==== + * https://validatedpatterns.io/learn/quickstart/[Install the tooling dependencies]. The use of this pattern depends on having at least one running Red Hat OpenShift cluster. However, consider creating a cluster for deploying the GitOps management hub assets and a separate cluster for the managed cluster. @@ -26,20 +59,20 @@ If you do not have a running Red Hat OpenShift cluster, you can start one on a p + [source,terminal] ---- -git clone git@github.com:your-username/retail.git +$ git clone git@github.com:your-username/retail.git ---- . Create a local copy of the secret values file that can safely include credentials. Run the following commands: + [source,terminal] ---- -cp values-secret.yaml.template ~/values-secret.yaml +$ cp values-secret.yaml.template ~/values-secret.yaml ---- . Edit `values-secret.yaml` populating with your quay `username` and `password`. + [source,yaml] ---- +---- # NEVER COMMIT THESE VALUES TO GIT version: "2.0" secrets: @@ -53,7 +86,7 @@ secrets: value: "my-quay-password" ---- + -[WARNING] +[NOTE] ==== Do not commit this file. You do not want to push personal credentials to GitHub. ==== @@ -74,9 +107,9 @@ $ git switch -c my-branch $ vi values-global.yaml ---- + -The values that you need to change are under the `imageregistry` key, to use your own account and hostname. If you like, you can change the `git` settings of `account`, `email` and `hostname` to reflect your own account settings. - -If you plan to customize the build of the applications themselves, there are `revision` and `imageTag` settings for each of them. The defaults should suffice if you just want to see the apps running. +The defaults should suffice if you just want to see the apps running. The values that you might change are under the `imageregistry`, if you copied the images to your own quay account and hostname. If you like, you can change the `git` settings of `account`, `email` and `hostname` to reflect your own account settings. ++ +If you plan to customize the build of the applications themselves, there are `revision` and `imageTag` settings for each of them. .. Stage the changes to the `values-hub.yaml` file by running the following commands: + @@ -140,30 +173,30 @@ $ ./pattern.sh make install .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. + - link:/images/retail/retail-v1-operators.png[image:/images/retail/retail-v1-operators.png[retail-v1-operators]] + link:/images/retail/retail-v1-operators.png[image:/images/retail/retail-v1-operators.png[retail-v1-operators] -. Track the progress through the Hub ArgoCD UI from the nines menu.: +. Track the progress through the Hub ArgoCD UI from the nines menu: + -link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu]] +link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] -Ensure that the Hub ArgoCD instance shows all of its apps in Healthy and Synced status once all of the images have been built: +. Ensure that the Hub ArgoCD instance shows all of its apps in Healthy and Synced status once all of the images have been built: + -link:/images/retail/retail-v1-argo-apps-p1.png[image:/images/retail/retail-v1-argo-apps-p1.png[retail-v1-argo-apps-p1]] +link:/images/retail/retail-v1-argo-apps-p1.png[image:/images/retail/retail-v1-argo-apps-p1.png[retail-v1-argo-apps-p1] . Check on the pipelines, if you chose to run them. They should all complete successfully: + -link:/images/retail/retail-v1-pipelines.png[image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines]] +link:/images/retail/retail-v1-pipelines.png[image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines] . Go to the *Quarkus Coffeeshop Landing Page* where you are presented with the applications in the pattern: + -link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page]] +link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] . Click the *Store Web Page* to open the Quarkus Coffeeshop Demo: + -link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page]] +link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] . Click the *TEST Store Web Page* to open a separate copy of the same demo. . Clicking the respective *Kafdrop* links to go to a Kafdrop instance that allows inspection of each of the respective environments. + -link:/images/retail/retail-v1-kafdrop.png[image:/images/retail/retail-v1-kafdrop.png[retail-v1-kafdrop]] +link:/images/retail/retail-v1-kafdrop.png[image:/images/retail/retail-v1-kafdrop.png[retail-v1-kafdrop] From 71c3b0cdc535f41adb1456ba589fdf2553e120fe Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 12:23:27 +0000 Subject: [PATCH 04/19] more updates 2 --- modules/retail-example-applications.adoc | 67 +++++++++++++++++ ...tail-understanding-rhacm-requirements.adoc | 72 +++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 modules/retail-example-applications.adoc create mode 100644 modules/retail-understanding-rhacm-requirements.adoc diff --git a/modules/retail-example-applications.adoc b/modules/retail-example-applications.adoc new file mode 100644 index 000000000..8a8e5f9d4 --- /dev/null +++ b/modules/retail-example-applications.adoc @@ -0,0 +1,67 @@ +:_content-type: PROCEDURE +:imagesdir: ../../../images + +[id="deploying-mcg-pattern"] += Demonstrating Retail example applications + +Up until now the Retail validated pattern has focused primarily on +successfully deploying the architectural pattern. Now it is time to see +the actual applications running as we have deployed them. + +If you have already deployed the hub cluster, then you have already seen +several applications deployed in the OpenShift GitOps console. If you +haven’t done this then we recommend you deploy the hub after you have +setup the Quay repositories described below. + +== Ordering Items at the Coffeeshop + +The easiest way to get to the coffeeshop store page is from the +OpenShift Console Menu Landing Page entry: + +link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] + +1. Click the *Quarkus Coffeeshop Landing Page* link will bring you to +this page: ++ +link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] + +2. Select either the `Store Web Page` or "`TEST Store Web Page`" +links brings you to a screen that looks like this: ++ +link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] ++ +[NOTE] +==== +The applications are initially identical. The `TEST`" site is +deployed to the `quarkuscoffeeshop-demo` namespace; the regular Store +site is deployed to the `quarkuscoffeeshop-store` namespace. + +Each store requires supporting services, in PostgreSQL and Kafka. In our +pattern, PostgreSQL is provided by the Crunchy PostgreSQL operator, and +Kafka is provided by the Red Hat AMQ Streams operator. Each instance, +the regular instance and the TEST instance, has its own instance of each +of these supporting services it uses. +==== + + +. Order by clicking the `Place an Order` button on the front page. The +menu should look like this: ++ +link:/images/retail/retail-v1-store-web-menu.png[image:/images/retail/retail-v1-store-web-menu.png[retail-v1-store-web-menu]] + +. Click the `Add` button next to a menu item; the item name will appear. +Add a name for the order: + +link:/images/retail/retail-v1-order-p1.png[image:/images/retail/retail-v1-order-p1.png[retail-v1-order-p1]] + +You can add as many orders as you want. On your last item, click the +"`Place Order`" button on the item dialog: + +link:/images/retail/retail-v1-place-order.png[image:/images/retail/retail-v1-place-order.png[retail-v1-place-order]] + +As the orders are serviced by the barista and kitchen services, you can +see their status in the "`Orders`" section of the page: + +link:/images/retail/retail-v1-orders-status.png[image:/images/retail/retail-v1-orders-status.png[retail-v1-orders-status] + + diff --git a/modules/retail-understanding-rhacm-requirements.adoc b/modules/retail-understanding-rhacm-requirements.adoc new file mode 100644 index 000000000..91cf91315 --- /dev/null +++ b/modules/retail-understanding-rhacm-requirements.adoc @@ -0,0 +1,72 @@ +:_content-type: CONCEPT +:imagesdir: ../../images + +[id="understanding-acm-requirements-managed-cluster"] += Understanding Red Hat Advanced Cluster Management requirements + +By default, Red Hat Advanced Cluster Management (RHACM) manages the `clusterGroup` applications that are deployed on all clusters. + +Add a `managedClusterGroup` for each cluster or group of clusters that you want to manage by following this procedure. + +.Procedure + +. Switch to your locally created feature branch by running the following command: ++ +[source,terminal] +---- +$ git checkout my-branch main +---- + +. In the `value-hub.yaml` file, a `managedClusterGroup` `raleigh` already exists as shown in this yaml extract: ++ +[source,yaml] +---- +managedClusterGroups: + raleigh: + name: store-raleigh + helmOverrides: + # Values must be strings! + - name: clusterGroup.isHubCluster + value: "false" + clusterSelector: + matchLabels: + clusterGroup: store-raleigh + matchExpressions: + - key: vendor + operator: In + values: + - OpenShift +---- ++ +The YAML file segment defines the `raleigh` managed cluster group, which deploys `clusterGroup` applications on clusters labeled with `clusterGroup=store-raleigh`. The clusterSelector ensures that only clusters with the `clusterGroup=store-raleigh` label and the `vendor=OpenShift` label are included in this group. Specific subscriptions, Operators, applications, and projects for this clusterGroup are managed through the values-store-raleigh.yaml file.. + +. To add a new `managedClusterGroup`, add a new entry to the `managedClusterGroups` block in the `values-hub.yaml` file as follows: ++ +[source,yaml] +---- +charlotte: + name: store-charlotte + helmOverrides: + - name: clusterGroup.isHubCluster + value: "false" + clusterSelector: + matchLabels: + clusterGroup: store-charlotte + matchExpressions: + - key: vendor + operator: In + values: + - OpenShift +---- ++ +[NOTE] +==== +The `charlotte` cluster group is managed separately, using its own `values-store-charlotte.yaml` file. +==== + +. Make a copy of the `values-store-raleigh.yaml` file and name it `values-store-charlotte.yaml`. Update the file with the appropriate values for the `charlotte` cluster group. + +[IMPORTANT] +==== +Ensure that you commit the changes and push them to GitHub so that GitOps can fetch your changes and apply them. +==== \ No newline at end of file From 9aa4420ac537049c754b94d636baad007e279615 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 14:04:24 +0000 Subject: [PATCH 05/19] more updates 3 --- content/patterns/retail/_index.md | 76 ------- content/patterns/retail/application.adoc | 5 +- content/patterns/retail/application.md | 47 ---- content/patterns/retail/cluster-sizing.adoc | 207 +----------------- content/patterns/retail/cluster-sizing.md | 122 ----------- content/patterns/retail/components.adoc | 93 +++----- content/patterns/retail/components.md | 77 ------- content/patterns/retail/getting-started.md | 168 -------------- .../retail/ideas-for-customization.adoc | 1 - .../retail/ideas-for-customization.md | 8 - content/patterns/retail/store.md | 104 --------- content/patterns/retail/troubleshooting.adoc | 3 - content/patterns/retail/troubleshooting.md | 9 - modules/retail-example-applications.adoc | 1 - 14 files changed, 46 insertions(+), 875 deletions(-) delete mode 100644 content/patterns/retail/_index.md delete mode 100644 content/patterns/retail/application.md delete mode 100644 content/patterns/retail/cluster-sizing.md delete mode 100644 content/patterns/retail/components.md delete mode 100644 content/patterns/retail/getting-started.md delete mode 100644 content/patterns/retail/ideas-for-customization.adoc delete mode 100644 content/patterns/retail/ideas-for-customization.md delete mode 100644 content/patterns/retail/store.md delete mode 100644 content/patterns/retail/troubleshooting.adoc delete mode 100644 content/patterns/retail/troubleshooting.md diff --git a/content/patterns/retail/_index.md b/content/patterns/retail/_index.md deleted file mode 100644 index 20b882944..000000000 --- a/content/patterns/retail/_index.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Retail -date: 2022-12-08 -tier: tested -summary: This pattern demonstrates a pattern that models the store side of a retail application. -rh_products: -- Red Hat OpenShift Container Platform -- Red Hat Advanced Cluster Management -- Red Hat AMQ -industries: -- Retail -aliases: /retail/ -# uncomment once this exists -# pattern_logo: retail.png -links: - install: getting-started - help: https://groups.google.com/g/validatedpatterns - bugs: https://github.com/validatedpatterns/retail/issues -# uncomment once this exists -ci: retail ---- - -# Retail Pattern - -## Background - -This pattern demonstrates a pattern that models the store side of a retail application. - -It is derived from the [Quarkus Coffeeshop Demo](https://quarkuscoffeeshop.github.io) done by Red -Hat Solution Architects. The demo models the use of multiple application microservices which use Kafka messaging to interact and a Postgres database to persist data. (There is a homeoffice analytics suite in the demo that we hope to include in a later version of the pattern. - -This demo pulls together several different strands of the demo and allows for multiple stores to be installed on remote clusters via ACM if the user desires. - -The demo allows users to go to the store's web page, order drinks and food items, and see those items "made" and served by the microservices in real time. - -The pattern includes build pipelines and a demo space, so that changes to the applications can be tested prior to "production" deployments. - -### Solution elements - -- How to use a GitOps approach to keep in control of configuration and operations -- How to centrally manage multiple clusters, including workloads -- How to build and deploy workloads across clusters using modern CI/CD -- How to architect a modern application using microservices and Kafka in Java - -### Red Hat Technologies - -- Red Hat OpenShift Container Platform (Kubernetes) -- Red Hat Advanced Cluster Management (Open Cluster Management) -- Red Hat OpenShift GitOps (ArgoCD) -- Red Hat OpenShift Pipelines (Tekton) -- Red Hat AMQ Streams (Apache Kafka Event Broker) - -## Architecture - -The following diagram shows the relationship between the microservices, messaging, and database components: - -[![Retail Pattern Architecture](/images/retail/retail-architecture.png)](/images/retail/retail-architecture.png) - -- The hub. This cluster hosts the CI/CD pipelines, a test instance of the applications and messaging/database services for testing purposes, and a single functional store. -- Optional remote clusters. Each remote site can support a complete store environment. The default one modelled is a "RALEIGH" store location. - -### Demo Scenario - -The Retail Validated Pattern / Demo Scenario is focused in the Quarkus Coffeeshop retail experience. In a full retail -environment, it would be easy to be overwhelmed by things like item files, tax tables, item movement/placement within the store and so on, so the demo does not attempt to model all those elements - instead offering a subset of services to give a sense of how data can flow in such a system, how microservices should interact (via API calls and message passing), and where data can be persisted. - -In the future we hope to expand this pattern with the homeoffice components, to further demonstrate how data can flow from leaf nodes to centralized data analytics services, which are crucial in retail IT environments. - -- Web Service - the point of sale within the store. Shows the menu, and allows the user to order food and drinks, and shows when orders are ready. -- Counter service - the "heart" of the store operation - receives orders and dispatches them to the barista and kitchen services, as appropriate. Users may order as many food and drink items in one order as they wish. -- Barista - the service responsible for providing items from the "drinks" side of the menu. -- Kitchen - the service responsible for providing items from the "food" side of the menu. - -Further documentation on the individual services is available at the upstream [Quarkus Coffeeshop](https://quarkuscoffeeshop.github.io/) documentation site. - -[![Demo Scenario](/images/retail/retail-highlevel.png)](/images/retail/retail-highlevel.png) diff --git a/content/patterns/retail/application.adoc b/content/patterns/retail/application.adoc index 572d9c2ac..be01afe7a 100644 --- a/content/patterns/retail/application.adoc +++ b/content/patterns/retail/application.adoc @@ -1,6 +1,6 @@ --- -title: Demonstrating Retail example applications -weight: 10 +title: Demonstrating retail example applications +weight: 40 aliases: /retail/application-demos/ --- @@ -9,3 +9,4 @@ aliases: /retail/application-demos/ :_content-type: ASSEMBLY include::modules/comm-attributes.adoc[] +include::modules/retail-example-applications.adoc[] diff --git a/content/patterns/retail/application.md b/content/patterns/retail/application.md deleted file mode 100644 index 8da0951f0..000000000 --- a/content/patterns/retail/application.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: Application Demos -weight: 30 -aliases: /retail/application/ ---- - -# Demonstrating Retail example applications - -## Background - -Up until now the Retail validated pattern has focused primarily on successfully deploying the architectural pattern. Now it is time to see the actual applications running as we have deployed them. - -If you have already deployed the hub cluster, then you have already seen several applications deployed in the OpenShift GitOps console. If you haven't done this then we recommend you deploy the hub after you have setup the Quay repositories described below. - -## Ordering Items at the Coffeeshop - -The easiest way to get to the coffeeshop store page is from the OpenShift Console Menu Landing Page entry: - -[![retail-v1-console-menu](/images/retail/retail-v1-console-menu.png)](/images/retail/retail-v1-console-menu.png) - -Clicking on the Quarkus Coffeeshop Landing Page link will bring you to this page: - -[![retail-v1-landing-page](/images/retail/retail-v1-landing-page.png)](/images/retail/retail-v1-landing-page.png) - -And clicking on either the "Store Web Page" or "TEST Store Web Page" links will bring you to a screen that looks like this: - -[![retail-v1-store-page](/images/retail/retail-v1-store-page.png)](/images/retail/retail-v1-store-page.png) - -*NOTE*: The applications are initially identical. The "TEST" site is deployed to the `quarkuscoffeeshop-demo` namespace; the regular Store site is deployed to the `quarkuscoffeeshop-store` namespace. - -Each store requires supporting services, in PostgreSQL and Kafka. In our pattern, PostgreSQL is provided by the Crunchy PostgreSQL operator, and Kafka is provided by the Red Hat AMQ Streams operator. Each instance, the regular instance and the TEST instance, has its own instance of each of these supporting services it uses. - -To order, click on the "Place an Order" button on the front page. The menu should look like this: - -[![retail-v1-store-web-menu](/images/retail/retail-v1-store-web-menu.png)](/images/retail/retail-v1-store-web-menu.png) - -Click the "Add" button next to a menu item; the item name will appear. Add a name for the order: - -[![retail-v1-order-p1](/images/retail/retail-v1-order-p1.png)](/images/retail/retail-v1-order-p1.png) - -You can add as many orders as you want. On your last item, click the "Place Order" button on the item dialog: - -[![retail-v1-place-order](/images/retail/retail-v1-place-order.png)](/images/retail/retail-v1-place-order.png) - -As the orders are serviced by the barista and kitchen services, you can see their status in the "Orders" section of the page: - -[![retail-v1-orders-status](/images/retail/retail-v1-orders-status.png)](/images/retail/retail-v1-orders-status.png) diff --git a/content/patterns/retail/cluster-sizing.adoc b/content/patterns/retail/cluster-sizing.adoc index f89eef60e..106dcaca5 100644 --- a/content/patterns/retail/cluster-sizing.adoc +++ b/content/patterns/retail/cluster-sizing.adoc @@ -1,199 +1,14 @@ -== OpenShift Cluster Sizing for the Retail Pattern +--- +title: Cluster Sizing +weight: 60 +aliases: /retail/retail-cluster-sizing/ +--- -=== Tested Platforms +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY -The *retail* pattern has been tested in the following Certified Cloud -Providers. +include::modules/comm-attributes.adoc[] +include::modules/retail/metadata-retail.adoc[] -[cols="<,<",options="header",] -|=== -|*Certified Cloud Providers* |4.10 -|Amazon Web Services |:heavy_check_mark: -|Microsoft Azure | -|Google Cloud Platform | -|=== - -=== General OpenShift Minimum Requirements - -OpenShift 4 has the following minimum requirements for sizing of nodes: - -* *Minimum 4 vCPU* (additional are strongly recommended). -* *Minimum 16 GB RAM* (additional memory is strongly recommended, -especially if etcd is colocated on masters). -* *Minimum 40 GB* hard disk space for the file system containing /var/. -* *Minimum 1 GB* hard disk space for the file system containing -/usr/local/bin/. - -There are several applications that comprise the *retail* pattern. In -addition, the *retail* pattern also includes a number of supporting -operators that are installed by *OpenShift GitOps* using ArgoCD. - -==== Retail Pattern OpenShift Datacenter HUB Cluster Size - -The retail pattern has been tested with a defined set of specifically -tested configurations that represent the most common combinations that -Red Hat OpenShift Container Platform (OCP) customers are using or -deploying for the x86_64 architecture. - -The Datacenter HUB OpenShift Cluster is made up of the the following on -the AWS deployment tested: - -[cols="<,^,<,<",options="header",] -|=== -|Node Type |Number of nodes |Cloud Provider |Instance Type -|Master |3 |Amazon Web Services |m5.xlarge -|Worker |3 |Amazon Web Services |m5.xlarge -|=== - -The Datacenter HUB OpenShift cluster needs to be a bit bigger than the -Factory/Edge clusters because this is where the developers will be -running pipelines to build and deploy the *Industrial Edge* pattern on -the cluster. The above cluster sizing is close to a *minimum* size for a -Datacenter HUB cluster. In the next few sections we take some snapshots -of the cluster utilization while the *Industrial Edge* pattern is -running. Keep in mind that resources will have to be added as more -developers are working building their applications. - -==== Retail Pattern OpenShift Store Edge Cluster Size - -The OpenShift cluster is made of 3 Nodes combining Master/Workers for -the Edge/Factory cluster. - -[cols="^,^,^,^",options="header",] -|=== -|Node Type |Number of nodes |Cloud Provider |Instance Type -|Master/Worker |3 |Google Cloud |n1-standard-8 -|Master/Worker |3 |Amazon Cloud Services |m5.2xlarge -|Master/Worker |3 |Microsoft Azure |Standard_D8s_v3 -|=== - -==== AWS Instance Types - -The *retail* pattern was tested with the highlighted AWS instances in -*bold*. The OpenShift installer will let you know if the instance type -meets the minimum requirements for a cluster. - -The message that the openshift installer will give you will be similar -to this message - -[source,text] ----- -INFO Credentials loaded from default AWS environment variables -FATAL failed to fetch Metadata: failed to load asset "Install Config": [controlPlane.platform.aws.type: Invalid value: "m4.large": instance type does not meet minimum resource requirements of 4 vCPUs, controlPlane.platform.aws.type: Invalid value: "m4.large": instance type does not meet minimum resource requirements of 16384 MiB Memory] ----- - -Below you can find a list of the AWS instance types that can be used to -deploy the *retail* pattern. - -[width="100%",cols="^26%,^20%,^20%,^17%,^17%",options="header",] -|=== -|Instance type |Default vCPUs |Memory (GiB) |Datacenter |Factory/Edge -| | | |3x3 OCP Cluster |3 Node OCP Cluster -|m4.xlarge |4 |16 |N |N -|m4.2xlarge |8 |32 |Y |Y -|m4.4xlarge |16 |64 |Y |Y -|m4.10xlarge |40 |160 |Y |Y -|m4.16xlarge |64 |256 |Y |Y -|*m5.xlarge* |4 |16 |Y |N -|m5.2xlarge |8 |32 |Y |Y -|m5.4xlarge |16 |64 |Y |Y -|m5.8xlarge |32 |128 |Y |Y -|m5.12xlarge |48 |192 |Y |Y -|m5.16xlarge |64 |256 |Y |Y -|m5.24xlarge |96 |384 |Y |Y -|=== - -The OpenShift cluster is made of 3 Masters and 3 Workers for the -Datacenter and the Edge/Factory cluster are made of 3 Master/Worker -nodes. For the node sizes we used the *m5.xlarge* on AWS and this -instance type met the minimum requirements to deploy the *retail* -pattern successfully on the Datacenter hub. On the Factory/Edge cluster -we used the *m5.2xlarge* since the minimum cluster was comprised of 3 -nodes. . - -To understand better what types of nodes you can use on other Cloud -Providers we provide some of the details below. - -==== Azure Instance Types - -The *retail* pattern was also deployed on Azure using the -*Standard_D8s_v3* VM size. Below is a table of different VM sizes -available for Azure. Keep in mind that due to limited access to Azure we -only used the *Standard_D8s_v3* VM size. - -The OpenShift cluster is made of 3 Master and 3 Workers for the -Datacenter cluster. - -The OpenShift cluster is made of 3 Nodes combining Master/Workers for -the Edge/Factory cluster. - -[width="100%",cols="<34%,<33%,<33%",options="header",] -|=== -|Type |Sizes |Description -|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-general[General -purpose] |B, Dsv3, Dv3, Dasv4, Dav4, DSv2, Dv2, Av2, DC, DCv2, Dv4, -Dsv4, Ddv4, Ddsv4 |Balanced CPU-to-memory ratio. Ideal for testing and -development, small to medium databases, and low to medium traffic web -servers. - -|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-compute[Compute -optimized] |F, Fs, Fsv2, FX |High CPU-to-memory ratio. Good for medium -traffic web servers, network appliances, batch processes, and -application servers. - -|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-memory[Memory -optimized] |Esv3, Ev3, Easv4, Eav4, Ev4, Esv4, Edv4, Edsv4, Mv2, M, -DSv2, Dv2 |High memory-to-CPU ratio. Great for relational database -servers, medium to large caches, and in-memory analytics. - -|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-storage[Storage -optimized] |Lsv2 |High disk throughput and IO ideal for Big Data, SQL, -NoSQL databases, data warehousing and large transactional databases. - -|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-gpu[GPU] -|NC, NCv2, NCv3, NCasT4_v3, ND, NDv2, NV, NVv3, NVv4 |Specialized -virtual machines targeted for heavy graphic rendering and video editing, -as well as model training and inferencing (ND) with deep learning. -Available with single or multiple GPUs. - -|https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-hpc[High -performance compute] |HB, HBv2, HBv3, HC, H |Our fastest and most -powerful CPU virtual machines with optional high-throughput network -interfaces (RDMA). -|=== - -For more information please refer to the -https://docs.microsoft.com/en-us/azure/virtual-machines/sizes[Azure VM -Size Page]. - -==== Google Cloud (GCP) Instance Types - -The *retail* pattern was also deployed on GCP using the *n1-standard-8* -VM size. Below is a table of different VM sizes available for GCP. Keep -in mind that due to limited access to GCP we only used the -*n1-standard-8* VM size. - -The OpenShift cluster is made of 3 Master and 3 Workers for the -Datacenter cluster. - -The OpenShift cluster is made of 3 Nodes combining Master/Workers for -the Edge/Factory cluster. - -The following table provides VM recommendations for different workloads. - -[verse] --- -*General purpose* | *Workload optimized* -Cost-optimized | Balanced | Scale-out optimized | Memory-optimized |Compute-optimized | Accelerator-optimized -:—- | :—- | :—- | :—- | :—- | :—- -E2 | N2, N2D, N1 | T2D | M2, M1 | C2 | A2 --- - -Day-to-day computing at a lower cost | Balanced price/performance across -a wide range of VM shapes | Best performance/cost for scale-out -workloads | Ultra high-memory workloads | Ultra high performance for -compute-intensive workloads | Optimized for high performance computing -workloads - -For more information please refer to the -https://cloud.google.com/compute/docs/machine-types[GCP VM Size Page]. +include::modules/cluster-sizing-template.adoc[] diff --git a/content/patterns/retail/cluster-sizing.md b/content/patterns/retail/cluster-sizing.md deleted file mode 100644 index 9cedcba28..000000000 --- a/content/patterns/retail/cluster-sizing.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Cluster Sizing -weight: 50 -aliases: /retail/cluster-sizing/ ---- -# OpenShift Cluster Sizing for the Retail Pattern - -## Tested Platforms - -The **retail** pattern has been tested in the following Certified Cloud Providers. - - -| **Certified Cloud Providers** | 4.10 | -| :---- | :---- | -| Amazon Web Services| :heavy_check_mark: | -| Microsoft Azure| | -| Google Cloud Platform| | - - -## General OpenShift Minimum Requirements - -OpenShift 4 has the following minimum requirements for sizing of nodes: - -* **Minimum 4 vCPU** (additional are strongly recommended). -* **Minimum 16 GB RAM** (additional memory is strongly recommended, especially if etcd is colocated on masters). -* **Minimum 40 GB** hard disk space for the file system containing /var/. -* **Minimum 1 GB** hard disk space for the file system containing /usr/local/bin/. - -There are several applications that comprise the **retail** pattern. In addition, the **retail** pattern also includes a number of supporting operators that are installed by **OpenShift GitOps** using ArgoCD. - -### Retail Pattern OpenShift Datacenter HUB Cluster Size - -The retail pattern has been tested with a defined set of specifically tested configurations that represent the most common combinations that Red Hat OpenShift Container Platform (OCP) customers are using or deploying for the x86_64 architecture. - -The Datacenter HUB OpenShift Cluster is made up of the the following on the AWS deployment tested: - -| Node Type | Number of nodes | Cloud Provider | Instance Type -| :---- | :----: | :---- | :---- -| Master | 3 | Amazon Web Services | m5.xlarge -| Worker | 3 | Amazon Web Services | m5.xlarge - -The Datacenter HUB OpenShift cluster needs to be a bit bigger than the Factory/Edge clusters because this is where the developers will be running pipelines to build and deploy the **Industrial Edge** pattern on the cluster. The above cluster sizing is close to a **minimum** size for a Datacenter HUB cluster. In the next few sections we take some snapshots of the cluster utilization while the **Industrial Edge** pattern is running. Keep in mind that resources will have to be added as more developers are working building their applications. - -### Retail Pattern OpenShift Store Edge Cluster Size - -The OpenShift cluster is made of 3 Nodes combining Master/Workers for the Edge/Factory cluster. - -| Node Type | Number of nodes | Cloud Provider | Instance Type -| :----: | :----: | :----: | :----: -| Master/Worker | 3 | Google Cloud | n1-standard-8 -| Master/Worker | 3 | Amazon Cloud Services | m5.2xlarge -| Master/Worker | 3 | Microsoft Azure | Standard_D8s_v3 - -### AWS Instance Types - -The **retail** pattern was tested with the highlighted AWS instances in **bold**. The OpenShift installer will let you know if the instance type meets the minimum requirements for a cluster. - -The message that the openshift installer will give you will be similar to this message - -```text -INFO Credentials loaded from default AWS environment variables -FATAL failed to fetch Metadata: failed to load asset "Install Config": [controlPlane.platform.aws.type: Invalid value: "m4.large": instance type does not meet minimum resource requirements of 4 vCPUs, controlPlane.platform.aws.type: Invalid value: "m4.large": instance type does not meet minimum resource requirements of 16384 MiB Memory] -``` - -Below you can find a list of the AWS instance types that can be used to deploy the **retail** pattern. - -| Instance type | Default vCPUs | Memory (GiB) | Datacenter | Factory/Edge -| :------: | :-----: | :-----: | :----: | :----: -| | | | 3x3 OCP Cluster | 3 Node OCP Cluster -| m4.xlarge | 4 | 16 | N | N -| m4.2xlarge | 8 | 32 | Y | Y -| m4.4xlarge | 16 | 64 | Y | Y -| m4.10xlarge | 40 | 160 | Y | Y -| m4.16xlarge | 64 | 256 | Y | Y -| **m5.xlarge** | 4 | 16 | Y | N -| m5.2xlarge | 8 | 32 | Y | Y -| m5.4xlarge | 16 | 64 | Y | Y -| m5.8xlarge | 32 | 128 | Y | Y -| m5.12xlarge | 48 | 192 | Y | Y -| m5.16xlarge | 64 | 256 | Y | Y -| m5.24xlarge | 96 | 384 | Y | Y - -The OpenShift cluster is made of 3 Masters and 3 Workers for the Datacenter and the Edge/Factory cluster are made of 3 Master/Worker nodes. For the node sizes we used the **m5.xlarge** on AWS and this instance type met the minimum requirements to deploy the **retail** pattern successfully on the Datacenter hub. On the Factory/Edge cluster we used the **m5.2xlarge** since the minimum cluster was comprised of 3 nodes. . - -To understand better what types of nodes you can use on other Cloud Providers we provide some of the details below. - -### Azure Instance Types - -The **retail** pattern was also deployed on Azure using the **Standard_D8s_v3** VM size. Below is a table of different VM sizes available for Azure. Keep in mind that due to limited access to Azure we only used the **Standard_D8s_v3** VM size. - -The OpenShift cluster is made of 3 Master and 3 Workers for the Datacenter cluster. - -The OpenShift cluster is made of 3 Nodes combining Master/Workers for the Edge/Factory cluster. - -| Type | Sizes | Description -| :---- | :---- | :---- -| [General purpose](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-general) |B, Dsv3, Dv3, Dasv4, Dav4, DSv2, Dv2, Av2, DC, DCv2, Dv4, Dsv4, Ddv4, Ddsv4 | Balanced CPU-to-memory ratio. Ideal for testing and development, small to medium databases, and low to medium traffic web servers. -| [Compute optimized](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-compute) | F, Fs, Fsv2, FX | High CPU-to-memory ratio. Good for medium traffic web servers, network appliances, batch processes, and application servers. -| [Memory optimized](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-memory) | Esv3, Ev3, Easv4, Eav4, Ev4, Esv4, Edv4, Edsv4, Mv2, M, DSv2, Dv2 | High memory-to-CPU ratio. Great for relational database servers, medium to large caches, and in-memory analytics. -| [Storage optimized](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-storage) | Lsv2 | High disk throughput and IO ideal for Big Data, SQL, NoSQL databases, data warehousing and large transactional databases. -| [GPU](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-gpu) | NC, NCv2, NCv3, NCasT4_v3, ND, NDv2, NV, NVv3, NVv4 | Specialized virtual machines targeted for heavy graphic rendering and video editing, as well as model training and inferencing (ND) with deep learning. Available with single or multiple GPUs. -| [High performance compute](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes-hpc) | HB, HBv2, HBv3, HC, H | Our fastest and most powerful CPU virtual machines with optional high-throughput network interfaces (RDMA). - -For more information please refer to the [Azure VM Size Page](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes). - -### Google Cloud (GCP) Instance Types - -The **retail** pattern was also deployed on GCP using the **n1-standard-8** VM size. Below is a table of different VM sizes available for GCP. Keep in mind that due to limited access to GCP we only used the **n1-standard-8** VM size. - -The OpenShift cluster is made of 3 Master and 3 Workers for the Datacenter cluster. - -The OpenShift cluster is made of 3 Nodes combining Master/Workers for the Edge/Factory cluster. - -The following table provides VM recommendations for different workloads. - -| **General purpose** | **Workload optimized** -| Cost-optimized | Balanced | Scale-out optimized | Memory-optimized |Compute-optimized | Accelerator-optimized -| :---- | :---- | :---- | :---- | :---- | :---- -| E2 | N2, N2D, N1 | T2D | M2, M1 | C2 | A2 -Day-to-day computing at a lower cost | Balanced price/performance across a wide range of VM shapes | Best performance/cost for scale-out workloads | Ultra high-memory workloads | Ultra high performance for compute-intensive workloads | Optimized for high performance computing workloads - -For more information please refer to the [GCP VM Size Page](https://cloud.google.com/compute/docs/machine-types). diff --git a/content/patterns/retail/components.adoc b/content/patterns/retail/components.adoc index 9a2c35e97..0b08bd085 100644 --- a/content/patterns/retail/components.adoc +++ b/content/patterns/retail/components.adoc @@ -1,99 +1,70 @@ -== Component Details +--- +title: Details of the components +weight: 50 +aliases: /retail/component-details/ +--- -=== The Quarkus Coffeeshop Store https://github.com/validatedpatterns/retail/tree/main/charts/store/quarkuscoffeeshop-charts[Chart] - -This chart is responsible for deploying the applications, services and -routes for the Quarkus Coffeeshop demo. It models a set of microservices -that would make sense for a coffeeshop retail operation. The detail of -what the microservices do is -https://quarkuscoffeeshop.github.io/coffeeshop/[here]. - -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-web[quarkuscoffeeshop-web] - -Serves as the "`front end`" for ordering food and drinks. +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY +include::modules/comm-attributes.adoc[] -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-counter[quarkuscoffeeshop-counter] -The counter service receives the orders, persists them in the database, -and notifies when they are ready. - -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-barista[quarkuscoffeeshop-barista] - -The barista service is responsible for preparing items from the -"`drink`" side of the menu. - -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-kitchen[quarkuscoffeeshop-kitchen] +=== The Quarkus Coffeeshop Store https://github.com/validatedpatterns/retail/tree/main/charts/store/quarkuscoffeeshop-charts[Chart] -The kitchen service is responsible for preparing items from the "`food`" -side of the menu. +This chart is responsible for deploying the applications, services and routes for the Quarkus Coffeeshop demo. It models a set of microservices +that would make sense for a coffeeshop retail operation. The detail of what the microservices do is +https://quarkuscoffeeshop.github.io/coffeeshop/[here]. -* https://github.com/quarkuscoffeeshop/customerloyalty[quarkuscoffeeshop-customerloyalty] +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-web[quarkuscoffeeshop-web] - Serves as the `front end` for ordering food and drinks. -The customerloyalty service is responsible for generating customer -loyalty events, when a customer enters the "`rewards`" email. This data -is not persisted or tracked anywhere. +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-counter[quarkuscoffeeshop-counter] - The counter service receives the orders, persists them in the database, and notifies when they are ready. -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-inventory[quarkuscoffeeshop-inventory] +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-barista[quarkuscoffeeshop-barista] - The barista service is responsible for preparing items from the `drink` side of the menu. -The inventory service is responsible for tracking food and drink -inventory. +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-kitchen[quarkuscoffeeshop-kitchen]- The kitchen service is responsible for preparing items from the `food` side of the menu. -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-customermocker[quarkuscoffeeshop-customermocker] +* https://github.com/quarkuscoffeeshop/customerloyalty[quarkuscoffeeshop-customerloyalty] - The customerloyalty service is responsible for generating customer loyalty events, when a customer enters the `rewards` email. This data is not persisted or tracked anywhere. -The customermocker can be used to generate test traffic. +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-inventory[quarkuscoffeeshop-inventory] - The inventory service is responsible for tracking food and drink inventory. -* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-majestic-monolith[quarkuscoffeeshop-majestic-monolith] +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-customermocker[quarkuscoffeeshop-customermocker] - The customermocker can be used to generate test traffic. -The "`majestic monolith`" builds all the apps into a single bundle, to -simplify the process of deploying this app on single node systems. +* https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-majestic-monolith[quarkuscoffeeshop-majestic-monolith] - The `majestic monolith` builds all the apps into a single bundle, to simplify the process of deploying this app on single node systems. All the components look like this in ArgoCD when deployed: -link:/images/retail/retail-v1-argo-coffeeshop-store.png[image:/images/retail/retail-v1-argo-coffeeshop-store.png[retail-v1-argo-coffeeshop-store]] +link:/images/retail/retail-v1-argo-coffeeshop-store.png[image:/images/retail/retail-v1-argo-coffeeshop-store.png[retail-v1-argo-coffeeshop-store] -The chart is designed such that the same chart can be deployed in the -hub cluster as the "`production`" store, the "`demo`" or TEST store, and -on a remote cluster. +The chart is designed such that the same chart can be deployed in the hub cluster as the `production` store, the `demo` or `TEST` store, and on a remote cluster. === The Quarkus Coffeeshop Database https://github.com/validatedpatterns/retail/tree/main/charts/all/crunchy-pgcluster[Chart] -This installs a database instance suitable for use in the Retail -pattern. It uses the Crunchy PostgreSQL -https://github.com/CrunchyData/postgres-operator[Operator] to provide -PostgreSQL services, which includes high availability and backup -services by default, and other features available. +This installs a database instance suitable for use in the Retail pattern. It uses the Crunchy PostgreSQL https://github.com/CrunchyData/postgres-operator[Operator] to provide PostgreSQL services, which includes high availability and backup services by default, and other features available. -Like the store chart, the Database chart can be deployed in the same -different scenarios. +Like the store chart, the Database chart can be deployed in the same different scenarios. In ArgoCD, it looks like this: -link:/images/retail/retail-v1-argo-coffeeshopdb.png[image:/images/retail/retail-v1-argo-coffeeshopdb.png[retail-v1-argo-coffeeshopdb]] +link:/images/retail/retail-v1-argo-coffeeshopdb.png[image:/images/retail/retail-v1-argo-coffeeshopdb.png[retail-v1-argo-coffeeshopdb] === The Quarkus Coffeeshop Kafka https://github.com/validatedpatterns/retail/tree/main/charts/all/quarkuscoffeeshop-kafka[Chart] -This chart installs Kafka for use in the Retail pattern. It uses the Red -Hat AMQ Streams +This chart installs Kafka for use in the Retail pattern. It uses the Red Hat AMQ Streams https://access.redhat.com/documentation/en-us/red_hat_amq/7.2/html/using_amq_streams_on_openshift_container_platform/index[operator]. === The Quarkus Coffeeshop Pipelines https://github.com/validatedpatterns/retail/tree/main/charts/hub/quarkuscoffeeshop-pipelines[Chart] The pipelines chart defines build pipelines using the Red Hat OpenShift -Pipelines -https://catalog.redhat.com/software/operators/detail/5ec54a4628834587a6b85ca5[Operator] -(tektoncd). Pipelines are provided for all of the application images -that ship with the pattern; the pipelines all build the app from source, -deploy them to the "`demo`" namespace, and push them to the configured +Pipelines https://catalog.redhat.com/software/operators/detail/5ec54a4628834587a6b85ca5[Operator] (tektoncd). Pipelines are provided for all of the application images that ship with the pattern; the pipelines all build the app from source, deploy them to the "`demo`" namespace, and push them to the configured image registry. -Like the store and database charts, the kafka chart supports all three -modes of deployment. +Like the store and database charts, the kafka chart supports all three modes of deployment. -link:/images/retail/retail-v1-argo-pipelines.png[image:/images/retail/retail-v1-argo-pipelines.png[retail-v1-argo-pipelines]] +link:/images/retail/retail-v1-argo-pipelines.png[image:/images/retail/retail-v1-argo-pipelines.png[retail-v1-argo-pipelines] === The Quarkus Coffeeshop Landing Page https://github.com/validatedpatterns/retail/tree/main/charts/all/landing-page[Chart] -The Landing Page chart builds the page that presents the links for the -demos in the pattern. +The Landing Page chart builds the page that presents the links for the demos in the pattern. -link:/images/retail/retail-v1-argo-landing-page.png[image:/images/retail/retail-v1-argo-landing-page.png[retail-v1-landing-page]] +link:/images/retail/retail-v1-argo-landing-page.png[image:/images/retail/retail-v1-argo-landing-page.png[retail-v1-landing-page] diff --git a/content/patterns/retail/components.md b/content/patterns/retail/components.md deleted file mode 100644 index a3448224f..000000000 --- a/content/patterns/retail/components.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Components -weight: 30 -aliases: /retail/components/ ---- - -# Component Details - -## The Quarkus Coffeeshop Store [Chart](https://github.com/validatedpatterns/retail/tree/main/charts/store/quarkuscoffeeshop-charts) - -This chart is responsible for deploying the applications, services and routes for the Quarkus Coffeeshop demo. It models a set of microservices that would make sense for a coffeeshop retail operation. The detail of what the microservices do is [here](https://quarkuscoffeeshop.github.io/coffeeshop/). - -* [quarkuscoffeeshop-web](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-web) - -Serves as the "front end" for ordering food and drinks. - -* [quarkuscoffeeshop-counter](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-counter) - -The counter service receives the orders, persists them in the database, and notifies when they are ready. - -* [quarkuscoffeeshop-barista](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-barista) - -The barista service is responsible for preparing items from the "drink" side of the menu. - -* [quarkuscoffeeshop-kitchen](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-kitchen) - -The kitchen service is responsible for preparing items from the "food" side of the menu. - -* [quarkuscoffeeshop-customerloyalty](https://github.com/quarkuscoffeeshop/customerloyalty) - -The customerloyalty service is responsible for generating customer loyalty events, when a customer enters the "rewards" email. This data is not persisted or tracked anywhere. - -* [quarkuscoffeeshop-inventory](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-inventory) - -The inventory service is responsible for tracking food and drink inventory. - -* [quarkuscoffeeshop-customermocker](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-customermocker) - -The customermocker can be used to generate test traffic. - -* [quarkuscoffeeshop-majestic-monolith](https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-majestic-monolith) - -The "majestic monolith" builds all the apps into a single bundle, to simplify the process of deploying this app on single node systems. - -All the components look like this in ArgoCD when deployed: - -[![retail-v1-argo-coffeeshop-store](/images/retail/retail-v1-argo-coffeeshop-store.png)](/images/retail/retail-v1-argo-coffeeshop-store.png) - -The chart is designed such that the same chart can be deployed in the hub cluster as the "production" store, the "demo" or TEST store, and on a remote cluster. - -## The Quarkus Coffeeshop Database [Chart](https://github.com/validatedpatterns/retail/tree/main/charts/all/crunchy-pgcluster) - -This installs a database instance suitable for use in the Retail pattern. It uses the Crunchy PostgreSQL [Operator](https://github.com/CrunchyData/postgres-operator) to provide PostgreSQL services, which includes high availability and backup services by default, and other features available. - -Like the store chart, the Database chart can be deployed in the same different scenarios. - -In ArgoCD, it looks like this: - -[![retail-v1-argo-coffeeshopdb](/images/retail/retail-v1-argo-coffeeshopdb.png)](/images/retail/retail-v1-argo-coffeeshopdb.png) - -## The Quarkus Coffeeshop Kafka [Chart](https://github.com/validatedpatterns/retail/tree/main/charts/all/quarkuscoffeeshop-kafka) - -This chart installs Kafka for use in the Retail pattern. It uses the Red Hat AMQ Streams [operator](https://access.redhat.com/documentation/en-us/red_hat_amq/7.2/html/using_amq_streams_on_openshift_container_platform/index). - -## The Quarkus Coffeeshop Pipelines [Chart](https://github.com/validatedpatterns/retail/tree/main/charts/hub/quarkuscoffeeshop-pipelines) - -The pipelines chart defines build pipelines using the Red Hat OpenShift Pipelines [Operator](https://catalog.redhat.com/software/operators/detail/5ec54a4628834587a6b85ca5) (tektoncd). Pipelines are provided for all of the application images that ship with the pattern; the pipelines all build the app from source, deploy them to the "demo" namespace, and push them to the configured image registry. - -Like the store and database charts, the kafka chart supports all three modes of deployment. - -[![retail-v1-argo-pipelines](/images/retail/retail-v1-argo-pipelines.png)](/images/retail/retail-v1-argo-pipelines.png) - -## The Quarkus Coffeeshop Landing Page [Chart](https://github.com/validatedpatterns/retail/tree/main/charts/all/landing-page) - -The Landing Page chart builds the page that presents the links for the demos in the pattern. - -[![retail-v1-landing-page](/images/retail/retail-v1-argo-landing-page.png)](/images/retail/retail-v1-argo-landing-page.png) diff --git a/content/patterns/retail/getting-started.md b/content/patterns/retail/getting-started.md deleted file mode 100644 index 977ed63a4..000000000 --- a/content/patterns/retail/getting-started.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: Getting Started -weight: 10 -aliases: /retail/getting-started/ ---- - -# Deploying the Retail Pattern - -## Prerequisites - -1. An OpenShift cluster (Go to [the OpenShift console](https://console.redhat.com/openshift/create)). Cluster must have a dynamic StorageClass to provision PersistentVolumes. See also [sizing your cluster](../../retail/cluster-sizing). -1. (Optional) A second OpenShift cluster for a second store environment, "raleigh". -1. A GitHub account -1. (Optional) A quay account that can update images; this is if you want to use the pipelines to customize the applications -1. (Optional) A quay account with the following repositories set as public, and which you can write to: - - - quarkuscoffeeshop-barista - - quarkuscoffeeshop-counter - - quarkuscoffeeshop-customerloyalty - - quarkuscoffeeshop-customermocker - - quarkuscoffeeshop-inventory - - quarkuscoffeeshop-kitchen - - quarkuscoffeeshop-majestic-monolith - - quarkuscoffeeshop-web - - These repos comprise the microservices that are in the demo. The public repos (quay.io/hybrid-cloud-patterns/*) contain pre-built images which will be downloaded and used by default; so the demo will run regardless of whether you choose to rebuild the apps or not. This mechanism is provided for transparency purposes (so you can reproduce the same results); or if you want to customize or change the apps themselves in some way. - -The use of this pattern depends on having at least one running Red Hat -OpenShift cluster. All of the apps will run on a single cluster; optionally you can use RHACM to apply the store apps to a second cluster. - -If you do not have a running Red Hat OpenShift cluster you can start one on a -public or private cloud by using [Red Hat's cloud -service](https://console.redhat.com/openshift/create). - -## Prerequisite Tools - -Install the installation tooling dependencies. You will need: - -{% include prerequisite-tools.md %} - -## How to deploy - -1. Fork the [retail](https://github.com/validatedpatterns/retail) repository on GitHub. - -1. Clone the forked copy of the `retail` repo. Use branch `v1.0'. - - ```sh - git clone git@github.com:{your-username}/retail.git - cd retail - git checkout v1.0 - ``` - -1. You could create your own branch where you specific values will be pushed to: - - ```sh - git checkout -b my-branch - ``` - -1. A `values-secret.yaml` file is used to automate setup of secrets needed for: - - - A container image registry (E.g. Quay) - - DO NOT COMMIT THIS FILE. You do not want to push personal credentials to GitHub. - - ```sh - cp values-secret.yaml.template ~/values-secret.yaml - vi ~/values-secret.yaml - ``` - -1. Customize the deployment for your cluster. Change the appropriate values in `values-global.yaml` - - ```sh - vi values-global.yaml - git add values-global.yaml - git commit values-global.yaml - git push origin my-branch - ``` - -In particular, the values that you need to change are under the `imageregistry` key, to use your own account and hostname. If you like, you can change the git settings (`account`, `email`, `hostname` to reflect your own account settings). - -If you plan to customize the build of the applications themselves, there `revision` and `imageTag` settings for each of them. The defaults should suffice if you just want to see the apps running. - -1. You can deploy the pattern using the [validated pattern operator](/infrastructure/using-validated-pattern-operator/). If you do use the operator then skip to Validating the Environment below. - -1. Preview the changes - - ```sh - ./pattern.sh make show - ``` - -1. Login to your cluster using oc login or exporting the KUBECONFIG - - ```sh - oc login - ``` - - or - - ```sh - export KUBECONFIG=~/my-ocp-env/retail-hub - ``` - -1. Apply the changes to your cluster - - ```sh - ./pattern-util.sh make install - ``` - -This will execute `make install` in the team's container, which will take a bit to load the first time. It contains ansible and other dependencies so that you do not need to install them on your workstation. - -The default `install` target will: - -1. Install the pattern via the operator -1. Load the imageregistry secret into the vault -1. Start the application build pipelines - -If you chose not to put in your registry credential, `make install` cannot complete successfully because it waits for the secret to be populated before starting the pipelines. - -If you do not want to run the (optional) components, another install target is provided: - -```text -./common/scripts/pattern-util.sh make install-no-pipelines -``` - -This skips the vault setup and the pipeline builds, but still installs both Vault and the Pipelines operator, so if you want to run those in your installation later, you can run `make install` to enable them. - -For more information on secrets management see [here](/secrets). For information on Hashicorp's Vault see [here](/secrets/vault) - -## Validating the Environment - -Check the operators have been installed - - ```text - UI -> Installed Operators - ``` - -[![retail-v1-operators](/images/retail/retail-v1-operators.png)](/images/retail/retail-v1-operators.png) - -The OpenShift console menu should look like this. We will use it to validate that the pattern is working as expected: - -[![retail-v1-console-menu](/images/retail/retail-v1-console-menu.png)](/images/retail/retail-v1-console-menu.png) - -Check on the pipelines, if you chose to run them. They should all complete successfully: - -[![retail-v1-pipelines](/images/retail/retail-v1-pipelines.png)](/images/retail/retail-v1-pipelines.png) - -Ensure that the Hub ArgoCD instance shows all of its apps in Healthy and Synced status once all of the images have been built: - -[![retail-v1-argo-apps-p1](/images/retail/retail-v1-argo-apps-p1.png)](/images/retail/retail-v1-argo-apps-p1.png) - -We will go to the Landing Page, which will present the applications in the pattern: - -[![retail-v1-landing-page](/images/retail/retail-v1-landing-page.png)](/images/retail/retail-v1-landing-page.png) - -Clicking on the Store Web Page will place us in the Quarkus Coffeeshop Demo: - -[![retail-v1-store-page](/images/retail/retail-v1-store-page.png)](/images/retail/retail-v1-store-page.png) - -Clicking on the TEST Store Web Page will place us in a separate copy of the same demo. - -Clicking on the respective Kafdrop links will go to a Kafdrop instance that allows inspection of each of the respective environments. - -[![retail-v1-kafdrop](/images/retail/retail-v1-kafdrop.png)](/images/retail/retail-v1-kafdrop.png) - -## Next Steps - -[Help & Feedback](https://groups.google.com/g/validatedpatterns){: .btn .fs-5 .mb-4 .mb-md-0 .mr-2 } -[Report Bugs](https://github.com/validatedpatterns/retail/issues){: .btn .btn-red .fs-5 .mb-4 .mb-md-0 .mr-2 } diff --git a/content/patterns/retail/ideas-for-customization.adoc b/content/patterns/retail/ideas-for-customization.adoc deleted file mode 100644 index cc68c9e5b..000000000 --- a/content/patterns/retail/ideas-for-customization.adoc +++ /dev/null @@ -1 +0,0 @@ -== Ideas for Customization diff --git a/content/patterns/retail/ideas-for-customization.md b/content/patterns/retail/ideas-for-customization.md deleted file mode 100644 index 5d450b128..000000000 --- a/content/patterns/retail/ideas-for-customization.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: Ideas for Customization -weight: 60 -aliases: /retail/ideas-for-customization/ ---- - -# Ideas for Customization - diff --git a/content/patterns/retail/store.md b/content/patterns/retail/store.md deleted file mode 100644 index 879ae34f4..000000000 --- a/content/patterns/retail/store.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: Store Sites -weight: 20 -aliases: /retail/store/ ---- - -# Having a store (edge) cluster join the datacenter (hub) - -## Allow ACM to deploy the store application to a subset of clusters - -A store ("ATLANTA") is installed on the hub cluster by default. This feature is interesting if you want to see how ACM can manage a remote cluster to install the same application on a different cluster. - -The way we apply this is through the managedClusterGroups block in `values-hub.yaml`: - -```json - managedClusterGroups: - - name: store - clusterSelector: - matchLabels: - clusterGroup: raleigh - matchExpressions: - - key: vendor - operator: In - values: - - OpenShift -``` - -Any cluster joined with the label `clusterGroup=raleigh` will be assigned the policies that deploy the store app to them. - -## Deploy a store cluster - -Rather than provide instructions on creating a store cluster it is assumed -that an OpenShift cluster has already been created. Use the `openshift-install` program provided at [cloud.redhat.com](https://console.redhat.com/openshift/create "Create an OpenShift cluster") - -There are a three ways to join the store to the datacenter. - -* Using the ACM user interface -* Using the `cm` tool -* Using the `clusteradm` tool - -## Store setup using the ACM UI - -After ACM is installed a message regarding a "Web console update is available" may be displayed. -Click on the "Refresh web console" link. - -On the upper-left side you'll see a pull down labeled "local-cluster". Select "All Clusters" from this pull down. -This will navigate to the ACM console and to its "Clusters" section - -Select the "Import cluster" option beside the Create Cluster button. - -![import-cluster](/images/import-cluster.png "Select Import cluster") - -On the "Import an existing cluster" page, enter the cluster name and choose Kubeconfig as the "import mode". Add the tag `site=store` Press import. Done. - -![import-with-kubeconfig](/images/import-with-kubeconfig.png "Import using kubeconfig") - -Using this method, you are done. Skip to the section [Store is joined](#store-is-joined) but ignore the part about adding the site tag. - -## Store setup using `cm` tool - -1. Install the `cm` (cluster management) command-line tool. See details [here](https://github.com/open-cluster-management/cm-cli/#installation) - -1. Obtain the KUBECONFIG file from the edge/store cluster. - -1. On the command-line login into the hub/datacenter cluster (use `oc login` or export the KUBECONFIG). - -1. Run the following command: - -```sh -cm attach cluster --cluster --cluster-kubeconfig -``` - -Skip to the section [Store is joined](#store-is-joined) - -## Store setup using `clusteradm` tool - -You can also use `clusteradm` to join a cluster. The following instructions explain what needs to be done. `clusteradm` is still in testing. - -1. To deploy a edge cluster you will need to get the datacenter (or hub) cluster's token. You will need to install `clusteradm`. On the existing *datacenter cluster*: - - `clusteradm get token` - -1. When you run the `clusteradm` command above it replies with the token and also shows you the command to use on the store. So first you must login to the store cluster - - `oc login` - or - - `export KUBECONFIG=~/my-ocp-env/store` - -1. Then request to that the store join the datacenter hub - - `clusteradm join --hub-token ` - -1. Back on the hub cluster accept the join request - - `clusteradm accept --clusters ` - -Skip to the next section, [Store is joined](#store-is-joined) - -## Store is joined - -### You're done - -That's it! Go to your store (edge) OpenShift console and check for the open-cluster-management-agent pod being launched. Be patient, it will take a while for the ACM agent and agent-addons to launch. After that, the operator OpenShift GitOps will run. When it's finished coming up launch the OpenShift GitOps (ArgoCD) console from the top right of the OpenShift console. diff --git a/content/patterns/retail/troubleshooting.adoc b/content/patterns/retail/troubleshooting.adoc deleted file mode 100644 index 37819b535..000000000 --- a/content/patterns/retail/troubleshooting.adoc +++ /dev/null @@ -1,3 +0,0 @@ -== Troubleshooting - -=== Our https://github.com/validatedpatterns/industrial-edge/issues[Issue Tracker] diff --git a/content/patterns/retail/troubleshooting.md b/content/patterns/retail/troubleshooting.md deleted file mode 100644 index afc1800fa..000000000 --- a/content/patterns/retail/troubleshooting.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Troubleshooting -weight: 40 -aliases: /retail/troubleshooting/ ---- - -# Troubleshooting - -## Our [Issue Tracker](https://github.com/validatedpatterns/industrial-edge/issues) diff --git a/modules/retail-example-applications.adoc b/modules/retail-example-applications.adoc index 8a8e5f9d4..1e231a9f6 100644 --- a/modules/retail-example-applications.adoc +++ b/modules/retail-example-applications.adoc @@ -43,7 +43,6 @@ the regular instance and the TEST instance, has its own instance of each of these supporting services it uses. ==== - . Order by clicking the `Place an Order` button on the front page. The menu should look like this: + From 59b051b44b5e5ac9d39019ac1438f10a0b56a291 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 14:33:12 +0000 Subject: [PATCH 06/19] correcting image path --- modules/retail-deploying.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 6edea7d43..2d807ae1f 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -173,7 +173,7 @@ $ ./pattern.sh make install .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. + - link:/images/retail/retail-v1-operators.png[image:/images/retail/retail-v1-operators.png[retail-v1-operators] + image::/images/retail/retail-v1-operators.png[retail-v1-operators] . Track the progress through the Hub ArgoCD UI from the nines menu: + From c66b29b3705feebe7c5079b25155c160f9e6e350 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 14:39:12 +0000 Subject: [PATCH 07/19] correcting image path 2 --- modules/retail-deploying.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 2d807ae1f..66e153732 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -173,7 +173,7 @@ $ ./pattern.sh make install .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. + - image::/images/retail/retail-v1-operators.png[retail-v1-operators] + image::/images/retail/retail-v1-operators.png[link="/images/retail/retail-v1-operators.png,retail-v1-operators] . Track the progress through the Hub ArgoCD UI from the nines menu: + From 3ee2a3ddaf1b6cd179fe6ed3aed9f95357976393 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 14:50:38 +0000 Subject: [PATCH 08/19] correcting image path 3 --- modules/retail-deploying.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 66e153732..8c1d04cfb 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -177,7 +177,7 @@ $ ./pattern.sh make install . Track the progress through the Hub ArgoCD UI from the nines menu: + -link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] +image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] . Ensure that the Hub ArgoCD instance shows all of its apps in Healthy and Synced status once all of the images have been built: + From 5025bceaa92f9053b3ef895de837ae1e56dbe419 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 14:55:04 +0000 Subject: [PATCH 09/19] fixing image display issue --- modules/retail-deploying.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 8c1d04cfb..445ee265c 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -173,7 +173,7 @@ $ ./pattern.sh make install .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. + - image::/images/retail/retail-v1-operators.png[link="/images/retail/retail-v1-operators.png,retail-v1-operators] + image::/images/retail/retail-v1-operators.png[link="/images/retail/retail-v1-operators.png",retail-v1-operators] . Track the progress through the Hub ArgoCD UI from the nines menu: + From d51849aa632469688378feca1d5d38ef7dc3fd40 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 14:58:11 +0000 Subject: [PATCH 10/19] fixing image display issue 2 --- modules/retail-deploying.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 445ee265c..85d308c57 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -173,7 +173,7 @@ $ ./pattern.sh make install .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. + - image::/images/retail/retail-v1-operators.png[link="/images/retail/retail-v1-operators.png",retail-v1-operators] + image:/images/retail/retail-v1-operators.png[retail-v1-operators] . Track the progress through the Hub ArgoCD UI from the nines menu: + From ab3275799b736e72b6ffa67c7ebc884f1adf3af8 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 15:03:32 +0000 Subject: [PATCH 11/19] fixing image display issue 3 --- modules/retail-deploying.adoc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index 85d308c57..c6040ad91 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -172,8 +172,8 @@ $ ./pattern.sh make install .. To verify, in the OpenShift Container Platform web console, navigate to *Operators → Installed Operators* page. .. Set your project to `All Projects` and verify the operators are installed and have a status of `Succeeded`. - + - image:/images/retail/retail-v1-operators.png[retail-v1-operators] ++ +image:/images/retail/retail-v1-operators.png[retail-v1-operators] . Track the progress through the Hub ArgoCD UI from the nines menu: + @@ -181,22 +181,22 @@ image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] . Ensure that the Hub ArgoCD instance shows all of its apps in Healthy and Synced status once all of the images have been built: + -link:/images/retail/retail-v1-argo-apps-p1.png[image:/images/retail/retail-v1-argo-apps-p1.png[retail-v1-argo-apps-p1] +image:/images/retail/retail-v1-argo-apps-p1.png[retail-v1-argo-apps-p1] . Check on the pipelines, if you chose to run them. They should all complete successfully: + -link:/images/retail/retail-v1-pipelines.png[image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines] +image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines] . Go to the *Quarkus Coffeeshop Landing Page* where you are presented with the applications in the pattern: + -link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] +image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] . Click the *Store Web Page* to open the Quarkus Coffeeshop Demo: + -link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] +image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] . Click the *TEST Store Web Page* to open a separate copy of the same demo. . Clicking the respective *Kafdrop* links to go to a Kafdrop instance that allows inspection of each of the respective environments. + -link:/images/retail/retail-v1-kafdrop.png[image:/images/retail/retail-v1-kafdrop.png[retail-v1-kafdrop] +image:/images/retail/retail-v1-kafdrop.png[retail-v1-kafdrop] From ae59a432588dc655dd099795e442d6a55685c7f7 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 15:20:27 +0000 Subject: [PATCH 12/19] cropping image --- modules/retail-deploying.adoc | 2 +- .../images/retail/retail-v1-landing-page-1.png | Bin 0 -> 35809 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 static/images/retail/retail-v1-landing-page-1.png diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index c6040ad91..e09109cdd 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -189,7 +189,7 @@ image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines] . Go to the *Quarkus Coffeeshop Landing Page* where you are presented with the applications in the pattern: + -image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] +image:/images/retail/retail-v1-landing-page-1.png[retail-v1-landing-page] . Click the *Store Web Page* to open the Quarkus Coffeeshop Demo: + diff --git a/static/images/retail/retail-v1-landing-page-1.png b/static/images/retail/retail-v1-landing-page-1.png new file mode 100644 index 0000000000000000000000000000000000000000..24a472ec25d7f1a0fb335834f1c5a4df6aa83ebe GIT binary patch literal 35809 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 literal 0 HcmV?d00001 From 00e5402eef95e2839a24f0545fc256911d1c9b92 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 15:22:44 +0000 Subject: [PATCH 13/19] cropping image 2 --- .../images/retail/retail-v1-landing-page.png | Bin 38584 -> 28119 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/static/images/retail/retail-v1-landing-page.png b/static/images/retail/retail-v1-landing-page.png index fff5c07b8cbbbc7e42d3479e12d9b64a6f08732b..d7798a0bdb4ccd3c4a75158161867ec06888106b 100644 GIT binary patch literal 28119 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�bgeU%V2=@t#<5o0)hf~fuc)VQBqH4;T(EjN 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 From ba591b7d6b45a2935ddc9958c4674f9c1d351c37 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 15:26:33 +0000 Subject: [PATCH 14/19] cropping image 3 --- modules/retail-deploying.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-deploying.adoc b/modules/retail-deploying.adoc index e09109cdd..c6040ad91 100644 --- a/modules/retail-deploying.adoc +++ b/modules/retail-deploying.adoc @@ -189,7 +189,7 @@ image:/images/retail/retail-v1-pipelines.png[retail-v1-pipelines] . Go to the *Quarkus Coffeeshop Landing Page* where you are presented with the applications in the pattern: + -image:/images/retail/retail-v1-landing-page-1.png[retail-v1-landing-page] +image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] . Click the *Store Web Page* to open the Quarkus Coffeeshop Demo: + From c7d152a926823745dd6b58dd6e30bf0db3d14b1a Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 15:43:42 +0000 Subject: [PATCH 15/19] cropping image 4 --- content/patterns/retail/application.adoc | 2 +- content/patterns/retail/components.adoc | 17 +++---- content/patterns/retail/store.adoc | 4 +- modules/retail-example-applications.adoc | 60 +++++++++--------------- 4 files changed, 32 insertions(+), 51 deletions(-) diff --git a/content/patterns/retail/application.adoc b/content/patterns/retail/application.adoc index be01afe7a..11d1afbfa 100644 --- a/content/patterns/retail/application.adoc +++ b/content/patterns/retail/application.adoc @@ -1,5 +1,5 @@ --- -title: Demonstrating retail example applications +title: Demonstrating a retail example applications weight: 40 aliases: /retail/application-demos/ --- diff --git a/content/patterns/retail/components.adoc b/content/patterns/retail/components.adoc index 0b08bd085..e27b31195 100644 --- a/content/patterns/retail/components.adoc +++ b/content/patterns/retail/components.adoc @@ -13,8 +13,7 @@ include::modules/comm-attributes.adoc[] === The Quarkus Coffeeshop Store https://github.com/validatedpatterns/retail/tree/main/charts/store/quarkuscoffeeshop-charts[Chart] This chart is responsible for deploying the applications, services and routes for the Quarkus Coffeeshop demo. It models a set of microservices -that would make sense for a coffeeshop retail operation. The detail of what the microservices do is -https://quarkuscoffeeshop.github.io/coffeeshop/[here]. +that would make sense for a coffeeshop retail operation. The detail of what the microservices do is https://quarkuscoffeeshop.github.io/coffeeshop/[here]. * https://github.com/quarkuscoffeeshop/quarkuscoffeeshop-web[quarkuscoffeeshop-web] - Serves as the `front end` for ordering food and drinks. @@ -34,7 +33,7 @@ https://quarkuscoffeeshop.github.io/coffeeshop/[here]. All the components look like this in ArgoCD when deployed: -link:/images/retail/retail-v1-argo-coffeeshop-store.png[image:/images/retail/retail-v1-argo-coffeeshop-store.png[retail-v1-argo-coffeeshop-store] +image:/images/retail/retail-v1-argo-coffeeshop-store.png[retail-v1-argo-coffeeshop-store] The chart is designed such that the same chart can be deployed in the hub cluster as the `production` store, the `demo` or `TEST` store, and on a remote cluster. @@ -42,11 +41,11 @@ The chart is designed such that the same chart can be deployed in the hub cluste This installs a database instance suitable for use in the Retail pattern. It uses the Crunchy PostgreSQL https://github.com/CrunchyData/postgres-operator[Operator] to provide PostgreSQL services, which includes high availability and backup services by default, and other features available. -Like the store chart, the Database chart can be deployed in the same different scenarios. +Similar to the store chart, the Database chart can be deployed in the same variety of scenarios. In ArgoCD, it looks like this: -link:/images/retail/retail-v1-argo-coffeeshopdb.png[image:/images/retail/retail-v1-argo-coffeeshopdb.png[retail-v1-argo-coffeeshopdb] +image:/images/retail/retail-v1-argo-coffeeshopdb.png[retail-v1-argo-coffeeshopdb] === The Quarkus Coffeeshop Kafka https://github.com/validatedpatterns/retail/tree/main/charts/all/quarkuscoffeeshop-kafka[Chart] @@ -55,16 +54,14 @@ https://access.redhat.com/documentation/en-us/red_hat_amq/7.2/html/using_amq_str === The Quarkus Coffeeshop Pipelines https://github.com/validatedpatterns/retail/tree/main/charts/hub/quarkuscoffeeshop-pipelines[Chart] -The pipelines chart defines build pipelines using the Red Hat OpenShift -Pipelines https://catalog.redhat.com/software/operators/detail/5ec54a4628834587a6b85ca5[Operator] (tektoncd). Pipelines are provided for all of the application images that ship with the pattern; the pipelines all build the app from source, deploy them to the "`demo`" namespace, and push them to the configured -image registry. +The pipelines chart defines build pipelines using the Red Hat OpenShift Pipelines https://catalog.redhat.com/software/operators/detail/5ec54a4628834587a6b85ca5[Operator] (tektoncd). Pipelines are provided for all of the application images that ship with the pattern; the pipelines all build the app from source, deploy them to the `demo` namespace, and push them to the configured image registry. Like the store and database charts, the kafka chart supports all three modes of deployment. -link:/images/retail/retail-v1-argo-pipelines.png[image:/images/retail/retail-v1-argo-pipelines.png[retail-v1-argo-pipelines] +image:/images/retail/retail-v1-argo-pipelines.png[retail-v1-argo-pipelines] === The Quarkus Coffeeshop Landing Page https://github.com/validatedpatterns/retail/tree/main/charts/all/landing-page[Chart] The Landing Page chart builds the page that presents the links for the demos in the pattern. -link:/images/retail/retail-v1-argo-landing-page.png[image:/images/retail/retail-v1-argo-landing-page.png[retail-v1-landing-page] +image:/images/retail/retail-v1-argo-landing-page.png[retail-v1-landing-page] diff --git a/content/patterns/retail/store.adoc b/content/patterns/retail/store.adoc index 1602b2e3b..d23e3ca9c 100644 --- a/content/patterns/retail/store.adoc +++ b/content/patterns/retail/store.adoc @@ -1,5 +1,5 @@ --- -title: Managed cluster sites +title: Managed store sites weight: 30 aliases: /retail/retail-managed-cluster/ --- @@ -17,7 +17,7 @@ A store ("`ATLANTA`") is installed on the hub cluster by default. This feature i cluster to install the same application on a different cluster. The way we apply this is through the `managedClusterGroups` block in `values-hub.yaml`: -+ + [source,yaml] ---- managedClusterGroups: diff --git a/modules/retail-example-applications.adoc b/modules/retail-example-applications.adoc index 1e231a9f6..acfedc39b 100644 --- a/modules/retail-example-applications.adoc +++ b/modules/retail-example-applications.adoc @@ -4,63 +4,47 @@ [id="deploying-mcg-pattern"] = Demonstrating Retail example applications -Up until now the Retail validated pattern has focused primarily on -successfully deploying the architectural pattern. Now it is time to see +Up until now the retail validated pattern has focused primarily on successfully deploying the architectural pattern. Now it is time to see the actual applications running as we have deployed them. -If you have already deployed the hub cluster, then you have already seen -several applications deployed in the OpenShift GitOps console. If you -haven’t done this then we recommend you deploy the hub after you have -setup the Quay repositories described below. +If you have already deployed the hub cluster, then you have already seen several applications deployed in the OpenShift GitOps console. If you +have not done this then we recommend you deploy the hub after you have setup the Quay repositories described below. == Ordering Items at the Coffeeshop -The easiest way to get to the coffeeshop store page is from the -OpenShift Console Menu Landing Page entry: +The easiest way to get to the coffeeshop store page is from the OpenShift Console Menu Landing Page entry: -link:/images/retail/retail-v1-console-menu.png[image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] +image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] -1. Click the *Quarkus Coffeeshop Landing Page* link will bring you to -this page: +1. Click the *Quarkus Coffeeshop Landing Page* link will bring you to this page: + -link:/images/retail/retail-v1-landing-page.png[image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] +image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] -2. Select either the `Store Web Page` or "`TEST Store Web Page`" -links brings you to a screen that looks like this: +2. Select either the `Store Web Page` or `TEST Store Web Page` links brings you to a screen that looks like this: + -link:/images/retail/retail-v1-store-page.png[image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] +image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] + [NOTE] ==== -The applications are initially identical. The `TEST`" site is -deployed to the `quarkuscoffeeshop-demo` namespace; the regular Store -site is deployed to the `quarkuscoffeeshop-store` namespace. +The applications are initially identical. The `TEST`" site is deployed to the `quarkuscoffeeshop-demo` namespace; the regular Store site is deployed to the `quarkuscoffeeshop-store` namespace. -Each store requires supporting services, in PostgreSQL and Kafka. In our -pattern, PostgreSQL is provided by the Crunchy PostgreSQL operator, and -Kafka is provided by the Red Hat AMQ Streams operator. Each instance, -the regular instance and the TEST instance, has its own instance of each -of these supporting services it uses. +Each store requires supporting services, in PostgreSQL and Kafka. In our pattern, PostgreSQL is provided by the Crunchy PostgreSQL operator, and Kafka is provided by the Red Hat AMQ Streams operator. Each instance, the regular instance and the TEST instance, has its own instance of each of these supporting services it uses. ==== -. Order by clicking the `Place an Order` button on the front page. The -menu should look like this: +. Order by clicking the `Place an Order` button on the front page. The menu should look like this: + -link:/images/retail/retail-v1-store-web-menu.png[image:/images/retail/retail-v1-store-web-menu.png[retail-v1-store-web-menu]] +image:/images/retail/retail-v1-store-web-menu.png[retail-v1-store-web-menu] -. Click the `Add` button next to a menu item; the item name will appear. -Add a name for the order: - -link:/images/retail/retail-v1-order-p1.png[image:/images/retail/retail-v1-order-p1.png[retail-v1-order-p1]] - -You can add as many orders as you want. On your last item, click the -"`Place Order`" button on the item dialog: - -link:/images/retail/retail-v1-place-order.png[image:/images/retail/retail-v1-place-order.png[retail-v1-place-order]] +. Click the `Add` button next to a menu item; the item name will appear. Add a name for the order: ++ +image:/images/retail/retail-v1-order-p1.png[image:/images/retail/retail-v1-order-p1.png[retail-v1-order-p1] -As the orders are serviced by the barista and kitchen services, you can -see their status in the "`Orders`" section of the page: +. Add as many orders as you want. On your last item, click the `Place Order` button on the item dialog: ++ +image:/images/retail/retail-v1-place-order.png[image:/images/retail/retail-v1-place-order.png[retail-v1-place-order] -link:/images/retail/retail-v1-orders-status.png[image:/images/retail/retail-v1-orders-status.png[retail-v1-orders-status] +As the orders are serviced by the barista and kitchen services, you can see their status in the `Orders` section of the page: ++ +image:/images/retail/retail-v1-orders-status.png[retail-v1-orders-status] From 8096ccab62a9f7e3a0a1dc4186921171b6ebfa35 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Fri, 21 Mar 2025 15:49:47 +0000 Subject: [PATCH 16/19] tidying up misc --- modules/retail-example-applications.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/retail-example-applications.adoc b/modules/retail-example-applications.adoc index acfedc39b..8c47d51a7 100644 --- a/modules/retail-example-applications.adoc +++ b/modules/retail-example-applications.adoc @@ -44,7 +44,7 @@ image:/images/retail/retail-v1-order-p1.png[image:/images/retail/retail-v1-order image:/images/retail/retail-v1-place-order.png[image:/images/retail/retail-v1-place-order.png[retail-v1-place-order] As the orders are serviced by the barista and kitchen services, you can see their status in the `Orders` section of the page: -+ + image:/images/retail/retail-v1-orders-status.png[retail-v1-orders-status] From 1aeeae3afc0501e3ffbff4113f5f53dedfb16704 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Mon, 24 Mar 2025 10:26:49 +0000 Subject: [PATCH 17/19] adding cluster sizinf for travelops --- .../comm-deploying-managed-cluster-using-cm-cli-tool.adoc | 6 +++--- modules/retail-example-applications.adoc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/comm-deploying-managed-cluster-using-cm-cli-tool.adoc b/modules/comm-deploying-managed-cluster-using-cm-cli-tool.adoc index c11a29fc8..3b60136ac 100644 --- a/modules/comm-deploying-managed-cluster-using-cm-cli-tool.adoc +++ b/modules/comm-deploying-managed-cluster-using-cm-cli-tool.adoc @@ -20,20 +20,20 @@ + [source,terminal] ---- -oc login +$ oc login --token= --server=https://api..:6443 ---- or + [source,terminal] ---- -export KUBECONFIG=~/ +$ export KUBECONFIG=~/ ---- . Run the following command: + [source,terminal] ---- -cm attach cluster --cluster --cluster-kubeconfig +$ cm attach cluster --cluster --cluster-kubeconfig ---- [role="_next-steps"] diff --git a/modules/retail-example-applications.adoc b/modules/retail-example-applications.adoc index 8c47d51a7..073d7b81b 100644 --- a/modules/retail-example-applications.adoc +++ b/modules/retail-example-applications.adoc @@ -16,11 +16,11 @@ The easiest way to get to the coffeeshop store page is from the OpenShift Consol image:/images/retail/retail-v1-console-menu.png[retail-v1-console-menu] -1. Click the *Quarkus Coffeeshop Landing Page* link will bring you to this page: +. Click the *Quarkus Coffeeshop Landing Page* link will bring you to this page: + image:/images/retail/retail-v1-landing-page.png[retail-v1-landing-page] -2. Select either the `Store Web Page` or `TEST Store Web Page` links brings you to a screen that looks like this: +. Select either the `Store Web Page` or `TEST Store Web Page` links brings you to a screen that looks like this: + image:/images/retail/retail-v1-store-page.png[retail-v1-store-page] + From fd1b2ae1026a0fdbcde4796c94e63c1c68b5eb8c Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Mon, 24 Mar 2025 10:26:57 +0000 Subject: [PATCH 18/19] adding cluster sizinf for travelops --- content/patterns/travelops/cluster-sizing.adoc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 content/patterns/travelops/cluster-sizing.adoc diff --git a/content/patterns/travelops/cluster-sizing.adoc b/content/patterns/travelops/cluster-sizing.adoc new file mode 100644 index 000000000..228882ca0 --- /dev/null +++ b/content/patterns/travelops/cluster-sizing.adoc @@ -0,0 +1,14 @@ +--- +title: Cluster Sizing +weight: 60 +aliases: /retail/travelops-sizing/ +--- + +:toc: +:imagesdir: /images +:_content-type: ASSEMBLY + +include::modules/comm-attributes.adoc[] +include::modules/travelops/metadata-travelops.adoc[] + +include::modules/cluster-sizing-template.adoc[] From 853daf8e47115b07a7edf607ceb361301c6fce01 Mon Sep 17 00:00:00 2001 From: Kevin Quinn Date: Mon, 24 Mar 2025 10:32:52 +0000 Subject: [PATCH 19/19] fixing soem minor look and feel errors --- content/learn/vp_add_ops_to_pattern.adoc | 4 ++-- content/learn/vp_add_specific_ops_to_pattern.adoc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/content/learn/vp_add_ops_to_pattern.adoc b/content/learn/vp_add_ops_to_pattern.adoc index d1f513216..5ce9af4a8 100644 --- a/content/learn/vp_add_ops_to_pattern.adoc +++ b/content/learn/vp_add_ops_to_pattern.adoc @@ -3,7 +3,7 @@ menu: learn: parent: Validated patterns frameworks title: Adding Operators to the framework -weight: 23 +weight: 26 aliases: /ocp-framework/adding-operator-to-framework/ --- @@ -39,7 +39,7 @@ This procedure describes how subscriptions to Operators are added to the validat For example, if you want to deploy Advanced Cluster Management, AMQ (messaging) and AMQ Streams (Kafka) in your factory cluster, you would follow the guidance here: The assumption is there is a `values-factory.yaml` file that is used to deploy the factory cluster. The file should include the following entries: -+ + [source,yaml] ---- namespaces: diff --git a/content/learn/vp_add_specific_ops_to_pattern.adoc b/content/learn/vp_add_specific_ops_to_pattern.adoc index d3b915a85..8280d42f9 100644 --- a/content/learn/vp_add_specific_ops_to_pattern.adoc +++ b/content/learn/vp_add_specific_ops_to_pattern.adoc @@ -3,7 +3,7 @@ menu: learn: parent: Validated patterns frameworks title: Adding a specific operator to hub values file -weight: 24 +weight: 27 aliases: /ocp-framework/adding-specific-operator-to-hub/ ---