diff --git a/applications/onlineboutique/README.md b/applications/onlineboutique/README.md new file mode 100644 index 00000000..8e086910 --- /dev/null +++ b/applications/onlineboutique/README.md @@ -0,0 +1,23 @@ +# Onlineboutique + +Demo replicated app for the google [onlineboutique](https://github.com/GoogleCloudPlatform/microservices-demo) microservices demo + +The purpose of this app is to demonstrate porting an existing established helm chart into a replicated release. + +# Currently implemented: + +- Initial set of helm values mapped to config options +- Config dependant status informers +- Embedded Cluster +- Replicated SDK included + + +# TODO: + +This is a work in progress, and there are several outstanding tasks: + +- Complete integration of helm values into replicated config options +- Use Replicated Proxy for images +- Ingress and TLS +- Custom metrics +- Build pipelines diff --git a/applications/onlineboutique/chart/Chart.yaml b/applications/onlineboutique/chart/Chart.yaml new file mode 100644 index 00000000..d20d11dd --- /dev/null +++ b/applications/onlineboutique/chart/Chart.yaml @@ -0,0 +1,11 @@ +# NOTICE modified by hedge-sparrow +apiVersion: v2 +appVersion: v0.9.0 +description: A Helm chart for Kubernetes for Online Boutique +name: onlineboutique +type: application +version: 0.14.0 +dependencies: +- name: replicated + repository: oci://registry.replicated.com/library + version: 1.0.0-beta.31 diff --git a/applications/onlineboutique/chart/LICENSE b/applications/onlineboutique/chart/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/applications/onlineboutique/chart/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/applications/onlineboutique/chart/README.md b/applications/onlineboutique/chart/README.md new file mode 100644 index 00000000..3073afc8 --- /dev/null +++ b/applications/onlineboutique/chart/README.md @@ -0,0 +1,38 @@ +# Helm chart for Online Boutique + +If you'd like to deploy Online Boutique via its Helm chart, you could leverage the following instructions. + +**Warning:** Online Boutique's Helm chart is currently experimental. If you have feedback or run into issues, let us know inside [GitHub Issue #1319](https://github.com/GoogleCloudPlatform/microservices-demo/issues/1319) or by creating a [new GitHub Issue](https://github.com/GoogleCloudPlatform/microservices-demo/issues/new/choose). + +Deploy the default setup of Online Boutique: +```sh +helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \ + --install +``` + +Deploy advanced scenario of Online Boutique: +```sh +helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \ + --install \ + --create-namespace \ + --set images.repository=us-docker.pkg.dev/my-project/containers/onlineboutique \ + --set frontend.externalService=false \ + --set redis.create=false \ + --set cartservice.database.type=spanner \ + --set cartservice.database.connectionString=projects/my-project/instances/onlineboutique/databases/carts \ + --set serviceAccounts.create=true \ + --set authorizationPolicies.create=true \ + --set networkPolicies.create=true \ + --set sidecars.create=true \ + --set frontend.virtualService.create=true \ + --set 'serviceAccounts.annotations.iam\.gke\.io/gcp-service-account=spanner-db-user@my-project.iam.gserviceaccount.com' \ + --set serviceAccounts.annotationsOnlyForCartservice=true \ + -n onlineboutique +``` + +For the full list of configurations, see [values.yaml](./values.yaml). + +You could also find advanced scenarios with these blogs below: +- [Online Boutique sample’s Helm chart, to simplify the setup of advanced and secured scenarios with Service Mesh and GitOps](https://medium.com/google-cloud/246119e46d53) +- [gRPC health probes with Kubernetes 1.24+](https://medium.com/google-cloud/b5bd26253a4c) +- [Use Google Cloud Spanner with the Online Boutique sample](https://medium.com/google-cloud/f7248e077339) \ No newline at end of file diff --git a/applications/onlineboutique/chart/templates/NOTES.txt b/applications/onlineboutique/chart/templates/NOTES.txt new file mode 100644 index 00000000..35cb49a8 --- /dev/null +++ b/applications/onlineboutique/chart/templates/NOTES.txt @@ -0,0 +1,15 @@ +{{- if and .Values.frontend.create .Values.frontend.externalService }} +Note: It may take a few minutes for the LoadBalancer IP to be available. + +Watch the status of the frontend IP address with: + kubectl get --namespace {{ .Release.Namespace }} svc -w {{ .Values.frontend.name }}-external + +Get the external IP address of the frontend: + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ .Values.frontend.name }}-external --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP +{{- end }} +{{- if .Values.frontend.virtualService.create }} +Get the external IP address of the ingress gateway: + export SERVICE_IP=$(kubectl get svc --namespace {{ .Values.frontend.virtualService.gateway.namespace }} {{ .Values.frontend.virtualService.gateway.name }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP +{{- end }} diff --git a/applications/onlineboutique/chart/templates/adservice.yaml b/applications/onlineboutique/chart/templates/adservice.yaml new file mode 100644 index 00000000..32d7d933 --- /dev/null +++ b/applications/onlineboutique/chart/templates/adservice.yaml @@ -0,0 +1,158 @@ +{{- if .Values.adService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.adService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.adService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.adService.name }} + template: + metadata: + labels: + app: {{ .Values.adService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.adService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.adService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 9555 + env: + - name: PORT + value: "9555" + resources: + {{- toYaml .Values.adService.resources | nindent 10 }} + readinessProbe: + initialDelaySeconds: 20 + periodSeconds: 15 + grpc: + port: 9555 + livenessProbe: + initialDelaySeconds: 20 + periodSeconds: 15 + grpc: + port: 9555 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.adService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.adService.name }} + ports: + - name: grpc + port: 9555 + targetPort: 9555 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.adService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.adService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + ports: + - port: 9555 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.adService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.adService.name }} + egress: + - hosts: + - istio-system/* + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.adService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.adService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.AdService/GetAds + methods: + - POST + ports: + - "9555" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/cartservice.yaml b/applications/onlineboutique/chart/templates/cartservice.yaml new file mode 100644 index 00000000..9d75f300 --- /dev/null +++ b/applications/onlineboutique/chart/templates/cartservice.yaml @@ -0,0 +1,178 @@ +{{- if .Values.cartService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.cartService.name }} + namespace: {{.Release.Namespace}} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.cartService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.cartService.name }} + template: + metadata: + {{- if .Values.cartDatabase.externalRedisTlsOrigination.enable }} + annotations: + sidecar.istio.io/userVolumeMount: '[{"name": "{{ .Values.cartDatabase.externalRedisTlsOrigination.name }}", "mountPath": "/etc/certs", "readonly": true}]' + sidecar.istio.io/userVolume: '[{"name": "{{ .Values.cartDatabase.externalRedisTlsOrigination.name }}", "secret": {"secretName": "{{ .Values.cartDatabase.externalRedisTlsOrigination.name }}"}}]' + proxy.istio.io/config: '{"holdApplicationUntilProxyStarts": true}' + {{- end }} + labels: + app: {{ .Values.cartService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.cartService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.cartService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 7070 + env: + {{- if eq .Values.cartDatabase.type "spanner" }} + - name: SPANNER_CONNECTION_STRING + {{- else }} + - name: REDIS_ADDR + {{- end }} + value: {{ .Values.cartDatabase.connectionString | quote }} + resources: + {{- toYaml .Values.cartService.resources | nindent 10 }} + readinessProbe: + initialDelaySeconds: 15 + grpc: + port: 7070 + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 10 + grpc: + port: 7070 +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.cartService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.cartService.name }} + ports: + - name: grpc + port: 7070 + targetPort: 7070 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.cartService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.cartService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + ports: + - port: 7070 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.cartService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.cartService.name }} + egress: + - hosts: + - istio-system/* + {{- if eq .Values.cartDatabase.type "redis" }} + {{- if .Values.cartDatabase.externalRedisTlsOrigination.enable }} + - ./{{ .Values.cartDatabase.externalRedisTlsOrigination.name }}.{{ .Release.Namespace }} + {{- else }} + - ./{{ .Values.cartDatabase.inClusterRedis.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} + {{- end }} + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.cartService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.cartService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.CartService/AddItem + - /hipstershop.CartService/GetCart + - /hipstershop.CartService/EmptyCart + methods: + - POST + ports: + - "7070" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/checkoutservice.yaml b/applications/onlineboutique/chart/templates/checkoutservice.yaml new file mode 100644 index 00000000..48aae406 --- /dev/null +++ b/applications/onlineboutique/chart/templates/checkoutservice.yaml @@ -0,0 +1,183 @@ +{{- if .Values.checkoutService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.checkoutService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.checkoutService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.checkoutService.name }} + template: + metadata: + labels: + app: {{ .Values.checkoutService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.checkoutService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.checkoutService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 5050 + readinessProbe: + grpc: + port: 5050 + livenessProbe: + grpc: + port: 5050 + env: + - name: PORT + value: "5050" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "{{ .Values.productCatalogService.name }}:3550" + - name: SHIPPING_SERVICE_ADDR + value: "{{ .Values.shippingService.name }}:50051" + - name: PAYMENT_SERVICE_ADDR + value: "{{ .Values.paymentService.name }}:50051" + - name: EMAIL_SERVICE_ADDR + value: "{{ .Values.emailService.name }}:5000" + - name: CURRENCY_SERVICE_ADDR + value: "{{ .Values.currencyService.name }}:7000" + - name: CART_SERVICE_ADDR + value: "{{ .Values.cartService.name }}:7070" + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if .Values.googleCloudOperations.profiler }} + - name: ENABLE_PROFILER + value: "1" + {{- end }} + resources: + {{- toYaml .Values.checkoutService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.checkoutService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.checkoutService.name }} + ports: + - name: grpc + port: 5050 + targetPort: 5050 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.checkoutService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + ports: + - port: 5050 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.checkoutService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.checkoutService.name }} + egress: + - hosts: + - istio-system/* + - ./{{ .Values.cartService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.currencyService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.emailService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.paymentService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.productCatalogService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.shippingService.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.checkoutService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.checkoutService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.CheckoutService/PlaceOrder + methods: + - POST + ports: + - "5050" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/common.yaml b/applications/onlineboutique/chart/templates/common.yaml new file mode 100644 index 00000000..fe01c488 --- /dev/null +++ b/applications/onlineboutique/chart/templates/common.yaml @@ -0,0 +1,21 @@ +{{- if .Values.networkPolicies.create }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: deny-all + namespace: {{ .Release.Namespace }} +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: deny-all + namespace: {{ .Release.Namespace }} +spec: {} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/currencyservice.yaml b/applications/onlineboutique/chart/templates/currencyservice.yaml new file mode 100644 index 00000000..a303570b --- /dev/null +++ b/applications/onlineboutique/chart/templates/currencyservice.yaml @@ -0,0 +1,172 @@ +{{- if .Values.currencyService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.currencyService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.currencyService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.currencyService.name }} + template: + metadata: + labels: + app: {{ .Values.currencyService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.currencyService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.currencyService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - name: grpc + containerPort: 7000 + env: + - name: PORT + value: "7000" + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if not .Values.googleCloudOperations.profiler }} + - name: DISABLE_PROFILER + value: "1" + {{- end }} + readinessProbe: + grpc: + port: 7000 + livenessProbe: + grpc: + port: 7000 + resources: + {{- toYaml .Values.currencyService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.currencyService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.currencyService.name }} + ports: + - name: grpc + port: 7000 + targetPort: 7000 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.currencyService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.currencyService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + ports: + - port: 7000 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.currencyService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.currencyService.name }} + egress: + - hosts: + - istio-system/* + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.currencyService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.currencyService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.CurrencyService/Convert + - /hipstershop.CurrencyService/GetSupportedCurrencies + methods: + - POST + ports: + - "7000" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/emailservice.yaml b/applications/onlineboutique/chart/templates/emailservice.yaml new file mode 100644 index 00000000..bd8f368f --- /dev/null +++ b/applications/onlineboutique/chart/templates/emailservice.yaml @@ -0,0 +1,168 @@ +{{- if .Values.emailService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.emailService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.emailService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.emailService.name }} + template: + metadata: + labels: + app: {{ .Values.emailService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.emailService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.emailService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 8080 + env: + - name: PORT + value: "8080" + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if not .Values.googleCloudOperations.profiler }} + - name: DISABLE_PROFILER + value: "1" + {{- end }} + readinessProbe: + periodSeconds: 5 + grpc: + port: 8080 + livenessProbe: + periodSeconds: 5 + grpc: + port: 8080 + resources: + {{- toYaml .Values.emailService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.emailService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.emailService.name }} + ports: + - name: grpc + port: 5000 + targetPort: 8080 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.emailService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.emailService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + ports: + - port: 8080 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.emailService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.emailService.name }} + egress: + - hosts: + - istio-system/* + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.emailService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.emailService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.EmailService/SendOrderConfirmation + methods: + - POST + ports: + - "8080" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/frontend.yaml b/applications/onlineboutique/chart/templates/frontend.yaml new file mode 100644 index 00000000..efb02a55 --- /dev/null +++ b/applications/onlineboutique/chart/templates/frontend.yaml @@ -0,0 +1,259 @@ +{{- if .Values.frontend.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.frontend.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.frontend.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.frontend.name }} + template: + metadata: + labels: + app: {{ .Values.frontend.name }} + annotations: + sidecar.istio.io/rewriteAppHTTPProbers: "true" + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.frontend.name }} + {{- else }} + serviceAccountName: default + {{- end }} + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.frontend.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 8080 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + httpHeaders: + - name: "Cookie" + value: "shop_session-id=x-readiness-probe" + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + httpHeaders: + - name: "Cookie" + value: "shop_session-id=x-liveness-probe" + env: + - name: PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "{{ .Values.productCatalogService.name }}:3550" + - name: CURRENCY_SERVICE_ADDR + value: "{{ .Values.currencyService.name }}:7000" + - name: CART_SERVICE_ADDR + value: "{{ .Values.cartService.name }}:7070" + - name: RECOMMENDATION_SERVICE_ADDR + value: "{{ .Values.recommendationService.name }}:8080" + - name: SHIPPING_SERVICE_ADDR + value: "{{ .Values.shippingService.name }}:50051" + - name: CHECKOUT_SERVICE_ADDR + value: "{{ .Values.checkoutService.name }}:5050" + - name: AD_SERVICE_ADDR + value: "{{ .Values.adService.name }}:9555" + - name: ENV_PLATFORM + value: {{ .Values.frontend.platform | quote }} + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if .Values.googleCloudOperations.profiler }} + - name: ENABLE_PROFILER + value: "1" + {{- end }} + - name: CYMBAL_BRANDING + value: {{ .Values.frontend.cymbalBranding | quote }} + - name: ENABLE_SINGLE_SHARED_SESSION + value: {{ .Values.frontend.singleSharedSession | quote }} + resources: + {{- toYaml .Values.frontend.resources | nindent 12 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.frontend.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.frontend.name }} + ports: + - name: http + port: 80 + targetPort: 8080 +{{- if .Values.frontend.externalService }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.frontend.name }}-external + namespace: {{ .Release.Namespace }} +spec: + type: LoadBalancer + selector: + app: {{ .Values.frontend.name }} + ports: + - name: http + port: 80 + targetPort: 8080 +{{- end }} +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.frontend.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + policyTypes: + - Ingress + - Egress + ingress: + {{- if .Values.frontend.externalService }} + - {} + {{- else }} + - from: + - podSelector: + matchLabels: + app: {{ .Values.loadGenerator.name }} + {{- if .Values.frontend.virtualService.create }} + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ .Values.frontend.virtualService.gateway.namespace }} + podSelector: + matchLabels: + {{ .Values.frontend.virtualService.gateway.labelKey }}: {{ .Values.frontend.virtualService.gateway.labelValue }} + {{- end }} + ports: + - port: 8080 + protocol: TCP + {{- end }} + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.frontend.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.frontend.name }} + egress: + - hosts: + - istio-system/* + - ./{{ .Values.adService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.cartService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.checkoutService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.currencyService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.productCatalogService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.recommendationService.name }}.{{ .Release.Namespace }}.svc.cluster.local + - ./{{ .Values.shippingService.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.frontend.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.frontend.name }} + rules: + {{- if .Values.frontend.externalService }} + - to: + {{- else }} + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.loadGenerator.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + {{- if .Values.frontend.virtualService.create }} + - cluster.local/ns/{{ .Values.frontend.virtualService.gateway.namespace }}/sa/{{ .Values.frontend.virtualService.gateway.name }} + {{- end }} + to: + {{- end }} + - operation: + methods: + - GET + - POST + ports: + - "8080" +{{- end }} +{{- if .Values.frontend.virtualService.create }} +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: {{ .Values.frontend.name }} + namespace: {{ .Release.Namespace }} +spec: + {{- with .Values.frontend.virtualService.hosts }} + hosts: + {{- toYaml . | nindent 2 }} + {{- end }} + gateways: + - {{ .Values.frontend.virtualService.gateway.namespace }}/{{ .Values.frontend.virtualService.gateway.name }} + http: + - route: + - destination: + host: {{ .Values.frontend.name }} + port: + number: 80 +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/ingress.yaml b/applications/onlineboutique/chart/templates/ingress.yaml new file mode 100644 index 00000000..c51fef0d --- /dev/null +++ b/applications/onlineboutique/chart/templates/ingress.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress +spec: + rules: + - host: + http: + paths: + - path: / + pathType: Prefix # or Absolute + backend: + service: + name: frontend + port: + number: 80 diff --git a/applications/onlineboutique/chart/templates/loadgenerator.yaml b/applications/onlineboutique/chart/templates/loadgenerator.yaml new file mode 100644 index 00000000..34715ded --- /dev/null +++ b/applications/onlineboutique/chart/templates/loadgenerator.yaml @@ -0,0 +1,140 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{{- if .Values.loadGenerator.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.loadGenerator.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.loadGenerator.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.loadGenerator.name }} + replicas: 1 + template: + metadata: + labels: + app: {{ .Values.loadGenerator.name }} + annotations: + sidecar.istio.io/rewriteAppHTTPProbers: "true" + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.loadGenerator.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + restartPolicy: Always + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + {{- if .Values.loadGenerator.checkFrontendInitContainer }} + initContainers: + - command: + - /bin/sh + - -exc + - | + echo "Init container pinging frontend: ${FRONTEND_ADDR}..." + STATUSCODE=$(wget --server-response http://${FRONTEND_ADDR} 2>&1 | awk '/^ HTTP/{print $2}') + if test $STATUSCODE -ne 200; then + echo "Error: Could not reach frontend - Status code: ${STATUSCODE}" + exit 1 + fi + name: frontend-check + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: busybox:latest@sha256:5c63a9b46e7139d2d5841462859edcbbf57f238af891b6096578e5894cfe5ae2 + env: + - name: FRONTEND_ADDR + value: "{{ .Values.frontend.name }}:80" + {{- end }} + containers: + - name: main + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.loadGenerator.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + env: + - name: FRONTEND_ADDR + value: "{{ .Values.frontend.name }}:80" + - name: USERS + value: "10" + resources: + {{- toYaml .Values.loadGenerator.resources | nindent 10 }} +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.loadGenerator.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.loadGenerator.name }} + policyTypes: + - Egress + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.loadGenerator.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.loadGenerator.name }} + egress: + - hosts: + - istio-system/* + - ./{{ .Values.frontend.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/opentelemetry-collector.yaml b/applications/onlineboutique/chart/templates/opentelemetry-collector.yaml new file mode 100644 index 00000000..a948bc26 --- /dev/null +++ b/applications/onlineboutique/chart/templates/opentelemetry-collector.yaml @@ -0,0 +1,260 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{{- if .Values.opentelemetryCollector.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.opentelemetryCollector.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.opentelemetryCollector.name }} + namespace: {{ .Release.Namespace }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ .Values.opentelemetryCollector.name }} + template: + metadata: + labels: + app: {{ .Values.opentelemetryCollector.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.opentelemetryCollector.name }} + {{- else }} + serviceAccountName: default + {{- end }} + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + {{- if eq .Values.opentelemetryCollector.projectId "PROJECT_ID" }} + initContainers: + # Init container retrieves the current cloud project id from the metadata server + # and inserts it into the collector config template + # https://cloud.google.com/compute/docs/storing-retrieving-metadata + - name: otel-gateway-init + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: busybox:latest@sha256:5c63a9b46e7139d2d5841462859edcbbf57f238af891b6096578e5894cfe5ae2 + command: + - '/bin/sh' + - '-c' + - | + sed "s/PROJECT_ID/$(curl -H 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/project/project-id)/" /template/collector-gateway-config-template.yaml >> /conf/collector-gateway-config.yaml + volumeMounts: + - name: collector-gateway-config-template + mountPath: /template + - name: collector-gateway-config + mountPath: /conf + {{- end }} + containers: + # This gateway container will receive traces and metrics from each microservice + # and forward it to GCP + - name: otel-gateway + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + args: + - --config=/conf/collector-gateway-config.yaml + image: otel/opentelemetry-collector-contrib:0.91.0@sha256:894dea0499cdcf083e30bd5352ef5c8f6ed2a4a928b1d3f995b7571b41eb9f08 + volumeMounts: + - name: collector-gateway-config + mountPath: /conf + volumes: + # Simple ConfigMap volume with template file + - name: collector-gateway-config-template + configMap: + items: + - key: collector-gateway-config-template.yaml + path: collector-gateway-config-template.yaml + name: collector-gateway-config-template + # Create a volume to store the expanded template (with correct cloud project ID) + - name: collector-gateway-config + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.opentelemetryCollector.name }} + namespace: {{ .Release.Namespace }} +spec: + ports: + - name: grpc-otlp + port: 4317 + protocol: TCP + targetPort: 4317 + selector: + app: {{ .Values.opentelemetryCollector.name }} + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: collector-gateway-config-template + namespace: {{ .Release.Namespace }} +# Open Telemetry Collector config +# https://opentelemetry.io/docs/collector/configuration/ +data: + collector-gateway-config-template.yaml: | + receivers: + otlp: + protocols: + grpc: + processors: + exporters: + googlecloud: + project: {{ .Values.opentelemetryCollector.projectId | quote }} + service: + pipelines: + traces: + receivers: [otlp] # Receive otlp-formatted data from other collector instances + processors: [] + exporters: [googlecloud] # Export traces directly to Google Cloud + metrics: + receivers: [otlp] + processors: [] + exporters: [googlecloud] # Export metrics to Google Cloud +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.opentelemetryCollector.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.opentelemetryCollector.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.adService.name }} + - podSelector: + matchLabels: + app: {{ .Values.cartService.name }} + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + - podSelector: + matchLabels: + app: {{ .Values.currencyService.name }} + - podSelector: + matchLabels: + app: {{ .Values.emailService.name }} + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + - podSelector: + matchLabels: + app: {{ .Values.loadGenerator.name }} + - podSelector: + matchLabels: + app: {{ .Values.paymentService.name }} + - podSelector: + matchLabels: + app: {{ .Values.productCatalogService.name }} + - podSelector: + matchLabels: + app: {{ .Values.recommendationService.name }} + - podSelector: + matchLabels: + app: {{ .Values.shippingService.name }} + ports: + - port: 4317 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.opentelemetryCollector.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.opentelemetryCollector.name }} + egress: + - hosts: + - istio-system/* +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.opentelemetryCollector.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.opentelemetryCollector.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.adService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.cartService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.currencyService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.emailService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.loadGenerator.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.paymentService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.productCatalogService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.recommendationService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.shippingService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + ports: + - "4317" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/paymentservice.yaml b/applications/onlineboutique/chart/templates/paymentservice.yaml new file mode 100644 index 00000000..3c983951 --- /dev/null +++ b/applications/onlineboutique/chart/templates/paymentservice.yaml @@ -0,0 +1,166 @@ +{{- if .Values.paymentService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.paymentService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.paymentService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.paymentService.name }} + template: + metadata: + labels: + app: {{ .Values.paymentService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.paymentService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.paymentService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 50051 + env: + - name: PORT + value: "50051" + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if not .Values.googleCloudOperations.profiler }} + - name: DISABLE_PROFILER + value: "1" + {{- end }} + readinessProbe: + grpc: + port: 50051 + livenessProbe: + grpc: + port: 50051 + resources: + {{- toYaml .Values.paymentService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.paymentService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.paymentService.name }} + ports: + - name: grpc + port: 50051 + targetPort: 50051 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.paymentService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.paymentService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + ports: + - port: 50051 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.paymentService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.paymentService.name }} + egress: + - hosts: + - istio-system/* + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.paymentService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.paymentService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.PaymentService/Charge + methods: + - POST + ports: + - "50051" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/preflight.yaml b/applications/onlineboutique/chart/templates/preflight.yaml new file mode 100644 index 00000000..6d7b0f1b --- /dev/null +++ b/applications/onlineboutique/chart/templates/preflight.yaml @@ -0,0 +1,47 @@ +apiVersion: v1 +kind: Secret +metadata: + labels: + troubleshoot.sh/kind: preflight + name: gitea-preflight-checks +stringData: + preflight.yaml: | + apiVersion: troubleshoot.sh/v1beta2 + kind: Preflight + metadata: + name: go-test-preflight + spec: + # TODO: mock a local HTTP server to send this to + #uploadResultsTo: http://someurl + collectors: + - data: + name: example.json + data: | + { + "foo": "bar", + "stuff": { + "foo": "bar", + "bar": true + }, + "morestuff": [ + { + "foo": { + "bar": 123 + } + } + ] + } + analyzers: + - jsonCompare: + checkName: Compare JSON Example + fileName: example.json + path: "morestuff.[0].foo.bar" + value: | + 123 + outcomes: + - fail: + when: "false" + message: The collected data does not match the value. + - pass: + when: "true" + message: The collected data matches the value. diff --git a/applications/onlineboutique/chart/templates/productcatalogservice.yaml b/applications/onlineboutique/chart/templates/productcatalogservice.yaml new file mode 100644 index 00000000..e92d7821 --- /dev/null +++ b/applications/onlineboutique/chart/templates/productcatalogservice.yaml @@ -0,0 +1,177 @@ +{{- if .Values.productCatalogService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.productCatalogService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.productCatalogService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.productCatalogService.name }} + template: + metadata: + labels: + app: {{ .Values.productCatalogService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.productCatalogService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.productCatalogService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 3550 + env: + - name: PORT + value: "3550" + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if not .Values.googleCloudOperations.profiler }} + - name: DISABLE_PROFILER + value: "1" + {{- end }} + - name: EXTRA_LATENCY + value: {{ .Values.productCatalogService.extraLatency }} + readinessProbe: + grpc: + port: 3550 + livenessProbe: + grpc: + port: 3550 + resources: + {{- toYaml .Values.productCatalogService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.productCatalogService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.productCatalogService.name }} + ports: + - name: grpc + port: 3550 + targetPort: 3550 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.productCatalogService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.productCatalogService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + - podSelector: + matchLabels: + app: {{ .Values.recommendationService.name }} + ports: + - port: 3550 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.productCatalogService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.productCatalogService.name }} + egress: + - hosts: + - istio-system/* + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.productCatalogService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.productCatalogService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.recommendationService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.ProductCatalogService/GetProduct + - /hipstershop.ProductCatalogService/ListProducts + methods: + - POST + ports: + - "3550" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/recommendationservice.yaml b/applications/onlineboutique/chart/templates/recommendationservice.yaml new file mode 100644 index 00000000..e4ecc2dc --- /dev/null +++ b/applications/onlineboutique/chart/templates/recommendationservice.yaml @@ -0,0 +1,171 @@ +{{- if .Values.recommendationService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.recommendationService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.recommendationService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.recommendationService.name }} + template: + metadata: + labels: + app: {{ .Values.recommendationService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.recommendationService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + terminationGracePeriodSeconds: 5 + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.recommendationService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 8080 + readinessProbe: + periodSeconds: 5 + grpc: + port: 8080 + livenessProbe: + periodSeconds: 5 + grpc: + port: 8080 + env: + - name: PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "{{ .Values.productCatalogService.name }}:3550" + {{- if .Values.opentelemetryCollector.create }} + - name: COLLECTOR_SERVICE_ADDR + value: "{{ .Values.opentelemetryCollector.name }}:4317" + {{- end }} + {{- if .Values.googleCloudOperations.tracing }} + - name: ENABLE_TRACING + value: "1" + {{- end }} + {{- if not .Values.googleCloudOperations.profiler }} + - name: DISABLE_PROFILER + value: "1" + {{- end }} + resources: + {{- toYaml .Values.recommendationService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.recommendationService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.recommendationService.name }} + ports: + - name: grpc + port: 8080 + targetPort: 8080 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.recommendationService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.recommendationService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + ports: + - port: 8080 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.recommendationService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.recommendationService.name }} + egress: + - hosts: + - istio-system/* + - ./{{ .Values.productCatalogService.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.recommendationService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.recommendationService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.RecommendationService/ListRecommendations + methods: + - POST + ports: + - "8080" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/templates/redis.yaml b/applications/onlineboutique/chart/templates/redis.yaml new file mode 100644 index 00000000..39e2e3bd --- /dev/null +++ b/applications/onlineboutique/chart/templates/redis.yaml @@ -0,0 +1,217 @@ +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{{- if .Values.cartDatabase.inClusterRedis.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.cartDatabase.inClusterRedis.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.cartDatabase.inClusterRedis.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.cartDatabase.inClusterRedis.name }} + template: + metadata: + labels: + app: {{ .Values.cartDatabase.inClusterRedis.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.cartDatabase.inClusterRedis.name }} + {{- else }} + serviceAccountName: default + {{- end }} + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: redis + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- if .Values.cartDatabase.inClusterRedis.publicRepository }} + image: redis:alpine@sha256:090276da2603db19b154602c374f505d94c10ea57e9749fc3e68e955284bf0fd + {{- else }} + image: {{ .Values.images.repository }}/redis:alpine + {{- end }} + ports: + - containerPort: 6379 + readinessProbe: + periodSeconds: 5 + tcpSocket: + port: 6379 + livenessProbe: + periodSeconds: 5 + tcpSocket: + port: 6379 + volumeMounts: + - mountPath: /data + name: redis-data + resources: + limits: + memory: 256Mi + cpu: 125m + requests: + cpu: 70m + memory: 200Mi + volumes: + - name: redis-data + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.cartDatabase.inClusterRedis.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.cartDatabase.inClusterRedis.name }} + ports: + - name: tcp-redis + port: 6379 + targetPort: 6379 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.cartDatabase.inClusterRedis.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.cartDatabase.inClusterRedis.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.cartService.name }} + ports: + - port: 6379 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.cartDatabase.inClusterRedis.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.cartDatabase.inClusterRedis.name }} + egress: + - hosts: + - istio-system/* +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.cartDatabase.inClusterRedis.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.cartDatabase.inClusterRedis.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.cartService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + ports: + - "6379" +{{- end }} +{{- end }} +{{- if .Values.cartDatabase.externalRedisTlsOrigination.enable }} +--- +apiVersion: v1 +data: + {{ .Values.cartDatabase.externalRedisTlsOrigination.name }}.pem: {{ .Values.cartDatabase.externalRedisTlsOrigination.certificate | b64enc | quote }} +kind: Secret +metadata: + name: {{ .Values.cartDatabase.externalRedisTlsOrigination.name }} + namespace: {{ .Release.Namespace }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: {{ .Values.cartDatabase.externalRedisTlsOrigination.name }} + namespace: {{ .Release.Namespace }} +spec: + exportTo: + - '.' + host: {{ .Values.cartDatabase.externalRedisTlsOrigination.name }}.{{ .Release.Namespace }} + trafficPolicy: + tls: + mode: SIMPLE + caCertificates: /etc/certs/{{ .Values.cartDatabase.externalRedisTlsOrigination.name }}.pem +--- +apiVersion: networking.istio.io/v1beta1 +kind: ServiceEntry +metadata: + name: {{ .Values.cartDatabase.externalRedisTlsOrigination.name }} + namespace: {{ .Release.Namespace }} +spec: + hosts: + - {{ .Values.cartDatabase.externalRedisTlsOrigination.name }}.{{ .Release.Namespace }} + addresses: + - {{ .Values.cartDatabase.externalRedisTlsOrigination.endpointAddress }}/32 + endpoints: + - address: {{ .Values.cartDatabase.externalRedisTlsOrigination.endpointAddress }} + location: MESH_EXTERNAL + resolution: STATIC + ports: + - number: {{ .Values.cartDatabase.externalRedisTlsOrigination.endpointPort }} + name: tcp-redis + protocol: TCP +{{- end }} diff --git a/applications/onlineboutique/chart/templates/shippingservice.yaml b/applications/onlineboutique/chart/templates/shippingservice.yaml new file mode 100644 index 00000000..2362bf35 --- /dev/null +++ b/applications/onlineboutique/chart/templates/shippingservice.yaml @@ -0,0 +1,163 @@ +{{- if .Values.shippingService.create }} +{{- if .Values.serviceAccounts.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.shippingService.name }} + namespace: {{.Release.Namespace}} + {{- if not .Values.serviceAccounts.annotationsOnlyForCartservice }} + {{- with .Values.serviceAccounts.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Values.shippingService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.shippingService.name }} + template: + metadata: + labels: + app: {{ .Values.shippingService.name }} + spec: + {{- if .Values.serviceAccounts.create }} + serviceAccountName: {{ .Values.shippingService.name }} + {{- else }} + serviceAccountName: default + {{- end }} + securityContext: + fsGroup: 1000 + runAsGroup: 1000 + runAsNonRoot: true + runAsUser: 1000 + {{- if .Values.seccompProfile.enable }} + seccompProfile: + type: {{ .Values.seccompProfile.type }} + {{- end }} + containers: + - name: server + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + image: {{ .Values.images.repository }}/{{ .Values.shippingService.name }}:{{ .Values.images.tag | default .Chart.AppVersion }} + ports: + - containerPort: 50051 + env: + - name: PORT + value: "50051" + {{- if not .Values.googleCloudOperations.profiler }} + - name: DISABLE_PROFILER + value: "1" + {{- end }} + readinessProbe: + periodSeconds: 5 + grpc: + port: 50051 + livenessProbe: + grpc: + port: 50051 + resources: + {{- toYaml .Values.shippingService.resources | nindent 10 }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.shippingService.name }} + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + selector: + app: {{ .Values.shippingService.name }} + ports: + - name: grpc + port: 50051 + targetPort: 50051 +{{- if .Values.networkPolicies.create }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ .Values.shippingService.name }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + app: {{ .Values.shippingService.name }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ .Values.frontend.name }} + - podSelector: + matchLabels: + app: {{ .Values.checkoutService.name }} + ports: + - port: 50051 + protocol: TCP + egress: + - {} +{{- end }} +{{- if .Values.sidecars.create }} +--- +apiVersion: networking.istio.io/v1beta1 +kind: Sidecar +metadata: + name: {{ .Values.shippingService.name }} + namespace: {{ .Release.Namespace }} +spec: + workloadSelector: + labels: + app: {{ .Values.shippingService.name }} + egress: + - hosts: + - istio-system/* + {{- if .Values.opentelemetryCollector.create }} + - ./{{ .Values.opentelemetryCollector.name }}.{{ .Release.Namespace }}.svc.cluster.local + {{- end }} +{{- end }} +{{- if .Values.authorizationPolicies.create }} +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: {{ .Values.shippingService.name }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + app: {{ .Values.shippingService.name }} + rules: + - from: + - source: + principals: + {{- if .Values.serviceAccounts.create }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.frontend.name }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/{{ .Values.checkoutService.name }} + {{- else }} + - cluster.local/ns/{{ .Release.Namespace }}/sa/default + {{- end }} + to: + - operation: + paths: + - /hipstershop.ShippingService/GetQuote + - /hipstershop.ShippingService/ShipOrder + methods: + - POST + ports: + - "50051" +{{- end }} +{{- end }} diff --git a/applications/onlineboutique/chart/values.yaml b/applications/onlineboutique/chart/values.yaml new file mode 100644 index 00000000..59367f03 --- /dev/null +++ b/applications/onlineboutique/chart/values.yaml @@ -0,0 +1,197 @@ +# Default values for onlineboutique. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +images: + repository: gcr.io/google-samples/microservices-demo + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +serviceAccounts: + # Specifies whether service accounts should be created. + create: false + # Annotations to add to the service accounts. + annotations: {} + # Annotations to add only for the cartservice app. This allows to follow the least privilege principle where only cartservice needs to connect to external database for example via Workload Identity. + annotationsOnlyForCartservice: false + +networkPolicies: + # Specifies if the NetworkPolicies are created or not. If true, one fine granular NetworkPolicy per app is created. + create: false + +sidecars: + # Specifies if the Sidecars are created or not. If true, one fine granular Sidecar per app is created. + create: false + +authorizationPolicies: + # Specifies if the AuthorizationPolicies are created or not. If true, one fine granular AuthorizationPolicy per app is created. + create: false + +opentelemetryCollector: + create: false + name: opentelemetrycollector + # Specifies the project id for the otel collector. If set as "PROJECT_ID" (default value), an initContainer will automatically retrieve the project id value from the metadata server. + projectId: "PROJECT_ID" + +googleCloudOperations: + profiler: false + tracing: false + metrics: false + +seccompProfile: + enable: false + type: RuntimeDefault + +adService: + create: true + name: adservice + resources: + requests: + cpu: 200m + memory: 180Mi + limits: + cpu: 300m + memory: 300Mi + +cartService: + create: true + name: cartservice + resources: + requests: + cpu: 200m + memory: 64Mi + limits: + cpu: 300m + memory: 128Mi + +checkoutService: + create: true + name: checkoutservice + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +currencyService: + create: true + name: currencyservice + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +emailService: + create: true + name: emailservice + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +frontend: + create: true + name: frontend + externalService: false + cymbalBranding: false + # One of: local, gcp, aws, azure, onprem, alibaba. When not set, defaults to "local" unless running in GKE, otherwise auto-sets to gcp. + platform: local + singleSharedSession: false + virtualService: + create: false + hosts: + - "*" + gateway: + name: asm-ingressgateway + namespace: asm-ingress + labelKey: asm + labelValue: ingressgateway + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +loadGenerator: + create: true + name: loadgenerator + checkFrontendInitContainer: true + resources: + requests: + cpu: 300m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +paymentService: + create: true + name: paymentservice + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +productCatalogService: + create: true + name: productcatalogservice + # Specifies an extra latency to any request on productcatalogservice, by default no extra latency. + extraLatency: "" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +recommendationService: + create: true + name: recommendationservice + resources: + requests: + cpu: 100m + memory: 220Mi + limits: + cpu: 200m + memory: 450Mi + +shippingService: + create: true + name: shippingservice + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi + +cartDatabase: + # Specifies the type of the cartservice's database, could be either redis or spanner. + type: redis + connectionString: "redis-cart:6379" + inClusterRedis: + create: true + name: redis-cart + # Uses the public redis image from Docker Hub, otherwise will use the images.repository. + publicRepository: true + externalRedisTlsOrigination: + enable: false + name: exernal-redis-tls-origination + endpointAddress: "" + endpointPort: "" + certificate: "" diff --git a/applications/onlineboutique/release/.gitignore b/applications/onlineboutique/release/.gitignore new file mode 100644 index 00000000..44cb6332 --- /dev/null +++ b/applications/onlineboutique/release/.gitignore @@ -0,0 +1 @@ +license.yaml diff --git a/applications/onlineboutique/release/app.yaml b/applications/onlineboutique/release/app.yaml new file mode 100644 index 00000000..6ac39f00 --- /dev/null +++ b/applications/onlineboutique/release/app.yaml @@ -0,0 +1,19 @@ +apiVersion: kots.io/v1beta1 +kind: Application +metadata: + name: onlineboutique +spec: + title: onlineboutique + releaseNotes: These are our release notes + statusInformers: + - '{{repl if (ConfigOption "adservice_create" | ParseBool) }}deployment/adservice{{repl end}}' + - '{{repl if (ConfigOption "cartservice_create" | ParseBool) }}deployment/cartservice{{repl end}}' + - '{{repl if (ConfigOption "checkoutservice_create" | ParseBool)}}deployment/checkoutservice{{repl end}}' + - '{{repl if (ConfigOption "currencyservice_create" | ParseBool)}}deployment/currencyservice{{repl end}}' + - '{{repl if (ConfigOption "emailservice_create" | ParseBool)}}deployment/emailservice{{repl end}}' + - '{{repl if (ConfigOption "frontend_create" | ParseBool)}}deployment/frontend{{repl end}}' + - '{{repl if (ConfigOption "paymentservice_create" | ParseBool)}}deployment/paymentservice{{repl end}}' + - '{{repl if (ConfigOption "pcs_create" | ParseBool)}}deployment/productcatalogservice{{repl end}}' + - '{{repl if (ConfigOption "recommendationservice_create" | ParseBool)|}}deployment/recommendationservice{{repl end}}' + - '{{repl if (ConfigOption "cartdatabase_create" | ParseBool)}}deployment/redis-cart{{repl end}}' + - '{{repl if (ConfigOption "shippingservice_create" | ParseBool)}}deployment/shippingservice{{repl end}}' diff --git a/applications/onlineboutique/release/cluster.yaml b/applications/onlineboutique/release/cluster.yaml new file mode 100644 index 00000000..b194f2c6 --- /dev/null +++ b/applications/onlineboutique/release/cluster.yaml @@ -0,0 +1,13 @@ +apiVersion: embeddedcluster.replicated.com/v1beta1 +kind: Config +spec: + version: 1.19.0+k8s-1.30 + roles: + controller: + name: controller + labels: + controller: "true" + custom: + - name: worker + labels: + worker: "true" diff --git a/applications/onlineboutique/release/config.yaml b/applications/onlineboutique/release/config.yaml new file mode 100644 index 00000000..9fae6ec3 --- /dev/null +++ b/applications/onlineboutique/release/config.yaml @@ -0,0 +1,59 @@ +apiVersion: kots.io/v1beta1 +kind: Config +metadata: + name: my-application +spec: + groups: + - name: services + title: Enabled Services + items: + - name: adservice_create + title: Enable Ad service + type: bool + default: "1" + - name: cartservice_create + title: Enable Cart service + type: bool + default: "1" + - name: checkoutservice_create + title: Enable Checkout service + type: bool + default: "1" + - name: currencyservice_create + title: Enable Currency service + type: bool + default: "1" + - name: emailservice_create + title: Enable Email service + type: bool + default: "1" + - name: frontend_create + title: Enable Front end + type: bool + default: "1" + - name: loadgen_create + title: Enable Load Generator + type: bool + default: "1" + - name: paymentservice_create + title: Enable Payment service + type: bool + default: "1" + - name: pcs_create + title: Enable Product Category service + type: bool + default: "1" + - name: recommendationservice_create + title: Enable Recommendation service + type: bool + default: "1" + - name: shippingservice_create + title: Enable Shipping service + type: bool + default: "1" + - name: cartdatabase_create + title: Enable Cart service database + type: bool + default: "1" + + diff --git a/applications/onlineboutique/release/configValues.yaml b/applications/onlineboutique/release/configValues.yaml new file mode 100644 index 00000000..448fb3d9 --- /dev/null +++ b/applications/onlineboutique/release/configValues.yaml @@ -0,0 +1,32 @@ +apiVersion: kots.io/v1beta1 +kind: ConfigValues +metadata: + creationTimestamp: null + name: onlineboutique +spec: + values: + adservice_create: + default: "1" + cartdatabase_create: + default: "1" + cartservice_create: + default: "1" + checkoutservice_create: + default: "1" + currencyservice_create: + default: "1" + emailservice_create: + default: "1" + frontend_create: + default: "1" + loadgen_create: + default: "1" + paymentservice_create: + default: "1" + pcs_create: + default: "1" + recommendationservice_create: + default: "1" + shippingservice_create: + default: "1" +status: {} diff --git a/applications/onlineboutique/release/onlineboutique.yaml b/applications/onlineboutique/release/onlineboutique.yaml new file mode 100644 index 00000000..c93db797 --- /dev/null +++ b/applications/onlineboutique/release/onlineboutique.yaml @@ -0,0 +1,39 @@ +apiVersion: kots.io/v1beta2 +kind: HelmChart +metadata: + name: helmtest +spec: + chart: + name: onlineboutique + chartVersion: 0.14.0 + releaseName: onlineboutique + helmVersion: v3 + values: + adService: + create: repl{{ ConfigOption "adservice_create"}} + cartService: + create: repl{{ ConfigOption "cartservice_create"}} + checkoutService: + create: repl{{ ConfigOption "checkoutservice_create"}} + currencyService: + create: repl{{ ConfigOption "currencyservice_create"}} + emailService: + create: repl{{ ConfigOption "emailservice_create"}} + frontend: + create: repl{{ ConfigOption "frontend_create"}} + loadGenerator: + create: repl{{ ConfigOption "loadgen_create"}} + paymentService: + create: repl{{ ConfigOption "paymentservice_create"}} + productCatalogService: + create: repl{{ ConfigOption "pcs_create"}} + recommendationService: + create: repl{{ ConfigOption "recommendationservice_create"}} + shippingService: + create: repl{{ ConfigOption "shippingservice_create"}} + cartDatabase: + create: repl{{ ConfigOption "cartdatabase_create"}} + + builder: {} + helmUpgradeFlags: + - --skip-schema-validation