diff --git a/Makefile b/Makefile index d7d554747c..b38313b55c 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,9 @@ THIS_FILE := $(lastword $(MAKEFILE_LIST)) -include Makefile.overrides -MAISTRA_VERSION ?= 2.4.3 -MAISTRA_BRANCH ?= maistra-2.4 -ISTIO_VERSION ?= 1.16.5 +MAISTRA_VERSION ?= 2.5.0 +MAISTRA_BRANCH ?= maistra-2.5 +ISTIO_VERSION ?= 1.18.0 REPLACES_PRODUCT_CSV ?= 2.4.2 REPLACES_COMMUNITY_CSV ?= 2.4.2 VERSION ?= development @@ -87,7 +87,7 @@ test: # Helm charts generation and templates processing ################################################################################ -SUPPORTED_VERSIONS := 2.1 2.2 2.3 2.4 +SUPPORTED_VERSIONS := 2.1 2.2 2.3 2.4 2.5 $(addprefix update-remote-maistra-,$(SUPPORTED_VERSIONS)): update-remote-maistra-%: $(eval version:=$*) @@ -181,10 +181,10 @@ endif # resource collection ################################################################################ .PHONY: collect-charts -collect-charts: collect-charts-2.1 collect-charts-2.2 collect-charts-2.3 collect-charts-2.4 +collect-charts: collect-charts-2.1 collect-charts-2.2 collect-charts-2.3 collect-charts-2.4 collect-charts-2.5 .PHONY: collect-templates -collect-templates: collect-templates-2.1 collect-templates-2.2 collect-templates-2.3 collect-templates-2.4 +collect-templates: collect-templates-2.1 collect-templates-2.2 collect-templates-2.3 collect-templates-2.4 collect-templates-2.5 .PHONY: collect-olm-manifests collect-olm-manifests: diff --git a/build/docker_build.sh b/build/docker_build.sh index faac6d9659..c039fbb7ea 100755 --- a/build/docker_build.sh +++ b/build/docker_build.sh @@ -36,4 +36,4 @@ mkdir "${HELM_DIR}" cp -r "${SOURCE_DIR}/tmp/_output/helm/istio-releases/istio-1.1.0" "${HELM_DIR}/1.1.0" echo "building container ${IMAGE}..." -${CONTAINER_CLI} build --no-cache -t "${IMAGE}" -f tmp/build/Dockerfile --build-arg build_type=${BUILD_TYPE} . +${CONTAINER_CLI} build --no-cache -t "${IMAGE}" -f tmp/build/Dockerfile --build-arg build_type="${BUILD_TYPE}" . diff --git a/build/download-charts.sh b/build/download-charts.sh index 1bdcd4d53d..752676ad91 100755 --- a/build/download-charts.sh +++ b/build/download-charts.sh @@ -6,14 +6,14 @@ set -e -u # shellcheck source=build/sed-wrapper.sh source "$(dirname "${BASH_SOURCE[0]}")/sed-wrapper.sh" -: "${MAISTRA_VERSION:=2.4.3}" +: "${MAISTRA_VERSION:=2.5.0}" : "${MAISTRA_REPO:=https://github.com/maistra/istio}" -: "${MAISTRA_BRANCH:=maistra-2.4}" +: "${MAISTRA_BRANCH:=maistra-2.5}" : "${SOURCE_DIR:=$(pwd)}" : "${OUT_DIR:=${SOURCE_DIR}/tmp/_output}" -: "${ISTIO_VERSION:=1.16.5}" +: "${ISTIO_VERSION:=1.18.0}" RELEASES_DIR=${OUT_DIR}/helm/istio-releases @@ -51,12 +51,12 @@ function retrieveIstioRelease() { ( echo "extracting Istio Helm charts to ${RELEASES_DIR}" cd "${RELEASES_DIR}" - rm -rf ${EXTRACT_DIR} + rm -rf "${EXTRACT_DIR}" ${EXTRACT_CMD} - cp -rf ${EXTRACT_DIR}/manifests/charts/* "${HELM_DIR}/" + cp -rf "${EXTRACT_DIR}"/manifests/charts/* "${HELM_DIR}/" # grafana dashboards mkdir -p "${HELM_DIR}/istio-telemetry/grafana/dashboards" - cp -rf ${EXTRACT_DIR}/manifests/addons/dashboards/* "${HELM_DIR}/istio-telemetry/grafana/dashboards/" + cp -rf "${EXTRACT_DIR}"/manifests/addons/dashboards/* "${HELM_DIR}/istio-telemetry/grafana/dashboards/" #( # cd "${HELM_DIR}/istio" # helm dep update diff --git a/build/generate-manifests.sh b/build/generate-manifests.sh index ef9a08bfde..a3c6260367 100755 --- a/build/generate-manifests.sh +++ b/build/generate-manifests.sh @@ -62,32 +62,32 @@ function generateDeploymentFile() { cat deploy/src/rbac.yaml; echo -e "\n---\n" cat deploy/src/serviceaccount.yaml; echo -e "\n---\n" cat deploy/src/service.yaml; echo -e "\n---\n" - cat deploy/src/deployment-${BUILD_TYPE}.yaml; } >${DEPLOYMENT_FILE} + cat deploy/src/deployment-${BUILD_TYPE}.yaml; } >"${DEPLOYMENT_FILE}" } function generateCSV() { YQ="go run github.com/mikefarah/yq/v4" - IMAGE_SRC=$(${YQ} eval 'select(.kind=="Deployment" and .metadata.name=="istio-operator") | .spec.template.spec.containers[0].image' ${DEPLOYMENT_FILE}) + IMAGE_SRC=$(${YQ} eval 'select(.kind=="Deployment" and .metadata.name=="istio-operator") | .spec.template.spec.containers[0].image' "${DEPLOYMENT_FILE}") if [ "$IMAGE_SRC" == "" ]; then echo "generateCSV(): Operator image source is empty, please verify source yaml/path to the field." exit 1 fi - DEPLOYMENT_SPEC=$(${YQ} eval 'select(.kind=="Deployment" and .metadata.name=="istio-operator") | .spec' ${DEPLOYMENT_FILE} | sed 's/^/ /') + DEPLOYMENT_SPEC=$(${YQ} eval 'select(.kind=="Deployment" and .metadata.name=="istio-operator") | .spec' "${DEPLOYMENT_FILE}" | sed 's/^/ /') if [ "$DEPLOYMENT_SPEC" == "" ]; then echo "generateCSV(): Operator deployment spec is empty, please verify source yaml/path to the field." exit 1 fi - CLUSTER_ROLE_RULES=$(${YQ} eval 'select(.kind=="ClusterRole" and .metadata.name=="istio-operator") | .rules' ${DEPLOYMENT_FILE} | sed 's/^/ /') + CLUSTER_ROLE_RULES=$(${YQ} eval 'select(.kind=="ClusterRole" and .metadata.name=="istio-operator") | .rules' "${DEPLOYMENT_FILE}" | sed 's/^/ /') if [ "$CLUSTER_ROLE_RULES" == "null" ]; then echo "generateCSV(): istio-operator cluster role source is empty, please verify source yaml/path to the field." exit 1 fi if [ "${BUILD_TYPE}" == "maistra" ]; then - RELATED_IMAGES=$(${YQ} eval 'select(.kind=="Deployment" and .metadata.name=="istio-operator") | .spec.template.metadata.annotations' ${DEPLOYMENT_FILE} | \ + RELATED_IMAGES=$(${YQ} eval 'select(.kind=="Deployment" and .metadata.name=="istio-operator") | .spec.template.metadata.annotations' "${DEPLOYMENT_FILE}" | \ sed -n 's/olm\.relatedImage\.\([^:]*\): *\([^ ]*\)/- name: \1\ image: \2/p' | \ sed 's/^/ /') @@ -146,9 +146,9 @@ $RELATED_IMAGES" function generatePackage() { local package_path=${MANIFESTS_DIR}/${BUILD_TYPE}.package.yaml - cp "${MY_LOCATION}/manifest-templates/package.yaml" ${package_path} - sed -i -e 's/__NAME__/'${OPERATOR_NAME}'/g' ${package_path} - sed -i -e 's/__VERSION__/'"${MAISTRA_VERSION}"'/g' ${package_path} + cp "${MY_LOCATION}/manifest-templates/package.yaml" "${package_path}" + sed -i -e 's/__NAME__/'${OPERATOR_NAME}'/g' "${package_path}" + sed -i -e 's/__VERSION__/'"${MAISTRA_VERSION}"'/g' "${package_path}" } checkDependencies diff --git a/build/manifest-templates/clusterserviceversion.yaml b/build/manifest-templates/clusterserviceversion.yaml index e1a1ab33c3..4de743360b 100644 --- a/build/manifest-templates/clusterserviceversion.yaml +++ b/build/manifest-templates/clusterserviceversion.yaml @@ -29,7 +29,7 @@ metadata: "namespace": "control-plane-namespace" }, "spec": { - "version": "v2.4", + "version": "v2.5", "tracing": { "type": "Jaeger", "sampling": 10000 @@ -200,6 +200,7 @@ __DEPLOYMENT_SPEC__ path: version x-descriptors: - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.5' - 'urn:alm:descriptor:com.tectonic.ui:select:v2.4' - 'urn:alm:descriptor:com.tectonic.ui:select:v2.3' - 'urn:alm:descriptor:com.tectonic.ui:select:v2.2' diff --git a/build/patch-charts.sh b/build/patch-charts.sh index 035c9d62ca..e3dc057c62 100755 --- a/build/patch-charts.sh +++ b/build/patch-charts.sh @@ -259,6 +259,10 @@ gateways: {}\n' "${HELM_DIR}/istio-control/istio-discovery/values.yaml" } function patchGateways() { + echo "move helpers file to gateways directory" + cp "${HELM_DIR}"/istio-control/istio-discovery/templates/_helpers.tpl "${HELM_DIR}/gateways/istio-ingress/templates" + cp "${HELM_DIR}"/istio-control/istio-discovery/templates/_helpers.tpl "${HELM_DIR}/gateways/istio-egress/templates" + echo "patching Gateways specific Helm charts" sed_wrap -i -r -e 's/type: LoadBalancer *(#.*)?$/type: ClusterIP/' "${HELM_DIR}/gateways/istio-ingress/values.yaml" @@ -302,6 +306,24 @@ gatewayAPI: tee >(cat >> "${HELM_DIR}/gateways/istio-ingress/values.yaml")\ >(cat >> "${HELM_DIR}/gateways/istio-egress/values.yaml") + echo " +telemetry: + enabled: true + v2: + enabled: true + prometheus: + enabled: true + configOverride: + gateway: {} + inboundSidecar: {} + outboundSidecar: {} + stackdriver: + enabled: false + configOverride: {} + disableOutbound: false" | \ + tee >(cat >> "${HELM_DIR}/gateways/istio-ingress/values.yaml")\ + >(cat >> "${HELM_DIR}/gateways/istio-egress/values.yaml") + sed_wrap -i -e '/ logLevel:/ a\\n tracer: zipkin' "${HELM_DIR}/gateways/istio-ingress/values.yaml" sed_wrap -i -e '/ logLevel:/ a\\n tracer: zipkin' "${HELM_DIR}/gateways/istio-egress/values.yaml" @@ -477,14 +499,15 @@ function removeUnsupportedCharts() { rm -rf "${HELM_DIR}/istiocoredns" rm -rf "${HELM_DIR}/istiod-remote" rm -rf "${HELM_DIR}/istio-operator" + rm -rf "${HELM_DIR}/ztunnel" } function moveEnvoyFiltersToMeshConfigChart() { echo "moving EnvoyFilter manifests to mesh-config" mv "${HELM_DIR}"/istio-control/istio-discovery/templates/telemetry*.yaml "${HELM_DIR}/mesh-config/templates" + cp "${HELM_DIR}"/istio-control/istio-discovery/templates/_helpers.tpl "${HELM_DIR}/mesh-config/templates" sed_nowrap -n -e '/^telemetry:/,/^ logWindowDuration/ p' "${HELM_DIR}/istio-control/istio-discovery/values.yaml" > "${HELM_DIR}/mesh-config/values.yaml" - sed_wrap -i -n -e '/^telemetry:/,/^ logWindowDuration/ d; p' "${HELM_DIR}/istio-control/istio-discovery/values.yaml" sed_wrap -i -e '/multiCluster:/ i\ # Default mtls policy. If true, mtls between services will be enabled by default.\ mtls:\ @@ -529,7 +552,7 @@ global:\ function copyGlobalValues() { echo "copying global.yaml file from overlay charts as global.yaml file is removed in upstream but it's still needed." - cp "${SOURCE_DIR}/resources/helm/overlays/global.yaml" "${SOURCE_DIR}/resources/helm/v2.4/" + cp "${SOURCE_DIR}/resources/helm/overlays/global.yaml" "${SOURCE_DIR}/resources/helm/v2.5/" } # This hack is hopefully only needed for a few versions until this PR is merged: https://github.com/istio/istio/pull/39375 diff --git a/build/patch-container-image.sh b/build/patch-container-image.sh index fabcde16ed..cc9cdfb210 100755 --- a/build/patch-container-image.sh +++ b/build/patch-container-image.sh @@ -51,30 +51,9 @@ function patch_oauth_proxy_image() { fi } -function patch_3scale_container_image() { - local file=$1 - if [ -f "$file" ]; then - if grep -q 'if contains "/" .Values.image' "${file}"; then return 0; fi - sed_wrap -i -re '/^ *- image:/,/^ *name: *3scale-istio-adapter *$/ { - /image:/!d - /image:/s+^( *)- image:.*$+\1- name: 3scale-istio-adapter\ -\{\{- if contains "/" .Values.image \}\}\ -\1 image: "\{\{ .Values.image \}\}"\ -\{\{- else \}\}\ -\1 image: "\{\{ .Values.hub \}\}/\{\{ .Values.image \}\}:\{\{ .Values.tag \}\}"\ -\{\{- end \}\}\ -\1 imagePullPolicy: Always+ - }' "${file}" - else - echo "ERROR: file does not exist: ${file}" - return 1 - fi -} - patch_container_image galley "${HELM_DIR}/istio/charts/galley/templates/deployment.yaml" patch_container_image '\{\{ .Chart.Name \}\}' "${HELM_DIR}/istio/charts/grafana/templates/deployment.yaml" patch_container_image citadel "${HELM_DIR}/istio/charts/security/templates/deployment.yaml" patch_container_image sidecar-injector-webhook "${HELM_DIR}/istio/charts/sidecarInjectorWebhook/templates/deployment.yaml" patch_oauth_proxy_image grafana-proxy "${HELM_DIR}/istio/charts/grafana/templates/deployment.yaml" patch_oauth_proxy_image prometheus-proxy "${HELM_DIR}/istio/charts/prometheus/templates/deployment.yaml" -patch_3scale_container_image "${HELM_DIR}/maistra-threescale/templates/deployment.yaml" diff --git a/deploy/maistra-operator.yaml b/deploy/maistra-operator.yaml index 9950bb1788..991a09a4ce 100644 --- a/deploy/maistra-operator.yaml +++ b/deploy/maistra-operator.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: service.beta.openshift.io/inject-cabundle: "true" controller-gen.kubebuilder.io/version: v0.4.1 @@ -10332,7 +10332,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: controller-gen.kubebuilder.io/version: v0.4.1 creationTimestamp: null @@ -10511,7 +10511,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: controller-gen.kubebuilder.io/version: v0.4.1 creationTimestamp: null @@ -10980,11 +10980,19 @@ spec: olm.relatedImage.v2_4.proxyv2: quay.io/maistra/proxyv2-ubi8:2.4.0 olm.relatedImage.v2_4.rls: quay.io/maistra/ratelimit-ubi8:2.4.0 + olm.relatedImage.v2_5.cni: quay.io/maistra/istio-cni-ubi8:2.5.0 + olm.relatedImage.v2_5.grafana: quay.io/maistra/grafana-ubi8:2.5.0 + olm.relatedImage.v2_5.pilot: quay.io/maistra/pilot-ubi8:2.5.0 + olm.relatedImage.v2_5.prometheus: quay.io/prometheus/prometheus:v2.42.0 + olm.relatedImage.v2_5.prometheus-config-reloader: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + olm.relatedImage.v2_5.proxyv2: quay.io/maistra/proxyv2-ubi8:2.5.0 + olm.relatedImage.v2_5.rls: quay.io/maistra/ratelimit-ubi8:2.5.0 + spec: serviceAccountName: istio-operator containers: - name: istio-operator - image: quay.io/maistra/istio-ubi8-operator:2.4.0 + image: quay.io/maistra/istio-ubi8-operator:2.5.0 ports: - containerPort: 11999 name: validation diff --git a/deploy/servicemesh-operator.yaml b/deploy/servicemesh-operator.yaml index 433b7ae293..911aa59e01 100644 --- a/deploy/servicemesh-operator.yaml +++ b/deploy/servicemesh-operator.yaml @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: service.beta.openshift.io/inject-cabundle: "true" controller-gen.kubebuilder.io/version: v0.4.1 @@ -10332,7 +10332,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: controller-gen.kubebuilder.io/version: v0.4.1 creationTimestamp: null @@ -10511,7 +10511,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: controller-gen.kubebuilder.io/version: v0.4.1 creationTimestamp: null @@ -10973,13 +10973,21 @@ spec: olm.relatedImage.v2_3.wasm-cacher: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_23} olm.relatedImage.v2_3.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_23} # 2.4 images - olm.relatedImage.v2_4.cni: ${OSSM_CNI_IMAGE} - olm.relatedImage.v2_4.grafana: ${OSSM_GRAFANA_IMAGE} - olm.relatedImage.v2_4.pilot: ${OSSM_PILOT_IMAGE} + olm.relatedImage.v2_4.cni: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-istio-cni-rhel8:${OSSM_24} + olm.relatedImage.v2_4.grafana: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-grafana-rhel8:${OSSM_24} + olm.relatedImage.v2_4.pilot: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_24} olm.relatedImage.v2_4.prometheus: registry.redhat.io/openshift4/ose-prometheus:v4.12 olm.relatedImage.v2_4.prometheus-config-reloader: registry.redhat.io/openshift4/ose-prometheus-config-reloader:v4.12 - olm.relatedImage.v2_4.proxyv2: ${OSSM_PROXY_IMAGE} - olm.relatedImage.v2_4.rls: ${OSSM_RATELIMIT_IMAGE} + olm.relatedImage.v2_4.proxyv2: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-proxyv2-rhel8:${OSSM_24} + olm.relatedImage.v2_4.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_24} + # 2.5 images + olm.relatedImage.v2_5.cni: ${OSSM_CNI_IMAGE} + olm.relatedImage.v2_5.grafana: ${OSSM_GRAFANA_IMAGE} + olm.relatedImage.v2_5.pilot: ${OSSM_PILOT_IMAGE} + olm.relatedImage.v2_5.prometheus: registry.redhat.io/openshift4/ose-prometheus:v4.13 + olm.relatedImage.v2_5.prometheus-config-reloader: registry.redhat.io/openshift4/ose-prometheus-config-reloader:v4.13 + olm.relatedImage.v2_5.proxyv2: ${OSSM_PROXY_IMAGE} + olm.relatedImage.v2_5.rls: ${OSSM_RATELIMIT_IMAGE} oauth-proxy.query: "true" oauth-proxy.namespace: openshift diff --git a/deploy/src/crd.yaml b/deploy/src/crd.yaml index afdf5ac1cb..48acc8cb03 100644 --- a/deploy/src/crd.yaml +++ b/deploy/src/crd.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: service.beta.openshift.io/inject-cabundle: "true" controller-gen.kubebuilder.io/version: v0.4.1 @@ -10331,7 +10331,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: controller-gen.kubebuilder.io/version: v0.4.1 creationTimestamp: null @@ -10510,7 +10510,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: labels: - maistra-version: 2.4.3 + maistra-version: 2.5.0 annotations: controller-gen.kubebuilder.io/version: v0.4.1 creationTimestamp: null diff --git a/deploy/src/deployment-maistra.yaml b/deploy/src/deployment-maistra.yaml index 4da16cd2a2..0a44cfe665 100644 --- a/deploy/src/deployment-maistra.yaml +++ b/deploy/src/deployment-maistra.yaml @@ -47,11 +47,19 @@ spec: olm.relatedImage.v2_4.proxyv2: quay.io/maistra/proxyv2-ubi8:2.4.0 olm.relatedImage.v2_4.rls: quay.io/maistra/ratelimit-ubi8:2.4.0 + olm.relatedImage.v2_5.cni: quay.io/maistra/istio-cni-ubi8:2.5.0 + olm.relatedImage.v2_5.grafana: quay.io/maistra/grafana-ubi8:2.5.0 + olm.relatedImage.v2_5.pilot: quay.io/maistra/pilot-ubi8:2.5.0 + olm.relatedImage.v2_5.prometheus: quay.io/prometheus/prometheus:v2.42.0 + olm.relatedImage.v2_5.prometheus-config-reloader: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + olm.relatedImage.v2_5.proxyv2: quay.io/maistra/proxyv2-ubi8:2.5.0 + olm.relatedImage.v2_5.rls: quay.io/maistra/ratelimit-ubi8:2.5.0 + spec: serviceAccountName: istio-operator containers: - name: istio-operator - image: quay.io/maistra/istio-ubi8-operator:2.4.0 + image: quay.io/maistra/istio-ubi8-operator:2.5.0 ports: - containerPort: 11999 name: validation diff --git a/deploy/src/deployment-servicemesh.yaml b/deploy/src/deployment-servicemesh.yaml index 9cdacb2d10..769fe5ec95 100644 --- a/deploy/src/deployment-servicemesh.yaml +++ b/deploy/src/deployment-servicemesh.yaml @@ -40,13 +40,21 @@ spec: olm.relatedImage.v2_3.wasm-cacher: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_23} olm.relatedImage.v2_3.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_23} # 2.4 images - olm.relatedImage.v2_4.cni: ${OSSM_CNI_IMAGE} - olm.relatedImage.v2_4.grafana: ${OSSM_GRAFANA_IMAGE} - olm.relatedImage.v2_4.pilot: ${OSSM_PILOT_IMAGE} + olm.relatedImage.v2_4.cni: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-istio-cni-rhel8:${OSSM_24} + olm.relatedImage.v2_4.grafana: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-grafana-rhel8:${OSSM_24} + olm.relatedImage.v2_4.pilot: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_24} olm.relatedImage.v2_4.prometheus: registry.redhat.io/openshift4/ose-prometheus:v4.12 olm.relatedImage.v2_4.prometheus-config-reloader: registry.redhat.io/openshift4/ose-prometheus-config-reloader:v4.12 - olm.relatedImage.v2_4.proxyv2: ${OSSM_PROXY_IMAGE} - olm.relatedImage.v2_4.rls: ${OSSM_RATELIMIT_IMAGE} + olm.relatedImage.v2_4.proxyv2: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-proxyv2-rhel8:${OSSM_24} + olm.relatedImage.v2_4.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_24} + # 2.5 images + olm.relatedImage.v2_5.cni: ${OSSM_CNI_IMAGE} + olm.relatedImage.v2_5.grafana: ${OSSM_GRAFANA_IMAGE} + olm.relatedImage.v2_5.pilot: ${OSSM_PILOT_IMAGE} + olm.relatedImage.v2_5.prometheus: registry.redhat.io/openshift4/ose-prometheus:v4.13 + olm.relatedImage.v2_5.prometheus-config-reloader: registry.redhat.io/openshift4/ose-prometheus-config-reloader:v4.13 + olm.relatedImage.v2_5.proxyv2: ${OSSM_PROXY_IMAGE} + olm.relatedImage.v2_5.rls: ${OSSM_RATELIMIT_IMAGE} oauth-proxy.query: "true" oauth-proxy.namespace: openshift diff --git a/manifests-maistra/2.5.0/maistraoperator.v2.5.0.clusterserviceversion.yaml b/manifests-maistra/2.5.0/maistraoperator.v2.5.0.clusterserviceversion.yaml new file mode 100644 index 0000000000..dcd1047092 --- /dev/null +++ b/manifests-maistra/2.5.0/maistraoperator.v2.5.0.clusterserviceversion.yaml @@ -0,0 +1,753 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + name: maistraoperator.v2.5.0 + namespace: placeholder + labels: + operatorframework.io/arch.amd64: supported + + annotations: + categories: "OpenShift Optional, Integration & Delivery" + capabilities: "Seamless Upgrades" + certified: "false" + repository: https://github.com/maistra/istio-operator + description: |- + The Maistra Operator enables you to install, configure, and manage an instance of Maistra service mesh. Maistra is based on the open source Istio project. + + containerImage: quay.io/maistra/istio-ubi8-operator:2.5.0 + createdAt: 2023-10-05T22:49:57CEST + support: Red Hat, Inc. + olm.skipRange: ">=1.0.2 <2.5.0-0" + operators.openshift.io/infrastructure-features: '[]' + + alm-examples: |- + [ + { + "apiVersion": "maistra.io/v2", + "kind": "ServiceMeshControlPlane", + "metadata": { + "name": "basic", + "namespace": "control-plane-namespace" + }, + "spec": { + "version": "v2.5", + "tracing": { + "type": "Jaeger", + "sampling": 10000 + }, + "policy": { + "type": "Istiod" + }, + "telemetry": { + "type": "Istiod" + }, + "addons": { + "jaeger": { + "install": { + "storage": { + "type": "Memory" + } + } + }, + "prometheus": { + "enabled": true + }, + "kiali": { + "enabled": true + }, + "grafana": { + "enabled": true + } + } + } + }, + { + "apiVersion": "maistra.io/v1", + "kind": "ServiceMeshMemberRoll", + "metadata": { + "name": "default", + "namespace": "control-plane-namespace" + }, + "spec": { + "members": [ + "your-project", + "another-of-your-projects" + ] + } + }, + { + "apiVersion": "maistra.io/v1", + "kind": "ServiceMeshMember", + "metadata": { + "name": "default", + "namespace": "application-namespace" + }, + "spec": { + "controlPlaneRef": { + "name": "basic", + "namespace": "control-plane-namespace" + } + } + } + ] +spec: + version: 2.5.0-0 + maturity: alpha + displayName: Maistra Service Mesh + description: |- + Maistra is a platform that provides behavioral insight and operational control over a service mesh, providing a uniform way to connect, secure, and monitor microservice applications. + + ### Overview + + Maistra Service Mesh, based on the open source [Istio](https://istio.io/) project, adds a transparent layer on existing + distributed applications without requiring any changes to the service code. You add Maistra Service Mesh + support to services by deploying a special sidecar proxy throughout your environment that intercepts all network + communication between microservices. You configure and manage the service mesh using the control plane features. + + Maistra Service Mesh provides an easy way to create a network of deployed services that provides discovery, + load balancing, service-to-service authentication, failure recovery, metrics, and monitoring. A service mesh also + provides more complex operational functionality, including A/B testing, canary releases, rate limiting, access + control, and end-to-end authentication. + + ### Core Capabilities + + Maistra Service Mesh supports uniform application of a number of key capabilities across a network of services: + + + **Traffic Management** - Control the flow of traffic and API calls between services, make calls more reliable, + and make the network more robust in the face of adverse conditions. + + + **Service Identity and Security** - Provide services in the mesh with a verifiable identity and provide the + ability to protect service traffic as it flows over networks of varying degrees of trustworthiness. + + + **Policy Enforcement** - Apply organizational policy to the interaction between services, ensure access policies + are enforced and resources are fairly distributed among consumers. Policy changes are made by configuring the + mesh, not by changing application code. + + + **Telemetry** - Gain understanding of the dependencies between services and the nature and flow of traffic between + them, providing the ability to quickly identify issues. + + ### Joining Projects Into a Mesh + + Once an instance of Maistra Service Mesh has been installed, it will only exercise control over services within its own + project. Other projects may be added into the mesh using one of two methods: + + 1. A **ServiceMeshMember** resource may be created in other projects to add those projects into the mesh. The + **ServiceMeshMember** specifies a reference to the **ServiceMeshControlPlane** object that was used to install + the control plane. The user creating the **ServiceMeshMember** resource must have permission to *use* the + **ServiceMeshControlPlane** object. The adminstrator for the project containing the control plane can grant + individual users or groups the *use* permissions. + + 2. A **ServiceMeshMemberRoll** resource may be created in the project containing the control plane. This resource + contains a single *members* list of all the projects that should belong in the mesh. The resource must be named + *default*. The user creating the resource must have *edit* or *admin* permissions for all projects in the + *members* list. + + ### More Information + + * [Documentation](https://maistra.io/) + * [Bugs](https://issues.redhat.com/projects/MAISTRA) + + icon: + - mediatype: image/png + base64data: |- + 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 + + keywords: [ 'istio', 'maistra', 'servicemesh' ] + maintainers: + - name: Red Hat, OpenShift Service Mesh + email: istio-feedback@redhat.com + provider: + name: Red Hat, Inc. + links: + - name: Maistra Service Mesh + url: https://maistra.io/ + - name: Istio + url: https://istio.io/ + - name: Operator Source Code + url: https://github.com/Maistra/istio-operator + - name: Bugs + url: https://issues.redhat.com/projects/MAISTRA + replaces: maistraoperator.v2.4.2 + installModes: + - type: OwnNamespace + supported: false + - type: SingleNamespace + supported: false + - type: MultiNamespace + supported: false + - type: AllNamespaces + supported: true + relatedImages: + - name: v2_1.cni + image: quay.io/maistra/istio-cni-ubi8:2.1.4 + - name: v2_1.grafana + image: quay.io/maistra/grafana-ubi8:2.1.4 + - name: v2_1.pilot + image: quay.io/maistra/pilot-ubi8:2.1.4 + - name: v2_1.prometheus + image: quay.io/maistra/prometheus-ubi8:2.1.4 + - name: v2_1.proxyv2 + image: quay.io/maistra/proxyv2-ubi8:2.1.4 + - name: v2_1.wasm-cacher + image: quay.io/maistra/pilot-ubi8:2.1.4 + - name: v2_1.rls + image: quay.io/maistra/ratelimit-ubi8:2.1.4 + - name: v2_2.cni + image: quay.io/maistra/istio-cni-ubi8:2.2.2 + - name: v2_2.grafana + image: quay.io/maistra/grafana-ubi8:2.2.2 + - name: v2_2.pilot + image: quay.io/maistra/pilot-ubi8:2.2.2 + - name: v2_2.prometheus + image: quay.io/maistra/prometheus-ubi8:2.2.2 + - name: v2_2.proxyv2 + image: quay.io/maistra/proxyv2-ubi8:2.2.2 + - name: v2_2.wasm-cacher + image: quay.io/maistra/pilot-ubi8:2.2.2 + - name: v2_2.rls + image: quay.io/maistra/ratelimit-ubi8:2.2.2 + - name: v2_3.cni + image: quay.io/maistra/istio-cni-ubi8:2.3.0 + - name: v2_3.grafana + image: quay.io/maistra/grafana-ubi8:2.3.0 + - name: v2_3.pilot + image: quay.io/maistra/pilot-ubi8:2.3.0 + - name: v2_3.prometheus + image: quay.io/maistra/prometheus-ubi8:2.3.0 + - name: v2_3.proxyv2 + image: quay.io/maistra/proxyv2-ubi8:2.3.0 + - name: v2_3.rls + image: quay.io/maistra/ratelimit-ubi8:2.3.0 + - name: v2_4.cni + image: quay.io/maistra/istio-cni-ubi8:2.4.0 + - name: v2_4.grafana + image: quay.io/maistra/grafana-ubi8:2.4.0 + - name: v2_4.pilot + image: quay.io/maistra/pilot-ubi8:2.4.0 + - name: v2_4.prometheus + image: quay.io/prometheus/prometheus:v2.42.0 + - name: v2_4.prometheus-config-reloader + image: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + - name: v2_4.proxyv2 + image: quay.io/maistra/proxyv2-ubi8:2.4.0 + - name: v2_4.rls + image: quay.io/maistra/ratelimit-ubi8:2.4.0 + - name: v2_5.cni + image: quay.io/maistra/istio-cni-ubi8:2.5.0 + - name: v2_5.grafana + image: quay.io/maistra/grafana-ubi8:2.5.0 + - name: v2_5.pilot + image: quay.io/maistra/pilot-ubi8:2.5.0 + - name: v2_5.prometheus + image: quay.io/prometheus/prometheus:v2.42.0 + - name: v2_5.prometheus-config-reloader + image: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + - name: v2_5.proxyv2 + image: quay.io/maistra/proxyv2-ubi8:2.5.0 + - name: v2_5.rls + image: quay.io/maistra/ratelimit-ubi8:2.5.0 + install: + strategy: deployment + spec: + clusterPermissions: + - serviceAccountName: istio-operator + rules: + + # operator-sdk rules + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - "" + resources: + - services/finalizers + verbs: + - '*' + # operator rules for managing istio + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - namespaces + - persistentvolumeclaims + - pods + - replicationcontrollers + - secrets + - serviceaccounts + - services + - events # is this needed? + verbs: + - '*' + - apiGroups: + - apps + - extensions + resources: + - daemonsets + - deployments + - deployments/finalizers + - ingresses # is this needed? should it be converted to a route? + - ingresses/status + - replicasets + - statefulsets + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - '*' + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - '*' + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - '*' + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' + - apiGroups: + - certmanager.k8s.io + resources: + - clusterissuers + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - ingresses + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - '*' + - apiGroups: + - authentication.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - config.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - networking.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - security.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - jaegertracing.io + resources: + - jaegers + verbs: + - '*' + - apiGroups: + - kiali.io + resources: + - kialis + verbs: + - '*' + - apiGroups: + - maistra.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - authentication.maistra.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.maistra.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - '*' + # required by smmr controller + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + - apiGroups: + - network.openshift.io + resources: + - clusternetworks + verbs: + - get + - list + - watch + - apiGroups: + - config.openshift.io + resources: + - networks + verbs: + - get + - list + - watch + - apiGroups: + - image.openshift.io + resources: + - imagestreams + verbs: + - get + - list + - watch + - apiGroups: + - network.openshift.io + resources: + - netnamespaces + verbs: + - get + - list + - watch + - update + - apiGroups: + - k8s.cni.cncf.io + resources: + - network-attachment-definitions + verbs: + - create + - delete + - get + - list + - patch + - watch + # required by cni daemonset + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - use + # required by pod locality controller + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + verbs: + - get + - list + - watch + - apiGroups: # might be required by citadel + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - nonResourceURLs: + - /metrics + verbs: + - get + deployments: + - name: istio-operator + spec: + + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + name: istio-operator + template: + metadata: + labels: + name: istio-operator + annotations: + olm.relatedImage.v2_1.cni: quay.io/maistra/istio-cni-ubi8:2.1.4 + olm.relatedImage.v2_1.grafana: quay.io/maistra/grafana-ubi8:2.1.4 + olm.relatedImage.v2_1.pilot: quay.io/maistra/pilot-ubi8:2.1.4 + olm.relatedImage.v2_1.prometheus: quay.io/maistra/prometheus-ubi8:2.1.4 + olm.relatedImage.v2_1.proxyv2: quay.io/maistra/proxyv2-ubi8:2.1.4 + olm.relatedImage.v2_1.wasm-cacher: quay.io/maistra/pilot-ubi8:2.1.4 + olm.relatedImage.v2_1.rls: quay.io/maistra/ratelimit-ubi8:2.1.4 + olm.relatedImage.v2_2.cni: quay.io/maistra/istio-cni-ubi8:2.2.2 + olm.relatedImage.v2_2.grafana: quay.io/maistra/grafana-ubi8:2.2.2 + olm.relatedImage.v2_2.pilot: quay.io/maistra/pilot-ubi8:2.2.2 + olm.relatedImage.v2_2.prometheus: quay.io/maistra/prometheus-ubi8:2.2.2 + olm.relatedImage.v2_2.proxyv2: quay.io/maistra/proxyv2-ubi8:2.2.2 + olm.relatedImage.v2_2.wasm-cacher: quay.io/maistra/pilot-ubi8:2.2.2 + olm.relatedImage.v2_2.rls: quay.io/maistra/ratelimit-ubi8:2.2.2 + olm.relatedImage.v2_3.cni: quay.io/maistra/istio-cni-ubi8:2.3.0 + olm.relatedImage.v2_3.grafana: quay.io/maistra/grafana-ubi8:2.3.0 + olm.relatedImage.v2_3.pilot: quay.io/maistra/pilot-ubi8:2.3.0 + olm.relatedImage.v2_3.prometheus: quay.io/maistra/prometheus-ubi8:2.3.0 + olm.relatedImage.v2_3.proxyv2: quay.io/maistra/proxyv2-ubi8:2.3.0 + olm.relatedImage.v2_3.rls: quay.io/maistra/ratelimit-ubi8:2.3.0 + olm.relatedImage.v2_4.cni: quay.io/maistra/istio-cni-ubi8:2.4.0 + olm.relatedImage.v2_4.grafana: quay.io/maistra/grafana-ubi8:2.4.0 + olm.relatedImage.v2_4.pilot: quay.io/maistra/pilot-ubi8:2.4.0 + olm.relatedImage.v2_4.prometheus: quay.io/prometheus/prometheus:v2.42.0 + olm.relatedImage.v2_4.prometheus-config-reloader: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + olm.relatedImage.v2_4.proxyv2: quay.io/maistra/proxyv2-ubi8:2.4.0 + olm.relatedImage.v2_4.rls: quay.io/maistra/ratelimit-ubi8:2.4.0 + olm.relatedImage.v2_5.cni: quay.io/maistra/istio-cni-ubi8:2.5.0 + olm.relatedImage.v2_5.grafana: quay.io/maistra/grafana-ubi8:2.5.0 + olm.relatedImage.v2_5.pilot: quay.io/maistra/pilot-ubi8:2.5.0 + olm.relatedImage.v2_5.prometheus: quay.io/prometheus/prometheus:v2.42.0 + olm.relatedImage.v2_5.prometheus-config-reloader: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + olm.relatedImage.v2_5.proxyv2: quay.io/maistra/proxyv2-ubi8:2.5.0 + olm.relatedImage.v2_5.rls: quay.io/maistra/ratelimit-ubi8:2.5.0 + spec: + serviceAccountName: istio-operator + containers: + - name: istio-operator + image: quay.io/maistra/istio-ubi8-operator:2.5.0 + ports: + - containerPort: 11999 + name: validation + - containerPort: 11200 + name: probes + - containerPort: 60000 + name: metrics + command: + - istio-operator + - --config + - /etc/operator/olm/config.properties + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + value: "" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: istio-operator + # - name: ISTIO_CNI_IMAGE_PULL_SECRET + # value: name-of-secret + readinessProbe: + httpGet: + scheme: HTTP + path: /readyz + port: 11200 + volumeMounts: + - name: operator-olm-config + mountPath: /etc/operator/olm + readOnly: true + - name: webhook-tls-volume + readOnly: true + mountPath: /tmp/k8s-webhook-server/serving-certs + - name: smcp-templates + readOnly: true + mountPath: /usr/local/share/istio-operator/templates/ + volumes: + - name: operator-olm-config + downwardAPI: + defaultMode: 420 + items: + - fieldRef: + fieldPath: metadata.annotations + path: config.properties + - name: webhook-tls-volume + secret: + secretName: maistra-operator-serving-cert + optional: true # this won't be available until service-ca creates the secret + - name: smcp-templates + configMap: + name: smcp-templates + optional: true + customresourcedefinitions: + owned: + - name: servicemeshcontrolplanes.maistra.io + version: v2 + kind: ServiceMeshControlPlane + displayName: Istio Service Mesh Control Plane + description: An Istio control plane installation + specDescriptors: + - displayName: Control Plane Version + description: Specify the version of the control plane you want to install + path: version + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.5' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.4' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.3' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.2' + - displayName: Control Plane Mode + description: 'NOTE: only applies if version is v2.4 or higher' + path: mode + - displayName: Control Plane Security + description: Enable mTLS for communication between control plane components + path: security.controlPlane.mtls + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Install Prometheus + description: Set to true to install Prometheus + path: addons.prometheus.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:metrics' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Data Plane Security + description: Enable mTLS for communcation between services in the mesh + path: security.dataPlane.mtls + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Install Kiali + description: Set to true to install Kiali + path: addons.kiali.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:visualization' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Install Grafana + description: Set to true to install Grafana + path: addons.grafana.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:visualization' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Tracing provider + description: Select the provider to use for tracing + path: tracing.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:tracing' + - 'urn:alm:descriptor:com.tectonic.ui:select:None' + - 'urn:alm:descriptor:com.tectonic.ui:select:Jaeger' + - 'urn:alm:descriptor:com.tectonic.ui:select:Stackdriver' + - displayName: Jaeger Storage Type + description: Set storage type for Jaeger (applies only when Jaeger is selected as the tracing provider) + path: addons.jaeger.install.storage.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:tracing' + - 'urn:alm:descriptor:com.tectonic.ui:select:Memory' + - 'urn:alm:descriptor:com.tectonic.ui:select:Elasticsearch' + - displayName: Type of Policy + description: Select "Mixer" when deploying a control plane version less than "v2.0" or when planning to install 3scale adapter + path: policy.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Policy' + - 'urn:alm:descriptor:com.tectonic.ui:select:Istiod' + - 'urn:alm:descriptor:com.tectonic.ui:select:Mixer' + - displayName: Install 3Scale Adapter + description: Set to true to install the Istio 3Scale adapter (applies only when Policy type is set to Mixer) + path: addons.3scale.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Policy' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Type of Telemetry + description: Select "Mixer" when deploying a control plane version less than "v2.0" + path: telemetry.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Telemetry' + - 'urn:alm:descriptor:com.tectonic.ui:select:Istiod' + - 'urn:alm:descriptor:com.tectonic.ui:select:Mixer' + - displayName: Default Resource Requirements + description: Set the default compute resource requests and limits for control plane components + path: runtime.defaults.container.resources + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements' + - 'urn:alm:descriptor:com.tectonic.ui:advanced' + statusDescriptors: + - displayName: Components + description: Status of components deployed by this ServiceMeshControlPlane resource + path: readiness.components + x-descriptors: + - "urn:alm:descriptor:com.tectonic.ui:podStatuses" + - name: servicemeshmembers.maistra.io + version: v1 + kind: ServiceMeshMember + displayName: Istio Service Mesh Member + description: Marks the containing namespace as a member of the referenced Service Mesh + specDescriptors: + - displayName: Namespace + description: The namespace of the ServiceMeshControlPlane to which this namespace belongs + path: controlPlaneRef.namespace + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Service_Mesh_Control_Plane' + - 'urn:alm:descriptor:io.kubernetes:Project' + - displayName: Name + description: The name of the ServiceMeshControlPlane to which this namespace belongs + path: controlPlaneRef.name + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Service_Mesh_Control_Plane' + - 'urn:alm:descriptor:com.tectonic.ui:text' + - name: servicemeshmemberrolls.maistra.io + version: v1 + kind: ServiceMeshMemberRoll + displayName: Istio Service Mesh Member Roll + description: A list of namespaces in Service Mesh diff --git a/manifests-maistra/2.5.0/servicemeshcontrolplanes.crd.yaml b/manifests-maistra/2.5.0/servicemeshcontrolplanes.crd.yaml new file mode 100644 index 0000000000..c9add32725 --- /dev/null +++ b/manifests-maistra/2.5.0/servicemeshcontrolplanes.crd.yaml @@ -0,0 +1,10325 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: 2.5.0 + annotations: + service.beta.openshift.io/inject-cabundle: "true" + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: servicemeshcontrolplanes.maistra.io +spec: + group: maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshControlPlane + listKind: ServiceMeshControlPlaneList + plural: servicemeshcontrolplanes + shortNames: + - smcp + singular: servicemeshcontrolplane + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: How many of the total number of components are ready + jsonPath: .status.annotations.readyComponentCount + name: Ready + type: string + - description: Whether or not the control plane installation is up to date. + jsonPath: .status.conditions[?(@.type=="Reconciled")].reason + name: Status + type: string + - description: The configuration template to use as the base. + jsonPath: .status.lastAppliedConfiguration.template + name: Template + type: string + - description: The actual current version of the control plane installation. + jsonPath: .status.lastAppliedConfiguration.version + name: Version + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: The image hub used as the base for all component images. + jsonPath: .status.lastAppliedConfiguration.istio.global.hub + name: Image HUB + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + istio: + type: object + x-kubernetes-preserve-unknown-fields: true + networkType: + type: string + profiles: + items: + type: string + type: array + template: + type: string + threeScale: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + status: + nullable: true + properties: + annotations: + additionalProperties: + type: string + type: object + components: + items: + properties: + children: + items: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + resource: + type: string + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + lastAppliedConfiguration: + properties: + istio: + type: object + x-kubernetes-preserve-unknown-fields: true + networkType: + type: string + profiles: + items: + type: string + type: array + template: + type: string + threeScale: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + observedGeneration: + format: int64 + type: integer + reconciledVersion: + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: How many of the total number of components are ready + jsonPath: .status.annotations.readyComponentCount + name: Ready + type: string + - description: Whether or not the control plane installation is up to date and ready to handle requests. + jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - description: The configuration profiles applied to the configuration. + jsonPath: .status.appliedSpec.profiles + name: Profiles + type: string + - description: The actual current version of the control plane installation. + jsonPath: .status.chartVersion + name: Version + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: The image registry used as the base for all component images. + jsonPath: .status.appliedSpec.runtime.defaults.container.registry + name: Image Registry + priority: 1 + type: string + name: v2 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + addons: + properties: + 3scale: + properties: + backend: + properties: + cache_flush_interval: + format: int32 + type: integer + enable_cache: + type: boolean + policy_fail_closed: + type: boolean + type: object + client: + properties: + allow_insecure_connections: + type: boolean + timeout: + format: int32 + type: integer + type: object + enabled: + type: boolean + grpc: + properties: + max_conn_timeout: + format: int32 + type: integer + type: object + listen_addr: + format: int32 + type: integer + log_grpc: + type: boolean + log_json: + type: boolean + log_level: + type: string + metrics: + properties: + port: + format: int32 + type: integer + report: + type: boolean + type: object + system: + properties: + cache_max_size: + format: int64 + type: integer + cache_refresh_interval: + format: int32 + type: integer + cache_refresh_retries: + format: int32 + type: integer + cache_ttl: + format: int32 + type: integer + type: object + type: object + grafana: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + config: + properties: + env: + additionalProperties: + type: string + type: object + envSecrets: + additionalProperties: + type: string + type: object + type: object + persistence: + properties: + accessMode: + type: string + capacity: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + enabled: + type: boolean + storageClassName: + type: string + type: object + security: + properties: + enabled: + type: boolean + passphraseKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + type: object + jaeger: + properties: + install: + properties: + ingress: + properties: + enabled: + type: boolean + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + type: object + storage: + properties: + elasticsearch: + properties: + indexCleaner: + type: object + x-kubernetes-preserve-unknown-fields: true + nodeCount: + format: int32 + type: integer + redundancyPolicy: + type: string + storage: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + memory: + properties: + maxTraces: + format: int64 + type: integer + type: object + type: + type: string + type: object + type: object + name: + type: string + type: object + kiali: + properties: + enabled: + type: boolean + install: + properties: + dashboard: + properties: + enableGrafana: + type: boolean + enablePrometheus: + type: boolean + enableTracing: + type: boolean + viewOnly: + type: boolean + type: object + deployment: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + name: + type: string + type: object + prometheus: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + retention: + type: string + scrapeInterval: + type: string + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + useTLS: + type: boolean + type: object + metricsExpiryDuration: + type: string + scrape: + type: boolean + type: object + stackdriver: + properties: + telemetry: + properties: + accessLogging: + properties: + enabled: + type: boolean + logWindowDuration: + type: string + type: object + auth: + properties: + apiKey: + type: string + appCredentials: + type: boolean + serviceAccountPath: + type: string + type: object + configOverride: + type: object + x-kubernetes-preserve-unknown-fields: true + enableContextGraph: + type: boolean + enableLogging: + type: boolean + enableMetrics: + type: boolean + enabled: + type: boolean + type: object + tracer: + properties: + debug: + type: boolean + maxNumberOfAnnotations: + format: int64 + type: integer + maxNumberOfAttributes: + format: int64 + type: integer + maxNumberOfMessageEvents: + format: int64 + type: integer + type: object + type: object + type: object + cluster: + properties: + meshExpansion: + properties: + enabled: + type: boolean + ilbGateway: + properties: + enabled: + type: boolean + namespace: + type: string + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + multiCluster: + properties: + enabled: + type: boolean + meshNetworks: + additionalProperties: + properties: + endpoints: + items: + properties: + fromCIDR: + type: string + fromRegistry: + type: string + type: object + type: array + gateways: + items: + properties: + address: + type: string + port: + format: int32 + type: integer + registryServiceName: + type: string + service: + type: string + type: object + type: array + type: object + type: object + type: object + name: + type: string + network: + type: string + type: object + gateways: + properties: + additionalEgress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + additionalIngress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + egress: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + enabled: + type: boolean + ingress: + properties: + enabled: + type: boolean + ingress: + type: boolean + meshExpansionPorts: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + openshiftRoute: + properties: + enabled: + type: boolean + type: object + type: object + general: + properties: + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + logAsJSON: + type: boolean + type: object + validationMessages: + type: boolean + type: object + meshConfig: + properties: + discoverySelectors: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + extensionProviders: + items: + properties: + envoyExtAuthzGrpc: + properties: + failOpen: + type: boolean + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + envoyExtAuthzHttp: + properties: + failOpen: + type: boolean + headersToDownstreamOnAllow: + items: + type: string + type: array + headersToDownstreamOnDeny: + items: + type: string + type: array + headersToUpstreamOnAllow: + items: + type: string + type: array + includeAdditionalHeadersInCheck: + additionalProperties: + type: string + type: object + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + includeRequestHeadersInCheck: + items: + type: string + type: array + pathPrefix: + type: string + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + name: + type: string + prometheus: + type: object + required: + - name + type: object + type: array + type: object + mode: + enum: + - MultiTenant + - ClusterWide + type: string + policy: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + useAdapterCRDs: + type: boolean + type: object + enableChecks: + type: boolean + failOpen: + type: boolean + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + createService: + type: boolean + enableChecks: + type: boolean + failOpen: + type: boolean + type: object + type: + type: string + type: object + profiles: + items: + type: string + type: array + proxy: + properties: + accessLogging: + properties: + envoyService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + file: + properties: + encoding: + type: string + format: + type: string + name: + type: string + type: object + type: object + adminPort: + format: int32 + type: integer + concurrency: + format: int32 + type: integer + envoyMetricsService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + injection: + properties: + alwaysInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + autoInject: + type: boolean + injectedAnnotations: + additionalProperties: + type: string + type: object + neverInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + type: object + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + level: + type: string + type: object + networking: + properties: + clusterDomain: + type: string + connectionTimeout: + type: string + dns: + properties: + refreshRate: + type: string + searchSuffixes: + items: + type: string + type: array + type: object + initialization: + properties: + initContainer: + properties: + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + type: + type: string + type: object + maxConnectionAge: + type: string + protocol: + properties: + autoDetect: + properties: + inbound: + type: boolean + outbound: + type: boolean + timeout: + type: string + type: object + type: object + trafficControl: + properties: + inbound: + properties: + excludedPorts: + items: + format: int32 + type: integer + type: array + includedPorts: + items: + type: string + type: array + interceptionMode: + type: string + type: object + outbound: + properties: + excludedIPRanges: + items: + type: string + type: array + excludedPorts: + items: + format: int32 + type: integer + type: array + includedIPRanges: + items: + type: string + type: array + policy: + type: string + type: object + type: object + type: object + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + readiness: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + rewriteApplicationProbes: + type: boolean + statusPort: + format: int32 + type: integer + type: object + type: object + type: object + runtime: + properties: + components: + additionalProperties: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + defaults: + properties: + container: + properties: + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + podDisruption: + properties: + enabled: + type: boolean + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: object + pod: + properties: + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + security: + properties: + certificateAuthority: + properties: + cert-manager: + properties: + address: + type: string + pilotSecretName: + type: string + rootCAConfigMapName: + type: string + type: object + custom: + properties: + address: + type: string + type: object + istiod: + properties: + privateKey: + properties: + rootCADir: + type: string + type: object + selfSigned: + properties: + checkPeriod: + type: string + enableJitter: + type: boolean + gracePeriod: + type: string + ttl: + type: string + type: object + type: + type: string + workloadCertTTLDefault: + type: string + workloadCertTTLMax: + type: string + type: object + type: + type: string + type: object + controlPlane: + properties: + certProvider: + type: string + mtls: + type: boolean + tls: + properties: + cipherSuites: + items: + type: string + type: array + ecdhCurves: + items: + type: string + type: array + maxProtocolVersion: + type: string + minProtocolVersion: + type: string + type: object + type: object + dataPlane: + properties: + automtls: + type: boolean + mtls: + type: boolean + type: object + identity: + properties: + thirdParty: + properties: + audience: + type: string + issuer: + type: string + type: object + type: + type: string + type: object + jwksResolverCA: + type: string + manageNetworkPolicy: + type: boolean + trust: + properties: + additionalDomains: + items: + type: string + type: array + domain: + type: string + type: object + type: object + techPreview: + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + stdio: + properties: + enabled: + type: boolean + outputAsJSON: + type: boolean + type: object + useAdapterCRDs: + type: boolean + type: object + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + loadshedding: + properties: + latencyThreshold: + type: string + mode: + type: string + type: object + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + createService: + type: boolean + type: object + type: + type: string + type: object + tracing: + properties: + sampling: + format: int32 + maximum: 10000 + minimum: 0 + type: integer + type: + type: string + type: object + version: + type: string + type: object + status: + properties: + annotations: + additionalProperties: + type: string + type: object + appliedSpec: + properties: + addons: + properties: + 3scale: + properties: + backend: + properties: + cache_flush_interval: + format: int32 + type: integer + enable_cache: + type: boolean + policy_fail_closed: + type: boolean + type: object + client: + properties: + allow_insecure_connections: + type: boolean + timeout: + format: int32 + type: integer + type: object + enabled: + type: boolean + grpc: + properties: + max_conn_timeout: + format: int32 + type: integer + type: object + listen_addr: + format: int32 + type: integer + log_grpc: + type: boolean + log_json: + type: boolean + log_level: + type: string + metrics: + properties: + port: + format: int32 + type: integer + report: + type: boolean + type: object + system: + properties: + cache_max_size: + format: int64 + type: integer + cache_refresh_interval: + format: int32 + type: integer + cache_refresh_retries: + format: int32 + type: integer + cache_ttl: + format: int32 + type: integer + type: object + type: object + grafana: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + config: + properties: + env: + additionalProperties: + type: string + type: object + envSecrets: + additionalProperties: + type: string + type: object + type: object + persistence: + properties: + accessMode: + type: string + capacity: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + enabled: + type: boolean + storageClassName: + type: string + type: object + security: + properties: + enabled: + type: boolean + passphraseKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + type: object + jaeger: + properties: + install: + properties: + ingress: + properties: + enabled: + type: boolean + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + type: object + storage: + properties: + elasticsearch: + properties: + indexCleaner: + type: object + x-kubernetes-preserve-unknown-fields: true + nodeCount: + format: int32 + type: integer + redundancyPolicy: + type: string + storage: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + memory: + properties: + maxTraces: + format: int64 + type: integer + type: object + type: + type: string + type: object + type: object + name: + type: string + type: object + kiali: + properties: + enabled: + type: boolean + install: + properties: + dashboard: + properties: + enableGrafana: + type: boolean + enablePrometheus: + type: boolean + enableTracing: + type: boolean + viewOnly: + type: boolean + type: object + deployment: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + name: + type: string + type: object + prometheus: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + retention: + type: string + scrapeInterval: + type: string + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + useTLS: + type: boolean + type: object + metricsExpiryDuration: + type: string + scrape: + type: boolean + type: object + stackdriver: + properties: + telemetry: + properties: + accessLogging: + properties: + enabled: + type: boolean + logWindowDuration: + type: string + type: object + auth: + properties: + apiKey: + type: string + appCredentials: + type: boolean + serviceAccountPath: + type: string + type: object + configOverride: + type: object + x-kubernetes-preserve-unknown-fields: true + enableContextGraph: + type: boolean + enableLogging: + type: boolean + enableMetrics: + type: boolean + enabled: + type: boolean + type: object + tracer: + properties: + debug: + type: boolean + maxNumberOfAnnotations: + format: int64 + type: integer + maxNumberOfAttributes: + format: int64 + type: integer + maxNumberOfMessageEvents: + format: int64 + type: integer + type: object + type: object + type: object + cluster: + properties: + meshExpansion: + properties: + enabled: + type: boolean + ilbGateway: + properties: + enabled: + type: boolean + namespace: + type: string + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + multiCluster: + properties: + enabled: + type: boolean + meshNetworks: + additionalProperties: + properties: + endpoints: + items: + properties: + fromCIDR: + type: string + fromRegistry: + type: string + type: object + type: array + gateways: + items: + properties: + address: + type: string + port: + format: int32 + type: integer + registryServiceName: + type: string + service: + type: string + type: object + type: array + type: object + type: object + type: object + name: + type: string + network: + type: string + type: object + gateways: + properties: + additionalEgress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + additionalIngress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + egress: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + enabled: + type: boolean + ingress: + properties: + enabled: + type: boolean + ingress: + type: boolean + meshExpansionPorts: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + openshiftRoute: + properties: + enabled: + type: boolean + type: object + type: object + general: + properties: + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + logAsJSON: + type: boolean + type: object + validationMessages: + type: boolean + type: object + meshConfig: + properties: + discoverySelectors: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + extensionProviders: + items: + properties: + envoyExtAuthzGrpc: + properties: + failOpen: + type: boolean + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + envoyExtAuthzHttp: + properties: + failOpen: + type: boolean + headersToDownstreamOnAllow: + items: + type: string + type: array + headersToDownstreamOnDeny: + items: + type: string + type: array + headersToUpstreamOnAllow: + items: + type: string + type: array + includeAdditionalHeadersInCheck: + additionalProperties: + type: string + type: object + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + includeRequestHeadersInCheck: + items: + type: string + type: array + pathPrefix: + type: string + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + name: + type: string + prometheus: + type: object + required: + - name + type: object + type: array + type: object + mode: + enum: + - MultiTenant + - ClusterWide + type: string + policy: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + useAdapterCRDs: + type: boolean + type: object + enableChecks: + type: boolean + failOpen: + type: boolean + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + createService: + type: boolean + enableChecks: + type: boolean + failOpen: + type: boolean + type: object + type: + type: string + type: object + profiles: + items: + type: string + type: array + proxy: + properties: + accessLogging: + properties: + envoyService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + file: + properties: + encoding: + type: string + format: + type: string + name: + type: string + type: object + type: object + adminPort: + format: int32 + type: integer + concurrency: + format: int32 + type: integer + envoyMetricsService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + injection: + properties: + alwaysInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + autoInject: + type: boolean + injectedAnnotations: + additionalProperties: + type: string + type: object + neverInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + type: object + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + level: + type: string + type: object + networking: + properties: + clusterDomain: + type: string + connectionTimeout: + type: string + dns: + properties: + refreshRate: + type: string + searchSuffixes: + items: + type: string + type: array + type: object + initialization: + properties: + initContainer: + properties: + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + type: + type: string + type: object + maxConnectionAge: + type: string + protocol: + properties: + autoDetect: + properties: + inbound: + type: boolean + outbound: + type: boolean + timeout: + type: string + type: object + type: object + trafficControl: + properties: + inbound: + properties: + excludedPorts: + items: + format: int32 + type: integer + type: array + includedPorts: + items: + type: string + type: array + interceptionMode: + type: string + type: object + outbound: + properties: + excludedIPRanges: + items: + type: string + type: array + excludedPorts: + items: + format: int32 + type: integer + type: array + includedIPRanges: + items: + type: string + type: array + policy: + type: string + type: object + type: object + type: object + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + readiness: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + rewriteApplicationProbes: + type: boolean + statusPort: + format: int32 + type: integer + type: object + type: object + type: object + runtime: + properties: + components: + additionalProperties: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + defaults: + properties: + container: + properties: + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + podDisruption: + properties: + enabled: + type: boolean + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: object + pod: + properties: + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + security: + properties: + certificateAuthority: + properties: + cert-manager: + properties: + address: + type: string + pilotSecretName: + type: string + rootCAConfigMapName: + type: string + type: object + custom: + properties: + address: + type: string + type: object + istiod: + properties: + privateKey: + properties: + rootCADir: + type: string + type: object + selfSigned: + properties: + checkPeriod: + type: string + enableJitter: + type: boolean + gracePeriod: + type: string + ttl: + type: string + type: object + type: + type: string + workloadCertTTLDefault: + type: string + workloadCertTTLMax: + type: string + type: object + type: + type: string + type: object + controlPlane: + properties: + certProvider: + type: string + mtls: + type: boolean + tls: + properties: + cipherSuites: + items: + type: string + type: array + ecdhCurves: + items: + type: string + type: array + maxProtocolVersion: + type: string + minProtocolVersion: + type: string + type: object + type: object + dataPlane: + properties: + automtls: + type: boolean + mtls: + type: boolean + type: object + identity: + properties: + thirdParty: + properties: + audience: + type: string + issuer: + type: string + type: object + type: + type: string + type: object + jwksResolverCA: + type: string + manageNetworkPolicy: + type: boolean + trust: + properties: + additionalDomains: + items: + type: string + type: array + domain: + type: string + type: object + type: object + techPreview: + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + stdio: + properties: + enabled: + type: boolean + outputAsJSON: + type: boolean + type: object + useAdapterCRDs: + type: boolean + type: object + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + loadshedding: + properties: + latencyThreshold: + type: string + mode: + type: string + type: object + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + createService: + type: boolean + type: object + type: + type: string + type: object + tracing: + properties: + sampling: + format: int32 + maximum: 10000 + minimum: 0 + type: integer + type: + type: string + type: object + version: + type: string + type: object + appliedValues: + properties: + istio: + type: object + x-kubernetes-preserve-unknown-fields: true + networkType: + type: string + profiles: + items: + type: string + type: array + template: + type: string + threeScale: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + chartVersion: + type: string + components: + items: + properties: + children: + items: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + resource: + type: string + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + observedGeneration: + format: int64 + type: integer + operatorVersion: + type: string + readiness: + properties: + components: + additionalProperties: + items: + type: string + type: array + type: object + type: object + required: + - readiness + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests-maistra/2.5.0/servicemeshmemberrolls.crd.yaml b/manifests-maistra/2.5.0/servicemeshmemberrolls.crd.yaml new file mode 100644 index 0000000000..8782b09458 --- /dev/null +++ b/manifests-maistra/2.5.0/servicemeshmemberrolls.crd.yaml @@ -0,0 +1,176 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: 2.5.0 + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: servicemeshmemberrolls.maistra.io +spec: + group: maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshMemberRoll + listKind: ServiceMeshMemberRollList + plural: servicemeshmemberrolls + shortNames: + - smmr + singular: servicemeshmemberroll + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: How many of the total number of member namespaces are configured + jsonPath: .status.annotations.configuredMemberCount + name: Ready + type: string + - description: Whether all member namespaces have been configured or why that's not the case + jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Namespaces that are members of this Control Plane + jsonPath: .status.members + name: Members + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + memberSelectors: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + members: + items: + type: string + nullable: true + type: array + type: object + status: + properties: + annotations: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + nullable: true + type: array + configuredMembers: + items: + type: string + nullable: true + type: array + memberStatuses: + items: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + namespace: + type: string + required: + - conditions + - namespace + type: object + nullable: true + type: array + members: + items: + type: string + nullable: true + type: array + meshGeneration: + format: int64 + type: integer + meshReconciledVersion: + type: string + observedGeneration: + format: int64 + type: integer + pendingMembers: + items: + type: string + nullable: true + type: array + terminatingMembers: + items: + type: string + nullable: true + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests-maistra/2.5.0/servicemeshmembers.crd.yaml b/manifests-maistra/2.5.0/servicemeshmembers.crd.yaml new file mode 100644 index 0000000000..50053225fe --- /dev/null +++ b/manifests-maistra/2.5.0/servicemeshmembers.crd.yaml @@ -0,0 +1,108 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: 2.5.0 + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: servicemeshmembers.maistra.io +spec: + group: maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshMember + listKind: ServiceMeshMemberList + plural: servicemeshmembers + shortNames: + - smm + singular: servicemeshmember + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The ServiceMeshControlPlane this namespace belongs to + jsonPath: .status.annotations.controlPlaneRef + name: Control Plane + type: string + - description: Whether or not namespace is configured as a member of the mesh. + jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + controlPlaneRef: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + required: + - controlPlaneRef + type: object + status: + properties: + annotations: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + meshGeneration: + format: int64 + type: integer + meshReconciledVersion: + type: string + observedGeneration: + format: int64 + type: integer + required: + - conditions + - observedGeneration + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests-maistra/maistra.package.yaml b/manifests-maistra/maistra.package.yaml index 4f5e2169f0..c02d39ec5d 100644 --- a/manifests-maistra/maistra.package.yaml +++ b/manifests-maistra/maistra.package.yaml @@ -1,5 +1,5 @@ packageName: maistraoperator channels: - name: "2.0" - currentCSV: maistraoperator.v2.4.3 + currentCSV: maistraoperator.v2.5.0 defaultChannel: "2.0" diff --git a/manifests-servicemesh/2.5.0/servicemeshcontrolplanes.crd.yaml b/manifests-servicemesh/2.5.0/servicemeshcontrolplanes.crd.yaml new file mode 100644 index 0000000000..c9add32725 --- /dev/null +++ b/manifests-servicemesh/2.5.0/servicemeshcontrolplanes.crd.yaml @@ -0,0 +1,10325 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: 2.5.0 + annotations: + service.beta.openshift.io/inject-cabundle: "true" + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: servicemeshcontrolplanes.maistra.io +spec: + group: maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshControlPlane + listKind: ServiceMeshControlPlaneList + plural: servicemeshcontrolplanes + shortNames: + - smcp + singular: servicemeshcontrolplane + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: How many of the total number of components are ready + jsonPath: .status.annotations.readyComponentCount + name: Ready + type: string + - description: Whether or not the control plane installation is up to date. + jsonPath: .status.conditions[?(@.type=="Reconciled")].reason + name: Status + type: string + - description: The configuration template to use as the base. + jsonPath: .status.lastAppliedConfiguration.template + name: Template + type: string + - description: The actual current version of the control plane installation. + jsonPath: .status.lastAppliedConfiguration.version + name: Version + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: The image hub used as the base for all component images. + jsonPath: .status.lastAppliedConfiguration.istio.global.hub + name: Image HUB + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + istio: + type: object + x-kubernetes-preserve-unknown-fields: true + networkType: + type: string + profiles: + items: + type: string + type: array + template: + type: string + threeScale: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + status: + nullable: true + properties: + annotations: + additionalProperties: + type: string + type: object + components: + items: + properties: + children: + items: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + resource: + type: string + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + lastAppliedConfiguration: + properties: + istio: + type: object + x-kubernetes-preserve-unknown-fields: true + networkType: + type: string + profiles: + items: + type: string + type: array + template: + type: string + threeScale: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + observedGeneration: + format: int64 + type: integer + reconciledVersion: + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: How many of the total number of components are ready + jsonPath: .status.annotations.readyComponentCount + name: Ready + type: string + - description: Whether or not the control plane installation is up to date and ready to handle requests. + jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - description: The configuration profiles applied to the configuration. + jsonPath: .status.appliedSpec.profiles + name: Profiles + type: string + - description: The actual current version of the control plane installation. + jsonPath: .status.chartVersion + name: Version + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: The image registry used as the base for all component images. + jsonPath: .status.appliedSpec.runtime.defaults.container.registry + name: Image Registry + priority: 1 + type: string + name: v2 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + addons: + properties: + 3scale: + properties: + backend: + properties: + cache_flush_interval: + format: int32 + type: integer + enable_cache: + type: boolean + policy_fail_closed: + type: boolean + type: object + client: + properties: + allow_insecure_connections: + type: boolean + timeout: + format: int32 + type: integer + type: object + enabled: + type: boolean + grpc: + properties: + max_conn_timeout: + format: int32 + type: integer + type: object + listen_addr: + format: int32 + type: integer + log_grpc: + type: boolean + log_json: + type: boolean + log_level: + type: string + metrics: + properties: + port: + format: int32 + type: integer + report: + type: boolean + type: object + system: + properties: + cache_max_size: + format: int64 + type: integer + cache_refresh_interval: + format: int32 + type: integer + cache_refresh_retries: + format: int32 + type: integer + cache_ttl: + format: int32 + type: integer + type: object + type: object + grafana: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + config: + properties: + env: + additionalProperties: + type: string + type: object + envSecrets: + additionalProperties: + type: string + type: object + type: object + persistence: + properties: + accessMode: + type: string + capacity: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + enabled: + type: boolean + storageClassName: + type: string + type: object + security: + properties: + enabled: + type: boolean + passphraseKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + type: object + jaeger: + properties: + install: + properties: + ingress: + properties: + enabled: + type: boolean + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + type: object + storage: + properties: + elasticsearch: + properties: + indexCleaner: + type: object + x-kubernetes-preserve-unknown-fields: true + nodeCount: + format: int32 + type: integer + redundancyPolicy: + type: string + storage: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + memory: + properties: + maxTraces: + format: int64 + type: integer + type: object + type: + type: string + type: object + type: object + name: + type: string + type: object + kiali: + properties: + enabled: + type: boolean + install: + properties: + dashboard: + properties: + enableGrafana: + type: boolean + enablePrometheus: + type: boolean + enableTracing: + type: boolean + viewOnly: + type: boolean + type: object + deployment: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + name: + type: string + type: object + prometheus: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + retention: + type: string + scrapeInterval: + type: string + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + useTLS: + type: boolean + type: object + metricsExpiryDuration: + type: string + scrape: + type: boolean + type: object + stackdriver: + properties: + telemetry: + properties: + accessLogging: + properties: + enabled: + type: boolean + logWindowDuration: + type: string + type: object + auth: + properties: + apiKey: + type: string + appCredentials: + type: boolean + serviceAccountPath: + type: string + type: object + configOverride: + type: object + x-kubernetes-preserve-unknown-fields: true + enableContextGraph: + type: boolean + enableLogging: + type: boolean + enableMetrics: + type: boolean + enabled: + type: boolean + type: object + tracer: + properties: + debug: + type: boolean + maxNumberOfAnnotations: + format: int64 + type: integer + maxNumberOfAttributes: + format: int64 + type: integer + maxNumberOfMessageEvents: + format: int64 + type: integer + type: object + type: object + type: object + cluster: + properties: + meshExpansion: + properties: + enabled: + type: boolean + ilbGateway: + properties: + enabled: + type: boolean + namespace: + type: string + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + multiCluster: + properties: + enabled: + type: boolean + meshNetworks: + additionalProperties: + properties: + endpoints: + items: + properties: + fromCIDR: + type: string + fromRegistry: + type: string + type: object + type: array + gateways: + items: + properties: + address: + type: string + port: + format: int32 + type: integer + registryServiceName: + type: string + service: + type: string + type: object + type: array + type: object + type: object + type: object + name: + type: string + network: + type: string + type: object + gateways: + properties: + additionalEgress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + additionalIngress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + egress: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + enabled: + type: boolean + ingress: + properties: + enabled: + type: boolean + ingress: + type: boolean + meshExpansionPorts: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + openshiftRoute: + properties: + enabled: + type: boolean + type: object + type: object + general: + properties: + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + logAsJSON: + type: boolean + type: object + validationMessages: + type: boolean + type: object + meshConfig: + properties: + discoverySelectors: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + extensionProviders: + items: + properties: + envoyExtAuthzGrpc: + properties: + failOpen: + type: boolean + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + envoyExtAuthzHttp: + properties: + failOpen: + type: boolean + headersToDownstreamOnAllow: + items: + type: string + type: array + headersToDownstreamOnDeny: + items: + type: string + type: array + headersToUpstreamOnAllow: + items: + type: string + type: array + includeAdditionalHeadersInCheck: + additionalProperties: + type: string + type: object + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + includeRequestHeadersInCheck: + items: + type: string + type: array + pathPrefix: + type: string + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + name: + type: string + prometheus: + type: object + required: + - name + type: object + type: array + type: object + mode: + enum: + - MultiTenant + - ClusterWide + type: string + policy: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + useAdapterCRDs: + type: boolean + type: object + enableChecks: + type: boolean + failOpen: + type: boolean + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + createService: + type: boolean + enableChecks: + type: boolean + failOpen: + type: boolean + type: object + type: + type: string + type: object + profiles: + items: + type: string + type: array + proxy: + properties: + accessLogging: + properties: + envoyService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + file: + properties: + encoding: + type: string + format: + type: string + name: + type: string + type: object + type: object + adminPort: + format: int32 + type: integer + concurrency: + format: int32 + type: integer + envoyMetricsService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + injection: + properties: + alwaysInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + autoInject: + type: boolean + injectedAnnotations: + additionalProperties: + type: string + type: object + neverInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + type: object + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + level: + type: string + type: object + networking: + properties: + clusterDomain: + type: string + connectionTimeout: + type: string + dns: + properties: + refreshRate: + type: string + searchSuffixes: + items: + type: string + type: array + type: object + initialization: + properties: + initContainer: + properties: + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + type: + type: string + type: object + maxConnectionAge: + type: string + protocol: + properties: + autoDetect: + properties: + inbound: + type: boolean + outbound: + type: boolean + timeout: + type: string + type: object + type: object + trafficControl: + properties: + inbound: + properties: + excludedPorts: + items: + format: int32 + type: integer + type: array + includedPorts: + items: + type: string + type: array + interceptionMode: + type: string + type: object + outbound: + properties: + excludedIPRanges: + items: + type: string + type: array + excludedPorts: + items: + format: int32 + type: integer + type: array + includedIPRanges: + items: + type: string + type: array + policy: + type: string + type: object + type: object + type: object + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + readiness: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + rewriteApplicationProbes: + type: boolean + statusPort: + format: int32 + type: integer + type: object + type: object + type: object + runtime: + properties: + components: + additionalProperties: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + defaults: + properties: + container: + properties: + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + podDisruption: + properties: + enabled: + type: boolean + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: object + pod: + properties: + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + security: + properties: + certificateAuthority: + properties: + cert-manager: + properties: + address: + type: string + pilotSecretName: + type: string + rootCAConfigMapName: + type: string + type: object + custom: + properties: + address: + type: string + type: object + istiod: + properties: + privateKey: + properties: + rootCADir: + type: string + type: object + selfSigned: + properties: + checkPeriod: + type: string + enableJitter: + type: boolean + gracePeriod: + type: string + ttl: + type: string + type: object + type: + type: string + workloadCertTTLDefault: + type: string + workloadCertTTLMax: + type: string + type: object + type: + type: string + type: object + controlPlane: + properties: + certProvider: + type: string + mtls: + type: boolean + tls: + properties: + cipherSuites: + items: + type: string + type: array + ecdhCurves: + items: + type: string + type: array + maxProtocolVersion: + type: string + minProtocolVersion: + type: string + type: object + type: object + dataPlane: + properties: + automtls: + type: boolean + mtls: + type: boolean + type: object + identity: + properties: + thirdParty: + properties: + audience: + type: string + issuer: + type: string + type: object + type: + type: string + type: object + jwksResolverCA: + type: string + manageNetworkPolicy: + type: boolean + trust: + properties: + additionalDomains: + items: + type: string + type: array + domain: + type: string + type: object + type: object + techPreview: + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + stdio: + properties: + enabled: + type: boolean + outputAsJSON: + type: boolean + type: object + useAdapterCRDs: + type: boolean + type: object + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + loadshedding: + properties: + latencyThreshold: + type: string + mode: + type: string + type: object + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + createService: + type: boolean + type: object + type: + type: string + type: object + tracing: + properties: + sampling: + format: int32 + maximum: 10000 + minimum: 0 + type: integer + type: + type: string + type: object + version: + type: string + type: object + status: + properties: + annotations: + additionalProperties: + type: string + type: object + appliedSpec: + properties: + addons: + properties: + 3scale: + properties: + backend: + properties: + cache_flush_interval: + format: int32 + type: integer + enable_cache: + type: boolean + policy_fail_closed: + type: boolean + type: object + client: + properties: + allow_insecure_connections: + type: boolean + timeout: + format: int32 + type: integer + type: object + enabled: + type: boolean + grpc: + properties: + max_conn_timeout: + format: int32 + type: integer + type: object + listen_addr: + format: int32 + type: integer + log_grpc: + type: boolean + log_json: + type: boolean + log_level: + type: string + metrics: + properties: + port: + format: int32 + type: integer + report: + type: boolean + type: object + system: + properties: + cache_max_size: + format: int64 + type: integer + cache_refresh_interval: + format: int32 + type: integer + cache_refresh_retries: + format: int32 + type: integer + cache_ttl: + format: int32 + type: integer + type: object + type: object + grafana: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + config: + properties: + env: + additionalProperties: + type: string + type: object + envSecrets: + additionalProperties: + type: string + type: object + type: object + persistence: + properties: + accessMode: + type: string + capacity: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + enabled: + type: boolean + storageClassName: + type: string + type: object + security: + properties: + enabled: + type: boolean + passphraseKey: + type: string + secretName: + type: string + usernameKey: + type: string + type: object + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + type: object + jaeger: + properties: + install: + properties: + ingress: + properties: + enabled: + type: boolean + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + type: object + storage: + properties: + elasticsearch: + properties: + indexCleaner: + type: object + x-kubernetes-preserve-unknown-fields: true + nodeCount: + format: int32 + type: integer + redundancyPolicy: + type: string + storage: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + memory: + properties: + maxTraces: + format: int64 + type: integer + type: object + type: + type: string + type: object + type: object + name: + type: string + type: object + kiali: + properties: + enabled: + type: boolean + install: + properties: + dashboard: + properties: + enableGrafana: + type: boolean + enablePrometheus: + type: boolean + enableTracing: + type: boolean + viewOnly: + type: boolean + type: object + deployment: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + type: object + name: + type: string + type: object + prometheus: + properties: + address: + type: string + enabled: + type: boolean + install: + properties: + retention: + type: string + scrapeInterval: + type: string + selfManaged: + type: boolean + service: + properties: + ingress: + properties: + contextPath: + type: string + enabled: + type: boolean + hosts: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + tls: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodePort: + format: int32 + type: integer + type: object + useTLS: + type: boolean + type: object + metricsExpiryDuration: + type: string + scrape: + type: boolean + type: object + stackdriver: + properties: + telemetry: + properties: + accessLogging: + properties: + enabled: + type: boolean + logWindowDuration: + type: string + type: object + auth: + properties: + apiKey: + type: string + appCredentials: + type: boolean + serviceAccountPath: + type: string + type: object + configOverride: + type: object + x-kubernetes-preserve-unknown-fields: true + enableContextGraph: + type: boolean + enableLogging: + type: boolean + enableMetrics: + type: boolean + enabled: + type: boolean + type: object + tracer: + properties: + debug: + type: boolean + maxNumberOfAnnotations: + format: int64 + type: integer + maxNumberOfAttributes: + format: int64 + type: integer + maxNumberOfMessageEvents: + format: int64 + type: integer + type: object + type: object + type: object + cluster: + properties: + meshExpansion: + properties: + enabled: + type: boolean + ilbGateway: + properties: + enabled: + type: boolean + namespace: + type: string + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + multiCluster: + properties: + enabled: + type: boolean + meshNetworks: + additionalProperties: + properties: + endpoints: + items: + properties: + fromCIDR: + type: string + fromRegistry: + type: string + type: object + type: array + gateways: + items: + properties: + address: + type: string + port: + format: int32 + type: integer + registryServiceName: + type: string + service: + type: string + type: object + type: array + type: object + type: object + type: object + name: + type: string + network: + type: string + type: object + gateways: + properties: + additionalEgress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + additionalIngress: + additionalProperties: + properties: + enabled: + type: boolean + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + type: object + egress: + properties: + enabled: + type: boolean + namespace: + type: string + requestedNetworkView: + items: + type: string + type: array + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + enabled: + type: boolean + ingress: + properties: + enabled: + type: boolean + ingress: + type: boolean + meshExpansionPorts: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + namespace: + type: string + routeConfig: + properties: + enabled: + type: boolean + type: object + routerMode: + type: string + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + sds: + properties: + enabled: + type: boolean + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + service: + properties: + clusterIP: + type: string + externalIPs: + items: + type: string + type: array + externalName: + type: string + externalTrafficPolicy: + type: string + healthCheckNodePort: + format: int32 + type: integer + ipFamily: + type: string + loadBalancerIP: + type: string + loadBalancerSourceRanges: + items: + type: string + type: array + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + ports: + items: + properties: + appProtocol: + type: string + name: + type: string + nodePort: + format: int32 + type: integer + port: + format: int32 + type: integer + protocol: + type: string + targetPort: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: array + x-kubernetes-list-map-keys: + - port + x-kubernetes-list-type: map + publishNotReadyAddresses: + type: boolean + selector: + additionalProperties: + type: string + type: object + sessionAffinity: + type: string + sessionAffinityConfig: + properties: + clientIP: + properties: + timeoutSeconds: + format: int32 + type: integer + type: object + type: object + topologyKeys: + items: + type: string + type: array + type: + type: string + type: object + volumes: + items: + properties: + volume: + properties: + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + type: object + volumeMount: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: object + type: array + type: object + openshiftRoute: + properties: + enabled: + type: boolean + type: object + type: object + general: + properties: + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + logAsJSON: + type: boolean + type: object + validationMessages: + type: boolean + type: object + meshConfig: + properties: + discoverySelectors: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + extensionProviders: + items: + properties: + envoyExtAuthzGrpc: + properties: + failOpen: + type: boolean + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + envoyExtAuthzHttp: + properties: + failOpen: + type: boolean + headersToDownstreamOnAllow: + items: + type: string + type: array + headersToDownstreamOnDeny: + items: + type: string + type: array + headersToUpstreamOnAllow: + items: + type: string + type: array + includeAdditionalHeadersInCheck: + additionalProperties: + type: string + type: object + includeRequestBodyInCheck: + properties: + allowPartialMessage: + type: boolean + maxRequestBytes: + format: int64 + type: integer + packAsBytes: + type: boolean + type: object + includeRequestHeadersInCheck: + items: + type: string + type: array + pathPrefix: + type: string + port: + format: int64 + type: integer + service: + type: string + statusOnError: + type: string + timeout: + type: string + required: + - port + - service + type: object + name: + type: string + prometheus: + type: object + required: + - name + type: object + type: array + type: object + mode: + enum: + - MultiTenant + - ClusterWide + type: string + policy: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + useAdapterCRDs: + type: boolean + type: object + enableChecks: + type: boolean + failOpen: + type: boolean + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + createService: + type: boolean + enableChecks: + type: boolean + failOpen: + type: boolean + type: object + type: + type: string + type: object + profiles: + items: + type: string + type: array + proxy: + properties: + accessLogging: + properties: + envoyService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + file: + properties: + encoding: + type: string + format: + type: string + name: + type: string + type: object + type: object + adminPort: + format: int32 + type: integer + concurrency: + format: int32 + type: integer + envoyMetricsService: + properties: + address: + type: string + enabled: + type: boolean + tcpKeepalive: + properties: + interval: + type: string + probes: + format: int32 + type: integer + time: + type: string + type: object + tlsSettings: + properties: + caCertificates: + type: string + clientCertificate: + type: string + mode: + type: string + privateKey: + type: string + sni: + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + injection: + properties: + alwaysInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + autoInject: + type: boolean + injectedAnnotations: + additionalProperties: + type: string + type: object + neverInjectSelector: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + type: object + logging: + properties: + componentLevels: + additionalProperties: + type: string + type: object + level: + type: string + type: object + networking: + properties: + clusterDomain: + type: string + connectionTimeout: + type: string + dns: + properties: + refreshRate: + type: string + searchSuffixes: + items: + type: string + type: array + type: object + initialization: + properties: + initContainer: + properties: + runtime: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + type: object + type: + type: string + type: object + maxConnectionAge: + type: string + protocol: + properties: + autoDetect: + properties: + inbound: + type: boolean + outbound: + type: boolean + timeout: + type: string + type: object + type: object + trafficControl: + properties: + inbound: + properties: + excludedPorts: + items: + format: int32 + type: integer + type: array + includedPorts: + items: + type: string + type: array + interceptionMode: + type: string + type: object + outbound: + properties: + excludedIPRanges: + items: + type: string + type: array + excludedPorts: + items: + format: int32 + type: integer + type: array + includedIPRanges: + items: + type: string + type: array + policy: + type: string + type: object + type: object + type: object + runtime: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + readiness: + properties: + failureThreshold: + format: int32 + type: integer + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + rewriteApplicationProbes: + type: boolean + statusPort: + format: int32 + type: integer + type: object + type: object + type: object + runtime: + properties: + components: + additionalProperties: + properties: + container: + properties: + env: + additionalProperties: + type: string + type: object + imageName: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + autoScaling: + properties: + enabled: + type: boolean + maxReplicas: + format: int32 + type: integer + minReplicas: + format: int32 + type: integer + targetCPUUtilizationPercentage: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringScheduling: + items: + properties: + key: + type: string + operator: + type: string + topologyKey: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + defaults: + properties: + container: + properties: + imagePullPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + imageRegistry: + type: string + imageTag: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + type: object + deployment: + properties: + podDisruption: + properties: + enabled: + type: boolean + maxUnavailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + minAvailable: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: object + pod: + properties: + nodeSelector: + additionalProperties: + type: string + type: object + priorityClassName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + type: object + type: object + security: + properties: + certificateAuthority: + properties: + cert-manager: + properties: + address: + type: string + pilotSecretName: + type: string + rootCAConfigMapName: + type: string + type: object + custom: + properties: + address: + type: string + type: object + istiod: + properties: + privateKey: + properties: + rootCADir: + type: string + type: object + selfSigned: + properties: + checkPeriod: + type: string + enableJitter: + type: boolean + gracePeriod: + type: string + ttl: + type: string + type: object + type: + type: string + workloadCertTTLDefault: + type: string + workloadCertTTLMax: + type: string + type: object + type: + type: string + type: object + controlPlane: + properties: + certProvider: + type: string + mtls: + type: boolean + tls: + properties: + cipherSuites: + items: + type: string + type: array + ecdhCurves: + items: + type: string + type: array + maxProtocolVersion: + type: string + minProtocolVersion: + type: string + type: object + type: object + dataPlane: + properties: + automtls: + type: boolean + mtls: + type: boolean + type: object + identity: + properties: + thirdParty: + properties: + audience: + type: string + issuer: + type: string + type: object + type: + type: string + type: object + jwksResolverCA: + type: string + manageNetworkPolicy: + type: boolean + trust: + properties: + additionalDomains: + items: + type: string + type: array + domain: + type: string + type: object + type: object + techPreview: + type: object + x-kubernetes-preserve-unknown-fields: true + telemetry: + properties: + mixer: + properties: + adapters: + properties: + kubernetesenv: + type: boolean + stdio: + properties: + enabled: + type: boolean + outputAsJSON: + type: boolean + type: object + useAdapterCRDs: + type: boolean + type: object + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + loadshedding: + properties: + latencyThreshold: + type: string + mode: + type: string + type: object + sessionAffinity: + type: boolean + type: object + remote: + properties: + address: + type: string + batching: + properties: + maxEntries: + format: int32 + type: integer + maxTime: + type: string + type: object + createService: + type: boolean + type: object + type: + type: string + type: object + tracing: + properties: + sampling: + format: int32 + maximum: 10000 + minimum: 0 + type: integer + type: + type: string + type: object + version: + type: string + type: object + appliedValues: + properties: + istio: + type: object + x-kubernetes-preserve-unknown-fields: true + networkType: + type: string + profiles: + items: + type: string + type: array + template: + type: string + threeScale: + type: object + x-kubernetes-preserve-unknown-fields: true + version: + type: string + type: object + chartVersion: + type: string + components: + items: + properties: + children: + items: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + resource: + type: string + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + observedGeneration: + format: int64 + type: integer + operatorVersion: + type: string + readiness: + properties: + components: + additionalProperties: + items: + type: string + type: array + type: object + type: object + required: + - readiness + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests-servicemesh/2.5.0/servicemeshmemberrolls.crd.yaml b/manifests-servicemesh/2.5.0/servicemeshmemberrolls.crd.yaml new file mode 100644 index 0000000000..8782b09458 --- /dev/null +++ b/manifests-servicemesh/2.5.0/servicemeshmemberrolls.crd.yaml @@ -0,0 +1,176 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: 2.5.0 + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: servicemeshmemberrolls.maistra.io +spec: + group: maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshMemberRoll + listKind: ServiceMeshMemberRollList + plural: servicemeshmemberrolls + shortNames: + - smmr + singular: servicemeshmemberroll + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: How many of the total number of member namespaces are configured + jsonPath: .status.annotations.configuredMemberCount + name: Ready + type: string + - description: Whether all member namespaces have been configured or why that's not the case + jsonPath: .status.conditions[?(@.type=="Ready")].reason + name: Status + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Namespaces that are members of this Control Plane + jsonPath: .status.members + name: Members + priority: 1 + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + memberSelectors: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: array + members: + items: + type: string + nullable: true + type: array + type: object + status: + properties: + annotations: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + nullable: true + type: array + configuredMembers: + items: + type: string + nullable: true + type: array + memberStatuses: + items: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + namespace: + type: string + required: + - conditions + - namespace + type: object + nullable: true + type: array + members: + items: + type: string + nullable: true + type: array + meshGeneration: + format: int64 + type: integer + meshReconciledVersion: + type: string + observedGeneration: + format: int64 + type: integer + pendingMembers: + items: + type: string + nullable: true + type: array + terminatingMembers: + items: + type: string + nullable: true + type: array + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests-servicemesh/2.5.0/servicemeshmembers.crd.yaml b/manifests-servicemesh/2.5.0/servicemeshmembers.crd.yaml new file mode 100644 index 0000000000..50053225fe --- /dev/null +++ b/manifests-servicemesh/2.5.0/servicemeshmembers.crd.yaml @@ -0,0 +1,108 @@ + +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: 2.5.0 + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: servicemeshmembers.maistra.io +spec: + group: maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshMember + listKind: ServiceMeshMemberList + plural: servicemeshmembers + shortNames: + - smm + singular: servicemeshmember + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The ServiceMeshControlPlane this namespace belongs to + jsonPath: .status.annotations.controlPlaneRef + name: Control Plane + type: string + - description: Whether or not namespace is configured as a member of the mesh. + jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - description: The age of the object + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + controlPlaneRef: + properties: + name: + type: string + namespace: + type: string + required: + - name + - namespace + type: object + required: + - controlPlaneRef + type: object + status: + properties: + annotations: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + meshGeneration: + format: int64 + type: integer + meshReconciledVersion: + type: string + observedGeneration: + format: int64 + type: integer + required: + - conditions + - observedGeneration + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/manifests-servicemesh/2.5.0/servicemeshoperator.v2.5.0.clusterserviceversion.yaml b/manifests-servicemesh/2.5.0/servicemeshoperator.v2.5.0.clusterserviceversion.yaml new file mode 100644 index 0000000000..aacf354bf7 --- /dev/null +++ b/manifests-servicemesh/2.5.0/servicemeshoperator.v2.5.0.clusterserviceversion.yaml @@ -0,0 +1,744 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + name: servicemeshoperator.v2.5.0 + namespace: placeholder + labels: + operatorframework.io/arch.amd64: supported + operatorframework.io/arch.s390x: supported + operatorframework.io/arch.ppc64le: supported + operatorframework.io/arch.arm64: supported + + annotations: + categories: "OpenShift Optional, Integration & Delivery" + capabilities: "Seamless Upgrades" + certified: "false" + repository: https://github.com/maistra/istio-operator + description: |- + The OpenShift Service Mesh Operator enables you to install, configure, and manage an instance of Red Hat OpenShift Service Mesh. OpenShift Service Mesh is based on the open source Istio project. + + containerImage: ${OSSM_OPERATOR_IMAGE} + createdAt: 2023-10-05T22:49:58CEST + support: Red Hat, Inc. + olm.skipRange: ">=1.0.2 <2.5.0-0" + operators.openshift.io/infrastructure-features: '["Disconnected","fips"]' + operators.openshift.io/valid-subscription: '["OpenShift Container Platform", "OpenShift Platform Plus"]' + alm-examples: |- + [ + { + "apiVersion": "maistra.io/v2", + "kind": "ServiceMeshControlPlane", + "metadata": { + "name": "basic", + "namespace": "control-plane-namespace" + }, + "spec": { + "version": "v2.5", + "tracing": { + "type": "Jaeger", + "sampling": 10000 + }, + "policy": { + "type": "Istiod" + }, + "telemetry": { + "type": "Istiod" + }, + "addons": { + "jaeger": { + "install": { + "storage": { + "type": "Memory" + } + } + }, + "prometheus": { + "enabled": true + }, + "kiali": { + "enabled": true + }, + "grafana": { + "enabled": true + } + } + } + }, + { + "apiVersion": "maistra.io/v1", + "kind": "ServiceMeshMemberRoll", + "metadata": { + "name": "default", + "namespace": "control-plane-namespace" + }, + "spec": { + "members": [ + "your-project", + "another-of-your-projects" + ] + } + }, + { + "apiVersion": "maistra.io/v1", + "kind": "ServiceMeshMember", + "metadata": { + "name": "default", + "namespace": "application-namespace" + }, + "spec": { + "controlPlaneRef": { + "name": "basic", + "namespace": "control-plane-namespace" + } + } + } + ] +spec: + version: 2.5.0-0 + maturity: alpha + displayName: Red Hat OpenShift Service Mesh + description: |- + Red Hat OpenShift Service Mesh is a platform that provides behavioral insight and operational control over a service mesh, providing a uniform way to connect, secure, and monitor microservice applications. + + ### Overview + + Red Hat OpenShift Service Mesh, based on the open source [Istio](https://istio.io/) project, adds a transparent layer on existing + distributed applications without requiring any changes to the service code. You add Red Hat OpenShift Service Mesh + support to services by deploying a special sidecar proxy throughout your environment that intercepts all network + communication between microservices. You configure and manage the service mesh using the control plane features. + + Red Hat OpenShift Service Mesh provides an easy way to create a network of deployed services that provides discovery, + load balancing, service-to-service authentication, failure recovery, metrics, and monitoring. A service mesh also + provides more complex operational functionality, including A/B testing, canary releases, rate limiting, access + control, and end-to-end authentication. + + ### Core Capabilities + + Red Hat OpenShift Service Mesh supports uniform application of a number of key capabilities across a network of services: + + + **Traffic Management** - Control the flow of traffic and API calls between services, make calls more reliable, + and make the network more robust in the face of adverse conditions. + + + **Service Identity and Security** - Provide services in the mesh with a verifiable identity and provide the + ability to protect service traffic as it flows over networks of varying degrees of trustworthiness. + + + **Policy Enforcement** - Apply organizational policy to the interaction between services, ensure access policies + are enforced and resources are fairly distributed among consumers. Policy changes are made by configuring the + mesh, not by changing application code. + + + **Telemetry** - Gain understanding of the dependencies between services and the nature and flow of traffic between + them, providing the ability to quickly identify issues. + + ### Joining Projects Into a Mesh + + Once an instance of Red Hat OpenShift Service Mesh has been installed, it will only exercise control over services within its own + project. Other projects may be added into the mesh using one of two methods: + + 1. A **ServiceMeshMember** resource may be created in other projects to add those projects into the mesh. The + **ServiceMeshMember** specifies a reference to the **ServiceMeshControlPlane** object that was used to install + the control plane. The user creating the **ServiceMeshMember** resource must have permission to *use* the + **ServiceMeshControlPlane** object. The adminstrator for the project containing the control plane can grant + individual users or groups the *use* permissions. + + 2. A **ServiceMeshMemberRoll** resource may be created in the project containing the control plane. This resource + contains a single *members* list of all the projects that should belong in the mesh. The resource must be named + *default*. The user creating the resource must have *edit* or *admin* permissions for all projects in the + *members* list. + + ### More Information + + * [Documentation](https://docs.openshift.com/container-platform/latest/service_mesh/v2x/servicemesh-release-notes.html) + * [Bugs](https://issues.redhat.com/projects/OSSM) + + icon: + - mediatype: image/png + base64data: |- + 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 + ylLtXP0/aeQGS1ZSYNsAAAAASUVORK5CYII= + + keywords: [ 'istio', 'maistra', 'servicemesh' ] + maintainers: + - name: Red Hat, OpenShift Service Mesh + email: istio-feedback@redhat.com + provider: + name: Red Hat, Inc. + links: + - name: Red Hat OpenShift Service Mesh + url: https://docs.openshift.com/container-platform/latest/service_mesh/v2x/servicemesh-release-notes.html + - name: Istio + url: https://istio.io/ + - name: Operator Source Code + url: https://github.com/Maistra/istio-operator + - name: Bugs + url: https://issues.redhat.com/projects/OSSM + replaces: servicemeshoperator.v2.4.2 + installModes: + - type: OwnNamespace + supported: false + - type: SingleNamespace + supported: false + - type: MultiNamespace + supported: false + - type: AllNamespaces + supported: true + + install: + strategy: deployment + spec: + clusterPermissions: + - serviceAccountName: istio-operator + rules: + + # operator-sdk rules + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - "" + resources: + - services/finalizers + verbs: + - '*' + # operator rules for managing istio + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - namespaces + - persistentvolumeclaims + - pods + - replicationcontrollers + - secrets + - serviceaccounts + - services + - events # is this needed? + verbs: + - '*' + - apiGroups: + - apps + - extensions + resources: + - daemonsets + - deployments + - deployments/finalizers + - ingresses # is this needed? should it be converted to a route? + - ingresses/status + - replicasets + - statefulsets + verbs: + - '*' + - apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - '*' + - apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - '*' + - apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - '*' + - apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - '*' + - apiGroups: + - certmanager.k8s.io + resources: + - clusterissuers + verbs: + - '*' + - apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - ingresses + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - '*' + - apiGroups: + - authentication.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - config.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - networking.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - security.istio.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - jaegertracing.io + resources: + - jaegers + verbs: + - '*' + - apiGroups: + - kiali.io + resources: + - kialis + verbs: + - '*' + - apiGroups: + - maistra.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - authentication.maistra.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.maistra.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - '*' + # required by smmr controller + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create + - apiGroups: + - network.openshift.io + resources: + - clusternetworks + verbs: + - get + - list + - watch + - apiGroups: + - config.openshift.io + resources: + - networks + verbs: + - get + - list + - watch + - apiGroups: + - image.openshift.io + resources: + - imagestreams + verbs: + - get + - list + - watch + - apiGroups: + - network.openshift.io + resources: + - netnamespaces + verbs: + - get + - list + - watch + - update + - apiGroups: + - k8s.cni.cncf.io + resources: + - network-attachment-definitions + verbs: + - create + - delete + - get + - list + - patch + - watch + # required by cni daemonset + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - use + # required by pod locality controller + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + verbs: + - get + - list + - watch + - apiGroups: # might be required by citadel + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - nonResourceURLs: + - /metrics + verbs: + - get + deployments: + - name: istio-operator + spec: + + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + name: istio-operator + template: + metadata: + labels: + name: istio-operator + annotations: + # 2.1 images + olm.relatedImage.v2_1.cni: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-istio-cni-rhel8:${OSSM_21} + olm.relatedImage.v2_1.grafana: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-grafana-rhel8:${OSSM_21} + olm.relatedImage.v2_1.pilot: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_21} + olm.relatedImage.v2_1.prometheus: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-prometheus-rhel8:${OSSM_21} + olm.relatedImage.v2_1.proxyv2: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-proxyv2-rhel8:${OSSM_21} + olm.relatedImage.v2_1.wasm-cacher: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_21} + olm.relatedImage.v2_1.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_21} + # 2.2 images + olm.relatedImage.v2_2.cni: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-istio-cni-rhel8:${OSSM_22} + olm.relatedImage.v2_2.grafana: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-grafana-rhel8:${OSSM_22} + olm.relatedImage.v2_2.pilot: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_22} + olm.relatedImage.v2_2.prometheus: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-prometheus-rhel8:${OSSM_22} + olm.relatedImage.v2_2.proxyv2: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-proxyv2-rhel8:${OSSM_22} + olm.relatedImage.v2_2.wasm-cacher: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_22} + olm.relatedImage.v2_2.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_22} + # 2.3 images + olm.relatedImage.v2_3.cni: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-istio-cni-rhel8:${OSSM_23} + olm.relatedImage.v2_3.grafana: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-grafana-rhel8:${OSSM_23} + olm.relatedImage.v2_3.pilot: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_23} + olm.relatedImage.v2_3.prometheus: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-prometheus-rhel8:${OSSM_23} + olm.relatedImage.v2_3.proxyv2: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-proxyv2-rhel8:${OSSM_23} + olm.relatedImage.v2_3.wasm-cacher: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_23} + olm.relatedImage.v2_3.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_23} + # 2.4 images + olm.relatedImage.v2_4.cni: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-istio-cni-rhel8:${OSSM_24} + olm.relatedImage.v2_4.grafana: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-grafana-rhel8:${OSSM_24} + olm.relatedImage.v2_4.pilot: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-pilot-rhel8:${OSSM_24} + olm.relatedImage.v2_4.prometheus: registry.redhat.io/openshift4/ose-prometheus:v4.12 + olm.relatedImage.v2_4.prometheus-config-reloader: registry.redhat.io/openshift4/ose-prometheus-config-reloader:v4.12 + olm.relatedImage.v2_4.proxyv2: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-proxyv2-rhel8:${OSSM_24} + olm.relatedImage.v2_4.rls: registry-proxy.engineering.redhat.com/rh-osbs/openshift-service-mesh-ratelimit-rhel8:${OSSM_24} + # 2.5 images + olm.relatedImage.v2_5.cni: ${OSSM_CNI_IMAGE} + olm.relatedImage.v2_5.grafana: ${OSSM_GRAFANA_IMAGE} + olm.relatedImage.v2_5.pilot: ${OSSM_PILOT_IMAGE} + olm.relatedImage.v2_5.prometheus: registry.redhat.io/openshift4/ose-prometheus:v4.13 + olm.relatedImage.v2_5.prometheus-config-reloader: registry.redhat.io/openshift4/ose-prometheus-config-reloader:v4.13 + olm.relatedImage.v2_5.proxyv2: ${OSSM_PROXY_IMAGE} + olm.relatedImage.v2_5.rls: ${OSSM_RATELIMIT_IMAGE} + oauth-proxy.query: "true" + oauth-proxy.namespace: openshift + oauth-proxy.name: oauth-proxy + oauth-proxy.tag: v4.4 + spec: + serviceAccountName: istio-operator + containers: + - name: istio-operator + image: ${OSSM_OPERATOR_IMAGE} + ports: + - containerPort: 11999 + name: validation + - containerPort: 11200 + name: probes + - containerPort: 60000 + name: metrics + command: + - istio-operator + - --config + - /etc/operator/olm/config.properties + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + value: "" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: istio-operator + # - name: ISTIO_CNI_IMAGE_PULL_SECRET + # value: name-of-secret + readinessProbe: + httpGet: + scheme: HTTP + path: /readyz + port: 11200 + volumeMounts: + - name: operator-olm-config + mountPath: /etc/operator/olm + readOnly: true + - name: webhook-tls-volume + readOnly: true + mountPath: /tmp/k8s-webhook-server/serving-certs + - name: smcp-templates + readOnly: true + mountPath: /usr/local/share/istio-operator/templates/ + volumes: + - name: operator-olm-config + downwardAPI: + defaultMode: 420 + items: + - fieldRef: + fieldPath: metadata.annotations + path: config.properties + - name: webhook-tls-volume + secret: + secretName: maistra-operator-serving-cert + optional: true # this won't be available until service-ca creates the secret + - name: smcp-templates + configMap: + name: smcp-templates + optional: true + customresourcedefinitions: + owned: + - name: servicemeshcontrolplanes.maistra.io + version: v2 + kind: ServiceMeshControlPlane + displayName: Istio Service Mesh Control Plane + description: An Istio control plane installation + specDescriptors: + - displayName: Control Plane Version + description: Specify the version of the control plane you want to install + path: version + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.5' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.4' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.3' + - 'urn:alm:descriptor:com.tectonic.ui:select:v2.2' + - displayName: Control Plane Mode + description: 'NOTE: only applies if version is v2.4 or higher' + path: mode + - displayName: Control Plane Security + description: Enable mTLS for communication between control plane components + path: security.controlPlane.mtls + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Install Prometheus + description: Set to true to install Prometheus + path: addons.prometheus.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:metrics' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Data Plane Security + description: Enable mTLS for communcation between services in the mesh + path: security.dataPlane.mtls + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:General' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Install Kiali + description: Set to true to install Kiali + path: addons.kiali.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:visualization' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Install Grafana + description: Set to true to install Grafana + path: addons.grafana.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:visualization' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Tracing provider + description: Select the provider to use for tracing + path: tracing.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:tracing' + - 'urn:alm:descriptor:com.tectonic.ui:select:None' + - 'urn:alm:descriptor:com.tectonic.ui:select:Jaeger' + - 'urn:alm:descriptor:com.tectonic.ui:select:Stackdriver' + - displayName: Jaeger Storage Type + description: Set storage type for Jaeger (applies only when Jaeger is selected as the tracing provider) + path: addons.jaeger.install.storage.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:tracing' + - 'urn:alm:descriptor:com.tectonic.ui:select:Memory' + - 'urn:alm:descriptor:com.tectonic.ui:select:Elasticsearch' + - displayName: Type of Policy + description: Select "Mixer" when deploying a control plane version less than "v2.0" or when planning to install 3scale adapter + path: policy.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Policy' + - 'urn:alm:descriptor:com.tectonic.ui:select:Istiod' + - 'urn:alm:descriptor:com.tectonic.ui:select:Mixer' + - displayName: Install 3Scale Adapter + description: Set to true to install the Istio 3Scale adapter (applies only when Policy type is set to Mixer) + path: addons.3scale.enabled + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Policy' + - 'urn:alm:descriptor:com.tectonic.ui:booleanSwitch' + - displayName: Type of Telemetry + description: Select "Mixer" when deploying a control plane version less than "v2.0" + path: telemetry.type + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Telemetry' + - 'urn:alm:descriptor:com.tectonic.ui:select:Istiod' + - 'urn:alm:descriptor:com.tectonic.ui:select:Mixer' + - displayName: Default Resource Requirements + description: Set the default compute resource requests and limits for control plane components + path: runtime.defaults.container.resources + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:resourceRequirements' + - 'urn:alm:descriptor:com.tectonic.ui:advanced' + statusDescriptors: + - displayName: Components + description: Status of components deployed by this ServiceMeshControlPlane resource + path: readiness.components + x-descriptors: + - "urn:alm:descriptor:com.tectonic.ui:podStatuses" + - name: servicemeshmembers.maistra.io + version: v1 + kind: ServiceMeshMember + displayName: Istio Service Mesh Member + description: Marks the containing namespace as a member of the referenced Service Mesh + specDescriptors: + - displayName: Namespace + description: The namespace of the ServiceMeshControlPlane to which this namespace belongs + path: controlPlaneRef.namespace + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Service_Mesh_Control_Plane' + - 'urn:alm:descriptor:io.kubernetes:Project' + - displayName: Name + description: The name of the ServiceMeshControlPlane to which this namespace belongs + path: controlPlaneRef.name + x-descriptors: + - 'urn:alm:descriptor:com.tectonic.ui:fieldGroup:Service_Mesh_Control_Plane' + - 'urn:alm:descriptor:com.tectonic.ui:text' + - name: servicemeshmemberrolls.maistra.io + version: v1 + kind: ServiceMeshMemberRoll + displayName: Istio Service Mesh Member Roll + description: A list of namespaces in Service Mesh diff --git a/manifests-servicemesh/servicemesh.package.yaml b/manifests-servicemesh/servicemesh.package.yaml index b02d5d52fa..90fcf5be1b 100644 --- a/manifests-servicemesh/servicemesh.package.yaml +++ b/manifests-servicemesh/servicemesh.package.yaml @@ -1,5 +1,5 @@ packageName: servicemeshoperator channels: - name: "2.0" - currentCSV: servicemeshoperator.v2.4.3 + currentCSV: servicemeshoperator.v2.5.0 defaultChannel: "2.0" diff --git a/pkg/bootstrap/cni.go b/pkg/bootstrap/cni.go index 4f35c02329..f91ab0e9aa 100644 --- a/pkg/bootstrap/cni.go +++ b/pkg/bootstrap/cni.go @@ -51,6 +51,7 @@ func internalRenderCNI(ctx context.Context, cl client.Client, config cni.Config, cni["image_v2_2"] = common.Config.OLM.Images.V2_2.CNI cni["image_v2_3"] = common.Config.OLM.Images.V2_3.CNI cni["image_v2_4"] = common.Config.OLM.Images.V2_4.CNI + cni["image_v2_5"] = common.Config.OLM.Images.V2_5.CNI cni["imagePullSecrets"] = config.ImagePullSecrets // TODO: imagePullPolicy, resources @@ -60,6 +61,7 @@ func internalRenderCNI(ctx context.Context, cl client.Client, config cni.Config, cni["configMap_v2_2"] = "cni_network_config_v2_2" cni["configMap_v2_3"] = "cni_network_config" cni["configMap_v2_4"] = "cni_network_config" + cni["configMap_v2_5"] = "cni_network_config" cni["chained"] = !config.UseMultus if config.UseMultus { @@ -71,6 +73,7 @@ func internalRenderCNI(ctx context.Context, cl client.Client, config cni.Config, cni["cniConfFileName_v2_2"] = "v2-2-istio-cni.conf" cni["cniConfFileName_v2_3"] = "v2-3-istio-cni.conf" cni["cniConfFileName_v2_4"] = "v2-4-istio-cni.conf" + cni["cniConfFileName_v2_5"] = "v2-5-istio-cni.conf" } var releases []string diff --git a/pkg/bootstrap/cni_test.go b/pkg/bootstrap/cni_test.go index 58073e2d0c..368f99bdae 100644 --- a/pkg/bootstrap/cni_test.go +++ b/pkg/bootstrap/cni_test.go @@ -73,6 +73,13 @@ func TestCNISupportedVersionRendering(t *testing.T) { containerNames: []string{"install-cni"}, daemonsetName: "istio-cni-node-v2-4", }, + { + name: "v2.5 only", + supportedVersions: []versions.Version{versions.V2_5}, + instanceVersion: versions.V2_5.Version(), + containerNames: []string{"install-cni"}, + daemonsetName: "istio-cni-node-v2-5", + }, } config := cni.Config{ diff --git a/pkg/controller/common/config.go b/pkg/controller/common/config.go index 7363c6c71d..02810a0158 100644 --- a/pkg/controller/common/config.go +++ b/pkg/controller/common/config.go @@ -39,6 +39,7 @@ type images struct { V2_2 v2_2ImageNames `json:"v2_2,omitempty"` V2_3 v2_3ImageNames `json:"v2_3,omitempty"` V2_4 v2_4ImageNames `json:"v2_4,omitempty"` + V2_5 v2_5ImageNames `json:"v2_5,omitempty"` } // V1_1ImageNames used by deployments @@ -119,6 +120,17 @@ type v2_4ImageNames struct { RLS string `json:"rls,omitempty"` } +// v2_5ImageNames used by deployments +type v2_5ImageNames struct { + CNI string `json:"cni,omitempty"` + Grafana string `json:"grafana,omitempty"` + Pilot string `json:"pilot,omitempty"` + Prometheus string `json:"prometheus,omitempty"` + PrometheusConfigReloader string `json:"prometheus-config-reloader,omitempty"` + ProxyV2 string `json:"proxyv2,omitempty"` + RLS string `json:"rls,omitempty"` +} + type oauthProxy struct { Namespace string `json:"namespace,omitempty"` Name string `json:"name,omitempty"` diff --git a/pkg/controller/servicemesh/controlplane/common_test.go b/pkg/controller/servicemesh/controlplane/common_test.go index 053d0ce961..c8924e1912 100644 --- a/pkg/controller/servicemesh/controlplane/common_test.go +++ b/pkg/controller/servicemesh/controlplane/common_test.go @@ -29,7 +29,6 @@ import ( "github.com/maistra/istio-operator/pkg/controller/common" "github.com/maistra/istio-operator/pkg/controller/common/test" "github.com/maistra/istio-operator/pkg/controller/hacks" - "github.com/maistra/istio-operator/pkg/controller/versions" ) var ctx = common.NewContextWithLog(context.Background(), logf.Log) @@ -160,24 +159,6 @@ func RunSimpleInstallTest(t *testing.T, tc IntegrationTestCase) { }) } -func New22SMCPResource(name, namespace string, spec *maistrav2.ControlPlaneSpec) *maistrav2.ServiceMeshControlPlane { - smcp := NewV2SMCPResource(name, namespace, spec) - smcp.Spec.Version = versions.V2_2.String() - return smcp -} - -func New21SMCPResource(name, namespace string, spec *maistrav2.ControlPlaneSpec) *maistrav2.ServiceMeshControlPlane { - smcp := NewV2SMCPResource(name, namespace, spec) - smcp.Spec.Version = versions.V2_1.String() - return smcp -} - -func New20SMCPResource(name, namespace string, spec *maistrav2.ControlPlaneSpec) *maistrav2.ServiceMeshControlPlane { - smcp := NewV2SMCPResource(name, namespace, spec) - smcp.Spec.Version = versions.V2_0.String() - return smcp -} - func NewV2xSMCPResource(name, namespace string, spec *maistrav2.ControlPlaneSpec, version string) *maistrav2.ServiceMeshControlPlane { smcp := NewV2SMCPResource(name, namespace, spec) smcp.Spec.Version = version diff --git a/pkg/controller/servicemesh/controlplane/gateways_test.go b/pkg/controller/servicemesh/controlplane/gateways_test.go index 9d5347324f..e2f4aaad79 100644 --- a/pkg/controller/servicemesh/controlplane/gateways_test.go +++ b/pkg/controller/servicemesh/controlplane/gateways_test.go @@ -14,6 +14,7 @@ import ( v2 "github.com/maistra/istio-operator/pkg/apis/maistra/v2" "github.com/maistra/istio-operator/pkg/controller/common" . "github.com/maistra/istio-operator/pkg/controller/common/test" + "github.com/maistra/istio-operator/pkg/controller/versions" ) func TestAdditionalIngressGatewayInstall(t *testing.T) { @@ -22,289 +23,254 @@ func TestAdditionalIngressGatewayInstall(t *testing.T) { additionalGatewayName := "additional-gateway" appNamespace := "app-namespace" const gatewayLabel = "maistra.io/gateway" - testCases := []IntegrationTestCase{ - { - name: "no-namespace", - smcp: New20SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - ClusterIngress: &v2.ClusterIngressGatewayConfig{ - IngressGatewayConfig: v2.IngressGatewayConfig{ - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{ - Enabled: &enabled, + var testCases []IntegrationTestCase + for _, v := range versions.TestedVersions { + testCases = append(testCases, + IntegrationTestCase{ + name: "no-namespace." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + ClusterIngress: &v2.ClusterIngressGatewayConfig{ + IngressGatewayConfig: v2.IngressGatewayConfig{ + GatewayConfig: v2.GatewayConfig{ + Enablement: v2.Enablement{ + Enabled: &enabled, + }, }, }, }, - }, - IngressGateways: map[string]*v2.IngressGatewayConfig{ - additionalGatewayName: { - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{ - Enabled: &enabled, + IngressGateways: map[string]*v2.IngressGatewayConfig{ + additionalGatewayName: { + GatewayConfig: v2.GatewayConfig{ + Enablement: v2.Enablement{ + Enabled: &enabled, + }, }, }, }, }, + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: VerifyActions( + Verify("create").On("deployments"). + Named("istio-ingressgateway").In(controlPlaneNamespace). + Passes(ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace)), + Verify("create").On("deployments"). + Named(additionalGatewayName).In(controlPlaneNamespace). + Passes(ExpectedLabelGatewayCreate(gatewayLabel, additionalGatewayName+"."+controlPlaneNamespace)), + ), + Assertions: ActionAssertions{}, }, - }), - create: IntegrationTestValidation{ - Verifier: VerifyActions( - Verify("create").On("deployments"). - Named("istio-ingressgateway").In(controlPlaneNamespace). - Passes(ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace)), - Verify("create").On("deployments"). - Named(additionalGatewayName).In(controlPlaneNamespace). - Passes(ExpectedLabelGatewayCreate(gatewayLabel, additionalGatewayName+"."+controlPlaneNamespace)), - ), - Assertions: ActionAssertions{}, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), + }, }, }, - }, - { - name: "cp-namespace", - smcp: New20SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - IngressGateways: map[string]*v2.IngressGatewayConfig{ - additionalGatewayName: { - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{ - Enabled: &enabled, + IntegrationTestCase{ + name: "cp-namespace." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + IngressGateways: map[string]*v2.IngressGatewayConfig{ + additionalGatewayName: { + GatewayConfig: v2.GatewayConfig{ + Enablement: v2.Enablement{ + Enabled: &enabled, + }, + Namespace: controlPlaneNamespace, }, - Namespace: controlPlaneNamespace, }, }, }, + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: Verify("create").On("deployments"). + Named(additionalGatewayName).In(controlPlaneNamespace). + Passes(ExpectedLabelGatewayCreate(gatewayLabel, additionalGatewayName+"."+controlPlaneNamespace)), + Assertions: ActionAssertions{}, }, - }), - create: IntegrationTestValidation{ - Verifier: Verify("create").On("deployments"). - Named(additionalGatewayName).In(controlPlaneNamespace). - Passes(ExpectedLabelGatewayCreate(gatewayLabel, additionalGatewayName+"."+controlPlaneNamespace)), - Assertions: ActionAssertions{}, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), - }, - }, - }, - { - name: "app-namespace", - resources: []runtime.Object{ - &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: appNamespace}}, - &v1.ServiceMeshMemberRoll{ - ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: controlPlaneNamespace}, - Status: v1.ServiceMeshMemberRollStatus{ - ConfiguredMembers: []string{ - appNamespace, - }, + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), }, }, }, - smcp: New20SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - IngressGateways: map[string]*v2.IngressGatewayConfig{ - additionalGatewayName: { - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{ - Enabled: &enabled, - }, - Namespace: appNamespace, + IntegrationTestCase{ + name: "app-namespace." + v.String(), + resources: []runtime.Object{ + &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: appNamespace}}, + &v1.ServiceMeshMemberRoll{ + ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: controlPlaneNamespace}, + Status: v1.ServiceMeshMemberRollStatus{ + ConfiguredMembers: []string{ + appNamespace, }, }, }, }, - }), - create: IntegrationTestValidation{ - Verifier: Verify("create").On("deployments"). - Named(additionalGatewayName).In(appNamespace). - Passes(ExpectedExternalGatewayCreate), - Assertions: ActionAssertions{}, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - // TODO: MAISTRA-1333 gateways in other namepsaces do not get deleted properly - // Assert("delete").On("deployments").Named(additionalGatewayName).In(appNamespace).IsSeen(), - }, - }, - }, - { - name: "labels", - smcp: New20SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - IngressGateways: map[string]*v2.IngressGatewayConfig{ - additionalGatewayName: { - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{ - Enabled: &enabled, - }, - Service: v2.GatewayServiceConfig{ - Metadata: &v2.MetadataConfig{ - Labels: map[string]string{ - "test": "test", - }, + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + IngressGateways: map[string]*v2.IngressGatewayConfig{ + additionalGatewayName: { + GatewayConfig: v2.GatewayConfig{ + Enablement: v2.Enablement{ + Enabled: &enabled, }, + Namespace: appNamespace, }, - Namespace: controlPlaneNamespace, }, }, }, + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: Verify("create").On("deployments"). + Named(additionalGatewayName).In(appNamespace). + Passes(ExpectedExternalGatewayCreate), + Assertions: ActionAssertions{}, }, - }), - create: IntegrationTestValidation{ - Verifier: VerifyActions( - Verify("create").On("networkpolicies").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( - ExpectedLabelMatchedByNetworkPolicy("istio", "ingressgateway"), - ), - Verify("create").On("networkpolicies").Named(additionalGatewayName).In(controlPlaneNamespace).Passes( - ExpectedLabelMatchedByNetworkPolicy("test", "test"), - ), - Verify("create").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).Passes( - ExpectedLabelGatewayCreate("test", "test"), - ), - ), - Assertions: ActionAssertions{}, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named(additionalGatewayName).In(appNamespace).IsSeen(), + }, }, }, - }, - { - name: "labels-2.1", - smcp: New21SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - IngressGateways: map[string]*v2.IngressGatewayConfig{ - additionalGatewayName: { - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{ - Enabled: &enabled, - }, - Service: v2.GatewayServiceConfig{ - Metadata: &v2.MetadataConfig{ - Labels: map[string]string{ - "test": "test", + IntegrationTestCase{ + name: "labels." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + IngressGateways: map[string]*v2.IngressGatewayConfig{ + additionalGatewayName: { + GatewayConfig: v2.GatewayConfig{ + Enablement: v2.Enablement{ + Enabled: &enabled, + }, + Service: v2.GatewayServiceConfig{ + Metadata: &v2.MetadataConfig{ + Labels: map[string]string{ + "test": "test", + }, }, }, + Namespace: controlPlaneNamespace, }, - Namespace: controlPlaneNamespace, }, }, }, - }, - }), - create: IntegrationTestValidation{ - Verifier: VerifyActions( - Verify("create").On("networkpolicies").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( - ExpectedLabelMatchedByNetworkPolicy("istio", "ingressgateway"), - ), - Verify("create").On("networkpolicies").Named(additionalGatewayName).In(controlPlaneNamespace).Passes( - ExpectedLabelMatchedByNetworkPolicy("test", "test"), + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: VerifyActions( + Verify("create").On("networkpolicies").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( + ExpectedLabelMatchedByNetworkPolicy("istio", "ingressgateway"), + ), + Verify("create").On("networkpolicies").Named(additionalGatewayName).In(controlPlaneNamespace).Passes( + ExpectedLabelMatchedByNetworkPolicy("test", "test"), + ), + Verify("create").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).Passes( + ExpectedLabelGatewayCreate("test", "test"), + ExpectedLabelGatewayCreate(gatewayLabel, additionalGatewayName+"."+controlPlaneNamespace), + ExpectedLabelGatewayCreate("app", additionalGatewayName), + ), ), - Verify("create").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).Passes( - ExpectedLabelGatewayCreate("test", "test"), - ExpectedLabelGatewayCreate(gatewayLabel, additionalGatewayName+"."+controlPlaneNamespace), - ExpectedLabelGatewayCreate("app", additionalGatewayName), - ), - ), - Assertions: ActionAssertions{}, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), + Assertions: ActionAssertions{}, + }, + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named(additionalGatewayName).In(controlPlaneNamespace).IsSeen(), + }, }, }, - }, - { - name: "cluster-ingress-route-enabled", - smcp: New21SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - ClusterIngress: &v2.ClusterIngressGatewayConfig{ - IngressGatewayConfig: v2.IngressGatewayConfig{ - RouteConfig: &v2.Enablement{ - Enabled: &enabled, + IntegrationTestCase{ + name: "cluster-ingress-route-enabled." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + ClusterIngress: &v2.ClusterIngressGatewayConfig{ + IngressGatewayConfig: v2.IngressGatewayConfig{ + RouteConfig: &v2.Enablement{ + Enabled: &enabled, + }, }, }, }, - }, - }), - create: IntegrationTestValidation{ - Verifier: VerifyActions( - Verify("create").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( - ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace), + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: VerifyActions( + Verify("create").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( + ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace), + ), ), - ), - Assertions: ActionAssertions{ - Assert("create").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + Assertions: ActionAssertions{ + Assert("create").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + }, }, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), - Assert("delete").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + Assert("delete").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + }, }, }, - }, - { - name: "cluster-ingress-route-disabled", - smcp: New21SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - ClusterIngress: &v2.ClusterIngressGatewayConfig{ - IngressGatewayConfig: v2.IngressGatewayConfig{ - RouteConfig: &v2.Enablement{ - Enabled: &disabled, + IntegrationTestCase{ + name: "cluster-ingress-route-disabled." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + ClusterIngress: &v2.ClusterIngressGatewayConfig{ + IngressGatewayConfig: v2.IngressGatewayConfig{ + RouteConfig: &v2.Enablement{ + Enabled: &disabled, + }, }, }, }, - }, - }), - create: IntegrationTestValidation{ - Verifier: VerifyActions( - Verify("create").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( - ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace), + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: VerifyActions( + Verify("create").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( + ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace), + ), ), - ), - Assertions: ActionAssertions{ - Assert("create").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsNotSeen(), + Assertions: ActionAssertions{ + Assert("create").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsNotSeen(), + }, }, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), - Assert("delete").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsNotSeen(), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + Assert("delete").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsNotSeen(), + }, }, }, - }, - { - // creating a route should be enabled by default - name: "cluster-ingress-route-undefined", - smcp: New21SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Gateways: &v2.GatewaysConfig{ - ClusterIngress: &v2.ClusterIngressGatewayConfig{}, - }, - }), - create: IntegrationTestValidation{ - Verifier: VerifyActions( - Verify("create").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( - ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace), + IntegrationTestCase{ + // creating a route should be enabled by default + name: "cluster-ingress-route-undefined." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Gateways: &v2.GatewaysConfig{ + ClusterIngress: &v2.ClusterIngressGatewayConfig{}, + }, + Version: v.String(), + }), + create: IntegrationTestValidation{ + Verifier: VerifyActions( + Verify("create").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).Passes( + ExpectedLabelGatewayCreate(gatewayLabel, "istio-ingressgateway."+controlPlaneNamespace), + ), ), - ), - Assertions: ActionAssertions{ - Assert("create").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + Assertions: ActionAssertions{ + Assert("create").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + }, }, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), - Assert("delete").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("deployments").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + Assert("delete").On("routes").Named("istio-ingressgateway").In(controlPlaneNamespace).IsSeen(), + }, }, - }, - }, + }) } RunSimpleInstallTests(t, testCases) } diff --git a/pkg/controller/servicemesh/controlplane/integration_test.go b/pkg/controller/servicemesh/controlplane/integration_test.go index affd818ed9..84e2c89142 100644 --- a/pkg/controller/servicemesh/controlplane/integration_test.go +++ b/pkg/controller/servicemesh/controlplane/integration_test.go @@ -33,35 +33,20 @@ import ( ) func TestDefaultInstall(t *testing.T) { - testCases := []IntegrationTestCase{ - { - name: "default." + versions.V2_2.String(), - smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &maistrav2.ControlPlaneSpec{Version: versions.V2_2.String()}), + var testCases []IntegrationTestCase + for _, v := range versions.TestedVersions { + testCases = append(testCases, IntegrationTestCase{ + name: "default." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &maistrav2.ControlPlaneSpec{Version: v.String()}), create: IntegrationTestValidation{ - Assertions: generateAssertions("create", "istiod-"+controlPlaneName, "wasm-cacher-"+controlPlaneName, - "istio-ingressgateway", "istio-egressgateway", "prometheus", "grafana"), + Assertions: generateAssertions("create", + "istiod-"+controlPlaneName, "istio-ingressgateway", "istio-egressgateway", "prometheus", "grafana"), }, delete: IntegrationTestValidation{ - Assertions: generateAssertions("delete", "istiod-"+controlPlaneName, "wasm-cacher-"+controlPlaneName, - "istio-ingressgateway", "istio-egressgateway", "prometheus", "grafana"), + Assertions: generateAssertions("delete", + "istiod-"+controlPlaneName, "istio-ingressgateway", "istio-egressgateway", "prometheus", "grafana"), }, - }, - } - for _, v := range versions.TestedVersions { - if v.AtLeast(versions.V2_3) { - testCases = append(testCases, IntegrationTestCase{ - name: "default." + v.String(), - smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &maistrav2.ControlPlaneSpec{Version: v.String()}), - create: IntegrationTestValidation{ - Assertions: generateAssertions("create", - "istiod-"+controlPlaneName, "istio-ingressgateway", "istio-egressgateway", "prometheus", "grafana"), - }, - delete: IntegrationTestValidation{ - Assertions: generateAssertions("delete", - "istiod-"+controlPlaneName, "istio-ingressgateway", "istio-egressgateway", "prometheus", "grafana"), - }, - }) - } + }) } RunSimpleInstallTests(t, testCases) } @@ -82,9 +67,9 @@ func TestBootstrapping(t *testing.T) { ) cniDaemonSetNames := map[versions.Version]string{ - versions.V2_2: "istio-cni-node", versions.V2_3: "istio-cni-node-v2-3", versions.V2_4: "istio-cni-node-v2-4", + versions.V2_5: "istio-cni-node-v2-5", } type testCase struct { diff --git a/pkg/controller/servicemesh/controlplane/networkpolicy_test.go b/pkg/controller/servicemesh/controlplane/networkpolicy_test.go index a7092db294..db1ada4752 100644 --- a/pkg/controller/servicemesh/controlplane/networkpolicy_test.go +++ b/pkg/controller/servicemesh/controlplane/networkpolicy_test.go @@ -12,61 +12,64 @@ import ( const numberOfNetworkPolicies = 8 func TestNetworkPolicy(t *testing.T) { - testCases := []IntegrationTestCase{ - { - name: "np.enabled", - smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Version: versions.V2_1.String(), - Security: &v2.SecurityConfig{ - ManageNetworkPolicy: ptrTrue, + var testCases []IntegrationTestCase + for _, v := range versions.TestedVersions { + testCases = append(testCases, + IntegrationTestCase{ + name: "np.enabled." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Version: v.String(), + Security: &v2.SecurityConfig{ + ManageNetworkPolicy: ptrTrue, + }, + }), + create: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("create").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + }, }, - }), - create: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("create").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + }, }, }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + IntegrationTestCase{ + name: "np.missing." + v.String(), // Same behavior as the above case, since the default value is `enabled`. + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Version: v.String(), + }), + create: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("create").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + }, }, - }, - }, - { - name: "np.missing", // Same behavior as the above case, since the default value is `enabled`. - smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Version: versions.V2_1.String(), - }), - create: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("create").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), - }, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("networkpolicies").In(controlPlaneNamespace).SeenCountIs(numberOfNetworkPolicies), + }, }, }, - }, - { - name: "np.disabled", - smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - Version: versions.V2_1.String(), - Security: &v2.SecurityConfig{ - ManageNetworkPolicy: ptrFalse, + IntegrationTestCase{ + name: "np.disabled." + v.String(), + smcp: NewV2SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ + Version: v.String(), + Security: &v2.SecurityConfig{ + ManageNetworkPolicy: ptrFalse, + }, + }), + create: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("create").On("networkpolicies").In(controlPlaneNamespace).IsNotSeen(), + }, }, - }), - create: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("create").On("networkpolicies").In(controlPlaneNamespace).IsNotSeen(), - }, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("networkpolicies").In(controlPlaneNamespace).IsNotSeen(), + delete: IntegrationTestValidation{ + Assertions: ActionAssertions{ + Assert("delete").On("networkpolicies").In(controlPlaneNamespace).IsNotSeen(), + }, }, }, - }, + ) } RunSimpleInstallTests(t, testCases) } diff --git a/pkg/controller/servicemesh/controlplane/profiles_test.go b/pkg/controller/servicemesh/controlplane/profiles_test.go deleted file mode 100644 index 137d9f68d7..0000000000 --- a/pkg/controller/servicemesh/controlplane/profiles_test.go +++ /dev/null @@ -1,546 +0,0 @@ -package controlplane - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - - v1 "github.com/maistra/istio-operator/pkg/apis/maistra/v1" - v2 "github.com/maistra/istio-operator/pkg/apis/maistra/v2" - "github.com/maistra/istio-operator/pkg/controller/common" - "github.com/maistra/istio-operator/pkg/controller/common/test" - "github.com/maistra/istio-operator/pkg/controller/versions" -) - -const ( - ProductImage11 = "1.1.18" - ProductImage20 = "2.0.11" - CommunityImage20 = "2.0.11" - CommunityImage21 = "2.1.6" - ProductImage21 = "2.1.6" -) - -func TestProfiles(t *testing.T) { - profileTestCases := []struct { - name string - v versions.Version - input *v2.ServiceMeshControlPlane - expected *v2.ServiceMeshControlPlane - patchupExpected func(*v2.ServiceMeshControlPlane) - skip bool - }{ - { - name: "maistra-profile-2.0", - v: versions.V2_0, - input: &v2.ServiceMeshControlPlane{ - Spec: v2.ControlPlaneSpec{ - Profiles: []string{"maistra"}, - }, - }, - expected: &v2.ServiceMeshControlPlane{ - Spec: v20ExpectedSpec, - }, - }, - { - name: "servicemesh-profile-2.0", - v: versions.V2_0, - input: &v2.ServiceMeshControlPlane{ - Spec: v2.ControlPlaneSpec{ - Profiles: []string{"servicemesh"}, - }, - }, - expected: &v2.ServiceMeshControlPlane{ - Spec: v20ExpectedSpec, - }, - patchupExpected: func(smcp *v2.ServiceMeshControlPlane) { - // the only thing changing here should be image names/tags/registries - smcp.Spec.Runtime.Defaults.Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.ImageTag = "2.0.0" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.ImageRegistry = "registry.redhat.io/openshift4" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.Image = "ose-oauth-proxy" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.ImageTag = "v4.4" - smcp.Spec.Runtime.Defaults.Container.ImageTag = ProductImage20 - }, - }, - { - name: "maistra-profile-2.1", - v: versions.V2_1, - input: &v2.ServiceMeshControlPlane{ - Spec: v2.ControlPlaneSpec{ - Profiles: []string{"maistra"}, - }, - }, - expected: &v2.ServiceMeshControlPlane{ - Spec: v20ExpectedSpec, - }, - patchupExpected: func(smcp *v2.ServiceMeshControlPlane) { - smcp.Spec.Proxy.Networking.Initialization.InitContainer.Runtime.Image = "injected-proxy-init-v2.1" - smcp.Spec.Proxy.Runtime.Container.Image = "injected-proxyv2-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.Image = "injected-3scale-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGrafana].Container.Image = "injected-grafana-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNamePilot].Container.Image = "injected-pilot-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNamePrometheus].Container.Image = "injected-prometheus-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameWASMCacher].Container.Image = "injected-wasm-cacher-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameRateLimiting] = &v2.ComponentRuntimeConfig{ - Container: &v2.ContainerConfig{Image: "injected-rls-v2.1"}, - } - delete(smcp.Spec.Runtime.Components, v2.ControlPlaneComponentNameMixer) - delete(smcp.Spec.Runtime.Components, v2.ControlPlaneComponentNameMixerPolicy) - delete(smcp.Spec.Runtime.Components, v2.ControlPlaneComponentNameMixerTelemetry) - smcp.Spec.Runtime.Defaults.Container.ImageTag = CommunityImage21 - smcp.Spec.TechPreview.RemoveField("wasmExtensions") - }, - }, - { - name: "servicemesh-profile-2.1", - v: versions.V2_1, - input: &v2.ServiceMeshControlPlane{ - Spec: v2.ControlPlaneSpec{ - Profiles: []string{"servicemesh"}, - }, - }, - expected: &v2.ServiceMeshControlPlane{ - Spec: v20ExpectedSpec, - }, - patchupExpected: func(smcp *v2.ServiceMeshControlPlane) { - // the only thing changing here should be image names/tags/registries - smcp.Spec.Proxy.Networking.Initialization.InitContainer.Runtime.Image = "injected-proxy-init-v2.1" - smcp.Spec.Proxy.Runtime.Container.Image = "injected-proxyv2-v2.1" - smcp.Spec.Runtime.Defaults.Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.Image = "injected-3scale-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.ImageTag = "2.0.0" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.ImageRegistry = "registry.redhat.io/openshift4" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.Image = "ose-oauth-proxy" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.ImageTag = "v4.4" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGrafana].Container.Image = "injected-grafana-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNamePilot].Container.Image = "injected-pilot-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNamePrometheus].Container.Image = "injected-prometheus-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameWASMCacher].Container.Image = "injected-wasm-cacher-v2.1" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameRateLimiting] = &v2.ComponentRuntimeConfig{ - Container: &v2.ContainerConfig{Image: "injected-rls-v2.1"}, - } - delete(smcp.Spec.Runtime.Components, v2.ControlPlaneComponentNameMixer) - delete(smcp.Spec.Runtime.Components, v2.ControlPlaneComponentNameMixerPolicy) - delete(smcp.Spec.Runtime.Components, v2.ControlPlaneComponentNameMixerTelemetry) - smcp.Spec.Runtime.Defaults.Container.ImageTag = ProductImage21 - smcp.Spec.TechPreview.RemoveField("wasmExtensions") - }, - }, - { - name: "MAISTRA-2409", - v: versions.V2_0, - input: &v2.ServiceMeshControlPlane{ - Spec: v2.ControlPlaneSpec{ - Profiles: []string{"servicemesh"}, - Proxy: &v2.ProxyConfig{ - Runtime: &v2.ProxyRuntimeConfig{ - Readiness: &v2.ProxyReadinessConfig{ - RewriteApplicationProbes: true, - }, - }, - }, - }, - }, - expected: &v2.ServiceMeshControlPlane{ - Spec: v20ExpectedSpec, - }, - patchupExpected: func(smcp *v2.ServiceMeshControlPlane) { - // the only thing changing here should be image names/tags/registries - smcp.Spec.Proxy.Runtime.Readiness = &v2.ProxyReadinessConfig{RewriteApplicationProbes: true} - smcp.Spec.Runtime.Defaults.Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Defaults.Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.ImageRegistry = "registry.redhat.io/openshift-service-mesh" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameThreeScale].Container.ImageTag = "2.0.0" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.ImageRegistry = "registry.redhat.io/openshift4" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.Image = "ose-oauth-proxy" - smcp.Spec.Runtime.Components[v2.ControlPlaneComponentNameGlobalOauthProxy].Container.ImageTag = "v4.4" - smcp.Spec.Runtime.Defaults.Container.ImageTag = ProductImage20 - }, - }, - } - testNamespace := "test-namespace" - testName := "test" - testCR := &common.ControllerResources{ - Scheme: test.GetScheme(), - } - InitializeGlobals("operator-namespace")() - for _, tc := range profileTestCases { - t.Run(tc.name, func(t *testing.T) { - if tc.skip { - t.Skip() - } - var err error - testSMCP := tc.input.DeepCopy() - testSMCP.Spec.Version = tc.v.String() - testSMCP.Name = testName - testSMCP.Namespace = testNamespace - v1smcp := &v1.ServiceMeshControlPlane{} - if err = v1smcp.ConvertFrom(testSMCP); err != nil { - t.Fatalf("unexpected error converting input: %v", err) - } - appliedV1SMCP := &v1.ServiceMeshControlPlane{} - if appliedV1SMCP.Spec, err = tc.v.Strategy().ApplyProfiles(context.TODO(), testCR, &v1smcp.Spec, testNamespace); err != nil { - t.Fatalf("unexpected error applying profiles: %v", err) - } - appliedV2SMCP := &v2.ServiceMeshControlPlane{} - if err = appliedV1SMCP.ConvertTo(appliedV2SMCP); err != nil { - t.Fatalf("unexpected error converting output: %v", err) - } - expected := tc.expected.DeepCopy() - expected.Spec.Version = tc.v.String() - expected.Spec.Profiles = append([]string(nil), tc.input.Spec.Profiles...) - if tc.patchupExpected != nil { - tc.patchupExpected(expected) - } - if diff := cmp.Diff(expected.Spec, appliedV2SMCP.Spec, cmp.AllowUnexported(v1.HelmValues{})); diff != "" { - t.Errorf("TestProfiles() case %s mismatch (-want +got):\n%s", tc.name, diff) - } - }) - } -} - -func TestMissingProfile(t *testing.T) { - smcp := &v2.ServiceMeshControlPlane{ - Spec: v2.ControlPlaneSpec{ - Profiles: []string{"missing-profile"}, - Version: versions.DefaultVersion.String(), - }, - } - - testCR := &common.ControllerResources{ - Scheme: test.GetScheme(), - } - - v1smcp := &v1.ServiceMeshControlPlane{} - if err := v1smcp.ConvertFrom(smcp); err != nil { - t.Fatalf("unexpected error converting input: %v", err) - } - for _, version := range versions.GetSupportedVersions() { - t.Run(version.String(), func(t *testing.T) { - var err error - appliedV1SMCP := &v1.ServiceMeshControlPlane{} - if appliedV1SMCP.Spec, err = version.Strategy().ApplyProfiles(context.TODO(), testCR, &v1smcp.Spec, controlPlaneNamespace); err == nil { - t.Error("expected ApplyProfiles to return error, but none was returned") - } - }) - } -} - -// Deprecated v1.1 is deprecated and skip V11Expected -var v20ExpectedSpec = v2.ControlPlaneSpec{ - Proxy: &v2.ProxyConfig{ - Networking: &v2.ProxyNetworkingConfig{ - Initialization: &v2.ProxyNetworkInitConfig{ - InitContainer: &v2.ProxyInitContainerConfig{ - Runtime: &v2.ContainerConfig{ - Image: "injected-proxy-init-v2.0", - }, - }, - }, - DNS: &v2.ProxyDNSConfig{ - RefreshRate: "300s", - }, - Protocol: &v2.ProxyNetworkProtocolConfig{ - AutoDetect: &v2.ProxyNetworkAutoProtocolDetectionConfig{ - Inbound: &falseVal, - Outbound: &falseVal, - }, - }, - }, - Runtime: &v2.ProxyRuntimeConfig{ - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - Image: "injected-proxyv2-v2.0", - }, - }, - Injection: &v2.ProxyInjectionConfig{ - AutoInject: &falseVal, - }, - }, - Security: &v2.SecurityConfig{ - Identity: &v2.IdentityConfig{ - Type: v2.IdentityConfigTypeKubernetes, - }, - }, - Telemetry: &v2.TelemetryConfig{ - Type: v2.TelemetryTypeIstiod, - }, - Policy: &v2.PolicyConfig{ - Type: v2.PolicyTypeNone, - }, - Tracing: &v2.TracingConfig{ - Type: v2.TracerTypeJaeger, - }, - Gateways: &v2.GatewaysConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - ClusterIngress: &v2.ClusterIngressGatewayConfig{ - IngressEnabled: &falseVal, - IngressGatewayConfig: v2.IngressGatewayConfig{ - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - Service: v2.GatewayServiceConfig{ - ServiceSpec: corev1.ServiceSpec{ - Type: corev1.ServiceTypeClusterIP, - }, - }, - Runtime: &v2.ComponentRuntimeConfig{ - Deployment: &v2.DeploymentRuntimeConfig{ - AutoScaling: &v2.AutoScalerConfig{ - Enablement: v2.Enablement{Enabled: &falseVal}, - }, - }, - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - }, - }, - }, - }, - }, - ClusterEgress: &v2.EgressGatewayConfig{ - GatewayConfig: v2.GatewayConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - Runtime: &v2.ComponentRuntimeConfig{ - Deployment: &v2.DeploymentRuntimeConfig{ - AutoScaling: &v2.AutoScalerConfig{ - Enablement: v2.Enablement{Enabled: &falseVal}, - }, - }, - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - }, - }, - }, - }, - OpenShiftRoute: &v2.OpenShiftRouteConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - }, - }, - General: &v2.GeneralConfig{ - Logging: &v2.LoggingConfig{ - ComponentLevels: v2.ComponentLogLevels{ - "default": "warn", - }, - }, - }, - Addons: &v2.AddonsConfig{ - Jaeger: &v2.JaegerAddonConfig{ - Name: "jaeger", - Install: &v2.JaegerInstallConfig{ - Storage: &v2.JaegerStorageConfig{ - Type: v2.JaegerStorageTypeMemory, - }, - Ingress: &v2.JaegerIngressConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - }, - }, - }, - Grafana: &v2.GrafanaAddonConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - Install: &v2.GrafanaInstallConfig{ - Service: &v2.ComponentServiceConfig{ - Metadata: &v2.MetadataConfig{ - Annotations: map[string]string{ - "service.alpha.openshift.io/serving-cert-secret-name": "grafana-tls", - }, - }, - Ingress: &v2.ComponentIngressConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - }, - }, - }, - }, - Kiali: &v2.KialiAddonConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - Name: "kiali", - Install: &v2.KialiInstallConfig{ - Dashboard: &v2.KialiDashboardConfig{ViewOnly: &falseVal}, - Service: &v2.ComponentServiceConfig{ - Ingress: &v2.ComponentIngressConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - }, - }, - }, - }, - Prometheus: &v2.PrometheusAddonConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - Install: &v2.PrometheusInstallConfig{ - Service: &v2.ComponentServiceConfig{ - Metadata: &v2.MetadataConfig{ - Annotations: map[string]string{ - "service.alpha.openshift.io/serving-cert-secret-name": "prometheus-tls", - }, - }, - Ingress: &v2.ComponentIngressConfig{ - Enablement: v2.Enablement{Enabled: &trueVal}, - }, - }, - }, - }, - }, - Runtime: &v2.ControlPlaneRuntimeConfig{ - Defaults: &v2.DefaultRuntimeConfig{ - Deployment: &v2.CommonDeploymentRuntimeConfig{ - PodDisruption: &v2.PodDisruptionBudget{ - Enablement: v2.Enablement{Enabled: &falseVal}, - }, - }, - Container: &v2.CommonContainerConfig{ - ImageRegistry: "docker.io/maistra", - ImageTag: CommunityImage20, - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - }, - Components: map[v2.ControlPlaneComponentName]*v2.ComponentRuntimeConfig{ - v2.ControlPlaneComponentNameGlobalOauthProxy: { - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - ImageRegistry: "quay.io/openshift", - ImageTag: "4.4", - ImagePullPolicy: corev1.PullIfNotPresent, - }, - Image: "origin-oauth-proxy", - }, - }, - v2.ControlPlaneComponentNamePilot: { - Deployment: &v2.DeploymentRuntimeConfig{ - AutoScaling: &v2.AutoScalerConfig{ - Enablement: v2.Enablement{Enabled: &falseVal}, - }, - }, - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - Image: "injected-pilot-v2.0", - }, - }, - v2.ControlPlaneComponentNameMixer: { - Container: &v2.ContainerConfig{ - Image: "injected-mixer-v2.0", - }, - }, - v2.ControlPlaneComponentNameMixerTelemetry: { - Deployment: &v2.DeploymentRuntimeConfig{ - AutoScaling: &v2.AutoScalerConfig{ - Enablement: v2.Enablement{Enabled: &falseVal}, - }, - }, - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - Image: "injected-mixer-v2.0", - }, - }, - v2.ControlPlaneComponentNameMixerPolicy: { - Deployment: &v2.DeploymentRuntimeConfig{ - AutoScaling: &v2.AutoScalerConfig{ - Enablement: v2.Enablement{Enabled: &falseVal}, - }, - }, - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - Image: "injected-mixer-v2.0", - }, - }, - v2.ControlPlaneComponentNamePrometheus: { - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - Image: "injected-prometheus-v2.0", - }, - }, - v2.ControlPlaneComponentNameGrafana: { - Container: &v2.ContainerConfig{ - Image: "injected-grafana-v2.0", - }, - }, - v2.ControlPlaneComponentNameThreeScale: { - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - ImageRegistry: "quay.io/3scale", - ImageTag: "v2.0.0", - }, - Image: "injected-3scale-v2.0", - }, - }, - v2.ControlPlaneComponentNameWASMCacher: { - Container: &v2.ContainerConfig{ - CommonContainerConfig: v2.CommonContainerConfig{ - Resources: &corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse("10m"), - corev1.ResourceMemory: resource.MustParse("128Mi"), - }, - }, - }, - Image: "injected-wasm-cacher-v2.0", - }, - }, - }, - }, - TechPreview: v1.NewHelmValues(map[string]interface{}{ - "sidecarInjectorWebhook": map[string]interface{}{ - "objectSelector": map[string]interface{}{ - "enabled": false, - }, - }, - "wasmExtensions": map[string]interface{}{ - "enabled": false, - }, - }), -} diff --git a/pkg/controller/servicemesh/controlplane/reconciler_test.go b/pkg/controller/servicemesh/controlplane/reconciler_test.go index 8ad5b56d19..b7814e3407 100644 --- a/pkg/controller/servicemesh/controlplane/reconciler_test.go +++ b/pkg/controller/servicemesh/controlplane/reconciler_test.go @@ -197,6 +197,7 @@ func TestManifestValidation(t *testing.T) { versions.V2_2: "namespace of manifest b/another-ingress not in mesh", versions.V2_3: "namespace of manifest b/another-ingress not in mesh", versions.V2_4: "namespace of manifest b/another-ingress not in mesh", + versions.V2_5: "namespace of manifest b/another-ingress not in mesh", }, }, { diff --git a/pkg/controller/servicemesh/controlplane/wasm_extensions_test.go b/pkg/controller/servicemesh/controlplane/wasm_extensions_test.go deleted file mode 100644 index 12dd321868..0000000000 --- a/pkg/controller/servicemesh/controlplane/wasm_extensions_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package controlplane - -import ( - "testing" - - v1 "github.com/maistra/istio-operator/pkg/apis/maistra/v1" - v2 "github.com/maistra/istio-operator/pkg/apis/maistra/v2" - . "github.com/maistra/istio-operator/pkg/controller/common/test" -) - -func TestWASMExtensionInstall(t *testing.T) { - testCases := []IntegrationTestCase{ - { - name: "wasm-extensions.enabled", - smcp: New20SMCPResource(controlPlaneName, controlPlaneNamespace, &v2.ControlPlaneSpec{ - TechPreview: v1.NewHelmValues(map[string]interface{}{ - "wasmExtensions": map[string]interface{}{ - "enabled": true, - }, - }), - }), - create: IntegrationTestValidation{ - Verifier: Verify("create").On("deployments").Named("wasm-cacher-" + controlPlaneName).In(controlPlaneNamespace).IsSeen(), - Assertions: ActionAssertions{}, - }, - delete: IntegrationTestValidation{ - Assertions: ActionAssertions{ - Assert("delete").On("deployments").Named("wasm-cacher-" + controlPlaneName).In(controlPlaneNamespace).IsSeen(), - }, - }, - }, - } - RunSimpleInstallTests(t, testCases) -} diff --git a/pkg/controller/versions/strategy_common.go b/pkg/controller/versions/strategy_common.go new file mode 100644 index 0000000000..bcef7fb682 --- /dev/null +++ b/pkg/controller/versions/strategy_common.go @@ -0,0 +1,15 @@ +package versions + +import ( + "fmt" + + v2 "github.com/maistra/istio-operator/pkg/apis/maistra/v2" +) + +func validatePrometheusEnabledWhenDefaultKialiEnabled(spec *v2.ControlPlaneSpec, allErrors []error) []error { + if spec.IsKialiEnabled() && !spec.IsCustomKialiConfigured() && !spec.IsPrometheusEnabled() { + return append(allErrors, fmt.Errorf(".spec.addons.prometheus.enabled must be true when "+ + ".spec.addons.kiali.enabled is true and spec.addons.kiali.name is not specified")) + } + return allErrors +} diff --git a/pkg/controller/versions/strategy_v2_4.go b/pkg/controller/versions/strategy_v2_4.go index d9ea43e9bf..c010f8a54a 100644 --- a/pkg/controller/versions/strategy_v2_4.go +++ b/pkg/controller/versions/strategy_v2_4.go @@ -794,14 +794,6 @@ func (v *versionStrategyV2_4) validateGlobal( return validateGlobal(ctx, version, meta, spec, cl, allErrors) } -func validatePrometheusEnabledWhenDefaultKialiEnabled(spec *v2.ControlPlaneSpec, allErrors []error) []error { - if spec.IsKialiEnabled() && !spec.IsCustomKialiConfigured() && !spec.IsPrometheusEnabled() { - return append(allErrors, fmt.Errorf(".spec.addons.prometheus.enabled must be true when "+ - ".spec.addons.kiali.enabled is true and spec.addons.kiali.name is not specified")) - } - return allErrors -} - func (v *versionStrategyV2_4) createMemberRoll(ctx context.Context, cr *common.ControllerResources, smcp *v2.ServiceMeshControlPlane) error { log := common.LogFromContext(ctx) diff --git a/pkg/controller/versions/strategy_v2_5.go b/pkg/controller/versions/strategy_v2_5.go new file mode 100644 index 0000000000..98ee77803f --- /dev/null +++ b/pkg/controller/versions/strategy_v2_5.go @@ -0,0 +1,816 @@ +package versions + +import ( + "context" + "fmt" + "net/http" + "path" + "time" + + pkgerrors "github.com/pkg/errors" + authorizationv1 "k8s.io/api/authorization/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/types" + utilerrors "k8s.io/apimachinery/pkg/util/errors" + "k8s.io/helm/pkg/chartutil" + "k8s.io/helm/pkg/manifest" + "k8s.io/utils/pointer" + apiv1 "maistra.io/api/core/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + "sigs.k8s.io/yaml" + + jaegerv1 "github.com/maistra/istio-operator/pkg/apis/external/jaeger/v1" + kialiv1alpha1 "github.com/maistra/istio-operator/pkg/apis/external/kiali/v1alpha1" + v1 "github.com/maistra/istio-operator/pkg/apis/maistra/v1" + v2 "github.com/maistra/istio-operator/pkg/apis/maistra/v2" + "github.com/maistra/istio-operator/pkg/controller/common" + "github.com/maistra/istio-operator/pkg/controller/common/cni" + "github.com/maistra/istio-operator/pkg/controller/common/helm" +) + +var v2_5ChartMapping = map[string]chartRenderingDetails{ + DiscoveryChart: { + path: "istio-control/istio-discovery", + enabledField: "", + }, + GatewayIngressChart: { + path: "gateways/istio-ingress", + enabledField: "", + }, + GatewayEgressChart: { + path: "gateways/istio-egress", + enabledField: "", + }, + TelemetryCommonChart: { + path: "istio-telemetry/telemetry-common", + enabledField: "", + }, + PrometheusChart: { + path: "istio-telemetry/prometheus", + enabledField: "prometheus", + }, + TracingChart: { + path: "istio-telemetry/tracing", + enabledField: "tracing", + }, + GrafanaChart: { + path: "istio-telemetry/grafana", + enabledField: "grafana", + }, + KialiChart: { + path: "istio-telemetry/kiali", + enabledField: "kiali", + }, + MeshConfigChart: { + path: "mesh-config", + enabledField: "", + }, + RLSChart: { + path: "rls", + enabledField: "rateLimiting.rls", + }, +} + +var v2_5ChartOrder = [][]string{ + {DiscoveryChart}, + {MeshConfigChart}, + {TelemetryCommonChart, PrometheusChart}, + {TracingChart, GatewayIngressChart, GatewayEgressChart, GrafanaChart}, + {KialiChart}, + {RLSChart}, +} + +type versionStrategyV2_5 struct { + Ver + conversionImpl v2xConversionStrategy +} + +var _ VersionStrategy = (*versionStrategyV2_5)(nil) + +func (v *versionStrategyV2_5) SetImageValues(_ context.Context, _ *common.ControllerResources, smcpSpec *v1.ControlPlaneSpec) error { + if err := common.UpdateField(smcpSpec.Istio, "grafana.image", common.Config.OLM.Images.V2_5.Grafana); err != nil { + return err + } + if err := common.UpdateField(smcpSpec.Istio, "pilot.image", common.Config.OLM.Images.V2_5.Pilot); err != nil { + return err + } + if err := common.UpdateField(smcpSpec.Istio, "prometheus.image", common.Config.OLM.Images.V2_5.Prometheus); err != nil { + return err + } + if err := common.UpdateField(smcpSpec.Istio, "prometheusConfigReloader.image", common.Config.OLM.Images.V2_5.PrometheusConfigReloader); err != nil { + return err + } + if err := common.UpdateField(smcpSpec.Istio, "global.proxy.image", common.Config.OLM.Images.V2_5.ProxyV2); err != nil { + return err + } + if err := common.UpdateField(smcpSpec.Istio, "rateLimiting.rls.image", common.Config.OLM.Images.V2_5.RLS); err != nil { + return err + } + return nil +} + +func (v *versionStrategyV2_5) IsClusterScoped(spec *v2.ControlPlaneSpec) (bool, error) { + return spec.Mode == v2.ClusterWideMode, nil +} + +func (v *versionStrategyV2_5) ValidateV1(_ context.Context, _ client.Client, _ *v1.ServiceMeshControlPlane) error { + return fmt.Errorf("must use v2 ServiceMeshControlPlane resource for v2.0+ installations") +} + +func (v *versionStrategyV2_5) ValidateV2(ctx context.Context, cl client.Client, meta *metav1.ObjectMeta, spec *v2.ControlPlaneSpec) error { + var allErrors []error + allErrors = v.validateGlobal(ctx, v.Version(), meta, spec, cl, allErrors) + allErrors = validateGateways(ctx, meta, spec, cl, allErrors) + allErrors = validatePolicyType(spec, v.Ver, allErrors) + allErrors = validateTelemetryType(spec, v.Ver, allErrors) + allErrors = validateProtocolDetection(spec, allErrors) + allErrors = v.validateRuntime(spec, allErrors) + allErrors = v.validateMixerDisabled(spec, allErrors) + allErrors = v.validateAddons(spec, allErrors) + allErrors = v.validateExtensionProviders(spec, allErrors) + return NewValidationError(allErrors...) +} + +func (v *versionStrategyV2_5) validateRuntime(spec *v2.ControlPlaneSpec, allErrors []error) []error { + if spec.Runtime == nil || spec.Runtime.Components == nil { + return allErrors + } + for component, config := range spec.Runtime.Components { + if config.Pod == nil || config.Pod.Affinity == nil { + continue + } + if component == v2.ControlPlaneComponentNameKiali { + if config.Pod.Affinity.PodAntiAffinity.RequiredDuringScheduling != nil || config.Pod.Affinity.PodAntiAffinity.PreferredDuringScheduling != nil { + allErrors = append(allErrors, fmt.Errorf("PodAntiAffinity configured via "+ + ".spec.runtime.components.pod.affinity.podAntiAffinity.requiredDuringScheduling and preferredDuringScheduling "+ + "is not supported for the %q component", v2.ControlPlaneComponentNameKiali)) + } + } else { + if config.Pod.Affinity.NodeAffinity != nil { + allErrors = append(allErrors, fmt.Errorf("nodeAffinity is only supported for the %q component", v2.ControlPlaneComponentNameKiali)) + } + if config.Pod.Affinity.PodAffinity != nil { + allErrors = append(allErrors, fmt.Errorf("podAffinity is only supported for the %q component", v2.ControlPlaneComponentNameKiali)) + } + if config.Pod.Affinity.PodAntiAffinity.PodAntiAffinity != nil { + allErrors = append(allErrors, fmt.Errorf("PodAntiAffinity configured via "+ + ".spec.runtime.components.pod.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution "+ + "and preferredDuringSchedulingIgnoredDuringExecution is only supported for the %q component", v2.ControlPlaneComponentNameKiali)) + } + } + } + return allErrors +} + +func (v *versionStrategyV2_5) validateMixerDisabled(spec *v2.ControlPlaneSpec, allErrors []error) []error { + if spec.Policy != nil && (spec.Policy.Type == v2.PolicyTypeMixer || spec.Policy.Mixer != nil) { + allErrors = append(allErrors, fmt.Errorf("support for policy.type %q and policy.Mixer options "+ + "have been removed in v2.1, please use another alternative", v2.PolicyTypeMixer)) + } + if spec.Telemetry != nil && (spec.Telemetry.Type == v2.TelemetryTypeMixer || spec.Telemetry.Mixer != nil) { + allErrors = append(allErrors, fmt.Errorf("support for telemetry.type %q and telemetry.Mixer options "+ + "have been removed in v2.1, please use another alternative", v2.TelemetryTypeMixer)) + } + return allErrors +} + +func (v *versionStrategyV2_5) validateAddons(spec *v2.ControlPlaneSpec, allErrors []error) []error { + if spec.Addons == nil { + return allErrors + } + + if spec.Addons.ThreeScale != nil { + allErrors = append(allErrors, fmt.Errorf("support for 3scale has been removed in v2.1; "+ + "please remove the spec.addons.3scale section from the SMCP and configure the 3scale WebAssembly adapter using a ServiceMeshExtension resource")) + } + return allErrors +} + +func (v *versionStrategyV2_5) validateExtensionProviders(spec *v2.ControlPlaneSpec, allErrors []error) []error { + if spec.MeshConfig == nil || spec.MeshConfig.ExtensionProviders == nil { + return allErrors + } + + for _, ext := range spec.MeshConfig.ExtensionProviders { + if ext.Name == "" { + allErrors = append(allErrors, fmt.Errorf("extension provider name cannot be empty")) + } + + counter := 0 + if ext.Prometheus != nil { + counter++ + } + if ext.EnvoyExtAuthzHTTP != nil { + counter++ + } + if ext.EnvoyExtAuthzGRPC != nil { + counter++ + } + if counter == 0 { + allErrors = append(allErrors, fmt.Errorf("extension provider '%s' does not define any provider - "+ + "it must specify one of: prometheus, envoyExtAuthzHttp, or envoyExtAuthzGrpc", ext.Name)) + } else if counter > 1 { + allErrors = append(allErrors, fmt.Errorf("extension provider '%s' must specify only one type of provider: "+ + "prometheus, envoyExtAuthzHttp, or envoyExtAuthzGrpc", ext.Name)) + } + + if ext.EnvoyExtAuthzHTTP != nil { + if ext.EnvoyExtAuthzHTTP.Timeout != nil { + if _, err := time.ParseDuration(*ext.EnvoyExtAuthzHTTP.Timeout); err != nil { + allErrors = append(allErrors, fmt.Errorf("invalid extension provider '%s': envoyExtAuthzHttp.timeout "+ + "must be specified in the duration format - got '%s'", ext.Name, *ext.EnvoyExtAuthzHTTP.Timeout)) + } + } + } + if ext.EnvoyExtAuthzGRPC != nil { + if ext.EnvoyExtAuthzGRPC.Timeout != nil { + if _, err := time.ParseDuration(*ext.EnvoyExtAuthzGRPC.Timeout); err != nil { + allErrors = append(allErrors, fmt.Errorf("invalid extension provider '%s': envoyExtAuthzGrpc.timeout "+ + "must be specified in the duration format - got '%s'", ext.Name, *ext.EnvoyExtAuthzGRPC.Timeout)) + } + } + } + } + return allErrors +} + +func (v *versionStrategyV2_5) validateServiceMeshExtensionsRemoved(ctx context.Context, cl client.Client, smcp metav1.Object) error { + serviceMeshExtensions := &apiv1.ServiceMeshExtensionList{} + if err := cl.List(ctx, serviceMeshExtensions); err != nil { + if !errors.IsNotFound(err) && !meta.IsNoMatchError(err) { + return NewValidationError(fmt.Errorf("upgrade validation failed: failed to list ServiceMeshExtensions in cluster (error: %s)", + err, + )) + } + } + if len(serviceMeshExtensions.Items) > 0 { + smmr := &v1.ServiceMeshMemberRoll{} + err := cl.Get(ctx, client.ObjectKey{Name: common.MemberRollName, Namespace: smcp.GetNamespace()}, smmr) + if err != nil { + if !errors.IsNotFound(err) { + return NewValidationError(fmt.Errorf("upgrade validation failed: failed to retrieve SMMR for SMCP (error: %s)", + err, + )) + } + } + meshNamespaces := common.GetMeshNamespaces(smcp.GetNamespace(), smmr) + for _, sme := range serviceMeshExtensions.Items { + if meshNamespaces.Has(sme.Namespace) { + return NewValidationError(fmt.Errorf("found a ServiceMeshExtension '%s' in namespace '%s'. "+ + "ServiceMeshExtension support has been removed; please migrate existing ServiceMeshExtensions to WasmPlugin", + sme.Name, + sme.Namespace, + )) + } + } + } + return nil +} + +func (v *versionStrategyV2_5) ValidateV2Full(ctx context.Context, cl client.Client, meta *metav1.ObjectMeta, spec *v2.ControlPlaneSpec) error { + var allErrors []error + err := v.ValidateV2(ctx, cl, meta, spec) + if err != nil { + if validationErr, ok := err.(ValidationError); ok { + allErrors = validationErr.Errors() + } else { + return err + } + } + // additional validation checks that are only performed just before reconciliation + allErrors = validatePrometheusEnabledWhenDefaultKialiEnabled(spec, allErrors) + return NewValidationError(allErrors...) +} + +func (v *versionStrategyV2_5) ValidateDowngrade(ctx context.Context, cl client.Client, smcp metav1.Object) error { + // TODO: what might prevent us from downgrading? + return nil +} + +func (v *versionStrategyV2_5) ValidateUpgrade(ctx context.Context, cl client.Client, smcp metav1.Object) error { + return v.validateServiceMeshExtensionsRemoved(ctx, cl, smcp) +} + +func (v *versionStrategyV2_5) ValidateUpdate(ctx context.Context, cl client.Client, oldSMCPObject, newSMCPObject metav1.Object) error { + oldSMCP, err := toSMCP(oldSMCPObject) + if err != nil { + return err + } + newSMCP, err := toSMCP(newSMCPObject) + if err != nil { + return err + } + + oldClusterScoped, err := v.IsClusterScoped(&oldSMCP.Spec) + if err != nil { + return err + } + newClusterScoped, err := v.IsClusterScoped(&newSMCP.Spec) + if err != nil { + return err + } + if oldClusterScoped != newClusterScoped { + return fmt.Errorf("field spec.mode is immutable; to change its value, delete the ServiceMeshControlPlane and recreate it") + } + return nil +} + +func (v *versionStrategyV2_5) ValidateRequest(ctx context.Context, cl client.Client, req admission.Request, obj metav1.Object) admission.Response { + smcp, err := toSMCP(obj) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + + clusterScoped, err := v.IsClusterScoped(&smcp.Spec) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + if clusterScoped { + // If a user has permission to deploy the control plane in any namespace, we can + // let them create a cluster-scoped control plane. By doing so, we're not opening + // any security issues, since the user could also have created a control plane + // in each namespace separately to get the same information from those namespaces. + isClusterAdmin, err := v.isRequesterAllowedToCreateSMCPInAnyNamespace(ctx, cl, req) + if err != nil { + return admission.Errored(http.StatusInternalServerError, err) + } + if !isClusterAdmin { + return admission.ValidationResponse(false, "a cluster-scoped SMCP may only be created by users with cluster-scoped \"create SMCP\" permissions") + } + } + + return admission.ValidationResponse(true, "") +} + +func (v *versionStrategyV2_5) isRequesterAllowedToCreateSMCPInAnyNamespace(ctx context.Context, cl client.Client, req admission.Request) (bool, error) { + sar := &authorizationv1.SubjectAccessReview{ + Spec: authorizationv1.SubjectAccessReviewSpec{ + User: req.AdmissionRequest.UserInfo.Username, + UID: req.AdmissionRequest.UserInfo.UID, + Extra: common.ConvertUserInfoExtra(req.AdmissionRequest.UserInfo.Extra), + Groups: req.AdmissionRequest.UserInfo.Groups, + ResourceAttributes: &authorizationv1.ResourceAttributes{ + Verb: "create", + Group: "maistra.io", + Resource: "servicemeshcontrolplanes", + }, + }, + } + err := cl.Create(ctx, sar) + if err != nil { + return false, err + } + return sar.Status.Allowed && !sar.Status.Denied, nil +} + +func (v *versionStrategyV2_5) GetChartInstallOrder() [][]string { + return v2_5ChartOrder +} + +// TODO: consider consolidating this with 2.0 rendering logic +func (v *versionStrategyV2_5) Render(ctx context.Context, cr *common.ControllerResources, cniConfig cni.Config, + smcp *v2.ServiceMeshControlPlane, +) (map[string][]manifest.Manifest, error) { + log := common.LogFromContext(ctx) + // Generate the spec + // XXX: we should apply v2 templates first, then convert to values.yaml (v1) + v1smcp := &v1.ServiceMeshControlPlane{} + if err := v1smcp.ConvertFrom(smcp); err != nil { + return nil, err + } + v1spec := &v1smcp.Spec + v1spec.Version = v.String() + + if v1spec.Istio == nil { + v1spec.Istio = v1.NewHelmValues(make(map[string]interface{})) + } + + var err error + smcp.Status.AppliedValues, err = v.ApplyProfiles(ctx, cr, v1spec, smcp.GetNamespace()) + if err != nil { + log.Error(err, "warning: failed to apply ServiceMeshControlPlane profiles") + + return nil, err + } + + spec := &smcp.Status.AppliedValues + + err = spec.Istio.SetField("revision", smcp.GetName()) + if err != nil { + return nil, err + } + + err = spec.Istio.SetField("istio_cni.enabled", cniConfig.Enabled) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.istio_cni.enabled: %v", err) + } + err = spec.Istio.SetField("istio_cni.istio_cni_network", v.GetCNINetworkName()) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.istio_cni.istio_cni_network: %v", err) + } + + // Override these globals to match the install namespace + err = spec.Istio.SetField("global.istioNamespace", smcp.GetNamespace()) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.global.istioNamespace: %v", err) + } + err = spec.Istio.SetField("meshConfig.rootNamespace", smcp.GetNamespace()) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.meshConfig.rootNamespace: %v", err) + } + err = spec.Istio.SetField("global.prometheusNamespace", smcp.GetNamespace()) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.global.prometheusNamespace: %v", err) + } + err = spec.Istio.SetField("global.configRootNamespace", smcp.GetNamespace()) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.global.configRootNamespace: %v", err) + } + err = spec.Istio.SetField("global.configNamespace", smcp.GetNamespace()) + if err != nil { + return nil, fmt.Errorf("could not set field status.lastAppliedConfiguration.istio.global.configNamespace: %v", err) + } + err = spec.Istio.SetField("meshConfig.ingressControllerMode", "OFF") + if err != nil { + return nil, fmt.Errorf("could not set field meshConfig.ingressControllerMode: %v", err) + } + + // XXX: using values.yaml settings, as things may have been overridden in profiles/templates + if isComponentEnabled(spec.Istio, v2_5ChartMapping[TracingChart].enabledField) { + if provider, _, _ := spec.Istio.GetString("tracing.provider"); provider == "jaeger" { + // if we're not installing the jaeger resource, we need to determine what has been installed, + // so control plane rules are created correctly + jaegerResource, _, _ := spec.Istio.GetString("tracing.jaeger.resourceName") + if jaegerResource == "" { + jaegerResource = "jaeger" + } + + // set the correct zipkin address + err = spec.Istio.SetField("meshConfig.defaultConfig.tracing.zipkin.address", fmt.Sprintf("%s-collector.%s.svc:9411", jaegerResource, smcp.GetNamespace())) + if err != nil { + return nil, fmt.Errorf("could not set field istio.meshConfig.defaultConfig.tracing.zipkin.address: %v", err) + } + + jaeger := &jaegerv1.Jaeger{} + jaeger.SetName(jaegerResource) + jaeger.SetNamespace(smcp.GetNamespace()) + if err := cr.Client.Get(ctx, client.ObjectKey{Name: jaeger.GetName(), Namespace: jaeger.GetNamespace()}, jaeger); err == nil { + if metav1.IsControlledBy(jaeger, smcp) { + // we're managing this install, so we'll update it + if err := spec.Istio.SetField("tracing.jaeger.install", true); err != nil { + return nil, fmt.Errorf("error enabling jaeger install") + } + } else { + // if the resource exists, we never overwrite it + if err := spec.Istio.SetField("tracing.jaeger.install", false); err != nil { + return nil, fmt.Errorf("error disabling jaeger install") + } + if strategy, _, _ := jaeger.Spec.GetString("strategy"); strategy == "" || strategy == "allInOne" { + if err := spec.Istio.SetField("tracing.jaeger.template", "all-in-one"); err != nil { + return nil, err + } + } else { + // we just want it to not be all-in-one. see the charts + if err := spec.Istio.SetField("tracing.jaeger.template", "production-elasticsearch"); err != nil { + return nil, err + } + } + } + } else if !errors.IsNotFound(err) { + if meta.IsNoMatchError(err) { + return nil, NewDependencyMissingError("Jaeger CRD", err) + } + return nil, pkgerrors.Wrapf(err, "error retrieving jaeger resource \"%s/%s\"", smcp.GetNamespace(), jaegerResource) + } else if err := spec.Istio.SetField("tracing.jaeger.install", true); err != nil { + return nil, pkgerrors.Wrapf(err, "error enabling jaeger install") + } + } + } + + if isComponentEnabled(spec.Istio, v2_5ChartMapping[PrometheusChart].enabledField) { + roll := &v1.ServiceMeshMemberRoll{} + + err := cr.Client.Get(ctx, types.NamespacedName{Namespace: smcp.GetNamespace(), Name: common.MemberRollName}, roll) + if err != nil { + if errors.IsNotFound(err) { + log.V(2).Info(fmt.Sprintf("memberroll not found in namespace %s", smcp.GetNamespace())) + } else { + return nil, fmt.Errorf("error setting prometheus namespaces: %s", err) + } + } + + namespaces := roll.Status.ConfiguredMembers + + log.Info(fmt.Sprintf("prometheus setting namespaces %v", namespaces)) + + err = spec.Istio.SetStringSlice("prometheus.scrapingNamespaces", namespaces) + + if err != nil { + return nil, fmt.Errorf("error setting field prometheus.scrapingNamespaces: %v", err) + } + + } + + if isComponentEnabled(spec.Istio, v2_5ChartMapping[KialiChart].enabledField) { + kialiResource, _, _ := spec.Istio.GetString("kiali.resourceName") + if kialiResource == "" { + kialiResource = "kiali" + } + kiali := &kialiv1alpha1.Kiali{} + kiali.SetName(kialiResource) + kiali.SetNamespace(smcp.GetNamespace()) + if err := cr.Client.Get(ctx, client.ObjectKey{Name: kiali.GetName(), Namespace: kiali.GetNamespace()}, kiali); err == nil { + if metav1.IsControlledBy(kiali, smcp) { + // we're managing this install, so we'll update it + if err := spec.Istio.SetField("kiali.install", true); err != nil { + return nil, fmt.Errorf("unexpected error disabling kiali install") + } + } else { + if err := spec.Istio.SetField("kiali.install", false); err != nil { + return nil, fmt.Errorf("unexpected error disabling kiali install") + } + } + } else if !errors.IsNotFound(err) { + if meta.IsNoMatchError(err) { + return nil, NewDependencyMissingError("Kiali CRD", err) + } + return nil, pkgerrors.Wrapf(err, "error retrieving kiali resource \"%s/%s\"", smcp.GetNamespace(), kialiResource) + } else if err := spec.Istio.SetField("kiali.install", true); err != nil { + return nil, pkgerrors.Wrapf(err, "error enabling kiali install") + } + } + + // convert back to the v2 type + smcp.Status.AppliedSpec = v2.ControlPlaneSpec{} + err = cr.Scheme.Convert(&smcp.Status.AppliedValues, &smcp.Status.AppliedSpec, nil) + if err != nil { + return nil, fmt.Errorf("unexpected error setting Status.AppliedSpec: %v", err) + } + + // Read in global.yaml + values, err := chartutil.ReadValuesFile(path.Join(v.GetChartsDir(), "global.yaml")) + if err != nil { + return nil, fmt.Errorf("error reading global.yaml file") + } + values.MergeInto(spec.Istio.GetContent()) + if log.V(5).Enabled() { + rawValues, _ := yaml.Marshal(values) + log.V(5).Info(fmt.Sprintf("rendering values:\n%s", string(rawValues))) + } + + // Update spec.Istio back with the previous content merged with global.yaml + spec.Istio = v1.NewHelmValues(values) + + // Validate the final AppliedSpec + err = v.ValidateV2Full(ctx, cr.Client, &smcp.ObjectMeta, &smcp.Status.AppliedSpec) + if err != nil { + return nil, err + } + + if err := validateAndConfigureRLS(spec.Istio); err != nil { + return nil, err + } + + serverVersion, err := cr.DiscoveryClient.ServerVersion() + if err != nil { + return nil, err + } + kubeVersion := serverVersion.String() + + if smcp.Status.AppliedSpec.Mode == v2.ClusterWideMode { + err = v.createMemberRoll(ctx, cr, smcp) + if err != nil { + return nil, err + } + } + + // Render the charts + allErrors := []error{} + renderings := make(map[string][]manifest.Manifest) + log.Info("rendering helm charts") + for name, chartDetails := range v2_5ChartMapping { + if specialCharts.Has(name) { + continue + } + if chartDetails.enabledField == "" || isComponentEnabled(spec.Istio, chartDetails.enabledField) { + log.V(2).Info(fmt.Sprintf("rendering %s chart", name)) + chart := path.Join(v.GetChartsDir(), v2_5ChartMapping[name].path) + if chartRenderings, _, err := helm.RenderChart(chart, smcp.GetNamespace(), kubeVersion, values); err == nil { + if name == "istio-discovery" { + renderings[name] = chartRenderings["istiod"] // quick dirty workaround (istio-discovery chart now has the name "istiod" in Chart.yaml) + } else { + renderings[name] = chartRenderings[name] + } + } else { + allErrors = append(allErrors, err) + } + } else { + log.V(2).Info(fmt.Sprintf("skipping disabled %s chart", name)) + } + } + + if isComponentEnabled(spec.Istio, "gateways") { + log.V(2).Info("rendering gateways charts") + if origGateways, ok := values.AsMap()["gateways"]; ok { + if origGatewaysMap, ok := origGateways.(map[string]interface{}); ok { + ns := &corev1.Namespace{} + if err := cr.Client.Get(ctx, types.NamespacedName{Name: smcp.GetNamespace()}, ns); err == nil { + userIDAutoassigned := ns.Annotations["openshift.io/sa.scc.uid-range"] != "" + + log.V(2).Info("rendering ingress gateway chart for istio-ingressgateway") + if ingressRenderings, _, err := v.renderIngressGateway("istio-ingressgateway", + smcp.GetNamespace(), kubeVersion, origGatewaysMap, spec.Istio, userIDAutoassigned); err == nil { + renderings[GatewayIngressChart] = ingressRenderings[GatewayIngressChart] + } else { + allErrors = append(allErrors, err) + } + log.V(2).Info("rendering egress gateway chart for istio-egressgateway") + if egressRenderings, _, err := v.renderEgressGateway("istio-egressgateway", + smcp.GetNamespace(), kubeVersion, origGatewaysMap, spec.Istio, userIDAutoassigned); err == nil { + renderings[GatewayEgressChart] = egressRenderings[GatewayEgressChart] + } else { + allErrors = append(allErrors, err) + } + if smcp.Spec.Gateways != nil { + for name, gateway := range smcp.Spec.Gateways.IngressGateways { + if gateway.Enabled == nil || !*gateway.Enabled { + continue + } + log.V(2).Info(fmt.Sprintf("rendering ingress gateway chart for %s", name)) + if ingressRenderings, _, err := v.renderIngressGateway(name, smcp.GetNamespace(), kubeVersion, + origGatewaysMap, spec.Istio, userIDAutoassigned); err == nil { + renderings[GatewayIngressChart] = append(renderings[GatewayIngressChart], ingressRenderings[GatewayIngressChart]...) + } else { + allErrors = append(allErrors, err) + } + } + for name, gateway := range smcp.Spec.Gateways.EgressGateways { + if gateway.Enabled == nil || !*gateway.Enabled { + continue + } + log.V(2).Info(fmt.Sprintf("rendering egress gateway chart for %s", name)) + if egressRenderings, _, err := v.renderEgressGateway(name, smcp.GetNamespace(), kubeVersion, + origGatewaysMap, spec.Istio, userIDAutoassigned); err == nil { + renderings[GatewayEgressChart] = append(renderings[GatewayEgressChart], egressRenderings[GatewayEgressChart]...) + } else { + allErrors = append(allErrors, err) + } + } + } + } else { + allErrors = append(allErrors, err) + } + if err := spec.Istio.SetField("gateways", origGateways); err != nil { + allErrors = append(allErrors, err) + } + } + } else { + allErrors = append(allErrors, fmt.Errorf("error retrieving values for gateways charts")) + } + } else { + log.V(2).Info("skipping disabled gateways charts") + } + + if len(allErrors) > 0 { + return nil, utilerrors.NewAggregate(allErrors) + } + + return renderings, nil +} + +func (v *versionStrategyV2_5) renderIngressGateway(name, namespace, kubeVersion string, gateways map[string]interface{}, + values *v1.HelmValues, userIDAutoassigned bool, +) (map[string][]manifest.Manifest, map[string]interface{}, error) { + return v.renderGateway(name, namespace, kubeVersion, v2_5ChartMapping[GatewayIngressChart].path, "istio-ingressgateway", gateways, values, userIDAutoassigned) +} + +func (v *versionStrategyV2_5) renderEgressGateway(name, namespace, kubeVersion string, gateways map[string]interface{}, + values *v1.HelmValues, userIDAutoassigned bool, +) (map[string][]manifest.Manifest, map[string]interface{}, error) { + return v.renderGateway(name, namespace, kubeVersion, v2_5ChartMapping[GatewayEgressChart].path, "istio-egressgateway", gateways, values, userIDAutoassigned) +} + +func (v *versionStrategyV2_5) renderGateway(name, namespace, kubeVersion string, chartPath string, typeName string, + gateways map[string]interface{}, values *v1.HelmValues, userIDAutoassigned bool, +) (map[string][]manifest.Manifest, map[string]interface{}, error) { + gateway, ok, _ := unstructured.NestedMap(gateways, name) + // if 'app' label is not provided, set it to gateway name + if _, found, _ := unstructured.NestedString(gateway, "labels", "app"); !found { + if err := unstructured.SetNestedField(gateway, name, "labels", "app"); err != nil { + return nil, nil, err + } + } + if !ok { + // XXX: return an error? + return map[string][]manifest.Manifest{}, nil, nil + } + if enabled, ok, _ := unstructured.NestedBool(gateway, "enabled"); !(ok && enabled) { + // XXX: return an error? + return map[string][]manifest.Manifest{}, nil, nil + } + if !userIDAutoassigned { + if gateway["runAsUser"] == nil { + gateway["runAsUser"] = "1337" + } + if gateway["runAsGroup"] == nil { + gateway["runAsGroup"] = "1337" + } + if gateway["fsGroup"] == nil { + gateway["fsGroup"] = "1337" + } + } + newGateways := make(map[string]interface{}) + newGateways["revision"] = gateways["revision"] + newGateways[typeName] = gateway + if err := values.SetField("gateways", newGateways); err != nil { + return nil, nil, err + } + return helm.RenderChart(path.Join(v.GetChartsDir(), chartPath), namespace, kubeVersion, values) +} + +func (v *versionStrategyV2_5) GetExpansionPorts() []corev1.ServicePort { + return v.conversionImpl.GetExpansionPorts() +} + +func (v *versionStrategyV2_5) GetTelemetryType(in *v1.HelmValues, mixerTelemetryEnabled, mixerTelemetryEnabledSet, remoteEnabled bool) v2.TelemetryType { + return v.conversionImpl.GetTelemetryType(in, mixerTelemetryEnabled, mixerTelemetryEnabledSet, remoteEnabled) +} + +func (v *versionStrategyV2_5) GetPolicyType(in *v1.HelmValues, mixerPolicyEnabled, mixerPolicyEnabledSet, remoteEnabled bool) v2.PolicyType { + return v.conversionImpl.GetPolicyType(in, mixerPolicyEnabled, mixerPolicyEnabledSet, remoteEnabled) +} + +func (v *versionStrategyV2_5) GetTrustDomainFieldPath() string { + return "meshConfig.trustDomain" +} + +func (v *versionStrategyV2_5) validateGlobal( + ctx context.Context, version Ver, meta *metav1.ObjectMeta, + spec *v2.ControlPlaneSpec, cl client.Client, allErrors []error, +) []error { + if spec.Mode != "" { + if spec.Mode != v2.ClusterWideMode && spec.Mode != v2.MultiTenantMode { + return append(allErrors, + fmt.Errorf("spec.mode must be either %s or %s", + v2.MultiTenantMode, v2.ClusterWideMode)) + } + } else if spec.TechPreview != nil { + if _, found, _ := spec.TechPreview.GetString(v2.TechPreviewControlPlaneModeKey); found { + return append(allErrors, + fmt.Errorf("the spec.techPreview.%s field is not supported in version 2.4+; use spec.mode", + v2.TechPreviewControlPlaneModeKey)) + } + } + + allErrors = checkDiscoverySelectors(spec, allErrors) + return validateGlobal(ctx, version, meta, spec, cl, allErrors) +} + +func (v *versionStrategyV2_5) createMemberRoll(ctx context.Context, cr *common.ControllerResources, smcp *v2.ServiceMeshControlPlane) error { + log := common.LogFromContext(ctx) + + memberRoll := &v1.ServiceMeshMemberRoll{} + err := cr.Client.Get(ctx, client.ObjectKey{Name: common.MemberRollName, Namespace: smcp.Namespace}, memberRoll) + if err != nil { + if !errors.IsNotFound(err) { + return err + } + // MemberRoll doesn't exist, let's create it + memberRoll = &v1.ServiceMeshMemberRoll{ + ObjectMeta: metav1.ObjectMeta{ + Name: common.MemberRollName, + Namespace: smcp.Namespace, + OwnerReferences: []metav1.OwnerReference{ + { + APIVersion: v2.SchemeGroupVersion.String(), + Kind: "ServiceMeshControlPlane", + Name: smcp.Name, + UID: smcp.UID, + Controller: pointer.BoolPtr(true), + }, + }, + }, + Spec: v1.ServiceMeshMemberRollSpec{ + MemberSelectors: []metav1.LabelSelector{ + { + MatchLabels: map[string]string{ + "istio-injection": "enabled", + }, + }, + }, + }, + } + + log.Info("Creating ServiceMeshMemberRoll", "ServiceMeshMemberRoll", common.ToNamespacedName(memberRoll).String()) + err = cr.Client.Create(ctx, memberRoll) + if err != nil && !errors.IsConflict(err) { + return pkgerrors.Wrapf(err, "Could not create ServiceMeshMemberRoll %s/%s", smcp.Namespace, memberRoll.Name) + } + } + return nil +} diff --git a/pkg/controller/versions/versions.go b/pkg/controller/versions/versions.go index 05f01bd86c..9ed9ada46a 100644 --- a/pkg/controller/versions/versions.go +++ b/pkg/controller/versions/versions.go @@ -32,13 +32,14 @@ const ( V2_3 // V2_4 -> v2.4 V2_4 + // V2_5 -> v2.5 + V2_5 // Add new versions here, above lastKnownVersion. Remember to add a string mapping in init() below lastKnownVersion Ver = iota - 1 ) var ( - AllV2Versions = []Version{V2_0, V2_1, V2_2, V2_3, V2_4} - TestedVersions = []Version{V2_2, V2_3, V2_4} + TestedVersions = []Version{V2_3, V2_4, V2_5} legacyVersions = map[string]bool{ "v1.0": true, } @@ -53,6 +54,7 @@ func init() { V2_2: "v2.2", V2_3: "v2.3", V2_4: "v2.4", + V2_5: "v2.5", } versionToStrategy = map[Ver]VersionStrategy{ @@ -63,6 +65,7 @@ func init() { V2_2: &versionStrategyV2_2{Ver: V2_2}, V2_3: &versionStrategyV2_3{Ver: V2_3}, V2_4: &versionStrategyV2_4{Ver: V2_4}, + V2_5: &versionStrategyV2_5{Ver: V2_5}, } versionToCNINetwork = map[Ver]string{ @@ -73,6 +76,7 @@ func init() { V2_2: "v2-2-istio-cni", V2_3: "v2-3-istio-cni", V2_4: "v2-4-istio-cni", + V2_5: "v2-5-istio-cni", } for v, str := range versionToString { diff --git a/resources/helm/overlays/istio_cni/templates/clusterrole-v2.5.yaml b/resources/helm/overlays/istio_cni/templates/clusterrole-v2.5.yaml new file mode 100644 index 0000000000..d7c1d0ce8b --- /dev/null +++ b/resources/helm/overlays/istio_cni/templates/clusterrole-v2.5.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.cni.defaultResourceName }} +rules: + - apiGroups: [""] + resources: + - pods + verbs: + - get + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - 'use' +{{- end }} diff --git a/resources/helm/overlays/istio_cni/templates/clusterrolebinding-v2.5.yaml b/resources/helm/overlays/istio_cni/templates/clusterrolebinding-v2.5.yaml new file mode 100644 index 0000000000..4bad0d3901 --- /dev/null +++ b/resources/helm/overlays/istio_cni/templates/clusterrolebinding-v2.5.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Values.cni.defaultResourceName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Values.cni.defaultResourceName }} +subjects: + - kind: ServiceAccount + name: {{ .Values.cni.defaultResourceName }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/resources/helm/overlays/istio_cni/templates/configmap-v2.5.yaml b/resources/helm/overlays/istio_cni/templates/configmap-v2.5.yaml new file mode 100644 index 0000000000..5fadc35292 --- /dev/null +++ b/resources/helm/overlays/istio_cni/templates/configmap-v2.5.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +# This ConfigMap is used to configure a self-hosted Istio CNI installation. +kind: ConfigMap +apiVersion: v1 +metadata: + name: {{ .Values.cni.defaultResourceName }}-config-v2-5 + namespace: {{ .Release.Namespace }} +data: + # The CNI network configuration to add to the plugin chain on each node. The special + # values in this config will be automatically populated. + cni_network_config: |- + { + "cniVersion": "0.3.1", + "name": "v2-5-istio-cni", + "type": "v2-5-istio-cni", + "log_level": {{ quote .Values.cni.logLevel }}, + "log_uds_address": "__LOG_UDS_ADDRESS__", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } +{{- end }} diff --git a/resources/helm/overlays/istio_cni/templates/daemonset-v2.5.yaml b/resources/helm/overlays/istio_cni/templates/daemonset-v2.5.yaml new file mode 100644 index 0000000000..1b156b47cf --- /dev/null +++ b/resources/helm/overlays/istio_cni/templates/daemonset-v2.5.yaml @@ -0,0 +1,126 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +# This manifest installs the Istio install-cni container, as well +# as the Istio CNI plugin and config on +# each master and worker node in a Kubernetes cluster. +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: istio-cni-node-v2-5 + namespace: {{ .Release.Namespace }} + labels: + k8s-app: istio-cni-node-v2-5 + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + k8s-app: istio-cni-node-v2-5 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + template: + metadata: + labels: + k8s-app: istio-cni-node-v2-5 + release: {{ .Release.Name }} + annotations: + sidecar.istio.io/inject: "false" + # Custom annotations + {{- if .Values.cni.podAnnotations }} +{{ toYaml .Values.cni.podAnnotations | indent 8 }} + {{- end }} + spec: + nodeSelector: + kubernetes.io/os: linux + tolerations: + # Make sure istio-cni-node gets scheduled on all nodes. + - effect: NoSchedule + operator: Exists + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + priorityClassName: system-node-critical + serviceAccountName: {{ .Values.cni.defaultResourceName }} + # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force + # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. + terminationGracePeriodSeconds: 5 +{{- if .Values.cni.imagePullSecrets }} + imagePullSecrets: +{{- range .Values.cni.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} + containers: + # This container installs the Istio CNI binaries + # and CNI network config file on each node. + - name: install-cni + image: "{{ .Values.cni.image_v2_5 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8000 + initialDelaySeconds: 5 + readinessProbe: + httpGet: + path: /readyz + port: 8000 + command: ["install-cni"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_5 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_5 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: {{ .Values.cni.defaultResourceName }}-config-v2-5 + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_5 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-5-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-5-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + - mountPath: /var/run/istio-cni + name: cni-log-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} + volumes: + # Used to install CNI. + - name: cni-bin-dir + hostPath: + path: {{ default "/opt/cni/bin" .Values.cni.cniBinDir }} + - name: etc-cni-dir + hostPath: + path: /etc/cni + # Used for UDS log + - name: cni-log-dir + hostPath: + path: /var/run/istio-cni +{{- end }} diff --git a/resources/helm/overlays/istio_cni/templates/serviceaccount-v2.5.yaml b/resources/helm/overlays/istio_cni/templates/serviceaccount-v2.5.yaml new file mode 100644 index 0000000000..b6ad0c202c --- /dev/null +++ b/resources/helm/overlays/istio_cni/templates/serviceaccount-v2.5.yaml @@ -0,0 +1,7 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.cni.defaultResourceName }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/resources/helm/overlays/maistra-threescale/Chart.yaml b/resources/helm/overlays/maistra-threescale/Chart.yaml deleted file mode 100644 index f5f6b39a8c..0000000000 --- a/resources/helm/overlays/maistra-threescale/Chart.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -name: maistra-threescale -version: 1.1.0 -appVersion: 1.1.0 -tillerVersion: ">=2.7.2-0" -description: Helm chart for Maistra 3scale -keywords: - - maistra - - threescale -sources: - - http://github.com/Maistra/istio-operator -engine: gotpl -icon: https://istio.io/favicons/android-192x192.png diff --git a/resources/helm/overlays/maistra-threescale/templates/_helpers.tpl b/resources/helm/overlays/maistra-threescale/templates/_helpers.tpl deleted file mode 100644 index 1413b0fae8..0000000000 --- a/resources/helm/overlays/maistra-threescale/templates/_helpers.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{{/* vim: set filetype=mustache: */}} -{{/* -Expand the name of the chart. -*/}} -{{- define "threescale.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} -{{- end -}} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "threescale.fullname" -}} -{{- if .Values.fullnameOverride -}} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- $name := default .Chart.Name .Values.nameOverride -}} -{{- if contains $name .Release.Name -}} -{{- .Release.Name | trunc 63 | trimSuffix "-" -}} -{{- else -}} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} -{{- end -}} -{{- end -}} -{{- end -}} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "threescale.chart" -}} -{{- .Chart.Name | trunc 63 | trimSuffix "-" -}} -{{- end -}} diff --git a/resources/helm/overlays/maistra-threescale/templates/deployment.yaml b/resources/helm/overlays/maistra-threescale/templates/deployment.yaml deleted file mode 100644 index 7ab90de203..0000000000 --- a/resources/helm/overlays/maistra-threescale/templates/deployment.yaml +++ /dev/null @@ -1,83 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: 3scale-istio-adapter - chart: {{ template "threescale.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - name: 3scale-istio-adapter - namespace: {{ .Release.Namespace }} -spec: - replicas: 1 - selector: - matchLabels: - app: 3scale-istio-adapter - strategy: - type: RollingUpdate - rollingUpdate: - maxSurge: 25% - maxUnavailable: 25% - template: - metadata: - labels: - app: 3scale-istio-adapter - chart: {{ template "threescale.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - spec: - serviceAccountName: threescale-service-account - containers: - - name: 3scale-istio-adapter -{{- if contains "/" .Values.image }} - image: "{{ .Values.image }}" -{{- else }} - image: "{{ .Values.hub }}/{{ .Values.image }}:{{ .Values.tag }}" -{{- end }} - imagePullPolicy: Always - ports: - - containerPort: {{ .Values.PARAM_THREESCALE_LISTEN_ADDR }} - protocol: TCP - name: adapter - - containerPort: {{ .Values.PARAM_THREESCALE_METRICS_PORT }} - protocol: TCP - name: prometheus - env: - - name: "LISTEN_ADDR" - value: "{{ .Values.PARAM_THREESCALE_LISTEN_ADDR }}" - - name: "LOG_LEVEL" - value: "{{ .Values.PARAM_THREESCALE_LOG_LEVEL }}" - - name: "LOG_JSON" - value: "{{ .Values.PARAM_THREESCALE_LOG_JSON }}" - - name: "LOG_GRPC" - value: "{{ .Values.PARAM_THREESCALE_LOG_GRPC }}" - - name: "REPORT_METRICS" - value: "{{ .Values.PARAM_THREESCALE_REPORT_METRICS }}" - - name: "METRICS_PORT" - value: "{{ .Values.PARAM_THREESCALE_METRICS_PORT }}" - - name: "CACHE_TTL_SECONDS" - value: "{{ .Values.PARAM_THREESCALE_CACHE_TTL_SECONDS }}" - - name: "CACHE_REFRESH_SECONDS" - value: "{{ .Values.PARAM_THREESCALE_CACHE_REFRESH_SECONDS }}" - - name: "CACHE_ENTRIES_MAX" - value: "{{ .Values.PARAM_THREESCALE_CACHE_ENTRIES_MAX }}" - - name: "CACHE_REFRESH_RETRIES" - value: "{{ .Values.PARAM_THREESCALE_CACHE_REFRESH_RETRIES }}" - - name: "ALLOW_INSECURE_CONN" - value: "{{ .Values.PARAM_THREESCALE_ALLOW_INSECURE_CONN }}" - - name: "CLIENT_TIMEOUT_SECONDS" - value: "{{ .Values.PARAM_THREESCALE_CLIENT_TIMEOUT_SECONDS }}" - - name: "GRPC_CONN_MAX_SECONDS" - value: "{{ .Values.PARAM_THREESCALE_GRPC_CONN_MAX_SECONDS }}" - - name: "USE_CACHED_BACKEND" - value: "{{ .Values.PARAM_THREESCALE_USE_CACHED_BACKEND }}" - - name: "BACKEND_CACHE_FLUSH_INTERVAL_SECONDS" - value: "{{ .Values.PARAM_THREESCALE_BACKEND_CACHE_FLUSH_INTERVAL_SECONDS }}" - - name: "BACKEND_CACHE_POLICY_FAIL_CLOSED" - value: "{{ .Values.PARAM_THREESCALE_BACKEND_CACHE_POLICY_FAIL_CLOSED }}" - resources: {} - terminationMessagePath: /dev/termination-log - dnsPolicy: ClusterFirst - restartPolicy: Always - securityContext: {} - terminationGracePeriodSeconds: 30 diff --git a/resources/helm/overlays/maistra-threescale/templates/service.yaml b/resources/helm/overlays/maistra-threescale/templates/service.yaml deleted file mode 100644 index 30d9f66983..0000000000 --- a/resources/helm/overlays/maistra-threescale/templates/service.yaml +++ /dev/null @@ -1,26 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: threescale-istio-adapter - namespace: {{ .Release.Namespace }} - labels: - app: 3scale-istio-adapter - chart: {{ template "threescale.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - annotations: - prometheus.io/scrape: "true" - prometheus.io/scheme: http - prometheus.io/path: /metrics - prometheus.io/port: "{{ .Values.PARAM_THREESCALE_METRICS_PORT }}" -spec: - ports: - - port: {{ .Values.PARAM_THREESCALE_LISTEN_ADDR }} - targetPort: {{ .Values.PARAM_THREESCALE_LISTEN_ADDR }} - name: adapter - - port: {{ .Values.PARAM_THREESCALE_METRICS_PORT }} - targetPort: {{ .Values.PARAM_THREESCALE_METRICS_PORT }} - name: prometheus - selector: - app: 3scale-istio-adapter - clusterIP: None diff --git a/resources/helm/overlays/maistra-threescale/templates/serviceaccount.yaml b/resources/helm/overlays/maistra-threescale/templates/serviceaccount.yaml deleted file mode 100644 index 5cdaa2989f..0000000000 --- a/resources/helm/overlays/maistra-threescale/templates/serviceaccount.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: threescale-service-account - namespace: {{ .Release.Namespace }} - labels: - app: 3scale-istio-adapter - chart: {{ template "threescale.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} diff --git a/resources/helm/overlays/maistra-threescale/templates/threescale-adapter.yaml b/resources/helm/overlays/maistra-threescale/templates/threescale-adapter.yaml deleted file mode 100644 index a6733c4589..0000000000 --- a/resources/helm/overlays/maistra-threescale/templates/threescale-adapter.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# this config is created through command -# mixgen adapter -c $GOPATH/src/istio.io/istio/mixer/adapter/3scale-istio-adapter/config/config.proto_descriptor -o $GOPATH/src/istio.io/istio/mixer/adapter/3scale-istio-adapter/config -s=false -n threescale -t authorization -apiVersion: "config.istio.io/v1alpha2" -kind: adapter -metadata: - name: threescale - namespace: {{ .Release.Namespace }} - labels: - app: 3scale-istio-adapter - chart: {{ template "threescale.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - description: - session_based: false - templates: - - threescale-authorization - config: CvD6AgogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJNChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUi5AQKE0ZpbGVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIYCgdwYWNrYWdlGAIgASgJUgdwYWNrYWdlEh4KCmRlcGVuZGVuY3kYAyADKAlSCmRlcGVuZGVuY3kSKwoRcHVibGljX2RlcGVuZGVuY3kYCiADKAVSEHB1YmxpY0RlcGVuZGVuY3kSJwoPd2Vha19kZXBlbmRlbmN5GAsgAygFUg53ZWFrRGVwZW5kZW5jeRJDCgxtZXNzYWdlX3R5cGUYBCADKAsyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvUgttZXNzYWdlVHlwZRJBCgllbnVtX3R5cGUYBSADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90b1IIZW51bVR5cGUSQQoHc2VydmljZRgGIAMoCzInLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvUgdzZXJ2aWNlEkMKCWV4dGVuc2lvbhgHIAMoCzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90b1IJZXh0ZW5zaW9uEjYKB29wdGlvbnMYCCABKAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNSB29wdGlvbnMSSQoQc291cmNlX2NvZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mb1IOc291cmNlQ29kZUluZm8SFgoGc3ludGF4GAwgASgJUgZzeW50YXgiuQYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRp6Cg5FeHRlbnNpb25SYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQSQAoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnNSB29wdGlvbnMaNwoNUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQifAoVRXh0ZW5zaW9uUmFuZ2VPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAYKFEZpZWxkRGVzY3JpcHRvclByb3RvEhIKBG5hbWUYASABKAlSBG5hbWUSFgoGbnVtYmVyGAMgASgFUgZudW1iZXISQQoFbGFiZWwYBCABKA4yKy5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWxSBWxhYmVsEj4KBHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZVIEdHlwZRIbCgl0eXBlX25hbWUYBiABKAlSCHR5cGVOYW1lEhoKCGV4dGVuZGVlGAIgASgJUghleHRlbmRlZRIjCg1kZWZhdWx0X3ZhbHVlGAcgASgJUgxkZWZhdWx0VmFsdWUSHwoLb25lb2ZfaW5kZXgYCSABKAVSCm9uZW9mSW5kZXgSGwoJanNvbl9uYW1lGAogASgJUghqc29uTmFtZRI3CgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1IHb3B0aW9ucyK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJFRBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyLjAgoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRo7ChFFbnVtUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQigwEKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgCIAEoBVIGbnVtYmVyEjsKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1IHb3B0aW9ucyKnAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj4KBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG9SBm1ldGhvZBI5CgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zUgdvcHRpb25zIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyK5CAoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSNwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZhbHNlUhJwaHBHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2VSDmNjRW5hYmxlQXJlbmFzEioKEW9iamNfY2xhc3NfcHJlZml4GCQgASgJUg9vYmpjQ2xhc3NQcmVmaXgSKQoQY3NoYXJwX25hbWVzcGFjZRglIAEoCVIPY3NoYXJwTmFtZXNwYWNlEiEKDHN3aWZ0X3ByZWZpeBgnIAEoCVILc3dpZnRQcmVmaXgSKAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCVIOcGhwQ2xhc3NQcmVmaXgSIwoNcGhwX25hbWVzcGFjZRgpIAEoCVIMcGhwTmFtZXNwYWNlElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAJKBAgmECci0QIKDk1lc3NhZ2VPcHRpb25zEjwKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZVIUbWVzc2FnZVNldFdpcmVGb3JtYXQSTAofbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2VSHG5vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3ISJQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSGwoJbWFwX2VudHJ5GAcgASgIUghtYXBFbnRyeRJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQICBAJSgQICRAKIuIDCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIZCgR3ZWFrGAogASgIOgVmYWxzZVIEd2VhaxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJKBAgEEAUicwoMT25lb2ZPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiwAEKC0VudW1PcHRpb25zEh8KC2FsbG93X2FsaWFzGAIgASgIUgphbGxvd0FsaWFzEiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYingEKEEVudW1WYWx1ZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKcAQoOU2VydmljZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiLgAgoNTWV0aG9kT3B0aW9ucxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJxChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV05SEGlkZW1wb3RlbmN5TGV2ZWwSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIimgMKE1VuaW50ZXJwcmV0ZWRPcHRpb24SQQoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0UgRuYW1lEikKEGlkZW50aWZpZXJfdmFsdWUYAyABKAlSD2lkZW50aWZpZXJWYWx1ZRIsChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKARSEHBvc2l0aXZlSW50VmFsdWUSLAoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDUhBuZWdhdGl2ZUludFZhbHVlEiEKDGRvdWJsZV92YWx1ZRgGIAEoAVILZG91YmxlVmFsdWUSIQoMc3RyaW5nX3ZhbHVlGAcgASgMUgtzdHJpbmdWYWx1ZRInCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAlSDmFnZ3JlZ2F0ZVZhbHVlGkoKCE5hbWVQYXJ0EhsKCW5hbWVfcGFydBgBIAIoCVIIbmFtZVBhcnQSIQoMaXNfZXh0ZW5zaW9uGAIgAigIUgtpc0V4dGVuc2lvbiKnAgoOU291cmNlQ29kZUluZm8SRAoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25SCGxvY2F0aW9uGs4BCghMb2NhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIWCgRzcGFuGAIgAygFQgIQAVIEc3BhbhIpChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJUg9sZWFkaW5nQ29tbWVudHMSKwoRdHJhaWxpbmdfY29tbWVudHMYBCABKAlSEHRyYWlsaW5nQ29tbWVudHMSOgoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCVIXbGVhZGluZ0RldGFjaGVkQ29tbWVudHMi0QEKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhptCgpBbm5vdGF0aW9uEhYKBHBhdGgYASADKAVCAhABUgRwYXRoEh8KC3NvdXJjZV9maWxlGAIgASgJUgpzb3VyY2VGaWxlEhQKBWJlZ2luGAMgASgFUgViZWdpbhIQCgNlbmQYBCABKAVSA2VuZEKPAQoTY29tLmdvb2dsZS5wcm90b2J1ZkIQRGVzY3JpcHRvclByb3Rvc0gBWj5naXRodWIuY29tL2dvbGFuZy9wcm90b2J1Zi9wcm90b2MtZ2VuLWdvL2Rlc2NyaXB0b3I7ZGVzY3JpcHRvcvgBAaICA0dQQqoCGkdvb2dsZS5Qcm90b2J1Zi5SZWZsZWN0aW9uSqrAAgoHEgUnAOcGAQqqDwoBDBIDJwASMsEMIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAogQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLwoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KCiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogKElOQ0xVRElORyBORUdMSUdF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bm5vdAogc3RvcmUgdGhlIHZhbHVlcyBpbiB0aGVtLiAgSW5zdGVhZCBpdCBzdG9yZXMgdGhlbSBpbiBhIGZpZWxkIGluIHRoZSAqT3B0aW9ucwogbWVzc2FnZSBjYWxsZWQgdW5pbnRlcnByZXRlZF9vcHRpb24uIFRoaXMgZmllbGQgbXVzdCBoYXZlIHRoZSBzYW1lIG5hbWUKIGFjcm9zcyBhbGwgKk9wdGlvbnMgbWVzc2FnZXMuIFdlIHRoZW4gdXNlIHRoaXMgZmllbGQgdG8gcG9wdWxhdGUgdGhlCiBleHRlbnNpb25zIHdoZW4gd2UgYnVpbGQgYSBkZXNjcmlwdG9yLCBhdCB3aGljaCBwb2ludCBhbGwgcHJvdG9zIGhhdmUgYmVlbgogcGFyc2VkIGFuZCBzbyBhbGwgZXh0ZW5zaW9ucyBhcmUga25vd24uCgogRXh0ZW5zaW9uIG51bWJlcnMgZm9yIGN1c3RvbSBvcHRpb25zIG1heSBiZSBjaG9zZW4gYXMgZm9sbG93czoKICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBvbmx5IGJlIHVzZWQgd2l0aGluIGEgc2luZ2xlIGFwcGxpY2F0aW9uIG9yCiAgIG9yZ2FuaXphdGlvbiwgb3IgZm9yIGV4cGVyaW1lbnRhbCBvcHRpb25zLCB1c2UgZmllbGQgbnVtYmVycyA1MDAwMAogICB0aHJvdWdoIDk5OTk5LiAgSXQgaXMgdXAgdG8geW91IHRvIGVuc3VyZSB0aGF0IHlvdSBkbyBub3QgdXNlIHRoZQogICBzYW1lIG51bWJlciBmb3IgbXVsdGlwbGUgb3B0aW9ucy4KICogRm9yIG9wdGlvbnMgd2hpY2ggd2lsbCBiZSBwdWJsaXNoZWQgYW5kIHVzZWQgcHVibGljbHkgYnkgbXVsdGlwbGUKICAgaW5kZXBlbmRlbnQgZW50aXRpZXMsIGUtbWFpbCBwcm90b2J1Zi1nbG9iYWwtZXh0ZW5zaW9uLXJlZ2lzdHJ5QGdvb2dsZS5jb20KICAgdG8gcmVzZXJ2ZSBleHRlbnNpb24gbnVtYmVycy4gU2ltcGx5IHByb3ZpZGUgeW91ciBwcm9qZWN0IG5hbWUgKGUuZy4KICAgT2JqZWN0aXZlLUMgcGx1Z2luKSBhbmQgeW91ciBwcm9qZWN0IHdlYnNpdGUgKGlmIGF2YWlsYWJsZSkgLS0gdGhlcmUncyBubwogICBuZWVkIHRvIGV4cGxhaW4gaG93IHlvdSBpbnRlbmQgdG8gdXNlIHRoZW0uIFVzdWFsbHkgeW91IG9ubHkgbmVlZCBvbmUKICAgZXh0ZW5zaW9uIG51bWJlci4gWW91IGNhbiBkZWNsYXJlIG11bHRpcGxlIG9wdGlvbnMgd2l0aCBvbmx5IG9uZSBleHRlbnNpb24KICAgbnVtYmVyIGJ5IHB1dHRpbmcgdGhlbSBpbiBhIHN1Yi1tZXNzYWdlLiBTZWUgdGhlIEN1c3RvbSBPcHRpb25zIHNlY3Rpb24gb2YKICAgdGhlIGRvY3MgZm9yIGV4YW1wbGVzOgogICBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzL2RvY3MvcHJvdG8jb3B0aW9ucwogICBJZiB0aGlzIHR1cm5zIG91dCB0byBiZSBwb3B1bGFyLCBhIHdlYiBzZXJ2aWNlIHdpbGwgYmUgc2V0IHVwCiAgIHRvIGF1dG9tYXRpY2FsbHkgYXNzaWduIG9wdGlvbiBudW1iZXJzLgoKCwoDBAoBEgS9AggTCvQBCgQECgIAEgTDAgIjGuUBIFNldHMgdGhlIEphdmEgcGFja2FnZSB3aGVyZSBjbGFzc2VzIGdlbmVyYXRlZCBmcm9tIHRoaXMgLnByb3RvIHdpbGwgYmUKIHBsYWNlZC4gIEJ5IGRlZmF1bHQsIHRoZSBwcm90byBwYWNrYWdlIGlzIHVzZWQsIGJ1dCB0aGlzIGlzIG9mdGVuCiBpbmFwcHJvcHJpYXRlIGJlY2F1c2UgcHJvdG8gcGFja2FnZXMgZG8gbm90IG5vcm1hbGx5IHN0YXJ0IHdpdGggYmFja3dhcmRzCiBkb21haW4gbmFtZXMuCgoNCgUECgIABBIEwwICCgoNCgUECgIABRIEwwILEQoNCgUECgIAARIEwwISHgoNCgUECgIAAxIEwwIhIgq/AgoEBAoCARIEywICKxqwAiBJZiBzZXQsIGFsbCB0aGUgY2xhc3NlcyBmcm9tIHRoZSAucHJvdG8gZmlsZSBhcmUgd3JhcHBlZCBpbiBhIHNpbmdsZQogb3V0ZXIgY2xh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CgUAEgSpAw0YCg0KBQQKBQABEgSpAw0RCg0KBQQKBQACEgSpAxUYCgsKAwQKCRIEqwMLDgoMCgQECgkAEgSrAwsNCg0KBQQKCQABEgSrAwsNCg0KBQQKCQACEgSrAwsNCgwKAgQLEgauAwDtAwEKCwoDBAsBEgSuAwgWCtgFCgQECwIAEgTBAwI8GskFIFNldCB0cnVlIHRvIHVzZSB0aGUgb2xkIHByb3RvMSBNZXNzYWdlU2V0IHdpcmUgZm9ybWF0IGZvciBleHRlbnNpb25zLgogVGhpcyBpcyBwcm92aWRlZCBmb3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgTWVzc2FnZVNldCB3aXJlCiBmb3JtYXQuICBZb3Ugc2hvdWxkIG5vdCB1c2UgdGhpcyBmb3IgYW55IG90aGVyIHJlYXNvbjogIEl0J3MgbGVzcwogZWZmaWNpZW50LCBoYXMgZmV3ZXIgZmVhdHVyZXMsIGFuZCBpcyBtb3JlIGNvbXBsaWNhdGVkLgoKIFRoZSBtZXNzYWdlIG11c3QgYmUgZGVmaW5lZCBleGFjdGx5IGFzIGZvbGxvd3M6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOwogICAgIGV4dGVuc2lvbnMgNCB0byBtYXg7CiAgIH0KIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBjYW5ub3QgaGF2ZSBhbnkgZGVmaW5lZCBmaWVsZHM7IE1lc3NhZ2VTZXRzIG9ubHkKIGhhdmUgZXh0ZW5zaW9ucy4KCiBBbGwgZXh0ZW5zaW9ucyBvZiB5b3VyIHR5cGUgbXVzdCBiZSBzaW5ndWxhciBtZXNzYWdlczsgZS5nLiB0aGV5IGNhbm5vdAogYmUgaW50MzJzLCBlbnVtcywgb3IgcmVwZWF0ZWQgbWVzc2FnZXMuCgogQmVjYXVzZSB0aGlzIGlzIGFuIG9wdGlvbiwgdGhlIGFib3ZlIHR3byByZXN0cmljdGlvbnMgYXJlIG5vdCBlbmZvcmNlZCBieQogdGhlIHByb3RvY29sIGNvbXBpbGVyLgoKDQoFBAsCAAQSBMEDAgoKDQoFBAsCAAUSBMEDCw8KDQoFBAsCAAESBMEDECcK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CiBhIG1vcmUgZWZmaWNpZW50IHJlcHJlc2VudGF0aW9uIG9uIHRoZSB3aXJlLiBSYXRoZXIgdGhhbiByZXBlYXRlZGx5CiB3cml0aW5nIHRoZSB0YWcgYW5kIHR5cGUgZm9yIGVhY2ggZWxlbWVudCwgdGhlIGVudGlyZSBhcnJheSBpcyBlbmNvZGVkIGFzCiBhIHNpbmdsZSBsZW5ndGgtZGVsaW1pdGVkIGJsb2IuIEluIHByb3RvMywgb25seSBleHBsaWNpdCBzZXR0aW5nIGl0IHRvCiBmYWxzZSB3aWxsIGF2b2lkIHVzaW5nIHBhY2tlZCBlbmNvZGluZy4KCg0KBQQMAgEEEgSCBAIKCg0KBQQMAgEFEgSCBAsPCg0KBQQMAgEBEgSCBBAWCg0KBQQMAgEDEgSCBBkaCpoFCgQEDAICEgSPBAIzGosFIFRoZSBqc3R5cGUgb3B0aW9uIGRldGVybWluZXMgdGhlIEphdmFTY3JpcHQgdHlwZSB1c2VkIGZvciB2YWx1ZXMgb2YgdGhlCiBmaWVsZC4gIFRoZSBvcHRpb24gaXMgcGVybWl0dGVkIG9ubHkgZm9yIDY0IGJpdCBpbnRlZ3JhbCBhbmQgZml4ZWQgdHlwZXMKIChpbnQ2NCwgdWludDY0LCBzaW50NjQsIGZpeGVkNjQsIHNmaXhlZDY0KS4gIEEgZmllbGQgd2l0aCBqc3R5cGUgSlNfU1RSSU5HCiBpcyByZXByZXNlbnRlZCBhcyBKYXZhU2NyaXB0IHN0cmluZywgd2hpY2ggYXZvaWRzIGxvc3Mgb2YgcHJlY2lzaW9uIHRoYXQKIGNhbiBoYXBwZW4gd2hlbiBhIGxhcmdlIHZhbHVlIGlzIGNvbnZlcnRlZCB0byBhIGZsb2F0aW5nIHBvaW50IEphdmFTY3JpcHQuCiBTcGVjaWZ5aW5nIEpTX05VTUJFUiBmb3IgdGhlIGpzdHlwZSBjYXVzZXMgdGhlIGdlbmVyYXRlZCBKYXZhU2NyaXB0IGNvZGUgdG8KIHVzZSB0aGUgSmF2YVNjcmlwdCAibnVtYmVyIiB0eXBlLiAgVGhlIGJlaGF2aW9yIG9mIHRoZSBkZWZhdWx0IG9wdGlvbgogSlNfTk9STUFMIGlzIGltcGxlbWVudGF0aW9uIGRlcGVuZGVudC4KCiBUaGlzIG9wdGlvbiBpcyBhbiBlbnVtIHRvIHBlcm1pdCBhZGRpdGlvbmFsIHR5cGVzIHRvIGJlIGFkZGVkLCBlLmcuCiBnb29nLm1hdGguSW50ZWdlci4KCg0KBQQMAgIEEgSPBAIKCg0KBQQMAgIGEgSPBAsRCg0KBQQMAgIBEgSPBBIYCg0KBQQMAgIDEgSPBBscCg0KBQQMAgIIEgSPBB0yCg0KBQQMAgIHEgSPBCgxCg4KBAQMBAESBpAEApkEAwoNCgUEDAQBARIEkAQHDQonCgYEDAQBAgASBJIEBBIaFyBVc2UgdGhlIGRlZmF1bHQgdHlwZS4KCg8KBwQMBAECAAESBJIEBA0KDwoHBAwEAQIAAhIEkgQQEQopCgYEDAQBAgESBJUEBBIaGSBVc2UgSmF2YVNjcmlwdCBzdHJpbmdzLgoKDwoHBAwEAQIBARIElQQEDQoPCgcEDAQBAgECEgSVBBARCikKBgQMBAECAhIEmAQEEhoZIFVzZSBKYXZhU2NyaXB0IG51bWJlcnMuCgoPCgcEDAQBAgIBEgSYBAQNCg8KBwQMBAECAgISBJgEEBEK7wwKBAQMAgMSBLcEAika4AwgU2hvdWxkIHRoaXMgZmllbGQgYmUgcGFyc2VkIGxhemlseT8gIExhenkgYXBwbGllcyBvbmx5IHRvIG1lc3NhZ2UtdHlwZQogZmllbGRzLiAgSXQgbWVhbnMgdGhhdCB3aGVuIHRoZSBvdXRlciBtZXNzYWdlIGlzIGluaXRpYWxseSBwYXJzZWQsIHRoZQogaW5uZXIgbWVzc2FnZSdzIGNvbnRlbnRzIHdpbGwgbm90IGJlIHBhcnNlZCBidXQgaW5zdGVhZCBzdG9yZWQgaW4gZW5jb2RlZAogZm9ybS4gIFRoZSBpbm5lciBtZXNzYWdlIHdpbGwgYWN0dWFsbHkgYmUgcGFyc2VkIHdoZW4gaXQgaXMgZmlyc3QgYWNjZXNzZWQuCgogVGhpcyBpcyBvbmx5IGEgaGludC4gIEltcGxlbWVudGF0aW9ucyBhcmUgZnJlZSB0byBjaG9vc2Ugd2hldGhlciB0byB1c2UKIGVhZ2VyIG9yIGxhenkgcGFyc2luZyByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZSBvZiB0aGlzIG9wdGlvbi4gIEhvd2V2ZXIsCiBzZXR0aW5nIHRoaXMgb3B0aW9uIHRydWUgc3VnZ2VzdHMgdGhhdCB0aGUgcHJvdG9jb2wgYXV0aG9yIGJlbGlldmVzIHRoYXQKIHVzaW5nIGxhenkgcGFyc2luZyBvbiB0aGlzIGZpZWxkIGlzIHdvcnRoIHRoZSBhZGRpdGlvbmFsIGJvb2trZWVwaW5nCiBvdmVyaGVhZCB0eXBpY2FsbHkgbmVlZGVkIHRvIGltcGxlbWVudCBpdC4KCiBUaGlzIG9wdGlvbiBkb2VzIG5vdCBhZmZlY3QgdGhlIHB1YmxpYyBpbnRlcmZhY2Ugb2YgYW55IGdlbmVyYXRlZCBjb2RlOwogYWxsIG1ldGhvZCBzaWduYXR1cmVzIHJlbWFpbiB0aGUgc2FtZS4gIEZ1cnRoZXJtb3JlLCB0aHJlYWQtc2FmZXR5IG9mIHRoZQogaW50ZXJmYWNlIGlzIG5vdCBhZmZlY3RlZCBieSB0aGlzIG9wdGlvbjsgY29uc3QgbWV0aG9kcyByZW1haW4gc2FmZSB0bwogY2FsbCBmcm9tIG11bHRpcGxlIHRocmVhZHMgY29uY3VycmVudGx5LCB3aGlsZSBub24tY29uc3QgbWV0aG9kcyBjb250aW51ZQogdG8gcmVxdWlyZSBleGNsdXNpdmUgYWNjZXNzLgoKCiBOb3RlIHRoYXQgaW1wbGVtZW50YXRpb25zIG1heSBjaG9vc2Ugbm90IHRvIGNoZWNrIHJlcXVpcmVkIGZpZWxkcyB3aXRoaW4KIGEgbGF6eSBzdWItbWVzc2FnZS4gIFRoYXQgaXMsIGNhbGxpbmcgSXNJbml0aWFsaXplZCgpIG9uIHRoZSBvdXRlciBtZXNzYWdlCiBtYXkgcmV0dXJuIHRydWUgZXZlbiBpZiB0aGUgaW5uZXIgbWVzc2FnZSBoYXMgbWlzc2luZyByZXF1aXJlZCBmaWVsZHMuCiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIG90aGVyd2lzZSB0aGUgaW5uZXIgbWVzc2FnZSB3b3VsZCBoYXZlIHRvIGJlCiBwYXJzZWQgaW4gb3JkZXIgdG8gcGVyZm9ybSB0aGUgY2hlY2ssIGRlZmVhdGluZyB0aGUgcHVycG9zZSBvZiBsYXp5CiBwYXJzaW5nLiAgQW4gaW1wbGVtZW50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dCByZWNvZ25pemUuIFRoaXMgb25seQogYXBwZWFycyBpbiBvcHRpb25zIHByb3RvcyBjcmVhdGVkIGJ5IHRoZSBjb21waWxlcjo6UGFyc2VyIGNsYXNzLgogRGVzY3JpcHRvclBvb2wgcmVzb2x2ZXMgdGhlc2Ugd2hlbiBidWlsZGluZyBEZXNjcmlwdG9yIG9iamVjdHMuIFRoZXJlZm9yZSwKIG9wdGlvbnMgcHJvdG9zIGluIGRlc2NyaXB0b3Igb2JqZWN0cyAoZS5nLiByZXR1cm5lZCBieSBEZXNjcmlwdG9yOjpvcHRpb25zKCksCiBvciBwcm9kdWNlZCBieSBEZXNjcmlwdG9yOjpDb3B5VG8oKSkgd2lsbCBuZXZlciBoYXZlIFVuaW50ZXJwcmV0ZWRPcHRpb25zCiBpbiB0aGVtLgoKCwoDBBIBEgSxBQgbCssCCgQEEgMAEga3BQK6BQMaugIgVGhlIG5hbWUgb2YgdGhlIHVuaW50ZXJwcmV0ZWQgb3B0aW9uLiAgRWFjaCBzdHJpbmcgcmVwcmVzZW50cyBhIHNlZ21lbnQgaW4KIGEgZG90LXNlcGFyYXRlZCBuYW1lLiAgaXNfZXh0ZW5zaW9uIGlzIHRydWUgaWZmIGEgc2VnbWVudCByZXByZXNlbnRzIGFuCiBleHRlbnNpb24gKGRlbm90ZWQgd2l0aCBwYXJlbnRoZXNlcyBpbiBvcHRpb25zIHNwZWNzIGluIC5wcm90byBmaWxlcykuCiBFLmcuLHsgWyJmb28iLCBmYWxzZV0sIFsiYmFyLmJheiIsIHRydWVdLCBbInF1eCIsIGZhbHNlXSB9IHJlcHJlc2VudHMKICJmb28uKGJhci5iYXopLnF1eCIuCgoNCgUEEgMAARIEtwUKEgoOCgYEEgMAAgASBLgFBCIKDwoHBBIDAAIABBIEuAUEDAoPCgcEEgMAAgAFEgS4BQ0TCg8KBwQSAwACAAESBLgFFB0KDwoHBBIDAAIAAxIEuAUgIQoOCgYEEgMAAgESBLkFBCMKDwoHBBIDAAIBBBIEuQUEDAoPCgcEEgMAAgEFEgS5BQ0RCg8KBwQSAwACAQESBLkFEh4KDwoHBBIDAAIBAxIEuQUhIgoMCgQEEgIAEgS7BQIdCg0KBQQSAgAEEgS7BQIKCg0KBQQSAgAGEgS7BQsTCg0KBQQSAgABEgS7BRQYCg0KBQQSAgADEgS7BRscCpwBCgQEEgIBEgS/BQInGo0BIFRoZSB2YWx1ZSBvZiB0aGUgdW5pbnRlcnByZXRlZCBvcHRpb24sIGluIHdoYXRldmVyIHR5cGUgdGhlIHRva2VuaXplcgogaWRlbnRpZmllZCBpdCBhcyBkdXJpbmcgcGFyc2luZy4gRXhhY3RseSBvbmUgb2YgdGhlc2Ugc2hvdWxkIGJlIHNldC4KCg0KBQQSAgEEEgS/BQIKCg0KBQQSAgEFEgS/BQsRCg0KBQQSAgEBEgS/BRIiCg0KBQQSAgEDEgS/BSUmCgwKBAQSAgISBMAFAikKDQoFBBICAgQSBMAFAgoKDQoFBBICAgUSBMAFCxEKDQoFBBICAgESBMAFEiQKDQoFBBICAgMSBMAFJygKDAoEBBICAxIEwQUCKAoNCgUEEgIDBBIEwQUCCgoNCgUEEgIDBRIEwQULEAoNCgUEEgIDARIEwQURIwoNCgUEEgIDAxIEwQUmJwoMCgQEEgIEEgTCBQIjCg0KBQQSAgQEEgTCBQIKCg0KBQQSAgQFEgTCBQsRCg0KBQQSAgQBEgTCBRIeCg0KBQQSAgQDEgTCBSEiCgwKBAQSAgUSBMMFAiIKDQoFBBICBQQSBMMFAgoKDQoFBBICBQUSBMMFCxAKDQoFBBICBQESBMMFER0KDQoFBBICBQMSBMMFICEKDAoEBBICBhIExAUCJgoNCgUEEgIGBBIExAUCCgoNCgUEEgIGBRIExAULEQoNCgUEEgIGARIExAUSIQoNCgUEEgIGAxIExAUkJQraAQoCBBMSBswFAM0GARpqIEVuY2Fwc3VsYXRlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgb3JpZ2luYWwgc291cmNlIGZpbGUgZnJvbSB3aGljaCBhCiBGaWxlRGVzY3JpcHRvclByb3RvIHdhcyBnZW5lcmF0ZWQuCjJgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIE9wdGlvbmFsIHNvdXJjZSBjb2RlIGluZm8KCgsKAwQTARIEzAUIFgqCEQoEBBMCABIE+AUCIRrzECBBIExvY2F0aW9uIGlkZW50aWZpZXMgYSBwaWVjZSBvZiBzb3VyY2UgY29kZSBpbiBhIC5wcm90byBmaWxlIHdoaWNoCiBjb3JyZXNwb25kcyB0byBhIHBhcnRpY3VsYXIgZGVmaW5pdGlvbi4gIFRoaXMgaW5mb3JtYXRpb24gaXMgaW50ZW5kZWQKIHRvIGJlIHVzZWZ1bCB0byBJREVzLCBjb2RlIGluZGV4ZXJzLCBkb2N1bWVudGF0aW9uIGdlbmVyYXRvcnMsIGFuZCBzaW1pbGFyCiB0b29scy4KCiBGb3IgZXhhbXBsZSwgc2F5IHdlIGhhdmUgYSBmaWxlIGxpa2U6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKICAgfQogTGV0J3MgbG9vayBhdCBqdXN0IHRoZSBmaWVsZCBkZWZpbml0aW9uOgogICBvcHRpb25hbCBzdHJpbmcgZm9vID0gMTsKICAgXiAgICAgICBeXiAgICAgXl4gIF4gIF5eXgogICBhICAgICAgIGJjICAgICBkZSAgZiAgZ2hpCiBXZSBoYXZlIHRoZSBmb2xsb3dpbmcgbG9jYXRpb25zOgogICBzcGFuICAgcGF0aCAgICAgICAgICAgICAgIHJlcHJlc2VudHMKICAgW2EsaSkgIFsgNCwgMCwgMiwgMCBdICAgICBUaGUgd2hvbGUgZmllbGQgZGVmaW5pdGlvbi4KICAgW2EsYikgIFsgNCwgMCwgMiwgMCwgNCBdICBUaGUgbGFiZWwgKG9wdGlvbmFsKS4KICAgW2MsZCkgIFsgNCwgMCwgMiwgMCwgNSBdICBUaGUgdHlwZSAoc3RyaW5nKS4KICAgW2UsZikgIFsgNCwgMCwgMiwgMCwgMSBdICBUaGUgbmFtZSAoZm9vKS4KICAgW2csaCkgIFsgNCwgMCwgMiwgMCwgMyBdICBUaGUgbnVtYmVyICgxKS4KCiBOb3RlczoKIC0gQSBsb2NhdGlvbiBtYXkgcmVmZXIgdG8gYSByZXBlYXRlZCBmaWVsZCBpdHNlbGYgKGkuZS4gbm90IHRvIGFueQogICBwYXJ0aWN1bGFyIGluZGV4IHdpdGhpbiBpdCkuICBUaGlzIGlzIHVzZWQgd2hlbmV2ZXIgYSBzZXQgb2YgZWxlbWVudHMgYXJlCiAgIGxvZ2ljYWxseSBlbmNsb3NlZCBpbiBhIHNpbmdsZSBjb2RlIHNlZ21lbnQuICBGb3IgZXhhbXBsZSwgYW4gZW50aXJlCiAgIGV4dGVuZCBibG9jayAocG9zc2libHkgY29udGFpbmluZyBtdWx0aXBsZSBleHRlbnNpb24gZGVmaW5pdGlvbnMpIHdpbGwKICAgaGF2ZSBhbiBvdXRlciBsb2NhdGlvbiB3aG9zZSBwYXRoIHJlZmVycyB0byB0aGUgImV4dGVuc2lvbnMiIHJlcGVhdGVkCiAgIGZpZWxkIHdpdGhvdXQgYW4gaW5kZXguCiAtIE11bHRpcGxlIGxvY2F0aW9ucyBtYXkgaGF2ZSB0aGUgc2FtZSBwYXRoLiAgVGhpcyBoYXBwZW5zIHdoZW4gYSBzaW5nbGUKICAgbG9naWNhbCBkZWNsYXJhdGlvbiBpcyBzcHJlYWQgb3V0IGFjcm9zcyBtdWx0aXBsZSBwbGFjZXMuICBUaGUgbW9zdAogICBvYnZpb3VzIGV4YW1wbGUgaXMgdGhlICJleHRlbmQiIGJsb2NrIGFnYWluIC0tIHRoZXJlIG1heSBiZSBtdWx0aXBsZQogICBleHRlbmQgYmxvY2tzIGluIHRoZSBzYW1lIHNjb3BlLCBlYWNoIG9mIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBwYXRoLgogLSBBIGxvY2F0aW9uJ3Mgc3BhbiBpcyBub3QgYWx3YXlzIGEgc3Vic2V0IG9mIGl0cyBwYXJlbnQncyBzcGFuLiAgRm9yCiAgIGV4YW1wbGUsIHRoZSAiZXh0ZW5kZWUiIG9mIGFuIGV4dGVuc2lvbiBkZWNsYXJhdGlvbiBhcHBlYXJzIGF0IHRoZQogICBiZWdpbm5pbmcgb2YgdGhlICJleHRlbmQiIGJsb2NrIGFuZCBpcyBzaGFyZWQgYnkgYWxsIGV4dGVuc2lvbnMgd2l0aGluCiAgIHRoZSBibG9jay4KIC0gSnVzdCBiZWNhdXNlIGEgbG9jYXRpb24ncyBzcGFuIGlzIGEgc3Vic2V0IG9mIHNvbWUgb3RoZXIgbG9jYXRpb24ncyBzcGFuCiAgIGRvZXMgbm90IG1lYW4gdGhhdCBpdCBpcyBhIGRlc2NlbmRlbnQuICBGb3IgZXhhbXBsZSwgYSAiZ3JvdXAiIGRlZmluZXMKICAgYm90aCBhIHR5cGUgYW5kIGEgZmllbGQgaW4gYSBzaW5nbGUgZGVjbGFyYXRpb24uICBUaHVzLCB0aGUgbG9jYXRpb25zCiAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUgYW5kIGZpZWxkIGFuZCB0aGVpciBjb21wb25lbnRzIHdpbGwgb3ZlcmxhcC4KIC0gQ29kZSB3aGljaCB0cmllcyB0byBpbnRlcnByZXQgbG9jYXRpb25zIHNob3VsZCBwcm9iYWJseSBiZSBkZXNpZ25lZCB0bwogICBpZ25vcmUgdGhvc2UgdGhhdCBpdCBkb2Vzbid0IHVuZGVyc3RhbmQsIGFzIG1vcmUgdHlwZXMgb2YgbG9jYXRpb25zIGNvdWxkCiAgIGJlIHJlY29yZGVkIGluIHRoZSBmdXR1cmUuCgoNCgUEEwIABBIE+AUCCgoNCgUEEwIABhIE+AULEwoNCgUEEwIAARIE+AUUHAoNCgUEEwIAAxIE+AUfIAoOCgQEEwMAEgb5BQLMBgMKDQoFBBMDAAESBPkFChIKgwcKBgQTAwACABIEkQYEKhryBiBJZGVudGlmaWVzIHdoaWNoIHBhcnQgb2YgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2FzIGRlZmluZWQgYXQgdGhpcwogbG9jYXRpb24uCgogRWFjaCBlbGVtZW50IGlzIGEgZmllbGQgbnVtYmVyIG9yIGFuIGluZGV4LiAgVGhleSBmb3JtIGEgcGF0aCBmcm9tCiB0aGUgcm9vdCBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBwbGFjZSB3aGVyZSB0aGUgZGVmaW5pdGlvbi4gIEZvcgogZXhhbXBsZSwgdGhpcyBwYXRoOgogICBbIDQsIDMsIDIsIDcsIDEgXQogcmVmZXJzIHRvOgogICBmaWxlLm1lc3NhZ2VfdHlwZSgzKSAgLy8gNCwgMwogICAgICAgLmZpZWxkKDcpICAgICAgICAgLy8gMiwgNwogICAgICAgLm5hbWUoKSAgICAgICAgICAgLy8gMQogVGhpcyBpcyBiZWNhdXNlIEZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlIGhhcyBmaWVsZCBudW1iZXIgNDoKICAgcmVwZWF0ZWQgRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CiBhbmQgRGVzY3JpcHRvclByb3RvLmZpZWxkIGhhcyBmaWVsZCBudW1iZXIgMjoKICAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOwogYW5kIEZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUgaGFzIGZpZWxkIG51bWJlciAxOgogICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CgogVGh1cywgdGhlIGFib3ZlIHBhdGggZ2l2ZXMgdGhlIGxvY2F0aW9uIG9mIGEgZmllbGQgbmFtZS4gIElmIHdlIHJlbW92ZWQKIHRoZSBsYXN0IGVsZW1lbnQ6CiAgIFsgNCwgMywgMiwgNyBdCiB0aGlzIHBhdGggcmVmZXJzIHRvIHRoZSB3aG9sZSBmaWVsZCBkZWNsYXJhdGlvbiAoZnJvbSB0aGUgYmVnaW5uaW5nCiBvZiB0aGUgbGFiZWwgdG8gdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbikuCgoPCgcEEwMAAgAEEgSRBgQMCg8KBwQTAwACAAUSBJEGDRIKDwoHBBMDAAIAARIEkQYTFwoPCgcEEwMAAgADEgSRBhobCg8KBwQTAwACAAgSBJEGHCkKEgoKBBMDAAIACOcHABIEkQYdKAoTCgsEEwMAAgAI5wcAAhIEkQYdIwoUCgwEEwMAAgAI5wcAAgASBJEGHSMKFQoNBBMDAAIACOcHAAIAARIEkQYdIwoTCgsEEwMAAgAI5wcAAxIEkQYkKArSAgoGBBMDAAIBEgSYBgQqGsECIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCiBlbmQgbGluZSAob3B0aW9uYWwsIG90aGVyd2lzZSBhc3N1bWVkIHNhbWUgYXMgc3RhcnQgbGluZSksIGVuZCBjb2x1bW4uCiBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQogYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAogMSB0byBlYWNoIGJlZm9yZSBkaXNwbGF5aW5nIHRvIGEgdXNlci4KCg8KBwQTAwACAQQSBJgGBAwKDwoHBBMDAAIBBRIEmAYNEgoPCgcEEwMAAgEBEgSYBhMXCg8KBwQTAwACAQMSBJgGGhsKDwoHBBMDAAIBCBIEmAYcKQoSCgoEEwMAAgEI5wcAEgSYBh0oChMKCwQTAwACAQjnBwACEgSYBh0jChQKDAQTAwACAQjnBwACABIEmAYdIwoVCg0EEwMAAgEI5wcAAgABEgSYBh0jChMKCwQTAwACAQjnBwADEgSYBiQoCqUMCgYEEwMAAgISBMkGBCkalAwgSWYgdGhpcyBTb3VyY2VDb2RlSW5mbyByZXByZXNlbnRzIGEgY29tcGxldGUgZGVjbGFyYXRpb24sIHRoZXNlIGFyZSBhbnkKIGNvbW1lbnRzIGFwcGVhcmluZyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBkZWNsYXJhdGlvbiB3aGljaCBhcHBlYXIgdG8gYmUKIGF0dGFjaGVkIHRvIHRoZSBkZWNsYXJhdGlvbi4KCiBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgogdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCgogbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyB3aWxsIGtlZXAgcGFyYWdyYXBocyBvZiBjb21tZW50cyB0aGF0IGFwcGVhcgogYmVmb3JlIChidXQgbm90IGNvbm5lY3RlZCB0bykgdGhlIGN1cnJlbnQgZWxlbWVudC4gRWFjaCBwYXJhZ3JhcGgsCiBzZXBhcmF0ZWQgYnkgZW1wdHkgbGluZXMsIHdpbGwgYmUgb25lIGNvbW1lbnQgZWxlbWVudCBpbiB0aGUgcmVwZWF0ZWQKIGZpZWxkLgoKIE9ubHkgdGhlIGNvbW1lbnQgY29udGVudCBpcyBwcm92aWRlZDsgY29tbWVudCBtYXJrZXJzIChlLmcuIC8vKSBhcmUKIHN0cmlwcGVkIG91dC4gIEZvciBibG9jayBjb21tZW50cywgbGVhZGluZyB3aGl0ZXNwYWNlIGFuZCBhbiBhc3Rlcmlzawogd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LgogTmV3bGluZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQuCgogRXhhbXBsZXM6CgogICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmFyLgogICBvcHRpb25hbCBpbnQzMiBiYXIgPSAyOwoKICAgb3B0aW9uYWwgc3RyaW5nIGJheiA9IDM7CiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmF6LgogICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgoKICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBxdXguCiAgIC8vCiAgIC8vIEFub3RoZXIgbGluZSBhdHRhY2hlZCB0byBxdXguCiAgIG9wdGlvbmFsIGRvdWJsZSBxdXggPSA0OwoKICAgLy8gRGV0YWNoZWQgY29tbWVudCBmb3IgY29yZ2UuIFRoaXMgaXMgbm90IGxlYWRpbmcgb3IgdHJhaWxpbmcgY29tbWVudHMKICAgLy8gdG8gcXV4IG9yIGNvcmdlIGJlY2F1c2UgdGhlcmUgYXJlIGJsYW5rIGxpbmVzIHNlcGFyYXRpbmcgaXQgZnJvbQogICAvLyBib3RoLgoKICAgLy8gRGV0YWNoZWQgY29tbWVudCBmb3IgY29yZ2UgcGFyYWdyYXBoIDIuCgogICBvcHRpb25hbCBzdHJpbmcgY29yZ2UgPSA1OwogICAvKiBCbG9jayBjb21tZW50IGF0dGFjaGVkCiAgICAqIHRvIGNvcmdlLiAgTGVhZGluZyBhc3Rlcmlza3MKICAgICogd2lsbCBiZSByZW1vdmVkLiAqLwogICAvKiBCbG9jayBjb21tZW50IGF0dGFjaGVkIHRvCiAgICAqIGdyYXVsdC4gKi8KICAgb3B0aW9uYWwgaW50MzIgZ3JhdWx0ID0gNjsKCiAg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bGUucHJvdG9idWYuRW51bU9wdGlvbnMYseQDIAEoCFIRZ29wcm90b0VudW1QcmVmaXg6UgoVZ29wcm90b19lbnVtX3N0cmluZ2VyEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMXkAyABKAhSE2dvcHJvdG9FbnVtU3RyaW5nZXI6QwoNZW51bV9zdHJpbmdlchIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxjG5AMgASgIUgxlbnVtU3RyaW5nZXI6RwoPZW51bV9jdXN0b21uYW1lEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMfkAyABKAlSDmVudW1DdXN0b21uYW1lOjoKCGVudW1kZWNsEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMjkAyABKAhSCGVudW1kZWNsOlYKFGVudW12YWx1ZV9jdXN0b21uYW1lEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY0YMEIAEoCVITZW51bXZhbHVlQ3VzdG9tbmFtZTpOChNnb3Byb3RvX2dldHRlcnNfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJnsAyABKAhSEWdvcHJvdG9HZXR0ZXJzQWxsOlUKF2dvcHJvdG9fZW51bV9wcmVmaXhfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJrsAyABKAhSFGdvcHJvdG9FbnVtUHJlZml4QWxsOlAKFGdvcHJvdG9fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJvsAyABKAhSEmdvcHJvdG9TdHJpbmdlckFsbDpKChF2ZXJib3NlX2VxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxic7AMgASgIUg92ZXJib3NlRXF1YWxBbGw6OQoIZmFjZV9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnewDIAEoCFIHZmFjZUFsbDpBCgxnb3N0cmluZ19hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnuwDIAEoCFILZ29zdHJpbmdBbGw6QQoMcG9wdWxhdGVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJ/sAyABKAhSC3BvcHVsYXRlQWxsOkEKDHN0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxig7AMgASgIUgtzdHJpbmdlckFsbDo/Cgtvbmx5b25lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxih7AMgASgIUgpvbmx5b25lQWxsOjsKCWVxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxil7AMgASgIUghlcXVhbEFsbDpHCg9kZXNjcmlwdGlvbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYpuwDIAEoCFIOZGVzY3JpcHRpb25BbGw6PwoLdGVzdGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYp+wDIAEoCFIKdGVzdGdlbkFsbDpBCgxiZW5jaGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYqOwDIAEoCFILYmVuY2hnZW5BbGw6QwoNbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxip7AMgASgIUgxtYXJzaGFsZXJBbGw6RwoPdW5tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKrsAyABKAhSDnVubWFyc2hhbGVyQWxsOlAKFHN0YWJsZV9tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKvsAyABKAhSEnN0YWJsZU1hcnNoYWxlckFsbDo7CglzaXplcl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYrOwDIAEoCFIIc2l6ZXJBbGw6WQoZZ29wcm90b19lbnVtX3N0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxit7AMgASgIUhZnb3Byb3RvRW51bVN0cmluZ2VyQWxsOkoKEWVudW1fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGK7sAyABKAhSD2VudW1TdHJpbmdlckFsbDpQChR1bnNhZmVfbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiv7AMgASgIUhJ1bnNhZmVNYXJzaGFsZXJBbGw6VAoWdW5zYWZlX3VubWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiw7AMgASgIUhR1bnNhZmVVbm1hcnNoYWxlckFsbDpbChpnb3Byb3RvX2V4dGVuc2lvbnNfbWFwX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxix7AMgASgIUhdnb3Byb3RvRXh0ZW5zaW9uc01hcEFsbDpYChhnb3Byb3RvX3VucmVjb2duaXplZF9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYsuwDIAEoCFIWZ29wcm90b1VucmVjb2duaXplZEFsbDpJChBnb2dvcHJvdG9faW1wb3J0EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLPsAyABKAhSD2dvZ29wcm90b0ltcG9ydDpFCg5wcm90b3NpemVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi07AMgASgIUg1wcm90b3NpemVyQWxsOj8KC2NvbXBhcmVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLXsAyABKAhSCmNvbXBhcmVBbGw6QQoMdHlwZWRlY2xfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLbsAyABKAhSC3R5cGVkZWNsQWxsOkEKDGVudW1kZWNsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi37AMgASgIUgtlbnVtZGVjbEFsbDpRChRnb3Byb3RvX3JlZ2lzdHJhdGlvbhIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi47AMgASgIUhNnb3Byb3RvUmVnaXN0cmF0aW9uOkcKD21lc3NhZ2VuYW1lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi57AMgASgIUg5tZXNzYWdlbmFtZUFsbDpKCg9nb3Byb3RvX2dldHRlcnMSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYgfQDIAEoCFIOZ29wcm90b0dldHRlcnM6TAoQZ29wcm90b19zdHJpbmdlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiD9AMgASgIUg9nb3Byb3RvU3RyaW5nZXI6RgoNdmVyYm9zZV9lcXVhbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiE9AMgASgIUgx2ZXJib3NlRXF1YWw6NQoEZmFjZRIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiF9AMgASgIUgRmYWNlOj0KCGdvc3RyaW5nEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIb0AyABKAhSCGdvc3RyaW5nOj0KCHBvcHVsYXRlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIf0AyABKAhSCHBvcHVsYXRlOj0KCHN0cmluZ2VyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGMCLBCABKAhSCHN0cmluZ2VyOjsKB29ubHlvbmUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYifQDIAEoCFIHb25seW9uZTo3CgVlcXVhbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiN9AMgASgIUgVlcXVhbDpDCgtkZXNjcmlwdGlvbhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiO9AMgASgIUgtkZXNjcmlwdGlvbjo7Cgd0ZXN0Z2VuEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI/0AyABKAhSB3Rlc3RnZW46PQoIYmVuY2hnZW4SHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYkPQDIAEoCFIIYmVuY2hnZW46PwoJbWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJH0AyABKAhSCW1hcnNoYWxlcjpDCgt1bm1hcnNoYWxlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiS9AMgASgIUgt1bm1hcnNoYWxlcjpMChBzdGFibGVfbWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJP0AyABKAhSD3N0YWJsZU1hcnNoYWxlcjo3CgVzaXplchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiU9AMgASgIUgVzaXplcjpMChB1bnNhZmVfbWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJf0AyABKAhSD3Vuc2FmZU1hcnNoYWxlcjpQChJ1bnNhZmVfdW5tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYmPQDIAEoCFIRdW5zYWZlVW5tYXJzaGFsZXI6VwoWZ29wcm90b19leHRlbnNpb25zX21hcBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiZ9AMgASgIUhRnb3Byb3RvRXh0ZW5zaW9uc01hcDpUChRnb3Byb3RvX3VucmVjb2duaXplZBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxia9AMgASgIUhNnb3Byb3RvVW5yZWNvZ25pemVkOkEKCnByb3Rvc2l6ZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnPQDIAEoCFIKcHJvdG9zaXplcjo7Cgdjb21wYXJlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJ30AyABKAhSB2NvbXBhcmU6PQoIdHlwZWRlY2wSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnvQDIAEoCFIIdHlwZWRlY2w6QwoLbWVzc2FnZW5hbWUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYofQDIAEoCFILbWVzc2FnZW5hbWU6OwoIbnVsbGFibGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOn7AyABKAhSCG51bGxhYmxlOjUKBWVtYmVkEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjq+wMgASgIUgVlbWJlZDo/CgpjdXN0b210eXBlEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjr+wMgASgJUgpjdXN0b210eXBlOj8KCmN1c3RvbW5hbWUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOz7AyABKAlSCmN1c3RvbW5hbWU6OQoHanNvbnRhZxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7fsDIAEoCVIHanNvbnRhZzo7Cghtb3JldGFncxIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7vsDIAEoCVIIbW9yZXRhZ3M6OwoIY2FzdHR5cGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGO/7AyABKAlSCGNhc3R0eXBlOjkKB2Nhc3RrZXkSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPD7AyABKAlSB2Nhc3RrZXk6PQoJY2FzdHZhbHVlEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjx+wMgASgJUgljYXN0dmFsdWU6OQoHc3RkdGltZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8vsDIAEoCFIHc3RkdGltZTpBCgtzdGRkdXJhdGlvbhIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8/sDIAEoCFILc3RkZHVyYXRpb25CRQoTY29tLmdvb2dsZS5wcm90b2J1ZkIKR29Hb1Byb3Rvc1oiZ2l0aHViLmNvbS9nb2dvL3Byb3RvYnVmL2dvZ29wcm90b0qaNQoHEgUcAIcBAQr8CgoBDBIDHAASMvEKIFByb3RvY29sIEJ1ZmZlcnMgZm9yIEdvIHdpdGggR2FkZ2V0cwoKIENvcHlyaWdodCAoYykgMjAxMywgVGhlIEdvR28gQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KIGh0dHA6Ly9naXRodWIuY29tL2dvZ28vcHJvdG9idWYKCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgoKIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMKICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IKIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUCiBPV05FUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwKIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLAogREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZCiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklM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 ---- diff --git a/resources/helm/overlays/maistra-threescale/templates/threescale-authorization-template.yaml b/resources/helm/overlays/maistra-threescale/templates/threescale-authorization-template.yaml deleted file mode 100644 index dc1d8bd6af..0000000000 --- a/resources/helm/overlays/maistra-threescale/templates/threescale-authorization-template.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# this config is created through command -# mixgen template -d $GOPATH/src/istio.io/istio/mixer/template/authorization/template_handler_service.descriptor_set -o $GOPATH/src/istio.io/istio/mixer/template/authorization/template.yaml -n authorization -apiVersion: "config.istio.io/v1alpha2" -kind: template -metadata: - name: threescale-authorization - namespace: {{ .Release.Namespace }} - labels: - app: 3scale-istio-adapter - chart: {{ template "threescale.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} -spec: - descriptor: "CsD3AgogZ29vZ2xlL3Byb3RvYnVmL2Rlc2NyaXB0b3IucHJvdG8SD2dvb2dsZS5wcm90b2J1ZiJNChFGaWxlRGVzY3JpcHRvclNldBI4CgRmaWxlGAEgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkZpbGVEZXNjcmlwdG9yUHJvdG9SBGZpbGUi5AQKE0ZpbGVEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIYCgdwYWNrYWdlGAIgASgJUgdwYWNrYWdlEh4KCmRlcGVuZGVuY3kYAyADKAlSCmRlcGVuZGVuY3kSKwoRcHVibGljX2RlcGVuZGVuY3kYCiADKAVSEHB1YmxpY0RlcGVuZGVuY3kSJwoPd2Vha19kZXBlbmRlbmN5GAsgAygFUg53ZWFrRGVwZW5kZW5jeRJDCgxtZXNzYWdlX3R5cGUYBCADKAsyIC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvUgttZXNzYWdlVHlwZRJBCgllbnVtX3R5cGUYBSADKAsyJC5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0b3JQcm90b1IIZW51bVR5cGUSQQoHc2VydmljZRgGIAMoCzInLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlRGVzY3JpcHRvclByb3RvUgdzZXJ2aWNlEkMKCWV4dGVuc2lvbhgHIAMoCzIlLmdvb2dsZS5wcm90b2J1Zi5GaWVsZERlc2NyaXB0b3JQcm90b1IJZXh0ZW5zaW9uEjYKB29wdGlvbnMYCCABKAsyHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnNSB29wdGlvbnMSSQoQc291cmNlX2NvZGVfaW5mbxgJIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5Tb3VyY2VDb2RlSW5mb1IOc291cmNlQ29kZUluZm8SFgoGc3ludGF4GAwgASgJUgZzeW50YXgiuQYKD0Rlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEjsKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvUgVmaWVsZBJDCglleHRlbnNpb24YBiADKAsyJS5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG9SCWV4dGVuc2lvbhJBCgtuZXN0ZWRfdHlwZRgDIAMoCzIgLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG9SCm5lc3RlZFR5cGUSQQoJZW51bV90eXBlGAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG9SCGVudW1UeXBlElgKD2V4dGVuc2lvbl9yYW5nZRgFIAMoCzIvLmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8uRXh0ZW5zaW9uUmFuZ2VSDmV4dGVuc2lvblJhbmdlEkQKCm9uZW9mX2RlY2wYCCADKAsyJS5nb29nbGUucHJvdG9idWYuT25lb2ZEZXNjcmlwdG9yUHJvdG9SCW9uZW9mRGVjbBI5CgdvcHRpb25zGAcgASgLMh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zUgdvcHRpb25zElUKDnJlc2VydmVkX3JhbmdlGAkgAygLMi4uZ29vZ2xlLnByb3RvYnVmLkRlc2NyaXB0b3JQcm90by5SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYCiADKAlSDHJlc2VydmVkTmFtZRp6Cg5FeHRlbnNpb25SYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQSQAoHb3B0aW9ucxgDIAEoCzImLmdvb2dsZS5wcm90b2J1Zi5FeHRlbnNpb25SYW5nZU9wdGlvbnNSB29wdGlvbnMaNwoNUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQifAoVRXh0ZW5zaW9uUmFuZ2VPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIimAYKFEZpZWxkRGVzY3JpcHRvclByb3RvEhIKBG5hbWUYASABKAlSBG5hbWUSFgoGbnVtYmVyGAMgASgFUgZudW1iZXISQQoFbGFiZWwYBCABKA4yKy5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uTGFiZWxSBWxhYmVsEj4KBHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8uVHlwZVIEdHlwZRIbCgl0eXBlX25hbWUYBiABKAlSCHR5cGVOYW1lEhoKCGV4dGVuZGVlGAIgASgJUghleHRlbmRlZRIjCg1kZWZhdWx0X3ZhbHVlGAcgASgJUgxkZWZhdWx0VmFsdWUSHwoLb25lb2ZfaW5kZXgYCSABKAVSCm9uZW9mSW5kZXgSGwoJanNvbl9uYW1lGAogASgJUghqc29uTmFtZRI3CgdvcHRpb25zGAggASgLMh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9uc1IHb3B0aW9ucyK2AgoEVHlwZRIPCgtUWVBFX0RPVUJMRRABEg4KClRZUEVfRkxPQVQQAhIOCgpUWVBFX0lOVDY0EAMSDwoLVFlQRV9VSU5UNjQQBBIOCgpUWVBFX0lOVDMyEAUSEAoMVFlQRV9GSVhFRDY0EAYSEAoMVFlQRV9GSVhFRDMyEAcSDQoJVFlQRV9CT09MEAgSDwoLVFlQRV9TVFJJTkcQCRIOCgpUWVBFX0dST1VQEAoSEAoMVFlQRV9NRVNTQUdFEAsSDgoKVFlQRV9CWVRFUxAMEg8KC1RZUEVfVUlOVDMyEA0SDQoJVFlQRV9FTlVNEA4SEQoNVFlQRV9TRklYRUQzMhAPEhEKDVRZUEVfU0ZJWEVENjQQEBIPCgtUWVBFX1NJTlQzMhAREg8KC1RZUEVfU0lOVDY0EBIiQwoFTGFiZWwSEgoOTEFCRUxfT1BUSU9OQUwQARISCg5MQUJFTF9SRVFVSVJFRBACEhIKDkxBQkVMX1JFUEVBVEVEEAMiYwoUT25lb2ZEZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRI3CgdvcHRpb25zGAIgASgLMh0uZ29vZ2xlLnByb3RvYnVmLk9uZW9mT3B0aW9uc1IHb3B0aW9ucyLjAgoTRW51bURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj8KBXZhbHVlGAIgAygLMikuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZURlc2NyaXB0b3JQcm90b1IFdmFsdWUSNgoHb3B0aW9ucxgDIAEoCzIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9uc1IHb3B0aW9ucxJdCg5yZXNlcnZlZF9yYW5nZRgEIAMoCzI2Lmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3RvLkVudW1SZXNlcnZlZFJhbmdlUg1yZXNlcnZlZFJhbmdlEiMKDXJlc2VydmVkX25hbWUYBSADKAlSDHJlc2VydmVkTmFtZRo7ChFFbnVtUmVzZXJ2ZWRSYW5nZRIUCgVzdGFydBgBIAEoBVIFc3RhcnQSEAoDZW5kGAIgASgFUgNlbmQigwEKGEVudW1WYWx1ZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEhYKBm51bWJlchgCIAEoBVIGbnVtYmVyEjsKB29wdGlvbnMYAyABKAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9uc1IHb3B0aW9ucyKnAQoWU2VydmljZURlc2NyaXB0b3JQcm90bxISCgRuYW1lGAEgASgJUgRuYW1lEj4KBm1ldGhvZBgCIAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG9SBm1ldGhvZBI5CgdvcHRpb25zGAMgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zUgdvcHRpb25zIokCChVNZXRob2REZXNjcmlwdG9yUHJvdG8SEgoEbmFtZRgBIAEoCVIEbmFtZRIdCgppbnB1dF90eXBlGAIgASgJUglpbnB1dFR5cGUSHwoLb3V0cHV0X3R5cGUYAyABKAlSCm91dHB1dFR5cGUSOAoHb3B0aW9ucxgEIAEoCzIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zUgdvcHRpb25zEjAKEGNsaWVudF9zdHJlYW1pbmcYBSABKAg6BWZhbHNlUg9jbGllbnRTdHJlYW1pbmcSMAoQc2VydmVyX3N0cmVhbWluZxgGIAEoCDoFZmFsc2VSD3NlcnZlclN0cmVhbWluZyKzCAoLRmlsZU9wdGlvbnMSIQoMamF2YV9wYWNrYWdlGAEgASgJUgtqYXZhUGFja2FnZRIwChRqYXZhX291dGVyX2NsYXNzbmFtZRgIIAEoCVISamF2YU91dGVyQ2xhc3NuYW1lEjUKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZhbHNlUhFqYXZhTXVsdGlwbGVGaWxlcxJECh1qYXZhX2dlbmVyYXRlX2VxdWFsc19hbmRfaGFzaBgUIAEoCEICGAFSGWphdmFHZW5lcmF0ZUVxdWFsc0FuZEhhc2gSOgoWamF2YV9zdHJpbmdfY2hlY2tfdXRmOBgbIAEoCDoFZmFsc2VSE2phdmFTdHJpbmdDaGVja1V0ZjgSUwoMb3B0aW1pemVfZm9yGAkgASgOMikuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zLk9wdGltaXplTW9kZToFU1BFRURSC29wdGltaXplRm9yEh0KCmdvX3BhY2thZ2UYCyABKAlSCWdvUGFja2FnZRI1ChNjY19nZW5lcmljX3NlcnZpY2VzGBAgASgIOgVmYWxzZVIRY2NHZW5lcmljU2VydmljZXMSOQoVamF2YV9nZW5lcmljX3NlcnZpY2VzGBEgASgIOgVmYWxzZVITamF2YUdlbmVyaWNTZXJ2aWNlcxI1ChNweV9nZW5lcmljX3NlcnZpY2VzGBIgASgIOgVmYWxzZVIRcHlHZW5lcmljU2VydmljZXMSNwoUcGhwX2dlbmVyaWNfc2VydmljZXMYKiABKAg6BWZhbHNlUhJwaHBHZW5lcmljU2VydmljZXMSJQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSLwoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoFZmFsc2VSDmNjRW5hYmxlQXJlbmFzEioKEW9iamNfY2xhc3NfcHJlZml4GCQgASgJUg9vYmpjQ2xhc3NQcmVmaXgSKQoQY3NoYXJwX25hbWVzcGFjZRglIAEoCVIPY3NoYXJwTmFtZXNwYWNlEiEKDHN3aWZ0X3ByZWZpeBgnIAEoCVILc3dpZnRQcmVmaXgSKAoQcGhwX2NsYXNzX3ByZWZpeBgoIAEoCVIOcGhwQ2xhc3NQcmVmaXgSIwoNcGhwX25hbWVzcGFjZRgpIAEoCVIMcGhwTmFtZXNwYWNlElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uIjoKDE9wdGltaXplTW9kZRIJCgVTUEVFRBABEg0KCUNPREVfU0laRRACEhAKDExJVEVfUlVOVElNRRADKgkI6AcQgICAgAIixQIKDk1lc3NhZ2VPcHRpb25zEjwKF21lc3NhZ2Vfc2V0X3dpcmVfZm9ybWF0GAEgASgIOgVmYWxzZVIUbWVzc2FnZVNldFdpcmVGb3JtYXQSTAofbm9fc3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2VSHG5vU3RhbmRhcmREZXNjcmlwdG9yQWNjZXNzb3ISJQoKZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSGwoJbWFwX2VudHJ5GAcgASgIUghtYXBFbnRyeRJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACItwDCgxGaWVsZE9wdGlvbnMSQQoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zLkNUeXBlOgZTVFJJTkdSBWN0eXBlEhYKBnBhY2tlZBgCIAEoCFIGcGFja2VkEkcKBmpzdHlwZRgGIAEoDjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19OT1JNQUxSBmpzdHlwZRIZCgRsYXp5GAUgASgIOgVmYWxzZVIEbGF6eRIlCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBIZCgR3ZWFrGAogASgIOgVmYWxzZVIEd2VhaxJYChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvblITdW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAIicwoMT25lb2ZPcHRpb25zElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIiugEKC0VudW1PcHRpb25zEh8KC2FsbG93X2FsaWFzGAIgASgIUgphbGxvd0FsaWFzEiUKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlUgpkZXByZWNhdGVkElgKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uUhN1bmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAIingEKEEVudW1WYWx1ZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBgBIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiKcAQoOU2VydmljZU9wdGlvbnMSJQoKZGVwcmVjYXRlZBghIAEoCDoFZmFsc2VSCmRlcHJlY2F0ZWQSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICAAiLgAgoNTWV0aG9kT3B0aW9ucxIlCgpkZXByZWNhdGVkGCEgASgIOgVmYWxzZVIKZGVwcmVjYXRlZBJxChFpZGVtcG90ZW5jeV9sZXZlbBgiIAEoDjIvLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zLklkZW1wb3RlbmN5TGV2ZWw6E0lERU1QT1RFTkNZX1VOS05PV05SEGlkZW1wb3RlbmN5TGV2ZWwSWAoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb25SE3VuaW50ZXJwcmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5DWV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVOVBACKgkI6AcQgICAgAIimgMKE1VuaW50ZXJwcmV0ZWRPcHRpb24SQQoEbmFtZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uLk5hbWVQYXJ0UgRuYW1lEikKEGlkZW50aWZpZXJfdmFsdWUYAyABKAlSD2lkZW50aWZpZXJWYWx1ZRIsChJwb3NpdGl2ZV9pbnRfdmFsdWUYBCABKARSEHBvc2l0aXZlSW50VmFsdWUSLAoSbmVnYXRpdmVfaW50X3ZhbHVlGAUgASgDUhBuZWdhdGl2ZUludFZhbHVlEiEKDGRvdWJsZV92YWx1ZRgGIAEoAVILZG91YmxlVmFsdWUSIQoMc3RyaW5nX3ZhbHVlGAcgASgMUgtzdHJpbmdWYWx1ZRInCg9hZ2dyZWdhdGVfdmFsdWUYCCABKAlSDmFnZ3JlZ2F0ZVZhbHVlGkoKCE5hbWVQYXJ0EhsKCW5hbWVfcGFydBgBIAIoCVIIbmFtZVBhcnQSIQoMaXNfZXh0ZW5zaW9uGAIgAigIUgtpc0V4dGVuc2lvbiKnAgoOU291cmNlQ29kZUluZm8SRAoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb25SCGxvY2F0aW9uGs4BCghMb2NhdGlvbhIWCgRwYXRoGAEgAygFQgIQAVIEcGF0aBIWCgRzcGFuGAIgAygFQgIQAVIEc3BhbhIpChBsZWFkaW5nX2NvbW1lbnRzGAMgASgJUg9sZWFkaW5nQ29tbWVudHMSKwoRdHJhaWxpbmdfY29tbWVudHMYBCABKAlSEHRyYWlsaW5nQ29tbWVudHMSOgoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCVIXbGVhZGluZ0RldGFjaGVkQ29tbWVudHMi0QEKEUdlbmVyYXRlZENvZGVJbmZvEk0KCmFubm90YXRpb24YASADKAsyLS5nb29nbGUucHJvdG9idWYuR2VuZXJhdGVkQ29kZUluZm8uQW5ub3RhdGlvblIKYW5ub3RhdGlvbhptCgpBbm5vdGF0aW9uEhYKBHBhdGgYASADKAVCAhABUgRwYXRoEh8KC3NvdXJjZV9maWxlGAIgASgJUgpzb3VyY2VGaWxlEhQKBWJlZ2luGAMgASgFUgViZWdpbhIQCgNlbmQYBCABKAVSA2VuZEJbChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaCmRlc2NyaXB0b3L4AQGiAgNHUEKqAhpHb29nbGUuUHJvdG9idWYuUmVmbGVjdGlvbkrNvQIKBxIFJwDlBgEKqg8KAQwSAycAEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJ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IG1lc3NhZ2UgY2FsbGVkIHVuaW50ZXJwcmV0ZWRfb3B0aW9uLiBUaGlzIGZpZWxkIG11c3QgaGF2ZSB0aGUgc2FtZSBuYW1lCiBhY3Jvc3MgYWxsICpPcHRpb25zIG1lc3NhZ2VzLiBXZSB0aGVuIHVzZSB0aGlzIGZpZWxkIHRvIHBvcHVsYXRlIHRoZQogZXh0ZW5zaW9ucyB3aGVuIHdlIGJ1aWxkIGEgZGVzY3JpcHRvciwgYXQgd2hpY2ggcG9pbnQgYWxsIHByb3RvcyBoYXZlIGJlZW4KIHBhcnNlZCBhbmQgc28gYWxsIGV4dGVuc2lvbnMgYXJlIGtub3duLgoKIEV4dGVuc2lvbiBudW1iZXJzIGZvciBjdXN0b20gb3B0aW9ucyBtYXkgYmUgY2hvc2VuIGFzIGZvbGxvd3M6CiAqIEZvciBvcHRpb25zIHdoaWNoIHdpbGwgb25seSBiZSB1c2VkIHdpdGhpbiBhIHNpbmdsZSBhcHBsaWNhdGlvbiBvcgogICBvcmdhbml6YXRpb24sIG9yIGZvciBleHBlcmltZW50YWwgb3B0aW9ucywgdXNlIGZpZWxkIG51bWJlcnMgNTAwMDAKICAgdGhyb3VnaCA5OTk5OS4gIEl0IGlzIHVwIHRvIHlvdSB0byBlbnN1cmUgdGhhdCB5b3UgZG8gbm90IHVzZSB0aGUKICAgc2FtZSBudW1iZXIgZm9yIG11bHRpcGxlIG9wdGlvbnMuCiAqIEZvciBvcHRpb25zIHdoaWNoIHdpbGwgYmUgcHVibGlzaGVkIGFuZCB1c2VkIHB1YmxpY2x5IGJ5IG11bHRpcGxlCiAgIGluZGVwZW5kZW50IGVudGl0aWVzLCBlLW1haWwgcHJvdG9idWYtZ2xvYmFsLWV4dGVuc2lvbi1yZWdpc3RyeUBnb29nbGUuY29tCiAgIHRvIHJlc2VydmUgZXh0ZW5zaW9uIG51bWJlcnMuIFNpbXBseSBwcm92aWRlIHlvdXIgcHJvamVjdCBuYW1lIChlLmcuCiAgIE9iamVjdGl2ZS1DIHBsdWdpbikgYW5kIHlvdXIgcHJvamVjdCB3ZWJzaXRlIChpZiBhdmFpbGFibGUpIC0tIHRoZXJlJ3Mgbm8KICAgbmVlZCB0byBleHBsYWluIGhvdyB5b3UgaW50ZW5kIHRvIHVzZSB0aGVtLiBVc3VhbGx5IHlvdSBvbmx5IG5lZWQgb25lCiAgIGV4dGVuc2lvbiBudW1iZXIuIFlvdSBjYW4gZGVjbGFyZSBtdWx0aXBsZSBvcHRpb25zIHdpdGggb25seSBvbmUgZXh0ZW5zaW9uCiAgIG51bWJlciBieSBwdXR0aW5nIHRoZW0gaW4gYSBzdWItbWVzc2FnZS4gU2VlIHRoZSBDdXN0b20gT3B0aW9ucyBzZWN0aW9uIG9mCiAgIHRoZSBkb2NzIGZvciBleGFtcGxlczoKICAgaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy9kb2NzL3Byb3RvI29wdGlvbnMKICAgSWYgdGhpcyB0dXJucyBvdXQgdG8gYmUgcG9wdWxhciwgYSB3ZWIgc2VydmljZSB3aWxsIGJlIHNldCB1cAogICB0byBhdXRvbWF0aWNhbGx5IGFzc2lnbiBvcHRpb24gbnVtYmVycy4KCgsKAwQKARIEvQIIEwr0AQoEBAoCABIEwwICIxrlASBTZXRzIHRoZSBKYXZhIHBhY2thZ2Ugd2hlcmUgY2xhc3NlcyBnZW5lcmF0ZWQgZnJvbSB0aGlzIC5wcm90byB3aWxsIGJlCiBwbGFjZWQuICBCeSBkZWZhdWx0LCB0aGUgcHJvdG8gcGFja2FnZSBpcyB1c2VkLCBidXQgdGhpcyBpcyBvZnRlbgogaW5hcHByb3ByaWF0ZSBiZWNhdXNlIHByb3RvIHBhY2thZ2VzIGRvIG5vdCBub3JtYWxseSBzdGFydCB3aXRoIGJhY2t3YXJkcwogZG9tYWluIG5hbWVzLgoKDQoFBAoCAAQSBMMCAgoKDQoFBAoCAAUSBMMCCxEKDQoFBAoCAAESBMMCEh4KDQoFBAoCAAMSBMMCISIKvwIKBAQKAgESBMsCAisasAIgSWYgc2V0LCBhbGwgdGhlIGNsYXNzZXMgZnJvbSB0aGUgLnByb3RvIGZpbGUgYXJlIHdyYXBwZWQgaW4gYSBzaW5nbGUKIG91dGVyIGNsYXNzIHdpdGggdGhlIGdpdmVuIG5hbWUuICBUaGlzIGFwcGxpZXMgdG8gYm90aCBQcm90bzEKIChlcXVpdmFsZW50IHRvIHRoZSBvbGQgIi0tb25lX2phdmFfZmlsZSIgb3B0aW9uKSBhbmQgUHJvdG8yICh3aGVyZQogYSAucHJvdG8gYWx3YXlzIHRyYW5zbGF0ZXMgdG8gYSBzaW5nbGUgY2xhc3MsIGJ1dCB5b3UgbWF5IHdhbnQgdG8KIGV4cGxpY2l0bHkgY2hvb3NlIHRoZSBjbGFzcyBuYW1lKS4KCg0KBQQKAgEEEgTLAgIKCg0KBQQKAgEFEgTLAgsRCg0KBQQKAgEBEgTLAhImCg0KBQQKAgEDEgTLAikqCqMDCgQECgICEgTTAgI5GpQDIElmIHNldCB0cnVlLCB0aGVuIHRoZSBKYXZhIGNvZGUgZ2VuZXJhdG9yIHdpbGwgZ2VuZXJhdGUgYSBzZXBhcmF0ZSAuamF2YQogZmlsZSBmb3IgZWFjaCB0b3AtbGV2ZWwgbWVzc2FnZSwgZW51bSwgYW5kIHNlcnZpY2UgZGVmaW5lZCBpbiB0aGUgLnByb3RvCiBmaWxlLiAgVGh1cywgdGhlc2UgdHlwZXMgd2lsbCAqbm90KiBiZSBuZXN0ZWQgaW5zaWRlIHRoZSBvdXRlciBjbGFzcwogbmFtZWQgYnkgamF2YV9vdXRlcl9jbGFzc25hbWUuICBIb3dldmVyLCB0aGUgb3V0ZXIgY2xhc3Mgd2lsbCBzdGlsbCBiZQogZ2VuZXJhdGVkIHRvIGNvbnRhaW4gdGhlIGZpbGUncyBnZXREZXNjcmlwdG9yKCkgbWV0aG9kIGFzIHdlbGwgYXMgYW55CiB0b3AtbGV2ZWwgZXh0ZW5zaW9ucyBkZWZpbmVkIGluIHRoZSBmaWxlLgoKDQoFBAoCAgQSBNMCAgoKDQoFBAoCAgUSBNMCCw8KDQoFBAoCAgESBNMCECMKDQoFBAoCAgMSBNMCJigKDQoFBAoCAggSBNMCKTgKDQoFBAoCAgcSBNMCMjcKKQoEBAoCAxIE1gICRRobIFRoaXMgb3B0aW9uIGRvZXMgbm90aGluZy4KCg0KBQQKAgMEEgTWAgIKCg0KBQQKAgMFEgTWAgsPCg0KBQQKAgMBEgTWAhAtCg0KBQQKAgMDEgTWAjAyCg0KBQQKAgMIEgTWAjNEChAKCAQKAgMI5wcAEgTWAjRDChEKCQQKAgMI5wcAAhIE1gI0PgoSCgoECgIDCOcHAAIAEgTWAjQ+ChMKCwQKAgMI5wcAAgABEgTWAjQ+ChEKCQQKAgMI5wcAAxIE1gI/QwrmAgoEBAoCBBIE3gICPBrXAiBJZiBzZXQgdHJ1ZSwgdGhlbiB0aGUgSmF2YTIgY29kZSBnZW5lcmF0b3Igd2lsbCBnZW5lcmF0ZSBjb2RlIHRoYXQKIHRocm93cyBhbiBleGNlcHRpb24gd2hlbmV2ZXIgYW4gYXR0ZW1wdCBpcyBtYWRlIHRvIGFzc2lnbiBhIG5vbi1VVEYtOAogYnl0ZSBzZXF1ZW5jZSB0byBhIHN0cmluZyBmaWVsZC4KIE1lc3NhZ2UgcmVmbGVjdGlvbiB3aWxsIGRvIHRoZSBzYW1lLgogSG93ZXZlciwgYW4gZXh0ZW5zaW9uIGZpZWxkIHN0aWxsIGFjY2VwdHMgbm9uLVVURi04IGJ5dGUgc2VxdWVuY2VzLgogVGhpcyBvcHRpb24gaGFzIG5vIGVmZmVjdCBvbiB3aGVuIHVzZWQgd2l0aCB0aGUgbGl0ZSBydW50aW1lLgoKDQoFBAoCBAQSBN4CAgoKDQoFBAoCBAUSBN4CCw8KDQoFBAoCBAESBN4CECYKDQoFBAoCBAMSBN4CKSsKDQoFBAoCBAgSBN4CLDsKDQoFBAoCBAcSBN4CNToKTAoEBAoEABIG4gIC5wIDGjwgR2VuZXJhdGVkIGNsYXNzZXMgY2FuIGJlIG9wdGltaXplZCBmb3Igc3BlZWQgb3IgY29kZSBzaXplLgoKDQoFBAoEAAESBOICBxMKRAoGBAoEAAIAEgTjAgQOIjQgR2VuZXJhdGUgY29tcGxldGUgY29kZSBmb3IgcGFyc2luZywgc2VyaWFsaXphdGlvbiwKCg8KBwQKBAACAAESBOMCBAkKDwoHBAoEAAIAAhIE4wIMDQpHCgYECgQAAgESBOUCBBIaBiBldGMuCiIvIFVzZSBSZWZsZWN0aW9uT3BzIHRvIGltcGxlbWVudCB0aGVzZSBtZXRob2RzLgoKDwoHBAoEAAIBARIE5QIEDQoPCgcECgQAAgECEgTlAhARCkcKBgQKBAACAhIE5gIEFSI3IEdlbmVyYXRlIGNvZGUgdXNpbmcgTWVzc2FnZUxpdGUgYW5kIHRoZSBsaXRlIHJ1bnRpbWUuCgoPCgcECgQAAgIBEgTmAgQQCg8KBwQKBAACAgISBOYCExQKDAoEBAoCBRIE6AICOQoNCgUECgIFBBIE6AICCgoNCgUECgIFBhIE6AILFwoNCgUECgIFARIE6AIYJAoNCgUECgIFAxIE6AInKAoNCgUECgIFCBIE6AIpOAoNCgUECgIFBxIE6AIyNwriAgoEBAoCBhIE7wICIhrTAiBTZXRzIHRoZSBHbyBwYWNrYWdlIHdoZXJlIHN0cnVjdHMgZ2VuZXJhdGVkIGZyb20gdGhpcyAucHJvdG8gd2lsbCBiZQogcGxhY2VkLiBJZiBvbWl0dGVkLCB0aGUgR28gcGFja2FnZSB3aWxsIGJlIGRlcml2ZWQgZnJvbSB0aGUgZm9sbG93aW5nOgogICAtIFRoZSBiYXNlbmFtZSBvZiB0aGUgcGFja2FnZSBpbXBvcnQgcGF0aCwgaWYgcHJvdmlkZWQuCiAgIC0gT3RoZXJ3aXNlLCB0aGUgcGFja2FnZSBzdGF0ZW1lbnQgaW4gdGhlIC5wcm90byBmaWxlLCBpZiBwcmVzZW50LgogICAtIE90aGVyd2lzZSwgdGhlIGJhc2VuYW1lIG9mIHRoZSAucHJvdG8gZmlsZSwgd2l0aG91dCBleHRlbnNpb24uCgoNCgUECgIGBBIE7wICCgoNCgUECgIGBRIE7wILEQoNCgUECgIGARIE7wISHAoNCgUECgIGAxIE7wIfIQrUBAoEBAoCBxIE/QICORrFBCBTaG91bGQgZ2VuZXJpYyBzZXJ2aWNlcyBiZSBnZW5lcmF0ZWQgaW4gZWFjaCBsYW5ndWFnZT8gICJHZW5lcmljIiBzZXJ2aWNlcwogYXJlIG5vdCBzcGVjaWZpYyB0byBhbnkgcGFydGljdWxhciBSUEMgc3lzdGVtLiAgVGhleSBhcmUgZ2VuZXJhdGVkIGJ5IHRoZQogbWFpbiBjb2RlIGdlbmVyYXRvcnMgaW4gZWFjaCBsYW5ndWFnZSAod2l0aG91dCBhZGRpdGlvbmFsIHBsdWdpbnMpLgogR2VuZXJpYyBzZXJ2aWNlcyB3ZXJlIHRoZSBvbmx5IGtpbmQgb2Ygc2VydmljZSBnZW5lcmF0aW9uIHN1cHBvcnRlZCBieQogZWFybHkgdmVyc2lvbnMgb2YgZ29vZ2xlLnByb3RvYnVmLgoKIEdlbmVyaWMgc2VydmljZXMgYXJlIG5vdyBjb25zaWRlcmVkIGRlcHJl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b3IgYmFja3dhcmRzLWNvbXBhdGliaWxpdHkgd2l0aCB0aGUgTWVzc2FnZVNldCB3aXJlCiBmb3JtYXQuICBZb3Ugc2hvdWxkIG5vdCB1c2UgdGhpcyBmb3IgYW55IG90aGVyIHJlYXNvbjogIEl0J3MgbGVzcwogZWZmaWNpZW50LCBoYXMgZmV3ZXIgZmVhdHVyZXMsIGFuZCBpcyBtb3JlIGNvbXBsaWNhdGVkLgoKIFRoZSBtZXNzYWdlIG11c3QgYmUgZGVmaW5lZCBleGFjdGx5IGFzIGZvbGxvd3M6CiAgIG1lc3NhZ2UgRm9vIHsKICAgICBvcHRpb24gbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQgPSB0cnVlOwogICAgIGV4dGVuc2lvbnMgNCB0byBtYXg7CiAgIH0KIE5vdGUgdGhhdCB0aGUgbWVzc2FnZSBjYW5ub3QgaGF2ZSBhbnkgZGVmaW5lZCBmaWVsZHM7IE1lc3NhZ2VTZXRzIG9ubHkKIGhhdmUgZXh0ZW5zaW9ucy4KCiBBbGwgZXh0ZW5zaW9ucyBvZiB5b3VyIHR5cGUgbXVzdCBiZSBzaW5ndWxhciBtZXNzYWdlczsgZS5nLiB0aGV5IGNhbm5vdAogYmUgaW50MzJzLCBlbnVtcywgb3IgcmVwZWF0ZWQgbWVzc2FnZXMuCgogQmVjYXVzZSB0aGlzIGlzIGFuIG9wdGlvbiwgdGhlIGFib3ZlIHR3byByZXN0cmljdGlvbnMgYXJlIG5vdCBlbmZvcmNlZCBieQogdGhlIHByb3RvY29sIGNvbXBpbGVyLgoKDQoFBAsCAAQSBL8DAgoKDQoFBAsCAAUSBL8DCw8KDQoFBAsCAAESBL8DECcKDQoFBAsCAAMSBL8DKisKDQoFBAsCAAgSBL8DLDsKDQoFBAsCAAcSBL8DNToK6wEKBAQLAgESBMQDAkQa3AEgRGlzYWJsZXMgdGhlIGdlbmVyYXRpb24gb2YgdGhlIHN0YW5kYXJkICJkZXNjcmlwdG9yKCkiIGFjY2Vzc29yLCB3aGljaCBjYW4KIGNvbmZsaWN0IHdpdGggYSBmaWVsZCBvZiB0aGUgc2FtZSBuYW1lLiAgVGhpcyBpcyBtZWFudCB0byBtYWtlIG1pZ3JhdGlvbgogZnJvbSBwcm90bzEgZWFzaWVy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GRoKmgUKBAQMAgISBI0EAjMaiwUgVGhlIGpzdHlwZSBvcHRpb24gZGV0ZXJtaW5lcyB0aGUgSmF2YVNjcmlwdCB0eXBlIHVzZWQgZm9yIHZhbHVlcyBvZiB0aGUKIGZpZWxkLiAgVGhlIG9wdGlvbiBpcyBwZXJtaXR0ZWQgb25seSBmb3IgNjQgYml0IGludGVncmFsIGFuZCBmaXhlZCB0eXBlcwogKGludDY0LCB1aW50NjQsIHNpbnQ2NCwgZml4ZWQ2NCwgc2ZpeGVkNjQpLiAgQSBmaWVsZCB3aXRoIGpzdHlwZSBKU19TVFJJTkcKIGlzIHJlcHJlc2VudGVkIGFzIEphdmFTY3JpcHQgc3RyaW5nLCB3aGljaCBhdm9pZHMgbG9zcyBvZiBwcmVjaXNpb24gdGhhdAogY2FuIGhhcHBlbiB3aGVuIGEgbGFyZ2UgdmFsdWUgaXMgY29udmVydGVkIHRvIGEgZmxvYXRpbmcgcG9pbnQgSmF2YVNjcmlwdC4KIFNwZWNpZnlpbmcgSlNfTlVNQkVSIGZvciB0aGUganN0eXBlIGNhdXNlcyB0aGUgZ2VuZXJhdGVkIEphdmFTY3JpcHQgY29kZSB0bwogdXNlIHRoZSBKYXZhU2NyaXB0ICJudW1iZXIiIHR5cGUuICBUaGUgYmVoYXZpb3Igb2YgdGhlIGRlZmF1bHQgb3B0aW9uCiBKU19OT1JNQUwgaXMgaW1wbGVtZW50YXRpb24gZGVwZW5kZW50LgoKIFRoaXMgb3B0aW9uIGlzIGFuIGVudW0gdG8gcGVybWl0IGFkZGl0aW9uYWwgdHlwZXMgdG8gYmUgYWRkZWQsIGUuZy4KIGdvb2cubWF0aC5JbnRlZ2VyLgoKDQoFBAwCAgQSBI0EAgoKDQoFBAwCAgYSBI0ECxEKDQoFBAwCAgESBI0EEhgKDQoFBAwCAgMSBI0EGxwKDQoFBAwCAggSBI0EHTIKDQoFBAwCAgcSBI0EKDEKDgoEBAwEARIGjgQClwQDCg0KBQQMBAEBEgSOBAcNCicKBgQMBAECABIEkAQEEhoXIFVzZSB0aGUgZGVmYXVsdCB0eXBlLgoKDwoHBAwEAQIAARIEkAQEDQoPCgcEDAQBAgACEgSQBBARCikKBgQMBAECARIEkwQEEhoZIFVzZSBKYXZhU2NyaXB0IHN0cmluZ3MuCgoPCgcEDAQBAgEBEgSTBAQNCg8KBwQMBAECAQISBJMEEBEKKQoGBAwEAQICEgSWBAQSGhkgVXNlIEphdmFTY3JpcHQgbnVtYmVycy4KCg8KBwQMBAECAgESBJYEBA0KDwoHBAwEAQICAhIElgQQEQrvDAoEBAwCAxIEtQQCKRrgDCBTaG91bGQgdGhpcyBmaWVsZCBiZSBwYXJzZWQgbGF6aWx5PyAgTGF6eSBhcHBsaWVzIG9ubHkgdG8gbWVzc2FnZS10eXBlCiBmaWVsZHMuICBJdCBtZWFucyB0aGF0IHdoZW4gdGhlIG91dGVyIG1lc3NhZ2UgaXMgaW5pdGlhbGx5IHBhcnNlZCwgdGhlCiBpbm5lciBtZXNzYWdlJ3MgY29udGVudHMgd2lsbCBub3QgYmUgcGFyc2VkIGJ1dCBpbnN0ZWFkIHN0b3JlZCBpbiBlbmNvZGVkCiBmb3JtLiAgVGhlIGlubmVyIG1lc3NhZ2Ugd2lsbCBhY3R1YWxseSBiZSBwYXJzZWQgd2hlbiBpdCBpcyBmaXJzdCBhY2Nlc3NlZC4KCiBUaGlzIGlzIG9ubHkgYSBoaW50LiAgSW1wbGVtZW50YXRpb25zIGFyZSBmcmVlIHRvIGNob29zZSB3aGV0aGVyIHRvIHVzZQogZWFnZXIgb3IgbGF6eSBwYXJzaW5nIHJlZ2FyZGxlc3Mgb2YgdGhlIHZhbHVlIG9mIHRoaXMgb3B0aW9uLiAgSG93ZXZlciwKIHNldHRpbmcgdGhpcyBvcHRpb24gdHJ1ZSBzdWdnZXN0cyB0aGF0IHRoZSBwcm90b2NvbCBhdXRob3IgYmVsaWV2ZXMgdGhhdAogdXNpbmcgbGF6eSBwYXJzaW5nIG9uIHRoaXMgZmllbGQgaXMgd29ydGggdGhlIGFkZGl0aW9uYWwgYm9va2tlZXBpbmcKIG92ZXJoZWFkIHR5cGljYWxseSBuZWVkZWQgdG8gaW1wbGVtZW50IGl0LgoKIFRoaXMgb3B0aW9uIGRvZXMgbm90IGFmZmVjdCB0aGUgcHVibGljIGludGVyZmFjZSBvZiBhbnkgZ2VuZXJhdGVkIGNvZGU7CiBhbGwgbWV0aG9kIHNpZ25hdHVyZXMgcmVtYWluIHRoZSBzYW1lLiAgRnVydGhlcm1vcmUsIHRocmVhZC1zYWZldHkgb2YgdGhlCiBpbnRlcmZhY2UgaXMgbm90IGFmZmVjdGVkIGJ5IHRoaXMgb3B0aW9uOyBjb25zdCBtZXRob2RzIHJlbWFpbiBzYWZlIHRvCiBjYWxsIGZyb20gbXVsdGlwbGUgdGhyZWFkcyBjb25jdXJyZW50bHksIHdoaWxlIG5vbi1jb25zdCBtZXRob2RzIGNvbnRpbnVlCiB0byByZXF1aXJlIGV4Y2x1c2l2ZSBhY2Nlc3MuCgoKIE5vdGUgdGhhdCBpbXBsZW1lbnRhdGlvbnMgbWF5IGNob29zZSBub3QgdG8gY2hlY2sgcmVxdWlyZWQgZmllbGRzIHdpdGhpbgogYSBsYXp5IHN1Yi1tZXNzYWdlLiAgVGhhdCBpcywgY2FsbGluZyBJc0luaXRpYWxpemVkKCkgb24gdGhlIG91dGVyIG1lc3NhZ2UKIG1heSByZXR1cm4gdHJ1ZSBldmVuIGlmIHRoZSBpbm5lciBtZXNzYWdlIGhhcyBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcy4KIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugb3RoZXJ3aXNlIHRoZSBpbm5lciBtZXNzYWdlIHdvdWxkIGhhdmUgdG8gYmUKIHBhcnNlZCBpbiBvcmRlciB0byBwZXJmb3JtIHRoZSBjaGVjaywgZGVmZWF0aW5nIHRoZSBwdXJwb3NlIG9mIGxhenkKIHBhcnNpbmcuICBBbiBpbXBsZW1lbnRhdGlvbiB3aGljaCBjaG9vc2VzIG5vdCB0byBjaGVjayByZXF1aXJlZCBmaWVsZHMKIG11c3QgYmUgY29uc2lzdGVudCBhYm91dCBpdC4gIFRoYXQgaXMsIGZvciBhbnkgcGFydGljdWxhciBzdWItbWVzc2FnZSwgdGhlCiBpbXBsZW1lbnRhdGlvbiBtdXN0IGVpdGhlciAqYWx3YXlzKiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCBvciAqbmV2ZXIqCiBjaGVjayBpdHMgcmVxdWlyZWQgZmllbGRzLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgb3Igbm90IHRoZSBtZXNzYWdlIGhhcwogYmVlbiBwYXJzZWQuCgoNCgUEDAIDBBIEtQQCCgoNCgUEDAIDBRIEtQQL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b2xsb3dpbmcgbG9jYXRpb25zOgogICBzcGFuICAgcGF0aCAgICAgICAgICAgICAgIHJlcHJlc2VudHMKICAgW2EsaSkgIFsgNCwgMCwgMiwgMCBdICAgICBUaGUgd2hvbGUgZmllbGQgZGVmaW5pdGlvbi4KICAgW2EsYikgIFsgNCwgMCwgMiwgMCwgNCBdICBUaGUgbGFiZWwgKG9wdGlvbmFsKS4KICAgW2MsZCkgIFsgNCwgMCwgMiwgMCwgNSBdICBUaGUgdHlwZSAoc3RyaW5nKS4KICAgW2UsZikgIFsgNCwgMCwgMiwgMCwgMSBdICBUaGUgbmFtZSAoZm9vKS4KICAgW2csaCkgIFsgNCwgMCwgMiwgMCwgMyBdICBUaGUgbnVtYmVyICgxKS4KCiBOb3RlczoKIC0gQSBsb2NhdGlvbiBtYXkgcmVmZXIgdG8gYSByZXBlYXRlZCBmaWVsZCBpdHNlbGYgKGkuZS4gbm90IHRvIGFueQogICBwYXJ0aWN1bGFyIGluZGV4IHdpdGhpbiBpdCkuICBUaGlzIGlzIHVzZWQgd2hlbmV2ZXIgYSBzZXQgb2YgZWxlbWVudHMgYXJlCiAgIGxvZ2ljYWxseSBlbmNsb3NlZCBpbiBhIHNpbmdsZSBjb2RlIHNlZ21lbnQuICBGb3IgZXhhbXBsZSwgYW4gZW50aXJlCiAgIGV4dGVuZCBibG9jayAocG9zc2libHkgY29udGFpbmluZyBtdWx0aXBsZSBleHRlbnNpb24gZGVmaW5pdGlvbnMpIHdpbGwKICAgaGF2ZSBhbiBvdXRlciBsb2NhdGlvbiB3aG9zZSBwYXRoIHJlZmVycyB0byB0aGUgImV4dGVuc2lvbnMiIHJlcGVhdGVkCiAgIGZpZWxkIHdpdGhvdXQgYW4gaW5kZXguCiAtIE11bHRpcGxlIGxvY2F0aW9ucyBtYXkgaGF2ZSB0aGUgc2FtZSBwYXRoLiAgVGhpcyBoYXBwZW5zIHdoZW4gYSBzaW5nbGUKICAgbG9naWNhbCBkZWNsYXJhdGlvbiBpcyBzcHJlYWQgb3V0IGFjcm9zcyBtdWx0aXBsZSBwbGFjZXMuICBUaGUgbW9zdAogICBvYnZpb3VzIGV4YW1wbGUgaXMgdGhlICJleHRlbmQiIGJsb2NrIGFnYWluIC0tIHRoZXJlIG1heSBiZSBtdWx0aXBsZQogICBleHRlbmQgYmxvY2tzIGluIHRoZSBzYW1lIHNjb3BlLCBlYWNoIG9mIHdoaWNoIHdpbGwgaGF2ZSB0aGUgc2FtZSBwYXRoLgogLSBBIGxvY2F0aW9uJ3Mgc3BhbiBpcyBub3QgYWx3YXlzIGEgc3Vic2V0IG9mIGl0cyBwYXJlbnQncyBzcGFuLiAgRm9yCiAgIGV4YW1wbGUsIHRoZSAiZXh0ZW5kZWUiIG9mIGFuIGV4dGVuc2lvbiBkZWNsYXJhdGlvbiBhcHBlYXJzIGF0IHRoZQogICBiZWdpbm5pbmcgb2YgdGhlICJleHRlbmQiIGJsb2NrIGFuZCBpcyBzaGFyZWQgYnkgYWxsIGV4dGVuc2lvbnMgd2l0aGluCiAgIHRoZSBibG9jay4KIC0gSnVzdCBiZWNhdXNlIGEgbG9jYXRpb24ncyBzcGFuIGlzIGEgc3Vic2V0IG9mIHNvbWUgb3RoZXIgbG9jYXRpb24ncyBzcGFuCiAgIGRvZXMgbm90IG1lYW4gdGhhdCBpdCBpcyBhIGRlc2NlbmRlbnQuICBGb3IgZXhhbXBsZSwgYSAiZ3JvdXAiIGRlZmluZXMKICAgYm90aCBhIHR5cGUgYW5kIGEgZmllbGQgaW4gYSBzaW5nbGUgZGVjbGFyYXRpb24uICBUaHVzLCB0aGUgbG9jYXRpb25zCiAgIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHR5cGUgYW5kIGZpZWxkIGFuZCB0aGVpciBjb21wb25lbnRzIHdpbGwgb3ZlcmxhcC4KIC0gQ29kZSB3aGljaCB0cmllcyB0byBpbnRlcnByZXQgbG9jYXRpb25zIHNob3VsZCBwcm9iYWJseSBiZSBkZXNpZ25lZCB0bwogICBpZ25vcmUgdGhvc2UgdGhhdCBpdCBkb2Vzbid0IHVuZGVyc3RhbmQsIGFzIG1vcmUgdHlwZXMgb2YgbG9jYXRpb25zIGNvdWxkCiAgIGJlIHJlY29yZGVkIGluIHRoZSBmdXR1cmUuCgoNCgUEEwIABBIE9gUCCgoNCgUEEwIABhIE9gULEwoNCgUEEwIAARIE9gUUHAoNCgUEEwIAAxIE9gUfIAoOCgQEEwMAEgb3BQLKBgMKDQoFBBMDAAESBPcFChIKgwcKBgQTAwACABIEjwYEKhryBiBJZGVudGlmaWVzIHdoaWNoIHBhcnQgb2YgdGhlIEZpbGVEZXNjcmlwdG9yUHJvdG8gd2FzIGRlZmluZWQgYXQgdGhpcwogbG9jYXRpb24uCgogRWFjaCBlbGVtZW50IGlzIGEgZmllbGQgbnVtYmVyIG9yIGFuIGluZGV4LiAgVGhleSBmb3JtIGEgcGF0aCBmcm9tCiB0aGUgcm9vdCBGaWxlRGVzY3JpcHRvclByb3RvIHRvIHRoZSBwbGFjZSB3aGVyZSB0aGUgZGVmaW5pdGlvbi4gIEZvcgogZXhhbXBsZSwgdGhpcyBwYXRoOgogICBbIDQsIDMsIDIsIDcsIDEgXQogcmVmZXJzIHRvOgogICBmaWxlLm1lc3NhZ2VfdHlwZSgzKSAgLy8gNCwgMwogICAgICAgLmZpZWxkKDcpICAgICAgICAgLy8gMiwgNwogICAgICAgLm5hbWUoKSAgICAgICAgICAgLy8gMQogVGhpcyBpcyBiZWNhdXNlIEZpbGVEZXNjcmlwdG9yUHJvdG8ubWVzc2FnZV90eXBlIGhhcyBmaWVsZCBudW1iZXIgNDoKICAgcmVwZWF0ZWQgRGVzY3JpcHRvclByb3RvIG1lc3NhZ2VfdHlwZSA9IDQ7CiBhbmQgRGVzY3JpcHRvclByb3RvLmZpZWxkIGhhcyBmaWVsZCBudW1iZXIgMjoKICAgcmVwZWF0ZWQgRmllbGREZXNjcmlwdG9yUHJvdG8gZmllbGQgPSAyOwogYW5kIEZpZWxkRGVzY3JpcHRvclByb3RvLm5hbWUgaGFzIGZpZWxkIG51bWJlciAxOgogICBvcHRpb25hbCBzdHJpbmcgbmFtZSA9IDE7CgogVGh1cywgdGhlIGFib3ZlIHBhdGggZ2l2ZXMgdGhlIGxvY2F0aW9uIG9mIGEgZmllbGQgbmFtZS4gIElmIHdlIHJlbW92ZWQKIHRoZSBsYXN0IGVsZW1lbnQ6CiAgIFsgNCwgMywgMiwgNyBdCiB0aGlzIHBhdGggcmVmZXJzIHRvIHRoZSB3aG9sZSBmaWVsZCBkZWNsYXJhdGlvbiAoZnJvbSB0aGUgYmVnaW5uaW5nCiBvZiB0aGUgbGFiZWwgdG8gdGhlIHRlcm1pbmF0aW5nIHNlbWljb2xvbikuCgoPCgcEEwMAAgAEEgSPBgQMCg8KBwQTAwACAAUSBI8GDRIKDwoHBBMDAAIAARIEjwYTFwoPCgcEEwMAAgADEgSPBhobCg8KBwQTAwACAAgSBI8GHCkKEgoKBBMDAAIACOcHABIEjwYdKAoTCgsEEwMAAgAI5wcAAhIEjwYdIwoUCgwEEwMAAgAI5wcAAgASBI8GHSMKFQoNBBMDAAIACOcHAAIAARIEjwYdIwoTCgsEEwMAAgAI5wcAAxIEjwYkKArSAgoGBBMDAAIBEgSWBgQqGsECIEFsd2F5cyBoYXMgZXhhY3RseSB0aHJlZSBvciBmb3VyIGVsZW1lbnRzOiBzdGFydCBsaW5lLCBzdGFydCBjb2x1bW4sCiBlbmQgbGluZSAob3B0aW9uYWwsIG90aGVyd2lzZSBhc3N1bWVkIHNhbWUgYXMgc3RhcnQgbGluZSksIGVuZCBjb2x1bW4uCiBUaGVzZSBhcmUgcGFja2VkIGludG8gYSBzaW5nbGUgZmllbGQgZm9yIGVmZmljaWVuY3kuICBOb3RlIHRoYXQgbGluZQogYW5kIGNvbHVtbiBudW1iZXJzIGFyZSB6ZXJvLWJhc2VkIC0tIHR5cGljYWxseSB5b3Ugd2lsbCB3YW50IHRvIGFkZAogMSB0byBlYWNoIGJlZm9yZSBkaXNwbGF5aW5nIHRvIGEgdXNlci4KCg8KBwQTAwACAQQSBJYGBAwKDwoHBBMDAAIBBRIElgYNEgoPCgcEEwMAAgEBEgSWBhMXCg8KBwQTAwACAQMSBJYGGhsKDwoHBBMDAAIBCBIElgYcKQoSCgoEEwMAAgEI5wcAEgSWBh0oChMKCwQTAwACAQjnBwACEgSWBh0jChQKDAQTAwACAQjnBwACABIElgYdIwoVCg0EEwMAAgEI5wcAAgABEgSWBh0jChMKCwQTAwACAQjnBwADEgSWBiQoCqUMCgYEEwMAAgISBMcGBCkalAwgSWYgdGhpcyBTb3VyY2VDb2RlSW5mbyByZXByZXNlbnRzIGEgY29tcGxldGUgZGVjbGFyYXRpb24sIHRoZXNlIGFyZSBhbnkKIGNvbW1lbnRzIGFwcGVhcmluZyBiZWZvcmUgYW5kIGFmdGVyIHRoZSBkZWNsYXJhdGlvbiB3aGljaCBhcHBlYXIgdG8gYmUKIGF0dGFjaGVkIHRvIHRoZSBkZWNsYXJhdGlvbi4KCiBBIHNlcmllcyBvZiBsaW5lIGNvbW1lbnRzIGFwcGVhcmluZyBvbiBjb25zZWN1dGl2ZSBsaW5lcywgd2l0aCBubyBvdGhlcgogdG9rZW5zIGFwcGVhcmluZyBvbiB0aG9zZSBsaW5lcywgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2luZ2xlIGNvbW1lbnQuCgogbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cyB3aWxsIGtlZXAgcGFyYWdyYXBocyBvZiBjb21tZW50cyB0aGF0IGFwcGVhcgogYmVmb3JlIChidXQgbm90IGNvbm5lY3RlZCB0bykgdGhlIGN1cnJlbnQgZWxlbWVudC4gRWFjaCBwYXJhZ3JhcGgsCiBzZXBhcmF0ZWQgYnkgZW1wdHkgbGluZXMsIHdpbGwgYmUgb25lIGNvbW1lbnQgZWxlbWVudCBpbiB0aGUgcmVwZWF0ZWQKIGZpZWxkLgoKIE9ubHkgdGhlIGNvbW1lbnQgY29udGVudCBpcyBwcm92aWRlZDsgY29tbWVudCBtYXJrZXJzIChlLmcuIC8vKSBhcmUKIHN0cmlwcGVkIG91dC4gIEZvciBibG9jayBjb21tZW50cywgbGVhZGluZyB3aGl0ZXNwYWNlIGFuZCBhbiBhc3Rlcmlzawogd2lsbCBiZSBzdHJpcHBlZCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgZWFjaCBsaW5lIG90aGVyIHRoYW4gdGhlIGZpcnN0LgogTmV3bGluZXMgYXJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQuCgogRXhhbXBsZXM6CgogICBvcHRpb25hbCBpbnQzMiBmb28gPSAxOyAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBmb28uCiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmFyLgogICBvcHRpb25hbCBpbnQzMiBiYXIgPSAyOwoKICAgb3B0aW9uYWwgc3RyaW5nIGJheiA9IDM7CiAgIC8vIENvbW1lbnQgYXR0YWNoZWQgdG8gYmF6LgogICAvLyBBbm90aGVyIGxpbmUgYXR0YWNoZWQgdG8gYmF6LgoKICAgLy8gQ29tbWVudCBhdHRhY2hlZCB0byBxdXguCiAgIC8vCiAgIC8v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ZCBvYmplY3QuCgoPCgcEFAMAAgIEEgTeBgQMCg8KBwQUAwACAgUSBN4GDRIKDwoHBBQDAAICARIE3gYTGAoPCgcEFAMAAgIDEgTeBhscCtsBCgYEFAMAAgMSBOMGBBsaygEgSWRlbnRpZmllcyB0aGUgZW5kaW5nIG9mZnNldCBpbiBieXRlcyBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUgdGhhdAogcmVsYXRlcyB0byB0aGUgaWRlbnRpZmllZCBvZmZzZXQuIFRoZSBlbmQgb2Zmc2V0IHNob3VsZCBiZSBvbmUgcGFzdAogdGhlIGxhc3QgcmVsZXZhbnQgYnl0ZSAoc28gdGhlIGxlbmd0aCBvZiB0aGUgdGV4dCA9IGVuZCAtIGJlZ2luKS4KCg8KBwQUAwACAwQSBOMGBAwKDwoHBBQDAAIDBRIE4wYNEgoPCgcEFAMAAgMBEgTjBhMWCg8KBwQUAwACAwMSBOMGGRoK/loKFGdvZ29wcm90by9nb2dvLnByb3RvEglnb2dvcHJvdG8aIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvOk4KE2dvcHJvdG9fZW51bV9wcmVmaXgSHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMYseQDIAEoCFIRZ29wcm90b0VudW1QcmVmaXg6UgoVZ29wcm90b19lbnVtX3N0cmluZ2VyEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMXkAyABKAhSE2dvcHJvdG9FbnVtU3RyaW5nZXI6QwoNZW51bV9zdHJpbmdlchIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9ucxjG5AMgASgIUgxlbnVtU3RyaW5nZXI6RwoPZW51bV9jdXN0b21uYW1lEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMfkAyABKAlSDmVudW1DdXN0b21uYW1lOjoKCGVudW1kZWNsEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1PcHRpb25zGMjkAyABKAhSCGVudW1kZWNsOlYKFGVudW12YWx1ZV9jdXN0b21uYW1lEiEuZ29vZ2xlLnByb3RvYnVmLkVudW1WYWx1ZU9wdGlvbnMY0YMEIAEoCVITZW51bXZhbHVlQ3VzdG9tbmFtZTpOChNnb3Byb3RvX2dldHRlcnNfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJnsAyABKAhSEWdvcHJvdG9HZXR0ZXJzQWxsOlUKF2dvcHJvdG9fZW51bV9wcmVmaXhfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJrsAyABKAhSFGdvcHJvdG9FbnVtUHJlZml4QWxsOlAKFGdvcHJvdG9fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJvsAyABKAhSEmdvcHJvdG9TdHJpbmdlckFsbDpKChF2ZXJib3NlX2VxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxic7AMgASgIUg92ZXJib3NlRXF1YWxBbGw6OQoIZmFjZV9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnewDIAEoCFIHZmFjZUFsbDpBCgxnb3N0cmluZ19hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYnuwDIAEoCFILZ29zdHJpbmdBbGw6QQoMcG9wdWxhdGVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGJ/sAyABKAhSC3BvcHVsYXRlQWxsOkEKDHN0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxig7AMgASgIUgtzdHJpbmdlckFsbDo/Cgtvbmx5b25lX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxih7AMgASgIUgpvbmx5b25lQWxsOjsKCWVxdWFsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxil7AMgASgIUghlcXVhbEFsbDpHCg9kZXNjcmlwdGlvbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYpuwDIAEoCFIOZGVzY3JpcHRpb25BbGw6PwoLdGVzdGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYp+wDIAEoCFIKdGVzdGdlbkFsbDpBCgxiZW5jaGdlbl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYqOwDIAEoCFILYmVuY2hnZW5BbGw6QwoNbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxip7AMgASgIUgxtYXJzaGFsZXJBbGw6RwoPdW5tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKrsAyABKAhSDnVubWFyc2hhbGVyQWxsOlAKFHN0YWJsZV9tYXJzaGFsZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGKvsAyABKAhSEnN0YWJsZU1hcnNoYWxlckFsbDo7CglzaXplcl9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYrOwDIAEoCFIIc2l6ZXJBbGw6WQoZZ29wcm90b19lbnVtX3N0cmluZ2VyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxit7AMgASgIUhZnb3Byb3RvRW51bVN0cmluZ2VyQWxsOkoKEWVudW1fc3RyaW5nZXJfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGK7sAyABKAhSD2VudW1TdHJpbmdlckFsbDpQChR1bnNhZmVfbWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiv7AMgASgIUhJ1bnNhZmVNYXJzaGFsZXJBbGw6VAoWdW5zYWZlX3VubWFyc2hhbGVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxiw7AMgASgIUhR1bnNhZmVVbm1hcnNoYWxlckFsbDpbChpnb3Byb3RvX2V4dGVuc2lvbnNfbWFwX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxix7AMgASgIUhdnb3Byb3RvRXh0ZW5zaW9uc01hcEFsbDpYChhnb3Byb3RvX3VucmVjb2duaXplZF9hbGwSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYsuwDIAEoCFIWZ29wcm90b1VucmVjb2duaXplZEFsbDpJChBnb2dvcHJvdG9faW1wb3J0EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLPsAyABKAhSD2dvZ29wcm90b0ltcG9ydDpFCg5wcm90b3NpemVyX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi07AMgASgIUg1wcm90b3NpemVyQWxsOj8KC2NvbXBhcmVfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLXsAyABKAhSCmNvbXBhcmVBbGw6QQoMdHlwZWRlY2xfYWxsEhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGLbsAyABKAhSC3R5cGVkZWNsQWxsOkEKDGVudW1kZWNsX2FsbBIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi37AMgASgIUgtlbnVtZGVjbEFsbDpRChRnb3Byb3RvX3JlZ2lzdHJhdGlvbhIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxi47AMgASgIUhNnb3Byb3RvUmVnaXN0cmF0aW9uOkoKD2dvcHJvdG9fZ2V0dGVycxIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiB9AMgASgIUg5nb3Byb3RvR2V0dGVyczpMChBnb3Byb3RvX3N0cmluZ2VyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIP0AyABKAhSD2dvcHJvdG9TdHJpbmdlcjpGCg12ZXJib3NlX2VxdWFsEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIT0AyABKAhSDHZlcmJvc2VFcXVhbDo1CgRmYWNlEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGIX0AyABKAhSBGZhY2U6PQoIZ29zdHJpbmcSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYhvQDIAEoCFIIZ29zdHJpbmc6PQoIcG9wdWxhdGUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYh/QDIAEoCFIIcG9wdWxhdGU6PQoIc3RyaW5nZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYwIsEIAEoCFIIc3RyaW5nZXI6OwoHb25seW9uZRIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiJ9AMgASgIUgdvbmx5b25lOjcKBWVxdWFsEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI30AyABKAhSBWVxdWFsOkMKC2Rlc2NyaXB0aW9uEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGI70AyABKAhSC2Rlc2NyaXB0aW9uOjsKB3Rlc3RnZW4SHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYj/QDIAEoCFIHdGVzdGdlbjo9CghiZW5jaGdlbhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiQ9AMgASgIUghiZW5jaGdlbjo/CgltYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYkfQDIAEoCFIJbWFyc2hhbGVyOkMKC3VubWFyc2hhbGVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJL0AyABKAhSC3VubWFyc2hhbGVyOkwKEHN0YWJsZV9tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYk/QDIAEoCFIPc3RhYmxlTWFyc2hhbGVyOjcKBXNpemVyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJT0AyABKAhSBXNpemVyOkwKEHVuc2FmZV9tYXJzaGFsZXISHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYl/QDIAEoCFIPdW5zYWZlTWFyc2hhbGVyOlAKEnVuc2FmZV91bm1hcnNoYWxlchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiY9AMgASgIUhF1bnNhZmVVbm1hcnNoYWxlcjpXChZnb3Byb3RvX2V4dGVuc2lvbnNfbWFwEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJn0AyABKAhSFGdvcHJvdG9FeHRlbnNpb25zTWFwOlQKFGdvcHJvdG9fdW5yZWNvZ25pemVkEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJr0AyABKAhSE2dvcHJvdG9VbnJlY29nbml6ZWQ6QQoKcHJvdG9zaXplchIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxic9AMgASgIUgpwcm90b3NpemVyOjsKB2NvbXBhcmUSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYnfQDIAEoCFIHY29tcGFyZTo9Cgh0eXBlZGVjbBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxie9AMgASgIUgh0eXBlZGVjbDo7CghudWxsYWJsZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY6fsDIAEoCFIIbnVsbGFibGU6NQoFZW1iZWQSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOr7AyABKAhSBWVtYmVkOj8KCmN1c3RvbXR5cGUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGOv7AyABKAlSCmN1c3RvbXR5cGU6PwoKY3VzdG9tbmFtZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7PsDIAEoCVIKY3VzdG9tbmFtZTo5Cgdqc29udGFnEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjt+wMgASgJUgdqc29udGFnOjsKCG1vcmV0YWdzEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxju+wMgASgJUghtb3JldGFnczo7CghjYXN0dHlwZRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY7/sDIAEoCVIIY2FzdHR5cGU6OQoHY2FzdGtleRIdLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMY8PsDIAEoCVIHY2FzdGtleTo9CgljYXN0dmFsdWUSHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGPH7AyABKAlSCWNhc3R2YWx1ZTo5CgdzdGR0aW1lEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjy+wMgASgIUgdzdGR0aW1lOkEKC3N0ZGR1cmF0aW9uEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxjz+wMgASgIUgtzdGRkdXJhdGlvbkJFChNjb20uZ29vZ2xlLnByb3RvYnVmQgpHb0dvUHJvdG9zWiJnaXRodWIuY29tL2dvZ28vcHJvdG9idWYvZ29nb3Byb3RvSv0zCgcSBRwAhAEBCvwKCgEMEgMcABIy8QogUHJvdG9jb2wgQnVmZmVycyBmb3IgR28gd2l0aCBHYWRnZXRzCgogQ29weXJpZ2h0IChjKSAyMDEzLCBUaGUgR29HbyBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cDovL2dpdGh1Yi5jb20vZ29nby9wcm90b2J1ZgoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9S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ARIDfhggCgoKAwdAAxIDfiMoCgkKAgdBEgN/CCgKCgoDB0ECEgN3ByMKCgoDB0EEEgN/CBAKCgoDB0EFEgN/ERcKCgoDB0EBEgN/GB8KCgoDB0EDEgN/IicKCgoCB0ISBIABCCoKCgoDB0ICEgN3ByMKCwoDB0IEEgSAAQgQCgsKAwdCBRIEgAERFwoLCgMHQgESBIABGCEKCwoDB0IDEgSAASQpCgoKAgdDEgSCAQgmCgoKAwdDAhIDdwcjCgsKAwdDBBIEggEIEAoLCgMHQwUSBIIBERUKCwoDB0MBEgSCARYdCgsKAwdDAxIEggEgJQoKCgIHRBIEgwEIKgoKCgMHRAISA3cHIwoLCgMHRAQSBIMBCBAKCwoDB0QFEgSDAREVCgsKAwdEARIEgwEWIQoLCgMHRAMSBIMBJCkKixUKLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvEiFpc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEaIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnByb3RvKpABCg9UZW1wbGF0ZVZhcmlldHkSGgoWVEVNUExBVEVfVkFSSUVUWV9DSEVDSxAAEhsKF1RFTVBMQVRFX1ZBUklFVFlfUkVQT1JUEAESGgoWVEVNUExBVEVfVkFSSUVUWV9RVU9UQRACEigKJFRFTVBMQVRFX1ZBUklFVFlfQVRUUklCVVRFX0dFTkVSQVRPUhADOn4KEHRlbXBsYXRlX3ZhcmlldHkSHC5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlvbnMYr8q8IiABKA4yMi5pc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEuVGVtcGxhdGVWYXJpZXR5Ug90ZW1wbGF0ZVZhcmlldHk6RAoNdGVtcGxhdGVfbmFtZRIcLmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxjQy7wiIAEoCVIMdGVtcGxhdGVOYW1lQipaKGlzdGlvLmlvL2FwaS9taXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTFKiBEKBhIEDgAvAQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIKQoICgEIEgMSAD0KCwoECOcHABIDEgA9CgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEjwKCQoCAwASAxQHKQp5CgIFABIEGAAlARptIFRoZSBhdmFpbGFibGUgdmFyaWV0aWVzIG9mIHRlbXBsYXRlcywgY29udHJvbGxpbmcgdGhlIHNlbWFudGljcyBvZiB3aGF0IGFuIGFkYXB0ZXIgZG9lcyB3aXRoIGVhY2ggaW5zdGFuY2UuCgoKCgMFAAESAxgFFArIAQoEBQACABIDGwQfGroBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIGNoZWNrIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHJlcG9ydCBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgABEgMbBBoKDAoFBQACAAISAxsdHgrIAQoEBQACARIDHgQgGroBIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHJlcG9ydCBjYWxscy4gSW5zdGFuY2VzIG9mIHN1Y2ggdGVtcGxhdGUgYXJlIGNyZWF0ZWQgZHVyaW5nCiBjaGVjayBjYWxscyBpbiBNaXhlciBhbmQgcGFzc2VkIHRvIHRoZSBoYW5kbGVycyBiYXNlZCBvbiB0aGUgcnVsZSBjb25maWd1cmF0aW9ucy4KCgwKBQUAAgEBEgMeBBsKDAoFBQACAQISAx4eHwrNAQoEBQACAhIDIQQfGr8BIE1ha2VzIHRoZSB0ZW1wbGF0ZSBhcHBsaWNhYmxlIGZvciBNaXhlcidzIHF1b3RhIGNhbGxzLiBJbnN0YW5jZXMgb2Ygc3VjaCB0ZW1wbGF0ZSBhcmUgY3JlYXRlZCBkdXJpbmcKIHF1b3RhIGNoZWNrIGNhbGxzIGluIE1peGVyIGFuZCBwYXNzZWQgdG8gdGhlIGhhbmRsZXJzIGJhc2VkIG9uIHRoZSBydWxlIGNvbmZpZ3VyYXRpb25zLgoKDAoFBQACAgESAyEEGgoMCgUFAAICAhIDIR0eCusBCgQFAAIDEgMkBC0a3QEgTWFrZXMgdGhlIHRlbXBsYXRlIGFwcGxpY2FibGUgZm9yIE1peGVyJ3MgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UuIEluc3RhbmNlcyBvZiBzdWNoIHRlbXBsYXRlIGFyZSBjcmVhdGVkIGR1cmluZwogcHJlLXByb2Nlc3NpbmcgYXR0cmlidXRlIGdlbmVyYXRpb24gcGhhc2UgYW5kIHBhc3NlZCB0byB0aGUgaGFuZGxlcnMgYmFzZWQgb24gdGhlIHJ1bGUgY29uZmlndXJhdGlvbnMuCgoMCgUFAAIDARIDJAQoCgwKBQUAAgMCEgMkKywKMQoBBxIEKAAvARomIEZpbGUgbGV2ZWwgb3B0aW9ucyBmb3IgdGhlIHRlbXBsYXRlLgoKNgoCBwASAyoEMBorIFJlcXVpcmVkOiBvcHRpb24gZm9yIHRoZSBUZW1wbGF0ZVZhcmlldHkuCgoKCgMHAAISAygHIgoLCgMHAAQSBCoEKCQKCgoDBwAGEgMqBBMKCgoDBwABEgMqFCQKCgoDBwADEgMqJy8KpAEKAgcBEgMuBCQamAEgT3B0aW9uYWw6IG9wdGlvbiBmb3IgdGhlIHRlbXBsYXRlIG5hbWUuCiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSB0ZW1wbGF0ZSBwcm90bydzIHBhY2thZ2UgbmFtZSBpcyB1c2VkIHRvCiBkZXJpdmUgdGhlIHRlbXBsYXRlIG5hbWUuCgoKCgMHAQISAygHIgoLCgMHAQQSBC4EKjAKCgoDBwEFEgMuBAoKCgoDBwEBEgMuCxgKCgoDBwEDEgMuGyNiBnByb3RvMwq8LAoZZ29vZ2xlL3Byb3RvYnVmL2FueS5wcm90bxIPZ29vZ2xlLnByb3RvYnVmIjYKA0FueRIZCgh0eXBlX3VybBgBIAEoCVIHdHlwZVVybBIUCgV2YWx1ZRgCIAEoDFIFdmFsdWVCTwoTY29tLmdvb2dsZS5wcm90b2J1ZkIIQW55UHJvdG9QAVoFdHlwZXOiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNK/CoKBxIFHgCUAQEKzAwKAQwSAx4AEjLBDCBQcm90b2NvbCBCdWZmZXJzIC0gR29vZ2xlJ3MgZGF0YSBpbnRlcmNoYW5nZSBmb3JtYXQKIENvcHlyaWdodCAyMDA4IEdvb2dsZSBJbmMuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vcHJvdG9jb2wtYnVmZmVycy8KCiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUKIG1ldDoKCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLgogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lcgogaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZQogZGlzdHJpYnV0aW9uLgogICAgICogTmVpdGhlciB0aGUgbmFtZSBvZiBHb29nbGUgSW5jLiBub3IgdGhlIG5hbWVzIG9mIGl0cwogY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cyBkZXJpdmVkIGZyb20KIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4KCggKAQISAyAIFwoICgEIEgMiADsKCwoECOcHABIDIgA7CgwKBQjnBwACEgMiBxcKDQoGCOcHAAIAEgMiBxcKDgoHCOcHAAIAARIDIgcXCgwKBQjnBwAHEgMiGjoKCAoBCBIDIwAcCgsKBAjnBwESAyMAHAoMCgUI5wcBAhIDIwcRCg0KBgjnBwECABIDIwcRCg4KBwjnBwECAAESAyMHEQoMCgUI5wcBBxIDIxQbCggKAQgSAyQALAoLCgQI5wcCEgMkACwKDAoFCOcHAgISAyQHEwoNCgYI5wcCAgASAyQHEwoOCgcI5wcCAgABEgMkBxMKDAoFCOcHAgcSAyQWKwoICgEIEgMlACkKCwoECOcHAxIDJQApCgwKBQjnBwMCEgMlBxsKDQoGCOcHAwIAEgMlBxsKDgoHCOcHAwIAARIDJQcbCgwKBQjnBwMHEgMlHigKCAoBCBIDJgAiCgsKBAjnBwQSAyYAIgoMCgUI5wcEAhIDJgcaCg0KBgjnBwQCABIDJgcaCg4KBwjnBwQCAAESAyYHGgoMCgUI5wcEAxIDJh0hCggKAQgSAycAIQoLCgQI5wcFEgMnACEKDAoFCOcHBQISAycHGAoNCgYI5wcFAgASAycHGAoOCgcI5wcFAgABEgMnBxgKDAoFCOcHBQcSAycbIArkEAoCBAASBXkAlAEBGtYQIGBBbnlgIGNvbnRhaW5zIGFuIGFyYml0cmFyeSBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBtZXNzYWdlIGFsb25nIHdpdGggYQogVVJMIHRoYXQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZSBzZXJpYWxpemVkIG1lc3NhZ2UuCgogUHJvdG9idWYgbGlicmFyeSBwcm92aWRlcyBzdXBwb3J0IHRvIHBhY2svdW5wYWNrIEFueSB2YWx1ZXMgaW4gdGhlIGZvcm0KIG9mIHV0aWxpdHkgZnVuY3Rpb25zIG9yIGFkZGl0aW9uYWwgZ2VuZXJhdGVkIG1ldGhvZHMgb2YgdGhlIEFueSB0eXBlLgoKIEV4YW1wbGUgMTogUGFjayBhbmQgdW5wYWNrIGEgbWVzc2FnZSBpbiBDKysuCgogICAgIEZvbyBmb28gPSAuLi47CiAgICAgQW55IGFueTsKICAgICBhbnkuUGFja0Zyb20oZm9vKTsKICAgICAuLi4KICAgICBpZiAoYW55LlVucGFja1RvKCZmb28pKSB7CiAgICAgICAuLi4KICAgICB9CgogRXhhbXBsZSAyOiBQYWNrIGFuZCB1bnBhY2sgYSBtZXNzYWdlIGluIEphdmEuCgogICAgIEZvbyBmb28gPSAuLi47CiAgICAgQW55IGFueSA9IEFueS5wYWNrKGZvbyk7CiAgICAgLi4uCiAgICAgaWYgKGFueS5pcyhGb28uY2xhc3MpKSB7CiAgICAgICBmb28gPSBhbnkudW5wYWNrKEZvby5jbGFzcyk7CiAgICAgfQoKICBFeGFtcGxlIDM6IFBhY2sgYW5kIHVucGFjayBhIG1lc3NhZ2UgaW4gUHl0aG9uLgoKICAgICBmb28gPSBGb28oLi4uKQogICAgIGFueSA9IEFueSgpCiAgICAgYW55LlBhY2soZm9vKQogICAgIC4uLgogICAgIGlmIGFueS5JcyhGb28uREVTQ1JJUFRPUik6CiAgICAgICBhbnkuVW5wYWNrKGZvbykKICAgICAgIC4uLgoKICBFeGFtcGxlIDQ6IFBhY2sgYW5kIHVucGFjayBhIG1lc3NhZ2UgaW4gR28KCiAgICAgIGZvbyA6PSAmcGIuRm9vey4uLn0KICAgICAgYW55LCBlcnIgOj0gcHR5cGVzLk1hcnNoYWxBbnkoZm9vKQogICAgICAuLi4KICAgICAgZm9vIDo9ICZwYi5Gb297fQogICAgICBpZiBlcnIgOj0gcHR5cGVzLlVubWFyc2hhbEFueShhbnksIGZvbyk7IGVyciAhPSBuaWwgewogICAgICAgIC4uLgogICAgICB9CgogVGhlIHBhY2sgbWV0aG9kcyBwcm92aWRlZCBieSBwcm90b2J1ZiBsaWJyYXJ5IHdpbGwgYnkgZGVmYXVsdCB1c2UKICd0eXBlLmdvb2dsZWFwaXMuY29tL2Z1bGwudHlwZS5uYW1lJyBhcyB0aGUgdHlwZSBVUkwgYW5kIHRoZSB1bnBhY2sKIG1ldGhvZHMgb25seSB1c2UgdGhlIGZ1bGx5IHF1YWxpZmllZCB0eXBlIG5hbWUgYWZ0ZXIgdGhlIGxhc3QgJy8nCiBpbiB0aGUgdHlwZSBVUkwsIGZvciBleGFtcGxlICJmb28uYmFyLmNvbS94L3kueiIgd2lsbCB5aWVsZCB0eXBlCiBuYW1lICJ5LnoiLgoKCiBKU09OCiA9PT09CiBUaGUgSlNPTiByZXByZXNlbnRhdGlvbiBvZiBhbiBgQW55YCB2YWx1ZSB1c2VzIHRoZSByZWd1bGFyCiByZXByZXNlbnRhdGlvbiBvZiB0aGUgZGVzZXJpYWxpemVkLCBlbWJlZGRlZCBtZXNzYWdlLCB3aXRoIGFuCiBhZGRpdGlvbmFsIGZpZWxkIGBAdHlwZWAgd2hpY2ggY29udGFpbnMgdGhlIHR5cGUgVVJMLiBFeGFtcGxlOgoKICAgICBwYWNrYWdlIGdvb2dsZS5wcm9maWxlOwogICAgIG1lc3NhZ2UgUGVyc29uIHsKICAgICAgIHN0cmluZyBmaXJzdF9uYW1lID0gMTsKICAgICAgIHN0cmluZyBsYXN0X25hbWUgPSAyOwogICAgIH0KCiAgICAgewogICAgICAgIkB0eXBlIjogInR5cGUuZ29vZ2xlYXBpcy5jb20vZ29vZ2xlLnByb2ZpbGUuUGVyc29uIiwKICAgICAgICJmaXJzdE5hbWUiOiA8c3RyaW5nPiwKICAgICAgICJsYXN0TmFtZSI6IDxzdHJpbmc+CiAgICAgfQoKIElmIHRoZSBlbWJlZGRlZCBtZXNzYWdlIHR5cGUgaXMgd2VsbC1rbm93biBhbmQgaGFzIGEgY3VzdG9tIEpTT04KIHJlcHJlc2VudGF0aW9uLCB0aGF0IHJlcHJlc2VudGF0aW9uIHdpbGwgYmUgZW1iZWRkZWQgYWRkaW5nIGEgZmllbGQKIGB2YWx1ZWAgd2hpY2ggaG9sZHMgdGhlIGN1c3RvbSBKU09OIGluIGFkZGl0aW9uIHRvIHRoZSBgQHR5cGVgCiBmaWVsZC4gRXhhbXBsZSAoZm9yIG1lc3NhZ2UgW2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbl1bXSk6CgogICAgIHsKICAgICAgICJAdHlwZSI6ICJ0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbiIsCiAgICAgICAidmFsdWUiOiAiMS4yMTJzIgogICAgIH0KCgoKCgMEAAESA3kICwrkBwoEBAACABIEkAECFhrVByBBIFVSTC9yZXNvdXJjZSBuYW1lIHdob3NlIGNvbnRlbnQgZGVzY3JpYmVzIHRoZSB0eXBlIG9mIHRoZQogc2VyaWFsaXplZCBwcm90b2NvbCBidWZmZXIgbWVzc2FnZS4KCiBGb3IgVVJMcyB3aGljaCB1c2UgdGhlIHNjaGVtZSBgaHR0cGAsIGBodHRwc2AsIG9yIG5vIHNjaGVtZSwgdGhlCiBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zIGFuZCBpbnRlcnByZXRhdGlvbnMgYXBwbHk6CgogKiBJZiBubyBzY2hlbWUgaXMgcHJvdmlkZWQsIGBodHRwc2AgaXMgYXNzdW1lZC4KICogVGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgVVJMJ3MgcGF0aCBtdXN0IHJlcHJlc2VudCB0aGUgZnVsbHkKICAgcXVhbGlmaWVkIG5hbWUgb2YgdGhlIHR5cGUgKGFzIGluIGBwYXRoL2dvb2dsZS5wcm90b2J1Zi5EdXJhdGlvbmApLgogICBUaGUgbmFtZSBzaG91bGQgYmUgaW4gYSBjYW5vbmljYWwgZm9ybSAoZS5nLiwgbGVhZGluZyAiLiIgaXMKICAgbm90IGFjY2VwdGVkKS4KICogQW4gSFRUUCBHRVQgb24gdGhlIFVSTCBtdXN0IHlpZWxkIGEgW2dvb2dsZS5wcm90b2J1Zi5UeXBlXVtdCiAgIHZhbHVlIGluIGJpbmFyeSBmb3JtYXQsIG9yIHByb2R1Y2UgYW4gZXJyb3IuCiAqIEFwcGxpY2F0aW9ucyBhcmUgYWxsb3dlZCB0byBjYWNoZSBsb29rdXAgcmVzdWx0cyBiYXNlZCBvbiB0aGUKICAgVVJMLCBvciBoYXZlIHRoZW0gcHJlY29tcGlsZWQgaW50byBhIGJpbmFyeSB0byBhdm9pZCBhbnkKICAgbG9va3VwLiBUaGVyZWZvcmUsIGJpbmFyeSBjb21wYXRpYmlsaXR5IG5lZWRzIHRvIGJlIHByZXNlcnZlZAogICBvbiBjaGFuZ2VzIHRvIHR5cGVzLiAoVXNlIHZlcnNpb25lZCB0eXBlIG5hbWVzIHRvIG1hbmFnZQogICBicmVha2luZyBjaGFuZ2VzLikKCiBTY2hlbWVzIG90aGVyIHRoYW4gYGh0dHBgLCBgaHR0cHNgIChvciB0aGUgZW1wdHkgc2NoZW1lKSBtaWdodCBiZQogdXNlZCB3aXRoIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIHNlbWFudGljcy4KCgoOCgUEAAIABBIFkAECeQ0KDQoFBAACAAUSBJABAggKDQoFBAACAAESBJABCREKDQoFBAACAAMSBJABFBUKVwoEBAACARIEkwECEhpJIE11c3QgYmUgYSB2YWxpZCBzZXJpYWxpemVkIHByb3RvY29sIGJ1ZmZlciBvZiB0aGUgYWJvdmUgc3BlY2lmaWVkIHR5cGUuCgoPCgUEAAIBBBIGkwECkAEWCg0KBQQAAgEFEgSTAQIHCg0KBQQAAgEBEgSTAQgNCg0KBQQAAgEDEgSTARARYgZwcm90bzMK9SgKHmdvb2dsZS9wcm90b2J1Zi9kdXJhdGlvbi5wcm90bxIPZ29vZ2xlLnByb3RvYnVmIjoKCER1cmF0aW9uEhgKB3NlY29uZHMYASABKANSB3NlY29uZHMSFAoFbmFub3MYAiABKAVSBW5hbm9zQlcKE2NvbS5nb29nbGUucHJvdG9idWZCDUR1cmF0aW9uUHJvdG9QAVoFdHlwZXP4AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNKpCcKBhIEHgB0AQrMDAoBDBIDHgASMsEMIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAogQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLwoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KCiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElO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ID0gLi4uOwoKICAgICBkdXJhdGlvbi5zZWNvbmRzID0gZW5kLnNlY29uZHMgLSBzdGFydC5zZWNvbmRzOwogICAgIGR1cmF0aW9uLm5hbm9zID0gZW5kLm5hbm9zIC0gc3RhcnQubmFub3M7CgogICAgIGlmIChkdXJhdGlvbi5zZWNvbmRzIDwgMCAmJiBkdXJhdGlvbi5uYW5vcyA+IDApIHsKICAgICAgIGR1cmF0aW9uLnNlY29uZHMgKz0gMTsKICAgICAgIGR1cmF0aW9uLm5hbm9zIC09IDEwMDAwMDAwMDA7CiAgICAgfSBlbHNlIGlmIChkdXJhdGlvbnMuc2Vjb25kcyA+IDAgJiYgZHVyYXRpb24ubmFub3MgPCAwKSB7CiAgICAgICBkdXJhdGlvbi5zZWNvbmRzIC09IDE7CiAgICAgICBkdXJhdGlvbi5uYW5vcyArPSAxMDAwMDAwMDAwOwogICAgIH0KCiBFeGFtcGxlIDI6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gVGltZXN0YW1wICsgRHVyYXRpb24gaW4gcHNldWRvIGNvZGUuCgogICAgIFRpbWVzdGFtcCBzdGFydCA9IC4uLjsKICAgICBEdXJhdGlvbiBkdXJhdGlvbiA9IC4uLjsKICAgICBUaW1lc3RhbXAgZW5kID0gLi4uOwoKICAgICBlbmQuc2Vjb25kcyA9IHN0YXJ0LnNlY29uZHMgKyBkdXJhdGlvbi5zZWNvbmRzOwogICAgIGVuZC5uYW5vcyA9IHN0YXJ0Lm5hbm9zICsgZHVyYXRpb24ubmFub3M7CgogICAgIGlmIChlbmQubmFub3MgPCAwKSB7CiAgICAgICBlbmQuc2Vjb25kcyAtPSAxOwogICAgICAgZW5kLm5hbm9zICs9IDEwMDAwMDAwMDA7CiAgICAgfSBlbHNlIGlmIChlbmQubmFub3MgPj0gMTAwMDAwMDAwMCkgewogICAgICAgZW5kLnNlY29uZHMgKz0gMTsKICAgICAgIGVuZC5uYW5vcyAtPSAxMDAwMDAwMDAwOwogICAgIH0KCiBFeGFtcGxlIDM6IENvbXB1dGUgRHVyYXRpb24gZnJvbSBkYXRldGltZS50aW1lZGVsdGEgaW4gUHl0aG9uLgoKICAgICB0ZCA9IGRhdGV0aW1lLnRpbWVkZWx0YShkYXlzPTMsIG1pbnV0ZXM9MTApCiAgICAgZHVyYXRpb24gPSBEdXJhdGlvbigpCiAgICAgZHVyYXRpb24uRnJvbVRpbWVkZWx0YSh0ZCkKCiAjIEpTT04gTWFwcGluZwoKIEluIEpTT04gZm9ybWF0LCB0aGUgRHVyYXRpb24gdHlwZSBpcyBlbmNvZGVkIGFzIGEgc3RyaW5nIHJhdGhlciB0aGFuIGFuCiBvYmplY3QsIHdoZXJlIHRoZSBzdHJpbmcgZW5kcyBpbiB0aGUgc3VmZml4ICJzIiAoaW5kaWNhdGluZyBzZWNvbmRzKSBhbmQKIGlzIHByZWNlZGVkIGJ5IHRoZSBudW1iZXIgb2Ygc2Vjb25kcywgd2l0aCBuYW5vc2Vjb25kcyBleHByZXNzZWQgYXMKIGZyYWN0aW9uYWwgc2Vjb25kcy4gRm9yIGV4YW1wbGUsIDMgc2Vjb25kcyB3aXRoIDAgbmFub3NlY29uZHMgc2hvdWxkIGJlCiBlbmNvZGVkIGluIEpTT04gZm9ybWF0IGFzICIzcyIsIHdoaWxlIDMgc2Vjb25kcyBhbmQgMSBuYW5vc2Vjb25kIHNob3VsZAogYmUgZXhwcmVzc2VkIGluIEpTT04gZm9ybWF0IGFzICIzLjAwMDAwMDAwMXMiLCBhbmQgMyBzZWNvbmRzIGFuZCAxCiBtaWNyb3NlY29uZCBzaG91bGQgYmUgZXhwcmVzc2VkIGluIEpTT04gZm9ybWF0IGFzICIzLjAwMDAwMXMiLgoKCgoKCgMEAAESA2YIEArcAQoEBAACABIDawIUGs4BIFNpZ25lZCBzZWNvbmRzIG9mIHRoZSBzcGFuIG9mIHRpbWUuIE11c3QgYmUgZnJvbSAtMzE1LDU3NiwwMDAsMDAwCiB0byArMzE1LDU3NiwwMDAsMDAwIGluY2x1c2l2ZS4gTm90ZTogdGhlc2UgYm91bmRzIGFyZSBjb21wdXRlZCBmcm9tOgogNjAgc2VjL21pbiAqIDYwIG1pbi9ociAqIDI0IGhyL2RheSAqIDM2NS4yNSBkYXlzL3llYXIgKiAxMDAwMCB5ZWFycwoKDQoFBAACAAQSBGsCZhIKDAoFBAACAAUSA2sCBwoMCgUEAAIAARIDawgPCgwKBQQAAgADEgNrEhMKgwMKBAQAAgESA3MCEhr1AiBTaWduZWQgZnJhY3Rpb25zIG9mIGEgc2Vjb25kIGF0IG5hbm9zZWNvbmQgcmVzb2x1dGlvbiBvZiB0aGUgc3Bhbgogb2YgdGltZS4gRHVyYXRpb25zIGxlc3MgdGhhbiBvbmUgc2Vjb25kIGFyZSByZXByZXNlbnRlZCB3aXRoIGEgMAogYHNlY29uZHNgIGZpZWxkIGFuZCBhIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGBuYW5vc2AgZmllbGQuIEZvciBkdXJhdGlvbnMKIG9mIG9uZSBzZWNvbmQgb3IgbW9yZSwgYSBub24temVybyB2YWx1ZSBmb3IgdGhlIGBuYW5vc2AgZmllbGQgbXVzdCBiZQogb2YgdGhlIHNhbWUgc2lnbiBhcyB0aGUgYHNlY29uZHNgIGZpZWxkLiBNdXN0IGJlIGZyb20gLTk5OSw5OTksOTk5CiB0byArOTk5LDk5OSw5OTkgaW5jbHVzaXZlLgoKDQoFBAACAQQSBHMCaxQKDAoFBAACAQUSA3MCBwoMCgUEAAIBARIDcwgNCgwKBQQAAgEDEgNzEBFiBnByb3RvMwqrIgoXZ29vZ2xlL3JwYy9zdGF0dXMucHJvdG8SCmdvb2dsZS5ycGMaGWdvb2dsZS9wcm90b2J1Zi9hbnkucHJvdG8iZgoGU3RhdHVzEhIKBGNvZGUYASABKAVSBGNvZGUSGAoHbWVzc2FnZRgCIAEoCVIHbWVzc2FnZRIuCgdkZXRhaWxzGAMgAygLMhQuZ29vZ2xlLnByb3RvYnVmLkFueVIHZGV0YWlsc0IqCg5jb20uZ29vZ2xlLnJwY0ILU3RhdHVzUHJvdG9QAVoDcnBjogIDUlBDSswgCgYSBA4AWwEKvQQKAQwSAw4AEjKyBCBDb3B5cmlnaHQgMjAxNyBHb29nbGUgSW5jLgoKIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CgogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsCiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoKCAoBAhIDEAgSCgkKAgMAEgMSByIKCAoBCBIDFAAaCgsKBAjnBwASAxQAGgoMCgUI5wcAAhIDFAcRCg0KBgjnBwACABIDFAcRCg4KBwjnBwACAAESAxQHEQoMCgUI5wcABxIDFBQZCggKAQgSAxUAIgoLCgQI5wcBEgMVACIKDAoFCOcHAQISAxUHGgoNCgYI5wcBAgASAxUHGgoOCgcI5wcBAgABEgMVBxoKDAoFCOcHAQMSAxUdIQoICgEIEgMWACwKCwoECOcHAhIDFgAsCgwKBQjnBwICEgMWBxsKDQoGCOcHAgIAEgMWBxsKDgoHCOcHAgIAARIDFgcbCgwKBQjnBwIHEgMWHisKCAoBCBIDFwAnCgsKBAjnBwMSAxcAJwoMCgUI5wcDAhIDFwcTCg0KBgjnBwMCABIDFwcTCg4KBwjnBwMCAAESAxcHEwoMCgUI5wcDBxIDFxYmCggKAQgSAxgAIQoLCgQI5wcEEgMYACEKDAoFCOcHBAISAxgHGAoNCgYI5wcEAgASAxgHGAoOCgcI5wcEAgABEgMYBxgKDAoFCOcHBAcSAxgbIArNEwoCBAASBE8AWwEawBMgVGhlIGBTdGF0dXNgIHR5cGUgZGVmaW5lcyBhIGxvZ2ljYWwgZXJyb3IgbW9kZWwgdGhhdCBpcyBzdWl0YWJsZSBmb3IgZGlmZmVyZW50CiBwcm9ncmFtbWluZyBlbnZpcm9ubWVudHMsIGluY2x1ZGluZyBSRVNUIEFQSXMgYW5kIFJQQyBBUElzLiBJdCBpcyB1c2VkIGJ5CiBbZ1JQQ10oaHR0cHM6Ly9naXRodWIuY29tL2dycGMpLiBUaGUgZXJyb3IgbW9kZWwgaXMgZGVzaWduZWQgdG8gYmU6CgogLSBTaW1wbGUgdG8gdXNlIGFuZCB1bmRlcnN0YW5kIGZvciBtb3N0IHVzZXJzCiAtIEZsZXhpYmxlIGVub3VnaCB0byBtZWV0IHVuZXhwZWN0ZWQgbmVlZHMKCiAjIE92ZXJ2aWV3CgogVGhlIGBTdGF0dXNgIG1lc3NhZ2UgY29udGFpbnMgdGhyZWUgcGllY2VzIG9mIGRhdGE6IGVycm9yIGNvZGUsIGVycm9yIG1lc3NhZ2UsCiBhbmQgZXJyb3IgZGV0YWlscy4gVGhlIGVycm9yIGNvZGUgc2hvdWxkIGJlIGFuIGVudW0gdmFsdWUgb2YKIFtnb29nbGUucnBjLkNvZGVdW2dvb2dsZS5ycGMuQ29kZV0sIGJ1dCBpdCBtYXkgYWNjZXB0IGFkZGl0aW9uYWwgZXJyb3IgY29kZXMgaWYgbmVlZGVkLiAgVGhlCiBlcnJvciBtZXNzYWdlIHNob3VsZCBiZSBhIGRldmVsb3Blci1mYWNpbmcgRW5nbGlzaCBtZXNzYWdlIHRoYXQgaGVscHMKIGRldmVsb3BlcnMgKnVuZGVyc3RhbmQqIGFuZCAqcmVzb2x2ZSogdGhlIGVycm9yLiBJZiBhIGxvY2FsaXplZCB1c2VyLWZhY2luZwogZXJyb3IgbWVzc2FnZSBpcyBuZWVkZWQsIHB1dCB0aGUgbG9jYWxpemVkIG1lc3NhZ2UgaW4gdGhlIGVycm9yIGRldGFpbHMgb3IKIGxvY2FsaXplIGl0IGluIHRoZSBjbGllbnQuIFRoZSBvcHRpb25hbCBlcnJvciBkZXRhaWxzIG1heSBjb250YWluIGFyYml0cmFyeQogaW5mb3JtYXRpb24gYWJvdXQgdGhlIGVycm9yLiBUaGVyZSBpcyBhIHByZWRlZmluZWQgc2V0IG9mIGVycm9yIGRldGFpbCB0eXBlcwogaW4gdGhlIHBhY2thZ2UgYGdvb2dsZS5ycGNgIHRoYXQgY2FuIGJlIHVzZWQgZm9yIGNvbW1vbiBlcnJvciBjb25kaXRpb25zLgoKICMgTGFuZ3VhZ2UgbWFwcGluZwoKIFRoZSBgU3RhdHVzYCBtZXNzYWdlIGlzIHRoZSBsb2dpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlcnJvciBtb2RlbCwgYnV0IGl0CiBpcyBub3QgbmVjZXNzYXJpbHkgdGhlIGFjdHVhbCB3aXJlIGZvcm1hdC4gV2hlbiB0aGUgYFN0YXR1c2AgbWVzc2FnZSBpcwogZXhwb3NlZCBpbiBkaWZmZXJlbnQgY2xpZW50IGxpYnJhcmllcyBhbmQgZGlmZmVyZW50IHdpcmUgcHJvdG9jb2xzLCBpdCBjYW4gYmUKIG1hcHBlZCBkaWZmZXJlbnRseS4gRm9yIGV4YW1wbGUsIGl0IHdpbGwgbGlrZWx5IGJlIG1hcHBlZCB0byBzb21lIGV4Y2VwdGlvbnMKIGluIEphdmEsIGJ1dCBtb3JlIGxpa2VseSBtYXBwZWQgdG8gc29tZSBlcnJvciBjb2RlcyBpbiBDLgoKICMgT3RoZXIgdXNlcwoKIFRoZSBlcnJvciBtb2RlbCBhbmQgdGhlIGBTdGF0dXNgIG1lc3NhZ2UgY2FuIGJlIHVzZWQgaW4gYSB2YXJpZXR5IG9mCiBlbnZpcm9ubWVudHMsIGVpdGhlciB3aXRoIG9yIHdpdGhvdXQgQVBJcywgdG8gcHJvdmlkZSBhCiBjb25zaXN0ZW50IGRldmVsb3BlciBleHBlcmllbmNlIGFjcm9zcyBkaWZmZXJlbnQgZW52aXJvbm1lbnRzLgoKIEV4YW1wbGUgdXNlcyBvZiB0aGlzIGVycm9yIG1vZGVsIGluY2x1ZGU6CgogLSBQYXJ0aWFsIGVycm9ycy4gSWYgYSBzZXJ2aWNlIG5lZWRzIHRvIHJldHVybiBwYXJ0aWFsIGVycm9ycyB0byB0aGUgY2xpZW50LAogICAgIGl0IG1heSBlbWJlZCB0aGUgYFN0YXR1c2AgaW4gdGhlIG5vcm1hbCByZXNwb25zZSB0byBpbmRpY2F0ZSB0aGUgcGFydGlhbAogICAgIGVycm9ycy4KCiAtIFdvcmtmbG93IGVycm9ycy4gQSB0eXBpY2FsIHdvcmtmbG93IGhhcyBtdWx0aXBsZSBzdGVwcy4gRWFjaCBzdGVwIG1heQogICAgIGhhdmUgYSBgU3RhdHVzYCBtZXNzYWdlIGZvciBlcnJvciByZXBvcnRpbmcuCgogLSBCYXRjaCBvcGVyYXRpb25zLiBJZiBhIGNsaWVudCB1c2VzIGJhdGNoIHJlcXVlc3QgYW5kIGJhdGNoIHJlc3BvbnNlLCB0aGUKICAgICBgU3RhdHVzYCBtZXNzYWdlIHNob3VsZCBiZSB1c2VkIGRpcmVjdGx5IGluc2lkZSBiYXRjaCByZXNwb25zZSwgb25lIGZvcgogICAgIGVhY2ggZXJyb3Igc3ViLXJlc3BvbnNlLgoKIC0gQXN5bmNocm9ub3VzIG9wZXJhdGlvbnMuIElmIGFuIEFQSSBjYWxsIGVtYmVkcyBhc3luY2hyb25vdXMgb3BlcmF0aW9uCiAgICAgcmVzdWx0cyBpbiBpdHMgcmVzcG9uc2UsIHRoZSBzdGF0dXMgb2YgdGhvc2Ugb3BlcmF0aW9ucyBzaG91bGQgYmUKICAgICByZXByZXNlbnRlZCBkaXJlY3RseSB1c2luZyB0aGUgYFN0YXR1c2AgbWVzc2FnZS4KCiAtIExvZ2dpbmcuIElmIHNvbWUgQVBJIGVycm9ycyBhcmUgc3RvcmVkIGluIGxvZ3MsIHRoZSBtZXNzYWdlIGBTdGF0dXNgIGNvdWxkCiAgICAgYmUgdXNlZCBkaXJlY3RseSBhZnRlciBhbnkgc3RyaXBwaW5nIG5lZWRlZCBmb3Igc2VjdXJpdHkvcHJpdmFjeSByZWFzb25zLgoKCgoDBAABEgNPCA4KZAoEBAACABIDUQIRGlcgVGhlIHN0YXR1cyBjb2RlLCB3aGljaCBzaG91bGQgYmUgYW4gZW51bSB2YWx1ZSBvZiBbZ29vZ2xlLnJwYy5Db2RlXVtnb29nbGUucnBjLkNvZGVdLgoKDQoFBAACAAQSBFECTxAKDAoFBAACAAUSA1ECBwoMCgUEAAIAARIDUQgMCgwKBQQAAgADEgNRDxAK6wEKBAQAAgESA1YCFRrdASBBIGRldmVsb3Blci1mYWNpbmcgZXJyb3IgbWVzc2FnZSwgd2hpY2ggc2hvdWxkIGJlIGluIEVuZ2xpc2guIEFueQogdXNlci1mYWNpbmcgZXJyb3IgbWVzc2FnZSBzaG91bGQgYmUgbG9jYWxpemVkIGFuZCBzZW50IGluIHRoZQogW2dvb2dsZS5ycGMuU3RhdHVzLmRldGFpbHNdW2dvb2dsZS5ycGMuU3RhdHVzLmRldGFpbHNdIGZpZWxkLCBvciBsb2NhbGl6ZWQgYnkgdGhlIGNsaWVudC4KCg0KBQQAAgEEEgRWAlERCgwKBQQAAgEFEgNWAggKDAoFBAACAQESA1YJEAoMCgUEAAIBAxIDVhMUCnkKBAQAAgISA1oCKxpsIEEgbGlzdCBvZiBtZXNzYWdlcyB0aGF0IGNhcnJ5IHRoZSBlcnJvciBkZXRhaWxzLiAgVGhlcmUgaXMgYSBjb21tb24gc2V0IG9mCiBtZXNzYWdlIHR5cGVzIGZvciBBUElzIHRvIHVzZS4KCgwKBQQAAgIEEgNaAgoKDAoFBAACAgYSA1oLHgoMCgUEAAICARIDWh8mCgwKBQQAAgIDEgNaKSpiBnByb3RvMwq8EQonbWl4ZXIvYWRhcHRlci9tb2RlbC92MWJldGExL2NoZWNrLnByb3RvEiFpc3Rpby5taXhlci5hZGFwdGVyLm1vZGVsLnYxYmV0YTEaFGdvZ29wcm90by9nb2dvLnByb3RvGh5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8aF2dvb2dsZS9ycGMvc3RhdHVzLnByb3RvIrMBCgtDaGVja1Jlc3VsdBIwCgZzdGF0dXMYASABKAsyEi5nb29nbGUucnBjLlN0YXR1c0IEyN4fAFIGc3RhdHVzEkoKDnZhbGlkX2R1cmF0aW9uGAIgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uQgjI3h8AmN8fAVINdmFsaWREdXJhdGlvbhImCg92YWxpZF91c2VfY291bnQYAyABKAVSDXZhbGlkVXNlQ291bnRCNlooaXN0aW8uaW8vYXBpL21peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMcjhHgCo4h4A8OEeAEqoDgoGEgQOACUBCr8ECgEMEgMOABIytAQgQ29weXJpZ2h0IDIwMTggSXN0aW8gQXV0aG9ycwoKIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNl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RxABEgkKBUlOVDY0EAISCgoGRE9VQkxFEAMSCAoEQk9PTBAEEg0KCVRJTUVTVEFNUBAFEg4KCklQX0FERFJFU1MQBhIRCg1FTUFJTF9BRERSRVNTEAcSBwoDVVJJEAgSDAoIRE5TX05BTUUQCRIMCghEVVJBVElPThAKEg4KClNUUklOR19NQVAQC0IdWhtpc3Rpby5pby9hcGkvcG9saWN5L3YxYmV0YTFKtQ4KBhIEDgA8AQq/BAoBDBIDDgASMrQEIENvcHlyaWdodCAyMDE4IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCggKAQISAxAIHAoICgEIEgMSADAKCwoECOcHABIDEgAwCgwKBQjnBwACEgMSBxEKDQoGCOcHAAIAEgMSBxEKDgoHCOcHAAIAARIDEgcRCgwKBQjnBwAHEgMSEi8KlgIKAgUAEgQYADwBGokCIFZhbHVlVHlwZSBkZXNjcmliZXMgdGhlIHR5cGVzIHRoYXQgdmFsdWVzIGluIHRoZSBJc3RpbyBzeXN0ZW0gY2FuIHRha2UuIFRoZXNlCiBhcmUgdXNlZCB0byBkZXNjcmliZSB0aGUgdHlwZSBvZiBBdHRyaWJ1dGVzIGF0IHJ1biB0aW1lLCBkZXNjcmliZSB0aGUgdHlwZSBvZgogdGhlIHJlc3VsdCBvZiBldmFsdWF0aW5nIGFuIGV4cHJlc3Npb24sIGFuZCB0byBkZXNjcmliZSB0aGUgcnVudGltZSB0eXBlIG9mCiBmaWVsZHMgb2Ygb3RoZXIgZGVzY3JpcHRvcnMuCgoKCgMFAAESAxgFDgomCgQFAAIAEgMaBB8aGSBJbnZhbGlkLCBkZWZhdWx0IHZhbHVlLgoKDAoFBQACAAESAxoEGgoMCgUFAAIAAhIDGh0eCjkKBAUAAgESAx0EDxosIEFuIHVuZGlzY3JpbWluYXRlZCB2YXJpYWJsZS1sZW5ndGggc3RyaW5nLgoKDAoFBQACAQESAx0ECgoMCgUFAAIBAhIDHQ0OCjgKBAUAAgISAyAEDhorIEFuIHVuZGlzY3JpbWluYXRlZCA2NC1iaXQgc2lnbmVkIGludGVnZXIuCgoMCgUFAAICARIDIAQJCgwKBQUAAgICEgMgDA0KPgoEBQACAxIDIwQPGjEgQW4gdW5kaXNjcmltaW5hdGVkIDY0LWJpdCBmbG9hdGluZy1wb2ludCB2YWx1ZS4KCgwKBQUAAgMBEgMjBAoKDAoFBQACAwISAyMNDgowCgQFAAIEEgMmBA0aIyBBbiB1bmRpc2NyaW1pbmF0ZWQgYm9vbGVhbiB2YWx1ZS4KCgwKBQUAAgQBEgMmBAgKDAoFBQACBAISAyYLDAofCgQFAAIFEgMpBBIaEiBBIHBvaW50IGluIHRpbWUuCgoMCgUFAAIFARIDKQQNCgwKBQUAAgUCEgMpEBEKHQoEBQACBhIDLAQTGhAgQW4gSVAgYWRkcmVzcy4KCgwKBQUAAgYBEgMsBA4KDAoFBQACBgISAywREgogCgQFAAIHEgMvBBYaEyBBbiBlbWFpbCBhZGRyZXNzLgoKDAoFBQACBwESAy8EEQoMCgUFAAIHAhIDLxQVChUKBAUAAggSAzIEDBoIIEEgVVJJLgoKDAoFBQACCAESAzIEBwoMCgUFAAIIAhIDMgoLChoKBAUAAgkSAzUEERoNIEEgRE5TIG5hbWUuCgoMCgUFAAIJARIDNQQMCgwKBQUAAgkCEgM1DxAKMQoEBQACChIDOAQSGiQgQSBzcGFuIGJldHdlZW4gdHdvIHBvaW50cyBpbiB0aW1lLgoKDAoFBQACCgESAzgEDAoMCgUFAAIKAhIDOA8RCkEKBAUAAgsSAzsEFBo0IEEgbWFwIHN0cmluZyAtPiBzdHJpbmcsIHR5cGljYWxseSB1c2VkIGJ5IGhlYWRlcnMuCgoMCgUFAAILARIDOwQOCgwKBQUAAgsCEgM7ERNiBnByb3RvMwqgMQofZ29vZ2xlL3Byb3RvYnVmL3RpbWVzdGFtcC5wcm90bxIPZ29vZ2xlLnByb3RvYnVmIjsKCVRpbWVzdGFtcBIYCgdzZWNvbmRzGAEgASgDUgdzZWNvbmRzEhQKBW5hbm9zGAIgASgFUgVuYW5vc0JYChNjb20uZ29vZ2xlLnByb3RvYnVmQg5UaW1lc3RhbXBQcm90b1ABWgV0eXBlc/gBAaICA0dQQqoCHkdvb2dsZS5Qcm90b2J1Zi5XZWxsS25vd25UeXBlc0rMLwoHEgUeAIQBAQrMDAoBDBIDHgASMsEMIFByb3RvY29sIEJ1ZmZlcnMgLSBHb29nbGUncyBkYXRhIGludGVyY2hhbmdlIGZvcm1hdAogQ29weXJpZ2h0IDIwMDggR29vZ2xlIEluYy4gIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9wcm90b2NvbC1idWZmZXJzLwoKIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQogbWV0OgoKICAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlCiBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyCiBpbiB0aGUgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlCiBkaXN0cmlidXRpb24uCiAgICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIEdvb2dsZSBJbmMuIG5vciB0aGUgbmFtZXMgb2YgaXRzCiBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbQogdGhpcyBzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4KCiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgoKCAoBAhIDIAgXCggKAQgSAyIAOwoLCgQI5wcAEgMiADsKDAoFCOcHAAISAyIHFwoNCgYI5wcAAgASAyIHFwoOCgcI5wcAAgABEgMiBxcKDAoFCOcHAAcSAyIaOgoICgEIEgMjAB8KCwoECOcHARIDIwAfCgwKBQjnBwECEgMjBxcKDQoGCOcHAQIAEgMjBxcKDgoHCOcHAQIAARIDIwcXCgwKBQjnBwEDEgMjGh4KCAoBCBIDJAAcCgsKBAjnBwISAyQAHAoMCgUI5wcCAhIDJAcRCg0KBgjnBwICABIDJAcRCg4KBwjnBwICAAESAyQHEQoMCgUI5wcCBxIDJBQbCggKAQgSAyUALAoLCgQI5wcDEgMlACwKDAoFCOcHAwISAyUHEwoNCgYI5wcDAgASAyUHEwoOCgcI5wcDAgABEgMlBxMKDAoFCOcHAwcSAyUWKwoICgEIEgMmAC8KCwoECOcHBBIDJgAvCgwKBQjnBwQCEgMmBxsKDQoGCOcHBAIAEgMmBxsKDgoHCOcHBAIAARIDJgcbCgwKBQjnBwQHEgMmHi4KCAoBCBIDJwAiCgsKBAjnBwUSAycAIgoMCgUI5wcFAhIDJwcaCg0KBgjnBwUCABIDJwcaCg4KBwjnBwUCAAESAycHGgoMCgUI5wcFAxIDJx0hCggKAQgSAygAIQoLCgQI5wcGEgMoACEKDAoFCOcHBgISAygHGAoNCgYI5wcGAgASAygHGAoOCgcI5wcGAgABEgMoBxgKDAoFCOcHBgcSAygbIAqgGgoCBAASBXgAhAEBGpIaIEEgVGltZXN0YW1wIHJlcHJlc2VudHMgYSBwb2ludCBpbiB0aW1lIGluZGVwZW5kZW50IG9mIGFueSB0aW1lIHpvbmUKIG9yIGNhbGVuZGFyLCByZXByZXNlbnRlZCBhcyBzZWNvbmRzIGFuZCBmcmFjdGlvbnMgb2Ygc2Vjb25kcyBhdAogbmFub3NlY29uZCByZXNvbHV0aW9uIGluIFVUQyBFcG9jaCB0aW1lLiBJdCBpcyBlbmNvZGVkIHVzaW5nIHRoZQogUHJvbGVwdGljIEdyZWdvcmlhbiBDYWxlbmRhciB3aGljaCBleHRlbmRzIHRoZSBHcmVnb3JpYW4gY2FsZW5kYXIKIGJhY2t3YXJkcyB0byB5ZWFyIG9uZS4gSXQgaXMgZW5jb2RlZCBhc3N1bWluZyBhbGwgbWludXRlcyBhcmUgNjAKIHNlY29uZHMgbG9uZywgaS5lLiBsZWFwIHNlY29uZHMgYXJlICJzbWVhcmVkIiBzbyB0aGF0IG5vIGxlYXAgc2Vjb25kCiB0YWJsZSBpcyBuZWVkZWQgZm9yIGludGVycHJldGF0aW9uLiBSYW5nZSBpcyBmcm9tCiAwMDAxLTAxLTAxVDAwOjAwOjAwWiB0byA5OTk5LTEyLTMxVDIzOjU5OjU5Ljk5OTk5OTk5OVouCiBCeSByZXN0cmljdGluZyB0byB0aGF0IHJhbmdlLCB3ZSBlbnN1cmUgdGhhdCB3ZSBjYW4gY29udmVydCB0bwogYW5kIGZyb20gIFJGQyAzMzM5IGRhdGUgc3RyaW5ncy4KIFNlZSBbaHR0cHM6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMzMzkudHh0XShodHRwczovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMzMzOS50eHQpLgoKICMgRXhhbXBsZXMKCiBFeGFtcGxlIDE6IENvbXB1dGUgVGltZXN0YW1wIGZyb20gUE9TSVggYHRpbWUoKWAuCgogICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CiAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKHRpbWUoTlVMTCkpOwogICAgIHRpbWVzdGFtcC5zZXRfbmFub3MoMCk7CgogRXhhbXBsZSAyOiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIFBPU0lYIGBnZXR0aW1lb2ZkYXkoKWAuCgogICAgIHN0cnVjdCB0aW1ldmFsIHR2OwogICAgIGdldHRpbWVvZmRheSgmdHYsIE5VTEwpOwoKICAgICBUaW1lc3RhbXAgdGltZXN0YW1wOwogICAgIHRpbWVzdGFtcC5zZXRfc2Vjb25kcyh0di50dl9zZWMpOwogICAgIHRpbWVzdGFtcC5zZXRfbmFub3ModHYudHZfdXNlYyAqIDEwMDApOwoKIEV4YW1wbGUgMzogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBXaW4zMiBgR2V0U3lzdGVtVGltZUFzRmlsZVRpbWUoKWAuCgogICAgIEZJTEVUSU1FIGZ0OwogICAgIEdldFN5c3RlbVRpbWVBc0ZpbGVUaW1lKCZmdCk7CiAgICAgVUlOVDY0IHRpY2tzID0gKCgoVUlOVDY0KWZ0LmR3SGlnaERhdGVUaW1lKSA8PCAzMikgfCBmdC5kd0xvd0RhdGVUaW1lOwoKICAgICAvLyBBIFdpbmRvd3MgdGljayBpcyAxMDAgbmFub3NlY29uZHMuIFdpbmRvd3MgZXBvY2ggMTYwMS0wMS0wMVQwMDowMDowMFoKICAgICAvLyBpcyAxMTY0NDQ3MzYwMCBzZWNvbmRzIGJlZm9yZSBVbml4IGVwb2NoIDE5NzAtMDEtMDFUMDA6MDA6MDBaLgogICAgIFRpbWVzdGFtcCB0aW1lc3RhbXA7CiAgICAgdGltZXN0YW1wLnNldF9zZWNvbmRzKChJTlQ2NCkgKCh0aWNrcyAvIDEwMDAwMDAwKSAtIDExNjQ0NDczNjAwTEwpKTsKICAgICB0aW1lc3RhbXAuc2V0X25hbm9zKChJTlQzMikgKCh0aWNrcyAlIDEwMDAwMDAwKSAqIDEwMCkpOwoKIEV4YW1wbGUgNDogQ29tcHV0ZSBUaW1lc3RhbXAgZnJvbSBKYXZhIGBTeXN0ZW0uY3VycmVudFRpbWVNaWxsaXMoKWAuCgogICAgIGxvbmcgbWlsbGlzID0gU3lzdGVtLmN1cnJlbnRUaW1lTWlsbGlzKCk7CgogICAgIFRpbWVzdGFtcCB0aW1lc3RhbXAgPSBUaW1lc3RhbXAubmV3QnVpbGRlcigpLnNldFNlY29uZHMobWlsbGlzIC8gMTAwMCkKICAgICAgICAgLnNldE5hbm9zKChpbnQpICgobWlsbGlzICUgMTAwMCkgKiAxMDAwMDAwKSkuYnVpbGQoKTsKCgogRXhhbXBsZSA1OiBDb21wdXRlIFRpbWVzdGFtcCBmcm9tIGN1cnJlbnQgdGltZSBpbiBQeXRob24uCgogICAgIHRpbWVzdGFtcCA9IFRpbWVzdGFtcCgpCiAgICAgdGltZXN0YW1wLkdldEN1cnJlbnRUaW1lKCkKCiAjIEpTT04gTWFwcGluZwoKIEluIEpTT04gZm9ybWF0LCB0aGUgVGltZXN0YW1wIHR5cGUgaXMgZW5jb2RlZCBhcyBhIHN0cmluZyBpbiB0aGUKIFtSRkMgMzMzOV0oaHR0cHM6Ly93d3cuaWV0Zi5vcmcvcmZjL3JmYzMzMzkudHh0KSBmb3JtYXQuIFRoYXQgaXMsIHRoZQogZm9ybWF0IGlzICJ7eWVhcn0te21vbnRofS17ZGF5fVR7aG91cn06e21pbn06e3NlY31bLntmcmFjX3NlY31dWiIKIHdoZXJlIHt5ZWFyfSBpcyBhbHdheXMgZXhwcmVzc2VkIHVzaW5nIGZvdXIgZGlnaXRzIHdoaWxlIHttb250aH0sIHtkYXl9LAoge2hvdXJ9LCB7bWlufSwgYW5kIHtzZWN9IGFyZSB6ZXJvLXBhZGRlZCB0byB0d28gZGlnaXRzIGVhY2guIFRoZSBmcmFjdGlvbmFsCiBzZWNvbmRzLCB3aGljaCBjYW4gZ28gdXAgdG8gOSBkaWdpdHMgKGkuZS4gdXAgdG8gMSBuYW5vc2Vjb25kIHJlc29sdXRpb24pLAogYXJlIG9wdGlvbmFsLiBUaGUgIloiIHN1ZmZpeCBpbmRpY2F0ZXMgdGhlIHRpbWV6b25lICgiVVRDIik7IHRoZSB0aW1lem9uZQogaXMgcmVxdWlyZWQsIHRob3VnaCBvbmx5IFVUQyAoYXMgaW5kaWNhdGVkIGJ5ICJaIikgaXMgcHJlc2VudGx5IHN1cHBvcnRlZC4KCiBGb3IgZXhhbXBsZSwgIjIwMTctMDEtMTVUMDE6MzA6MTUuMDFaIiBlbmNvZGVzIDE1LjAxIHNlY29uZHMgcGFzdAogMDE6MzAgVVRDIG9uIEphbnVhcnkgMTUsIDIwMTcuCgogSW4gSmF2YVNjcmlwdCwgb25lIGNhbiBjb252ZXJ0IGEgRGF0ZSBvYmplY3QgdG8gdGhpcyBmb3JtYXQgdXNpbmcgdGhlCiBzdGFuZGFyZCBbdG9JU09TdHJpbmcoKV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvRGF0ZS90b0lTT1N0cmluZ10KIG1ldGhvZC4gSW4gUHl0aG9uLCBhIHN0YW5kYXJkIGBkYXRldGltZS5kYXRldGltZWAgb2JqZWN0IGNhbiBiZSBjb252ZXJ0ZWQKIHRvIHRoaXMgZm9ybWF0IHVzaW5nIFtgc3RyZnRpbWVgXShodHRwczovL2RvY3MucHl0aG9uLm9yZy8yL2xpYnJhcnkvdGltZS5odG1sI3RpbWUuc3RyZnRpbWUpCiB3aXRoIHRoZSB0aW1lIGZvcm1hdCBzcGVjICclWS0lbS0lZFQlSDolTTolUy4lZlonLiBMaWtld2lzZSwgaW4gSmF2YSwgb25lCiBjYW4gdXNlIHRoZSBKb2RhIFRpbWUncyBbYElTT0RhdGVUaW1lRm9ybWF0LmRhdGVUaW1lKClgXSgKIGh0dHA6Ly9qb2RhLXRpbWUuc291cmNlZm9yZ2UubmV0L2FwaWRvY3Mvb3JnL2pvZGEvdGltZS9mb3JtYXQvSVNPRGF0ZVRpbWVGb3JtYXQuaHRtbCNkYXRlVGltZSgpKQogdG8gb2J0YWluIGEgZm9ybWF0dGVyIGNhcGFibGUgb2YgZ2VuZXJhdGluZyB0aW1lc3RhbXBzIGluIHRoaXMgZm9ybWF0LgoKCgoKCgMEAAESA3gIEQqcAQoEBAACABIDfQIUGo4BIFJlcHJlc2VudHMgc2Vjb25kcyBvZiBVVEMgdGltZSBzaW5jZSBVbml4IGVwb2NoCiAxOTcwLTAxLTAxVDAwOjAwOjAwWi4gTXVzdCBiZSBmcm9tIDAwMDEtMDEtMDFUMDA6MDA6MDBaIHRvCiA5OTk5LTEyLTMxVDIzOjU5OjU5WiBpbmNsdXNpdmUuCgoNCgUEAAIABBIEfQJ4EwoMCgUEAAIABRIDfQIHCgwKBQQAAgABEgN9CA8KDAoFBAACAAMSA30SEwrlAQoEBAACARIEgwECEhrWASBOb24tbmVnYXRpdmUgZnJhY3Rpb25zIG9mIGEgc2Vjb25kIGF0IG5hbm9zZWNvbmQgcmVzb2x1dGlvbi4gTmVnYXRpdmUKIHNlY29uZCB2YWx1ZXMgd2l0aCBmcmFjdGlvbnMgbXVzdCBzdGlsbCBoYXZlIG5vbi1uZWdhdGl2ZSBuYW5vcyB2YWx1ZXMKIHRoYXQgY291bnQgZm9yd2FyZCBpbiB0aW1lLiBNdXN0IGJlIGZyb20gMCB0byA5OTksOTk5LDk5OQogaW5jbHVzaXZlLgoKDgoFBAACAQQSBYMBAn0UCg0KBQQAAgEFEgSDAQIHCg0KBQQAAgEBEgSDAQgNCg0KBQQAAgEDEgSDARARYgZwcm90bzMKpy8KGXBvbGljeS92MWJldGExL3R5cGUucHJvdG8SFGlzdGlvLnBvbGljeS52MWJldGExGh5nb29nbGUvcHJvdG9idWYvZHVyYXRpb24ucHJvdG8aH2dvb2dsZS9wcm90b2J1Zi90aW1lc3RhbXAucHJvdG8i1wQKBVZhbHVlEiMKDHN0cmluZ192YWx1ZRgBIAEoCUgAUgtzdHJpbmdWYWx1ZRIhCgtpbnQ2NF92YWx1ZRgCIAEoA0gAUgppbnQ2NFZhbHVlEiMKDGRvdWJsZV92YWx1ZRgDIAEoAUgAUgtkb3VibGVWYWx1ZRIfCgpib29sX3ZhbHVlGAQgASgISABSCWJvb2xWYWx1ZRJLChBpcF9hZGRyZXNzX3ZhbHVlGAUgASgLMh8uaXN0aW8ucG9saWN5LnYxYmV0YTEuSVBBZGRyZXNzSABSDmlwQWRkcmVzc1ZhbHVlEkoKD3RpbWVzdGFtcF92YWx1ZRgGIAEoCzIfLmlzdGlvLnBvbGljeS52MWJldGExLlRpbWVTdGFtcEgAUg50aW1lc3RhbXBWYWx1ZRJHCg5kdXJhdGlvbl92YWx1ZRgHIAEoCzIeLmlzdGlvLnBvbGljeS52MWJldGExLkR1cmF0aW9uSABSDWR1cmF0aW9uVmFsdWUSVAoTZW1haWxfYWRkcmVzc192YWx1ZRgIIAEoCzIiLmlzdGlvLnBvbGljeS52MWJldGExLkVtYWlsQWRkcmVzc0gAUhFlbWFpbEFkZHJlc3NWYWx1ZRJFCg5kbnNfbmFtZV92YWx1ZRgJIAEoCzIdLmlzdGlvLnBvbGljeS52MWJldGExLkROU05hbWVIAFIMZG5zTmFtZVZhbHVlEjgKCXVyaV92YWx1ZRgKIAEoCzIZLmlzdGlvLnBvbGljeS52MWJldGExLlVyaUgAUgh1cmlWYWx1ZUIHCgV2YWx1ZSIhCglJUEFkZHJlc3MSFAoFdmFsdWUYASABKAxSBXZhbHVlIjsKCER1cmF0aW9uEi8KBXZhbHVlGAEgASgLMhkuZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uUgV2YWx1ZSI9CglUaW1lU3RhbXASMAoFdmFsdWUYASABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wUgV2YWx1ZSIfCgdETlNOYW1lEhQKBXZhbHVlGAEgASgJUgV2YWx1ZSIkCgxFbWFpbEFkZHJlc3MSFAoFdmFsdWUYASABKAlSBXZhbHVlIhsKA1VyaRIUCgV2YWx1ZRgBIAEoCVIFdmFsdWVCHVobaXN0aW8uaW8vYXBpL3BvbGljeS92MWJldGExSq4nCgYSBA4AfgEKvwQKAQwSAw4AEjK0BCBDb3B5cmlnaHQgMjAxOCBJc3RpbyBBdXRob3JzCgogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKCiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCgoICgECEgMQCBwKCAoBCBIDEgAwCgsKBAjnBwASAxIAMAoMCgUI5wcAAhIDEgcRCg0KBgjnBwACABIDEgcRCg4KBwjnBwACAAESAxIHEQoMCgUI5wcABxIDEhIvCgkKAgMAEgMUBycKCQoCAwESAxUHKArIBgoCBAASBCAAQAEauwYgQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBWYWx1ZSBkZW5vdGVzIHRoYXQgdGhlIGV4cHJlc3Npb24gZm9yIHRoZSBmaWVsZCBpcyBvZiBkeW5hbWljIHR5cGUgYW5kIGNhbiBldmFsYXV0ZSB0byBhbnkKIFtWYWx1ZVR5cGVdW2lzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZV0gZW51bSB2YWx1ZXMuIEZvciBleGFtcGxlLCB3aGVuCiBhdXRob3JpbmcgYW4gaW5zdGFuY2UgY29uZmlndXJhdGlvbiBmb3IgYSB0ZW1wbGF0ZSB0aGF0IGhhcyBhIGZpZWxkIGBkYXRhYCBvZiB0eXBlIGBpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZWAsCiBib3RoIG9mIHRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbnMgYXJlIHZhbGlkIGBkYXRhOiBzb3VyY2UuaXAgfCBpcCgiMC4wLjAuMCIpYCwgYGRhdGE6IHJlcXVlc3QuaWQgfCAiImA7CiB0aGUgcmVzdWx0aW5nIHR5cGUgaXMgZWl0aGVyIFZhbHVlVHlwZS5JUF9BRERSRVNTIG9yIFZhbHVlVHlwZS5TVFJJTkcgZm9yIHRoZSB0d28gY2FzZXMgcmVzcGVjdGl2ZWx5LgoKIE9iamVjdHMgb2YgdHlwZSBWYWx1ZSBhcmUgYWxzbyBwYXNzZWQgdG8gdGhlIGFkYXB0ZXJzIGR1cmluZyByZXF1ZXN0LXRpbWUuIFRoZXJlIGlzIGEgMToxIG1hcHBpbmcgYmV0d2Vlbgogb25lb2YgZmllbGRzIGluIGBWYWx1ZWAgYW5kIGVudW0gdmFsdWVzIGluc2lkZSBgVmFsdWVUeXBlYC4gRGVwZW5kaW5nIG9uIHRoZSBleHByZXNzaW9uJ3MgZXZhbHVhdGVkIGBWYWx1ZVR5cGVgLAogdGhlIGVxdWl2YWxlbnQgb25lb2YgZmllbGQgaW4gYFZhbHVlYCBpcyBwb3B1bGF0ZWQgYnkgTWl4ZXIgYW5kIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMuCgoKCgMEAAESAyAIDQoMCgQEAAgAEgQhBD8FCgwKBQQACAABEgMhCg8KLQoEBAACABIDIwggGiAgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgU1RSSU5HCgoMCgUEAAIABRIDIwgOCgwKBQQAAgABEgMjDxsKDAoFBAACAAMSAyMeHwosCgQEAAIBEgMmCB4aHyBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBJTlQ2NAoKDAoFBAACAQUSAyYIDQoMCgUEAAIBARIDJg4ZCgwKBQQAAgEDEgMmHB0KLQoEBAACAhIDKQggGiAgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgRE9VQkxFCgoMCgUEAAICBRIDKQgOCgwKBQQAAgIBEgMpDxsKDAoFBAACAgMSAykeHworCgQEAAIDEgMsCBwaHiBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBCT09MCgoMCgUEAAIDBRIDLAgMCgwKBQQAAgMBEgMsDRcKDAoFBAACAwMSAywaGwowCgQEAAIEEgMvCCcaIyBVc2VkIGZvciB2YWx1ZXMgb2YgdHlwZSBJUEFkZHJlc3MKCgwKBQQAAgQGEgMvCBEKDAoFBAACBAESAy8SIgoMCgUEAAIEAxIDLyUmCjAKBAQAAgUSAzIIJhojIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIFRJTUVTVEFNUAoKDAoFBAACBQYSAzIIEQoMCgUEAAIFARIDMhIhCgwKBQQAAgUDEgMyJCUKLwoEBAACBhIDNQgkGiIgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgRFVSQVRJT04KCgwKBQQAAgYGEgM1CBAKDAoFBAACBgESAzURHwoMCgUEAAIGAxIDNSIjCjMKBAQAAgcSAzgILRomIFVzZWQgZm9yIHZhbHVlcyBvZiB0eXBlIEVtYWlsQWRkcmVzcwoKDAoFBAACBwYSAzgIFAoMCgUEAAIHARIDOBUoCgwKBQQAAgcDEgM4KywKLgoEBAACCBIDOwgjGiEgVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgRE5TTmFtZQoKDAoFBAACCAYSAzsIDwoMCgUEAAIIARIDOxAeCgwKBQQAAggDEgM7ISIKKgoEBAACCRIDPggbGh0gVXNlZCBmb3IgdmFsdWVzIG9mIHR5cGUgVXJpCgoMCgUEAAIJBhIDPggLCgwKBQQAAgkBEgM+DBUKDAoFBAACCQMSAz4YGgqrAgoCBAESBEcASgEangIgQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBJUEFkZHJlc3MgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5JUF9BRERSRVNTXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuSVBfQUREUkVTU10KCiBPYmplY3RzIG9mIHR5cGUgSVBBZGRyZXNzIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBJUEFkZHJlc3MKCgoKAwQBARIDRwgRCioKBAQBAgASA0kEFBodIElQQWRkcmVzcyBlbmNvZGVkIGFzIGJ5dGVzLgoKDQoFBAECAAQSBEkERxMKDAoFBAECAAUSA0kECQoMCgUEAQIAARIDSQoPCgwKBQQBAgADEgNJEhMKpAIKAgQCEgRRAFQBGpcCIEFuIGluc3RhbmNlIGZpZWxkIG9mIHR5cGUgRHVyYXRpb24gZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5EVVJBVElPTl1baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlLkRVUkFUSU9OXQoKIE9iamVjdHMgb2YgdHlwZSBEdXJhdGlvbiBhcmUgYWxzbyBwYXNzZWQgdG8gdGhlIGFkYXB0ZXJzIGR1cmluZyByZXF1ZXN0LXRpbWUgZm9yIHRoZSBpbnN0YW5jZSBmaWVsZHMgb2YKIHR5cGUgRHVyYXRpb24KCgoKAwQCARIDUQgQCjwKBAQCAgASA1MEJxovIER1cmF0aW9uIGVuY29kZWQgYXMgZ29vZ2xlLnByb3RvYnVmLkR1cmF0aW9uLgoKDQoFBAICAAQSBFMEURIKDAoFBAICAAYSA1MEHAoMCgUEAgIAARIDUx0iCgwKBQQCAgADEgNTJSYKqQIKAgQDEgRbAF4BGpwCIEFuIGluc3RhbmNlIGZpZWxkIG9mIHR5cGUgVGltZVN0YW1wIGRlbm90ZXMgdGhhdCB0aGUgZXhwcmVzc2lvbiBmb3IgdGhlIGZpZWxkIG11c3QgZXZhbGF1dGUgdG8KIFtWYWx1ZVR5cGUuVElNRVNUQU1QXVtpc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGUuVElNRVNUQU1QXQoKIE9iamVjdHMgb2YgdHlwZSBUaW1lU3RhbXAgYXJlIGFsc28gcGFzc2VkIHRvIHRoZSBhZGFwdGVycyBkdXJpbmcgcmVxdWVzdC10aW1lIGZvciB0aGUgaW5zdGFuY2UgZmllbGRzIG9mCiB0eXBlIFRpbWVTdGFtcAoKCgoDBAMBEgNbCBEKPgoEBAMCABIDXQQoGjEgVGltZVN0YW1wIGVuY29kZWQgYXMgZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcC4KCg0KBQQDAgAEEgRdBFsTCgwKBQQDAgAGEgNdBB0KDAoFBAMCAAESA10eIwoMCgUEAwIAAxIDXSYnCqECCgIEBBIEZQBoARqUAiBBbiBpbnN0YW5jZSBmaWVsZCBvZiB0eXBlIEROU05hbWUgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5ETlNfTkFNRV1baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlLkROU19OQU1FXQoKIE9iamVjdHMgb2YgdHlwZSBETlNOYW1lIGFyZSBhbHNvIHBhc3NlZCB0byB0aGUgYWRhcHRlcnMgZHVyaW5nIHJlcXVlc3QtdGltZSBmb3IgdGhlIGluc3RhbmNlIGZpZWxkcyBvZgogdHlwZSBETlNOYW1lCgoKCgMEBAESA2UIDwopCgQEBAIAEgNnBBUaHCBETlNOYW1lIGVuY29kZWQgYXMgc3RyaW5nLgoKDQoFBAQCAAQSBGcEZREKDAoFBAQCAAUSA2cECgoMCgUEBAIAARIDZwsQCgwKBQQEAgADEgNnExQK2wIKAgQFEgRwAHMBGs4CIERPIE5PVCBVU0UgISEgVW5kZXIgRGV2ZWxvcG1lbnQKIEFuIGluc3RhbmNlIGZpZWxkIG9mIHR5cGUgRW1haWxBZGRyZXNzIGRlbm90ZXMgdGhhdCB0aGUgZXhwcmVzc2lvbiBmb3IgdGhlIGZpZWxkIG11c3QgZXZhbGF1dGUgdG8KIFtWYWx1ZVR5cGUuRU1BSUxfQUREUkVTU11baXN0aW8ucG9saWN5LnYxYmV0YTEuVmFsdWVUeXBlLkVNQUlMX0FERFJFU1NdCgogT2JqZWN0cyBvZiB0eXBlIEVtYWlsQWRkcmVzcyBhcmUgYWxzbyBwYXNzZWQgdG8gdGhlIGFkYXB0ZXJzIGR1cmluZyByZXF1ZXN0LXRpbWUgZm9yIHRoZSBpbnN0YW5jZSBmaWVsZHMgb2YKIHR5cGUgRW1haWxBZGRyZXNzCgoKCgMEBQESA3AIFAouCgQEBQIAEgNyBBUaISBFbWFpbEFkZHJlc3MgZW5jb2RlZCBhcyBzdHJpbmcuCgoNCgUEBQIABBIEcgRwFgoMCgUEBQIABRIDcgQKCgwKBQQFAgABEgNyCxAKDAoFBAUCAAMSA3ITFAqsAgoCBAYSBHsAfgEanwIgRE8gTk9UIFVTRSAhISBVbmRlciBEZXZlbG9wbWVudAogQW4gaW5zdGFuY2UgZmllbGQgb2YgdHlwZSBVcmkgZGVub3RlcyB0aGF0IHRoZSBleHByZXNzaW9uIGZvciB0aGUgZmllbGQgbXVzdCBldmFsYXV0ZSB0bwogW1ZhbHVlVHlwZS5VUkldW2lzdGlvLnBvbGljeS52MWJldGExLlZhbHVlVHlwZS5VUkldCgogT2JqZWN0cyBvZiB0eXBlIFVyaSBhcmUgYWxzbyBwYXNzZWQgdG8gdGhlIGFkYXB0ZXJzIGR1cmluZyByZXF1ZXN0LXRpbWUgZm9yIHRoZSBpbnN0YW5jZSBmaWVsZHMgb2YKIHR5cGUgVXJpCgoKCgMEBgESA3sICwolCgQEBgIAEgN9BBUaGCBVcmkgZW5jb2RlZCBhcyBzdHJpbmcuCgoNCgUEBgIABBIEfQR7DQoMCgUEBgIABRIDfQQKCgwKBQQGAgABEgN9CxAKDAoFBAYCAAMSA30TFGIGcHJvdG8zCrVSCjttaXhlci90ZW1wbGF0ZS9hdXRob3JpemF0aW9uL3RlbXBsYXRlX2hhbmRsZXJfc2VydmljZS5wcm90bxINYXV0aG9yaXphdGlvbhoUZ29nb3Byb3RvL2dvZ28ucHJvdG8aLG1peGVyL2FkYXB0ZXIvbW9kZWwvdjFiZXRhMS9leHRlbnNpb25zLnByb3RvGhlnb29nbGUvcHJvdG9idWYvYW55LnByb3RvGidtaXhlci9hZGFwdGVyL21vZGVsL3YxYmV0YTEvY2hlY2sucHJvdG8aH3BvbGljeS92MWJldGExL3ZhbHVlX3R5cGUucHJvdG8aGXBvbGljeS92MWJldGExL3R5cGUucHJvdG8irAEKGkhhbmRsZUF1dGhvcml6YXRpb25SZXF1ZXN0EjYKCGluc3RhbmNlGAEgASgLMhouYXV0aG9yaXphdGlvbi5JbnN0YW5jZU1zZ1IIaW5zdGFuY2USOwoOYWRhcHRlcl9jb25maWcYAiABKAsyFC5nb29nbGUucHJvdG9idWYuQW55Ug1hZGFwdGVyQ29uZmlnEhkKCGRlZHVwX2lkGAMgASgJUgdkZWR1cElkIosBCgtJbnN0YW5jZU1zZxIVCgRuYW1lGK/KvCIgASgJUgRuYW1lEjMKB3N1YmplY3QYASABKAsyGS5hdXRob3JpemF0aW9uLlN1YmplY3RNc2dSB3N1YmplY3QSMAoGYWN0aW9uGAIgASgLMhguYXV0aG9yaXphdGlvbi5BY3Rpb25Nc2dSBmFjdGlvbiLfAQoKU3ViamVjdE1zZxISCgR1c2VyGAEgASgJUgR1c2VyEhYKBmdyb3VwcxgCIAEoCVIGZ3JvdXBzEkkKCnByb3BlcnRpZXMYAyADKAsyKS5hdXRob3JpemF0aW9uLlN1YmplY3RNc2cuUHJvcGVydGllc0VudHJ5Ugpwcm9wZXJ0aWVzGloKD1Byb3BlcnRpZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIxCgV2YWx1ZRgCIAEoCzIbLmlzdGlvLnBvbGljeS52MWJldGExLlZhbHVlUgV2YWx1ZToCOAEilQIKCUFjdGlvbk1zZxIcCgluYW1lc3BhY2UYASABKAlSCW5hbWVzcGFjZRIYCgdzZXJ2aWNlGAIgASgJUgdzZXJ2aWNlEhYKBm1ldGhvZBgDIAEoCVIGbWV0aG9kEhIKBHBhdGgYBCABKAlSBHBhdGgSSAoKcHJvcGVydGllcxgFIAMoCzIoLmF1dGhvcml6YXRpb24uQWN0aW9uTXNnLlByb3BlcnRpZXNFbnRyeVIKcHJvcGVydGllcxpaCg9Qcm9wZXJ0aWVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSMQoFdmFsdWUYAiABKAsyGy5pc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVIFdmFsdWU6AjgBIm8KBFR5cGUSNAoHc3ViamVjdBgBIAEoCzIaLmF1dGhvcml6YXRpb24uU3ViamVjdFR5cGVSB3N1YmplY3QSMQoGYWN0aW9uGAIgASgLMhkuYXV0aG9yaXphdGlvbi5BY3Rpb25UeXBlUgZhY3Rpb24iuQEKC1N1YmplY3RUeXBlEkoKCnByb3BlcnRpZXMYAyADKAsyKi5hdXRob3JpemF0aW9uLlN1YmplY3RUeXBlLlByb3BlcnRpZXNFbnRyeVIKcHJvcGVydGllcxpeCg9Qcm9wZXJ0aWVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSNQoFdmFsdWUYAiABKA4yHy5pc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGVSBXZhbHVlOgI4ASK3AQoKQWN0aW9uVHlwZRJJCgpwcm9wZXJ0aWVzGAUgAygLMikuYXV0aG9yaXphdGlvbi5BY3Rpb25UeXBlLlByb3BlcnRpZXNFbnRyeVIKcHJvcGVydGllcxpeCg9Qcm9wZXJ0aWVzRW50cnkSEAoDa2V5GAEgASgJUgNrZXkSNQoFdmFsdWUYAiABKA4yHy5pc3Rpby5wb2xpY3kudjFiZXRhMS5WYWx1ZVR5cGVSBXZhbHVlOgI4ASKKAQoNSW5zdGFuY2VQYXJhbRI9CgdzdWJqZWN0GAEgASgLMiMuYXV0aG9yaXphdGlvbi5TdWJqZWN0SW5zdGFuY2VQYXJhbVIHc3ViamVjdBI6CgZhY3Rpb24YAiABKAsyIi5hdXRob3JpemF0aW9uLkFjdGlvbkluc3RhbmNlUGFyYW1SBmFjdGlvbiLWAQoUU3ViamVjdEluc3RhbmNlUGFyYW0SEgoEdXNlchgBIAEoCVIEdXNlchIWCgZncm91cHMYAiABKAlSBmdyb3VwcxJTCgpwcm9wZXJ0aWVzGAMgAygLMjMuYXV0aG9yaXphdGlvbi5TdWJqZWN0SW5zdGFuY2VQYXJhbS5Qcm9wZXJ0aWVzRW50cnlSCnByb3BlcnRpZXMaPQoPUHJvcGVydGllc0VudHJ5EhAKA2tleRgBIAEoCVIDa2V5EhQKBXZhbHVlGAIgASgJUgV2YWx1ZToCOAEijAIKE0FjdGlvbkluc3RhbmNlUGFyYW0SHAoJbmFtZXNwYWNlGAEgASgJUgluYW1lc3BhY2USGAoHc2VydmljZRgCIAEoCVIHc2VydmljZRIWCgZtZXRob2QYAyABKAlSBm1ldGhvZBISCgRwYXRoGAQgASgJUgRwYXRoElIKCnByb3BlcnRpZXMYBSADKAsyMi5hdXRob3JpemF0aW9uLkFjdGlvbkluc3RhbmNlUGFyYW0uUHJvcGVydGllc0VudHJ5Ugpwcm9wZXJ0aWVzGj0KD1Byb3BlcnRpZXNFbnRyeRIQCgNrZXkYASABKAlSA2tleRIUCgV2YWx1ZRgCIAEoCVIFdmFsdWU6AjgBMo4BChpIYW5kbGVBdXRob3JpemF0aW9uU2VydmljZRJwChNIYW5kbGVBdXRob3JpemF0aW9uEikuYXV0aG9yaXphdGlvbi5IYW5kbGVBdXRob3JpemF0aW9uUmVxdWVzdBouLmlzdGlvLm1peGVyLmFkYXB0ZXIubW9kZWwudjFiZXRhMS5DaGVja1Jlc3VsdEIl+NLkkwIAgt3kkwINYXV0aG9yaXphdGlvbsjhHgCo4h4A8OEeAErPPwoHEgUQAOIBAQroBAoBDBIDEAASMrQEIENvcHlyaWdodCAyMDE3IElzdGlvIEF1dGhvcnMKCiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKCiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlCiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kCiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KMicgVEhJUyBGSUxFIElTIEFVVE9NQVRJQ0FMTFkgR0VORVJBVEVELgoKnAkKAQISAzQIFRqRCSBUaGUgYGF1dGhvcml6YXRpb25gIHRlbXBsYXRlIGRlZmluZXMgcGFyYW1ldGVycyBmb3IgcGVyZm9ybWluZyBwb2xpY3kKIGVuZm9yY2VtZW50IHdpdGhpbiBJc3Rpby4gSXQgaXMgcHJpbWFyaWx5IGNvbmNlcm5lZCB3aXRoIGVuYWJsaW5nIE1peGVyCiAKIEV4YW1wbGUgY29uZmlnOgogCiBgYGB5YW1sCiBhcGlWZXJzaW9uOiAiY29uZmlnLmlzdGlvLmlvL3YxYWxwaGEyIgoga2luZDogYXV0aG9yaXphdGlvbgogbWV0YWRhdGE6CiAgIG5hbWU6IGF1dGhpbmZvCiAgIG5hbWVzcGFjZTogaXN0aW8tc3lzdGVtCiBzcGVjOgogIHN1YmplY3Q6CiAgICB1c2VyOiBzb3VyY2UudXNlciB8IHJlcXVlc3QuYXV0aC50b2tlblt1c2VyXSB8ICIiCiAgICBncm91cHM6IHJlcXVlc3QuYXV0aC50b2tlbltncm91cHNdCiAgICBwcm9wZXJ0aWVzOgogICAgIGlzczogcmVxdWVzdC5hdXRoLnRva2VuWyJpc3MiXQogIGFjdGlvbjoKICAgIG5hbWVzcGFjZTogZGVzdGluYXRpb24ubmFtZXNwYWNlIHwgImRlZmF1bHQiCiAgICBzZXJ2aWNlOiBkZXN0aW5hdGlvbi5zZXJ2aWNlIHwgIiIKICAgIHBhdGg6IHJlcXVl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dGhlcmVmb3JlIG9wdCB0byByZWNlaXZlIGhhbmRsZXIgY29uZmlndXJhdGlvbiBkdXJpbmcgc2Vzc2lvbiBjcmVhdGlvbiB0aHJvdWdoIFtJbmZyYXN0cnVjdHVyZUJhY2tlbmQuQ3JlYXRlU2Vzc2lvbl1bVE9ETzogTGluayB0byB0aGlzIGZyYWdtZW50XQogY2FsbC4gSW4gdGhhdCBjYXNlLCBhZGFwdGVyX2NvbmZpZyB3aWxsIGhhdmUgdHlwZV91cmwgYXMgJ2dvb2dsZS5wcm90b2J1Zi5BbnkudHlwZV91cmwnIGFuZCB3b3VsZCBjb250YWluIHN0cmluZwogdmFsdWUgb2Ygc2Vzc2lvbl9pZCAocmV0dXJuZWQgZnJvbSBJbmZyYXN0cnVjdHVyZUJhY2tlbmQuQ3JlYXRlU2Vzc2lvbikuCgoNCgUEAAIBBBIEWARQHQoMCgUEAAIBBhIDWAQXCgwKBQQAAgEBEgNYGCYKDAoFBAACAQMSA1gpKgo6CgQEAAICEgNbBBgaLSBJZCB0byBkZWR1cGUgaWRlbnRpY2FsIHJlcXVlc3RzIGZyb20gTWl4ZXIuCgoNCgUEAAICBBIEWwRYKwoMCgUEAAICBRIDWwQKCgwKBQQAAgIBEgNbCxMKDAoFBAACAgMSA1sWFwq9AQoCBAESBGAAbAEasAEgQ29udGFpbnMgaW5zdGFuY2UgcGF5bG9hZCBmb3IgJ2F1dGhvcml6YXRpb24nIHRlbXBsYXRlLiBUaGlzIGlzIHBhc3NlZCB0byBpbmZyYXN0cnVjdHVyZSBiYWNrZW5kcyBkdXJpbmcgcmVxdWVzdC10aW1lCiB0aHJvdWdoIEhhbmRsZUF1dGhvcml6YXRpb25TZXJ2aWNlLkhhbmRsZUF1dGhvcml6YXRpb24uCgoKCgMEAQESA2AIEwpCCgQEAQIAEgNjBBsaNSBOYW1lIG9mIHRoZSBpbnN0YW5jZSBhcyBzcGVjaWZpZWQgaW4gY29uZmlndXJhdGlvbi4KCg0KBQQBAgAEEgRjBGAVCgwKBQQBAgAFEgNjBAoKDAoFBAECAAESA2MLDwoMCgUEAQIAAxIDYxIaCloKBAQBAgESA2cEGxpNIEEgc3ViamVjdCBjb250YWlucyBhIGxpc3Qgb2YgYXR0cmlidXRlcyB0aGF0IGlk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" ---- diff --git a/resources/helm/overlays/maistra-threescale/values.yaml b/resources/helm/overlays/maistra-threescale/values.yaml deleted file mode 100644 index 8055bb8120..0000000000 --- a/resources/helm/overlays/maistra-threescale/values.yaml +++ /dev/null @@ -1,21 +0,0 @@ -enabled: false - -hub: quay.io/3scale -image: 3scale-istio-adapter - -PARAM_THREESCALE_LISTEN_ADDR: 3333 -PARAM_THREESCALE_LOG_LEVEL: info -PARAM_THREESCALE_LOG_JSON: true -PARAM_THREESCALE_LOG_GRPC: false -PARAM_THREESCALE_REPORT_METRICS: true -PARAM_THREESCALE_METRICS_PORT: 8080 -PARAM_THREESCALE_CACHE_TTL_SECONDS: 300 -PARAM_THREESCALE_CACHE_REFRESH_SECONDS: 180 -PARAM_THREESCALE_CACHE_ENTRIES_MAX: 1000 -PARAM_THREESCALE_CACHE_REFRESH_RETRIES: 1 -PARAM_THREESCALE_ALLOW_INSECURE_CONN: false -PARAM_THREESCALE_CLIENT_TIMEOUT_SECONDS: 10 -PARAM_THREESCALE_GRPC_CONN_MAX_SECONDS: 60 -PARAM_THREESCALE_USE_CACHED_BACKEND: false -PARAM_THREESCALE_BACKEND_CACHE_FLUSH_INTERVAL_SECONDS: 15 -PARAM_THREESCALE_BACKEND_CACHE_POLICY_FAIL_CLOSED: true diff --git a/resources/helm/v2.5/README.md b/resources/helm/v2.5/README.md new file mode 100644 index 0000000000..6575a50c70 --- /dev/null +++ b/resources/helm/v2.5/README.md @@ -0,0 +1,136 @@ +# Istio Installer + +Note: If making any changes to the charts or values.yaml in this dir, first read [UPDATING-CHARTS.md](UPDATING-CHARTS.md) + +Istio installer is a modular, 'a-la-carte' installer for Istio. It is based on a +fork of the Istio helm templates, refactored to increase modularity and isolation. + +Goals: +- Improve upgrade experience: users should be able to gradually roll upgrades, with proper +canary deployments for Istio components. It should be possible to deploy a new version while keeping the +stable version in place and gradually migrate apps to the new version. + +- More flexibility: the new installer allows multiple 'environments', allowing applications to select +a set of control plane settings and components. While the entire mesh respects the same APIs and config, +apps may target different 'environments' which contain different instances and variants of Istio. + +- Better security: separate Istio components reside in different namespaces, allowing different teams or +roles to manage different parts of Istio. For example, a security team would maintain the +root CA and policy, a telemetry team may only have access to Prometheus, +and a different team may maintain the control plane components (which are highly security sensitive). + +The install is organized in 'environments' - each environment consists of a set of components +in different namespaces that are configured to work together. Regardless of 'environment', +workloads can talk with each other and obey the Istio configuration resources, but each environment +can use different Istio versions and different configuration defaults. + +`istioctl kube-inject` or the automatic sidecar injector are used to select the environment. +In the case of the sidecar injector, the namespace label `istio-env: ` is used instead +of the conventional `istio-injected: true`. The name of the environment is defined as the namespace +where the corresponding control plane components (config, discovery, auto-injection) are running. +In the examples below, by default this is the `istio-control` namespace. Pod annotations can also +be used to select a different 'environment'. + +## Installing + +The new installer is intended to be modular and very explicit about what is installed. It has +far more steps than the Istio installer - but each step is smaller and focused on a specific +feature, and can be performed by different people/teams at different times. + +It is strongly recommended that different namespaces are used, with different service accounts. +In particular access to the security-critical production components (root CA, policy, control) +should be locked down and restricted. The new installer allows multiple instances of +policy/control/telemetry - so testing/staging of new settings and versions can be performed +by a different role than the prod version. + +The intended users of this repo are users running Istio in production who want to select, tune +and understand each binary that gets deployed, and select which combination to use. + +Note: each component can be installed in parallel with an existing Istio 1.0 or 1.1 install in +`istio-system`. The new components will not interfere with existing apps, but can interoperate +and it is possible to gradually move apps from Istio 1.0/1.1 to the new environments and +across environments ( for example canary -> prod ) + +Note: there are still some cluster roles that may need to be fixed, most likely cluster permissions +will need to move to the security component. + +## Everything is Optional + +Each component in the new installer is optional. Users can install the component defined in the new installer, +use the equivalent component in `istio-system`, configured with the official installer, or use a different +version or implementation. + +For example you may use your own Prometheus and Grafana installs, or you may use a specialized/custom +certificate provisioning tool, or use components that are centrally managed and running in a different cluster. + +This is a work in progress - building on top of the multi-cluster installer. + +As an extreme, the goal is to be possible to run Istio workloads in a cluster without installing any Istio component +in that cluster. Currently the minimum we require is the security provider (node agent or citadel). + +### Install Istio CRDs + +This is the first step of the install. Please do not remove or edit any CRD - config currently requires +all CRDs to be present. On each upgrade it is recommended to reapply the file, to make sure +you get all CRDs. CRDs are separated by release and by component type in the CRD directory. + +Istio has strong integration with certmanager. Some operators may want to keep their current certmanager +CRDs in place and not have Istio modify them. In this case, it is necessary to apply CRD files individually. + +```bash +kubectl apply -k github.com/istio/installer/base +``` + +or + +```bash +kubectl apply -f base/files +``` + +### Install Istio-CNI + +This is an optional step - CNI must run in a dedicated namespace, it is a 'singleton' and extremely +security sensitive. Access to the CNI namespace must be highly restricted. + +**NOTE:** The environment variable `ISTIO_CLUSTER_ISGKE` is assumed to be set to `true` if the cluster +is a GKE cluster. + +```bash +ISTIO_CNI_ARGS= +# TODO: What k8s data can we use for this check for whether GKE? +if [[ "${ISTIO_CLUSTER_ISGKE}" == "true" ]]; then + ISTIO_CNI_ARGS="--set cni.cniBinDir=/home/kubernetes/bin" +fi +iop kube-system istio-cni $IBASE/istio-cni/ ${ISTIO_CNI_ARGS} +``` + +TODO. It is possible to add Istio-CNI later, and gradually migrate. + +### Install Control plane + +This can run in any cluster. A mesh should have at least one cluster should run Pilot or equivalent XDS server, +and it is recommended to have Pilot running in each region and in multiple availability zones for multi cluster. + +```bash +iop istio-control istio-discovery $IBASE/istio-control/istio-discovery \ + --set global.istioNamespace=istio-system + +# Second istio-discovery, using master version of istio +TAG=latest HUB=gcr.io/istio-testing iop istio-master istio-discovery-master $IBASE/istio-control/istio-discovery \ + --set policy.enable=false \ + --set global.istioNamespace=istio-master +``` + +### Gateways + +A cluster may use multiple Gateways, each with a different load balancer IP, domains and certificates. + +Since the domain certificates are stored in the gateway namespace, it is recommended to keep each +gateway in a dedicated namespace and restrict access. + +For large-scale gateways it is optionally possible to use a dedicated pilot in the gateway namespace. + +### Additional test templates + +A number of helm test setups are general-purpose and should be installable in any cluster, to confirm +Istio works properly and allow testing the specific install. diff --git a/resources/helm/v2.5/UPDATING-CHARTS.md b/resources/helm/v2.5/UPDATING-CHARTS.md new file mode 100644 index 0000000000..6156884dc0 --- /dev/null +++ b/resources/helm/v2.5/UPDATING-CHARTS.md @@ -0,0 +1,67 @@ +# Updating charts and values.yaml + +## Acceptable Pull Requests + +Helm charts `values.yaml` represent a complex user facing API that tends to grow uncontrollably over time +due to design choices in Helm. +The underlying Kubernetes resources we configure have 1000s of fields; given enough users and bespoke use cases, +eventually someone will want to customize every one of those fields. +If all fields are exposed in `values.yaml`, we end up with an massive API that is also likely worse than just using the Kubernetes API directly. + +To avoid this, the project attempts to minimize additions to the `values.yaml` API where possible. + +If the change is a dynamic runtime configuration, it probably belongs in the [MeshConfig API](https://github.com/istio/api/blob/master/mesh/v1alpha1/config.proto). +This allows configuration without re-installing or restarting deployments. + +If the change is to a Kubernetes field (such as modifying a Deployment attribute), it will likely need to be install-time configuration. +However, that doesn't necessarily mean a PR to add a value will be accepted. +The `values.yaml` API is intended to maintain a *minimal core set of configuration* that most users will use. +For bespoke use cases, [Helm Chart Customization](https://istio.io/latest/docs/setup/additional-setup/customize-installation-helm/#advanced-helm-chart-customization) can be used +to allow arbitrary customizations. + +If the change truly is generally purpose, it is generally preferred to have broader APIs. For example, instead of providing +direct access to each of the complex fields in [affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/), just providing +a single `affinity` field that is passed through as-is to the Kubernetes resource. +This provides maximum flexibility with minimal API surface overhead. + +## Making changes + +## Step 1. Make changes in charts and values.yaml in `manifests` directory + +Be sure to provide sufficient documentation and example usage in values.yaml. +If the chart has a `values.schema.json`, that should be updated as well. + +## Step 2. Update the istioctl/Operator values + +If you are modifying the `gateway` chart, you can stop here. +All other charts, however, are exposed by `istioctl` and need to follow the steps below. + +The charts in the `manifests` directory are used in istioctl to generate an installation manifest. + +If `values.yaml` is changed, be sure to update corresponding values changes in [../profiles/default.yaml](../profiles/default.yaml) + +## Step 3. Update istioctl schema + +Istioctl uses a [schema](../../operator/pkg/apis/istio/v1alpha1/values_types.proto) to validate the values. Any changes to +the schema must be added here, otherwise istioctl users will see errors. +Once the schema file is updated, run: + +```bash +$ make operator-proto +``` + +This will regenerate the Go structs used for schema validation. + +## Step 4. Update the generated manifests + +Tests of istioctl use the auto-generated manifests to ensure that the istioctl binary has the correct version of the charts. +These manifests can be found in [gen-istio.yaml](../charts/istio-control/istio-discovery/files/gen-istio.yaml). +To regenerate the manifests, run: + +```bash +$ make copy-templates gen-kustomize update-golden +``` + +## Step 5. Create a PR using outputs from Steps 1 to 4 + +Your PR should pass all the checks if you followed these steps. diff --git a/resources/helm/v2.5/default/Chart.yaml b/resources/helm/v2.5/default/Chart.yaml new file mode 100644 index 0000000000..90ddf7568b --- /dev/null +++ b/resources/helm/v2.5/default/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +name: istio-default +# This version is never actually shipped. istio/release-builder will replace it at build-time +# with the appropriate version +version: 1.0.0 +appVersion: 1.0.0 +description: Helm chart for istio default revision components. +keywords: + - istio +sources: + - https://github.com/istio/istio +engine: gotpl +icon: https://istio.io/latest/favicons/android-192x192.png diff --git a/resources/helm/v2.5/default/templates/mutatingwebhook.yaml b/resources/helm/v2.5/default/templates/mutatingwebhook.yaml new file mode 100644 index 0000000000..0790baab3f --- /dev/null +++ b/resources/helm/v2.5/default/templates/mutatingwebhook.yaml @@ -0,0 +1,124 @@ +# Adapted from istio-discovery/templates/mutatingwebhook.yaml +# Removed paths for legacy and default selectors since a revision tag +# is inherently created from a specific revision +{{/* Copy just what we need to avoid expensive deepCopy */}} +{{- $whv := dict + "revision" .Values.revision + "injectionURL" .Values.istiodRemote.injectionURL + "namespace" .Release.Namespace }} +{{- define "core" }} +- name: {{.Prefix}}sidecar-injector.istio.io + clientConfig: + {{- if .injectionURL }} + url: {{ .injectionURL }} + {{- else }} + service: + name: istiod{{- if not (eq .revision "") }}-{{ .revision }}{{- end }} + namespace: {{ .namespace }} + path: "/inject" + {{- end }} + sideEffects: None + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + failurePolicy: Fail + admissionReviewVersions: ["v1beta1", "v1"] +{{- end }} + +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: istio-revision-tag-default + labels: + maistra-version: "2.5.0" + istio.io/tag: "default" + istio.io/rev: {{ .Values.revision | default "default" }} + app: sidecar-injector + release: {{ .Release.Name }} +webhooks: +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "rev.namespace.") ) }} + namespaceSelector: + matchExpressions: + - key: istio.io/rev + operator: In + values: + - "default" + - key: istio-injection + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "rev.object.") ) }} + namespaceSelector: + matchExpressions: + - key: istio.io/rev + operator: DoesNotExist + - key: istio-injection + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + - key: istio.io/rev + operator: In + values: + - "default" + +{{- /* Case 1: Namespace selector enabled, and object selector is not injected */}} +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "namespace.") ) }} + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: In + values: + - enabled + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + +{{- /* Case 2: no namespace label, but object selector is enabled (and revision label is not, which has priority) */}} +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "object.") ) }} + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: In + values: + - "true" + - key: istio.io/rev + operator: DoesNotExist + +{{- if .Values.sidecarInjectorWebhook.enableNamespacesByDefault }} +{{- /* Special case 3: no labels at all */}} +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "auto.") ) }} + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist + - key: "kubernetes.io/metadata.name" + operator: "NotIn" + values: ["kube-system","kube-public","kube-node-lease","local-path-storage"] + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist +{{- end }} diff --git a/resources/helm/v2.5/default/templates/validatingwebhook.yaml b/resources/helm/v2.5/default/templates/validatingwebhook.yaml new file mode 100644 index 0000000000..fc0102b048 --- /dev/null +++ b/resources/helm/v2.5/default/templates/validatingwebhook.yaml @@ -0,0 +1,47 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: istiod-default-validator + labels: + maistra-version: "2.5.0" + app: istiod + istio: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + istio.io/tag: "default" + # Required to make sure this resource is removed + # when purging Istio resources +webhooks: + - name: validation.istio.io + clientConfig: + {{- if .Values.base.validationURL }} + url: {{ .Values.base.validationURL }} + {{- else }} + service: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + path: "/validate" + {{- end }} + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - security.istio.io + - networking.istio.io + - telemetry.istio.io + - extensions.istio.io + {{- if .Values.base.validateGateway }} + - gateway.networking.k8s.io + {{- end }} + apiVersions: + - "*" + resources: + - "*" + failurePolicy: Ignore + sideEffects: None + admissionReviewVersions: ["v1beta1", "v1"] + objectSelector: + matchExpressions: + - key: istio.io/rev + operator: DoesNotExist +--- diff --git a/resources/helm/v2.5/default/values.yaml b/resources/helm/v2.5/default/values.yaml new file mode 100644 index 0000000000..f0b1c35d34 --- /dev/null +++ b/resources/helm/v2.5/default/values.yaml @@ -0,0 +1,27 @@ +global: + # Used to locate istiod. + istioNamespace: "istio-system" + +base: + # Validation webhook configuration url + # For example: https://$remotePilotAddress:15017/validate + validationURL: "" + # If enabled, gateway-api types will be validated using the standard upstream validation logic. + # This is an alternative to deploying the standalone validation server the project provides. + # This is disabled by default, as the cluster may already have a validation server; while technically + # it works to have multiple redundant validations, this adds complexity and operational risks. + # Users should consider enabling this if they want full gateway-api validation but don't have other validation servers. + validateGateway: false + +istiodRemote: + # Sidecar injector mutating webhook configuration url + # For example: https://$remotePilotAddress:15017/inject + injectionURL: "" + +# Revision is set as 'version' label and part of the resource names when installing multiple control planes. +revision: "" + +sidecarInjectorWebhook: + # This enables injection of sidecar in all namespaces, + enableNamespacesByDefault: false + diff --git a/resources/helm/v2.5/gateway/Chart.yaml b/resources/helm/v2.5/gateway/Chart.yaml new file mode 100644 index 0000000000..03251ea2e8 --- /dev/null +++ b/resources/helm/v2.5/gateway/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +name: gateway +description: Helm chart for deploying Istio gateways +type: application + +# This version is never actually shipped. istio/release-builder will replace it at build-time +# with the appropriate version +version: 1.0.0 +appVersion: 1.0.0 + +sources: +- https://github.com/istio/istio +icon: https://istio.io/latest/favicons/android-192x192.png +keywords: +- istio +- gateways \ No newline at end of file diff --git a/resources/helm/v2.5/gateway/README.md b/resources/helm/v2.5/gateway/README.md new file mode 100644 index 0000000000..0e58c00f20 --- /dev/null +++ b/resources/helm/v2.5/gateway/README.md @@ -0,0 +1,148 @@ +# Istio Gateway Helm Chart + +This chart installs an Istio gateway deployment. + +## Setup Repo Info + +```console +helm repo add istio https://istio-release.storage.googleapis.com/charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `istio-ingressgateway`: + +```console +helm install istio-ingressgateway istio/gateway +``` + +## Uninstalling the Chart + +To uninstall/delete the `istio-ingressgateway` deployment: + +```console +helm delete istio-ingressgateway +``` + +## Configuration + +To view support configuration options and documentation, run: + +```console +helm show values istio/gateway +``` + +### `image: auto` Information + +The image used by the chart, `auto`, may be unintuitive. +This exists because the pod spec will be automatically populated at runtime, using the same mechanism as [Sidecar Injection](istio.io/latest/docs/setup/additional-setup/sidecar-injection). +This allows the same configurations and lifecycle to apply to gateways as sidecars. + +Note: this does mean that the namespace the gateway is deployed in must not have the `istio-injection=disabled` label. +See [Controlling the injection policy](https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#controlling-the-injection-policy) for more info. + +### Examples + +#### Egress Gateway + +Deploying a Gateway to be used as an [Egress Gateway](https://istio.io/latest/docs/tasks/traffic-management/egress/egress-gateway/): + +```yaml +service: + # Egress gateways do not need an external LoadBalancer IP + type: ClusterIP +``` + +#### Multi-network/VM Gateway + +Deploying a Gateway to be used as a [Multi-network Gateway](https://istio.io/latest/docs/setup/install/multicluster/) for network `network-1`: + +```yaml +networkGateway: network-1 +``` + +### Migrating from other installation methods + +Installations from other installation methods (such as istioctl, Istio Operator, other helm charts, etc) can be migrated to use the new Helm charts +following the guidance below. +If you are able to, a clean installation is simpler. However, this often requires an external IP migration which can be challenging. + +WARNING: when installing over an existing deployment, the two deployments will be merged together by Helm, which may lead to unexpected results. + +#### Legacy Gateway Helm charts + +Istio historically offered two different charts - `manifests/charts/gateways/istio-ingress` and `manifests/charts/gateways/istio-egress`. +These are replaced by this chart. +While not required, it is recommended all new users use this chart, and existing users migrate when possible. + +This chart has the following benefits and differences: +* Designed with Helm best practices in mind (standardized values options, values schema, values are not all nested under `gateways.istio-ingressgateway.*`, release name and namespace taken into account, etc). +* Utilizes Gateway injection, simplifying upgrades, allowing gateways to run in any namespace, and avoiding repeating config for sidecars and gateways. +* Published to official Istio Helm repository. +* Single chart for all gateways (Ingress, Egress, East West). + +#### General concerns + +For a smooth migration, the resource names and `Deployment.spec.selector` labels must match. + +If you install with `helm install istio-gateway istio/gateway`, resources will be named `istio-gateway` and the `selector` labels set to: + +```yaml +app: istio-gateway +istio: gateway # the release name with leading istio- prefix stripped +``` + +If your existing installation doesn't follow these names, you can override them. For example, if you have resources named `my-custom-gateway` with `selector` labels +`foo=bar,istio=ingressgateway`: + +```yaml +name: my-custom-gateway # Override the name to match existing resources +labels: + app: "" # Unset default app selector label + istio: ingressgateway # override default istio selector label + foo: bar # Add the existing custom selector label +``` + +#### Migrating an existing Helm release + +An existing helm release can be `helm upgrade`d to this chart by using the same release name. For example, if a previous +installation was done like: + +```console +helm install istio-ingress manifests/charts/gateways/istio-ingress -n istio-system +``` + +It could be upgraded with + +```console +helm upgrade istio-ingress manifests/charts/gateway -n istio-system --set name=istio-ingressgateway --set labels.app=istio-ingressgateway --set labels.istio=ingressgateway +``` + +Note the name and labels are overridden to match the names of the existing installation. + +Warning: the helm charts here default to using port 80 and 443, while the old charts used 8080 and 8443. +If you have AuthorizationPolicies that reference port these ports, you should update them during this process, +or customize the ports to match the old defaults. +See the [security advisory](https://istio.io/latest/news/security/istio-security-2021-002/) for more information. + +#### Other migrations + +If you see errors like `rendered manifests contain a resource that already exists` during installation, you may need to forcibly take ownership. + +The script below can handle this for you. Replace `RELEASE` and `NAMESPACE` with the name and namespace of the release: + +```console +KINDS=(service deployment) +RELEASE=istio-ingressgateway +NAMESPACE=istio-system +for KIND in "${KINDS[@]}"; do + kubectl --namespace $NAMESPACE --overwrite=true annotate $KIND $RELEASE meta.helm.sh/release-name=$RELEASE + kubectl --namespace $NAMESPACE --overwrite=true annotate $KIND $RELEASE meta.helm.sh/release-namespace=$NAMESPACE + kubectl --namespace $NAMESPACE --overwrite=true label $KIND $RELEASE app.kubernetes.io/managed-by=Helm +done +``` + +You may ignore errors about resources not being found. diff --git a/resources/helm/v2.5/gateway/templates/NOTES.txt b/resources/helm/v2.5/gateway/templates/NOTES.txt new file mode 100644 index 0000000000..78451d33eb --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/NOTES.txt @@ -0,0 +1,9 @@ +"{{ include "gateway.name" . }}" successfully installed! + +To learn more about the release, try: + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + +Next steps: + * Deploy an HTTP Gateway: https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/ + * Deploy an HTTPS Gateway: https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/ diff --git a/resources/helm/v2.5/gateway/templates/_helpers.tpl b/resources/helm/v2.5/gateway/templates/_helpers.tpl new file mode 100644 index 0000000000..a777d43bcc --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/_helpers.tpl @@ -0,0 +1,61 @@ +{{- define "gateway.name" -}} +{{- if eq .Release.Name "RELEASE-NAME" -}} + {{- .Values.name | default "istio-ingressgateway" -}} +{{- else -}} + {{- .Values.name | default .Release.Name | default "istio-ingressgateway" -}} +{{- end -}} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "gateway.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "gateway.labels" -}} +helm.sh/chart: {{ include "gateway.chart" . }} +{{ include "gateway.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/name: {{ include "gateway.name" . }} +{{- range $key, $val := .Values.labels }} +{{- if not (or (eq $key "app") (eq $key "istio")) }} +{{ $key | quote }}: {{ $val | quote }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "gateway.podLabels" -}} +{{ include "gateway.selectorLabels" . }} +{{- range $key, $val := .Values.labels }} +{{- if not (or (eq $key "app") (eq $key "istio")) }} +{{ $key | quote }}: {{ $val | quote }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "gateway.selectorLabels" -}} +{{- if hasKey .Values.labels "app" }} +{{- with .Values.labels.app }}app: {{.|quote}} +{{- end}} +{{- else }}app: {{ include "gateway.name" . }} +{{- end }} +{{- if hasKey .Values.labels "istio" }} +{{- with .Values.labels.istio }} +istio: {{.|quote}} +{{- end}} +{{- else }} +istio: {{ include "gateway.name" . | trimPrefix "istio-" }} +{{- end }} +{{- end }} + +{{- define "gateway.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- .Values.serviceAccount.name | default (include "gateway.name" .) }} +{{- else }} +{{- .Values.serviceAccount.name | default "default" }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateway/templates/deployment.yaml b/resources/helm/v2.5/gateway/templates/deployment.yaml new file mode 100644 index 0000000000..94d519b4da --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/deployment.yaml @@ -0,0 +1,109 @@ +apiVersion: apps/v1 +kind: {{ .Values.kind | default "Deployment" }} +metadata: + name: {{ include "gateway.name" . }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + {{- include "gateway.labels" . | nindent 4}} + annotations: + {{- .Values.annotations | toYaml | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "gateway.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + maistra-version: "2.5.0" + sidecar.istio.io/inject: "true" + {{- with .Values.revision }} + istio.io/rev: {{ . }} + {{- end }} + {{- include "gateway.podLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "gateway.serviceAccountName" . }} + securityContext: + {{- if .Values.securityContext }} + {{- toYaml .Values.securityContext | nindent 8 }} + {{- else if (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion) }} + # Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326 + sysctls: + - name: net.ipv4.ip_unprivileged_port_start + value: "0" + {{- end }} + containers: + - name: istio-proxy + # "auto" will be populated at runtime by the mutating webhook. See https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#customizing-injection + image: auto + {{- with .Values.imagePullPolicy }} + imagePullPolicy: {{ . }} + {{- end }} + securityContext: + {{- if .Values.containerSecurityContext }} + {{- toYaml .Values.containerSecurityContext | nindent 12 }} + {{- else if (semverCompare ">=1.22-0" .Capabilities.KubeVersion.GitVersion) }} + # Safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326 + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsUser: 1337 + runAsGroup: 1337 + runAsNonRoot: true + {{- else }} + capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + runAsUser: 0 + runAsGroup: 1337 + runAsNonRoot: false + allowPrivilegeEscalation: true + readOnlyRootFilesystem: true + {{- end }} + env: + {{- with .Values.networkGateway }} + - name: ISTIO_META_REQUESTED_NETWORK_VIEW + value: "{{.}}" + {{- end }} + {{- range $key, $val := .Values.env }} + - name: {{ $key }} + value: {{ $val | quote }} + {{- end }} + ports: + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/resources/helm/v2.5/gateway/templates/hpa.yaml b/resources/helm/v2.5/gateway/templates/hpa.yaml new file mode 100644 index 0000000000..765910804e --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if and (.Values.autoscaling.enabled) (eq .Values.kind "Deployment") }} +{{- if (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion)}} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta2 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "gateway.name" . }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + {{- include "gateway.labels" . | nindent 4 }} + annotations: + {{- .Values.annotations | toYaml | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: {{ .Values.kind | default "Deployment" }} + name: {{ include "gateway.name" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + type: Utilization + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateway/templates/role.yaml b/resources/helm/v2.5/gateway/templates/role.yaml new file mode 100644 index 0000000000..6eb0aa8a4c --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/role.yaml @@ -0,0 +1,35 @@ +{{/*Set up roles for Istio Gateway. Not required for gateway-api*/}} +{{- if .Values.rbac.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "gateway.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + {{- include "gateway.labels" . | nindent 4}} + annotations: + {{- .Values.annotations | toYaml | nindent 4 }} +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "gateway.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + {{- include "gateway.labels" . | nindent 4}} + annotations: + {{- .Values.annotations | toYaml | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "gateway.serviceAccountName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "gateway.serviceAccountName" . }} +{{- end }} diff --git a/resources/helm/v2.5/gateway/templates/service.yaml b/resources/helm/v2.5/gateway/templates/service.yaml new file mode 100644 index 0000000000..8c01f75772 --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/service.yaml @@ -0,0 +1,51 @@ +{{- if not (eq .Values.service.type "None") }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "gateway.name" . }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + {{- include "gateway.labels" . | nindent 4 }} + {{- with .Values.networkGateway }} + topology.istio.io/network: "{{.}}" + {{- end }} + annotations: + {{- merge (deepCopy .Values.service.annotations) .Values.annotations | toYaml | nindent 4 }} +spec: +{{- with .Values.service.loadBalancerIP }} + loadBalancerIP: "{{ . }}" +{{- end }} +{{- with .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml . | indent 4 }} +{{- end }} +{{- with .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: "{{ . }}" +{{- end }} + type: {{ .Values.service.type }} + ports: +{{- if .Values.networkGateway }} + - name: status-port + port: 15021 + targetPort: 15021 + - name: tls + port: 15443 + targetPort: 15443 + - name: tls-istiod + port: 15012 + targetPort: 15012 + - name: tls-webhook + port: 15017 + targetPort: 15017 +{{- else }} +{{ .Values.service.ports | toYaml | indent 4 }} +{{- end }} +{{- if .Values.service.externalIPs }} + externalIPs: {{- range .Values.service.externalIPs }} + - {{.}} + {{- end }} +{{- end }} + selector: + {{- include "gateway.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/resources/helm/v2.5/gateway/templates/serviceaccount.yaml b/resources/helm/v2.5/gateway/templates/serviceaccount.yaml new file mode 100644 index 0000000000..d159a72778 --- /dev/null +++ b/resources/helm/v2.5/gateway/templates/serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "gateway.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + {{- include "gateway.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateway/values.schema.json b/resources/helm/v2.5/gateway/values.schema.json new file mode 100644 index 0000000000..f651d4063e --- /dev/null +++ b/resources/helm/v2.5/gateway/values.schema.json @@ -0,0 +1,204 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "global": { + "type": "object" + }, + "affinity": { + "type": "object" + }, + "securityContext": { + "type": ["object", "null"] + }, + "containerSecurityContext": { + "type": ["object", "null"] + }, + "kind":{ + "type": "string", + "enum": ["Deployment", "DaemonSet"] + }, + "annotations": { + "additionalProperties": { + "type": [ + "string", + "integer" + ] + }, + "type": "object" + }, + "autoscaling": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxReplicas": { + "type": "integer" + }, + "minReplicas": { + "type": "integer" + }, + "targetCPUUtilizationPercentage": { + "type": "integer" + } + } + }, + "env": { + "type": "object" + }, + "labels": { + "type": "object" + }, + "name": { + "type": "string" + }, + "nodeSelector": { + "type": "object" + }, + "podAnnotations": { + "type": "object", + "properties": { + "inject.istio.io/templates": { + "type": "string" + }, + "prometheus.io/path": { + "type": "string" + }, + "prometheus.io/port": { + "type": "string" + }, + "prometheus.io/scrape": { + "type": "string" + } + } + }, + "replicaCount": { + "type": "integer" + }, + "resources": { + "type": "object", + "properties": { + "limits": { + "type": "object", + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + } + }, + "requests": { + "type": "object", + "properties": { + "cpu": { + "type": "string" + }, + "memory": { + "type": "string" + } + } + } + } + }, + "revision": { + "type": "string" + }, + "runAsRoot": { + "type": "boolean" + }, + "unprivilegedPort": { + "type": ["string", "boolean"], + "enum": [true, false, "auto"] + }, + "service": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "externalTrafficPolicy": { + "type": "string" + }, + "loadBalancerIP": { + "type": "string" + }, + "loadBalancerSourceRanges": { + "type": "array" + }, + "ports": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": "integer" + }, + "protocol": { + "type": "string" + }, + "targetPort": { + "type": "integer" + } + } + } + }, + "type": { + "type": "string" + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": "object" + }, + "name": { + "type": "string" + }, + "create": { + "type": "boolean" + } + } + }, + "rbac": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "tolerations": { + "type": "array" + }, + "topologySpreadConstraints": { + "type": "array" + }, + "networkGateway": { + "type": "string" + }, + "imagePullPolicy": { + "type": "string", + "enum": ["", "Always", "IfNotPresent", "Never"] + }, + "imagePullSecrets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + } + } +} diff --git a/resources/helm/v2.5/gateway/values.yaml b/resources/helm/v2.5/gateway/values.yaml new file mode 100644 index 0000000000..b62c3eaeb3 --- /dev/null +++ b/resources/helm/v2.5/gateway/values.yaml @@ -0,0 +1,97 @@ +# Name allows overriding the release name. Generally this should not be set +name: "" +# revision declares which revision this gateway is a part of +revision: "" + +replicaCount: 1 + +kind: Deployment + +rbac: + # If enabled, roles will be created to enable accessing certificates from Gateways. This is not needed + # when using http://gateway-api.org/. + enabled: true + +serviceAccount: + # If set, a service account will be created. Otherwise, the default is used + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set, the release name is used + name: "" + +podAnnotations: + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + prometheus.io/path: "/stats/prometheus" + inject.istio.io/templates: "gateway" + sidecar.istio.io/inject: "true" + +# Define the security context for the pod. +# If unset, this will be automatically set to the minimum privileges required to bind to port 80 and 443. +# On Kubernetes 1.22+, this only requires the `net.ipv4.ip_unprivileged_port_start` sysctl. +securityContext: ~ +containerSecurityContext: ~ + +service: + # Type of service. Set to "None" to disable the service entirely + type: LoadBalancer + ports: + - name: status-port + port: 15021 + protocol: TCP + targetPort: 15021 + - name: http2 + port: 80 + protocol: TCP + targetPort: 80 + - name: https + port: 443 + protocol: TCP + targetPort: 443 + annotations: {} + loadBalancerIP: "" + loadBalancerSourceRanges: [] + externalTrafficPolicy: "" + externalIPs: [] + +resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 2000m + memory: 1024Mi + +autoscaling: + enabled: true + minReplicas: 1 + maxReplicas: 5 + targetCPUUtilizationPercentage: 80 + +# Pod environment variables +env: {} + +# Labels to apply to all resources +labels: {} + +# Annotations to apply to all resources +annotations: {} + +nodeSelector: {} + +tolerations: [] + +topologySpreadConstraints: [] + +affinity: {} + +# If specified, the gateway will act as a network gateway for the given network. +networkGateway: "" + +# Specify image pull policy if default behavior isn't desired. +# Default behavior: latest images will be Always else IfNotPresent +imagePullPolicy: "" + +imagePullSecrets: [] diff --git a/resources/helm/v2.5/gateways/istio-egress/Chart.yaml b/resources/helm/v2.5/gateways/istio-egress/Chart.yaml new file mode 100644 index 0000000000..aaa0ea9b16 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +name: istio-egress +# This version is never actually shipped. istio/release-builder will replace it at build-time +# with the appropriate version +version: 1.0.0 +appVersion: 1.0.0 +description: Helm chart for deploying Istio gateways +keywords: + - istio + - egressgateway + - gateways +sources: + - https://github.com/istio/istio +engine: gotpl +icon: https://istio.io/latest/favicons/android-192x192.png diff --git a/resources/helm/v2.5/gateways/istio-egress/NOTES.txt b/resources/helm/v2.5/gateways/istio-egress/NOTES.txt new file mode 100644 index 0000000000..9baacc0ea0 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/NOTES.txt @@ -0,0 +1,45 @@ + +Changes: +- separate namespace allows: +-- easier reconfig of just the gateway +-- TLS secrets and domain name management is isolated, for better security +-- simplified configuration +-- multiple versions of the ingress can be used, to minize upgrade risks + +- the new chart uses the default namespace service account, and doesn't require +additional RBAC permissions. + +- simplified label structure. Label change is not supported on upgrade. + +- for 'internal load balancer' you should deploy a separate gateway, in a different +namespace. + +All ingress gateway have a "app:ingressgateway" label, used to identify it as an +ingress, and an "istio: ingressgateway$SUFFIX" label of Gateway selection. + +The Gateways use "istio: ingressgateway$SUFFIX" selectors. + + +# Multiple gateway versions + + + +# Using different pilot versions + + + +# Migration from istio-system + +Istio 1.0 includes the gateways in istio-system. Since the external IP is associated +with the Service and bound to the namespace, it is recommended to: + +1. Install the new gateway in a new namespace. +2. Copy any TLS certificate to the new namespace, and configure the domains. +3. Checking the new gateway work - for example by overriding the IP in /etc/hosts +4. Modify the DNS server to add the A record of the new namespace +5. Check traffic +6. Delete the A record corresponding to the gateway in istio-system +7. Upgrade istio-system, disabling the ingressgateway +8. Delete the domain TLS certs from istio-system. + +If using certmanager, all Certificate and associated configs must be moved as well. diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/_affinity.tpl b/resources/helm/v2.5/gateways/istio-egress/templates/_affinity.tpl new file mode 100644 index 0000000000..fc1ec54077 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/_affinity.tpl @@ -0,0 +1,104 @@ +{{/* affinity - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ */}} + +{{ define "nodeaffinity" }} +nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityRequiredDuringScheduling" . }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityPreferredDuringScheduling" . }} +{{- end }} + +{{- define "nodeAffinityRequiredDuringScheduling" }} + {{- $nodeSelector := default .global.defaultNodeSelector .nodeSelector -}} + {{- if or .global.arch $nodeSelector }} + nodeSelectorTerms: + - matchExpressions: + {{- if .global.arch }} + - key: kubernetes.io/arch + operator: In + values: + {{- range $key, $val := .global.arch }} + {{- if gt ($val | int) 0 }} + - {{ $key | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $val := $nodeSelector }} + - key: {{ $key }} + operator: In + values: + - {{ $val | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "nodeAffinityPreferredDuringScheduling" }} + {{- range $key, $val := .global.arch }} + {{- if gt ($val | int) 0 }} + - weight: {{ $val | int }} + preference: + matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - {{ $key | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinity" }} +{{- if or .podAntiAffinityLabelSelector .podAntiAffinityTermLabelSelector}} + podAntiAffinity: + {{- if .podAntiAffinityLabelSelector }} + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityRequiredDuringScheduling" . }} + {{- end }} + {{- if .podAntiAffinityTermLabelSelector }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityPreferredDuringScheduling" . }} + {{- end }} +{{- end }} +{{- end }} + +{{- define "podAntiAffinityRequiredDuringScheduling" }} + {{- range $index, $item := .podAntiAffinityLabelSelector }} + - labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + {{- if $item.namespaces }} + namespaces: + {{- $ns := split "," $item.namespaces }} + {{- range $i, $n := $ns }} + - {{ $n | quote }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinityPreferredDuringScheduling" }} + {{- range $index, $item := .podAntiAffinityTermLabelSelector }} + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + weight: 100 + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/_helpers.tpl b/resources/helm/v2.5/gateways/istio-egress/templates/_helpers.tpl new file mode 100644 index 0000000000..ccf8a077f1 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/_helpers.tpl @@ -0,0 +1,35 @@ +{{/* Prometheus is enabled if its enabled and there are no config overrides set */}} +{{ define "prometheus" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.prometheus.enabled + (not (or + .Values.telemetry.v2.prometheus.configOverride.gateway + .Values.telemetry.v2.prometheus.configOverride.inboundSidecar + .Values.telemetry.v2.prometheus.configOverride.outboundSidecar + )) }} +{{- end }} + +{{/* SD has metrics and logging split. Metrics are enabled if SD is enabled and there are no config overrides set */}} +{{ define "sd-metrics" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} + +{{/* SD has metrics and logging split. */}} +{{ define "sd-logs" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + (has .Values.telemetry.v2.stackdriver.outboundAccessLogging (list "" "ERRORS_ONLY")) + (has .Values.telemetry.v2.stackdriver.inboundAccessLogging (list "" "ALL")) + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/autoscale.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/autoscale.yaml new file mode 100644 index 0000000000..5e9865bf67 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/autoscale.yaml @@ -0,0 +1,58 @@ +{{ $gateway := index .Values "gateways" "istio-egressgateway" }} +{{- if and $gateway.autoscaleEnabled $gateway.autoscaleMin $gateway.autoscaleMax }} +{{- if not .Values.global.autoscalingv2API }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ $gateway.autoscaleMax }} + minReplicas: {{ $gateway.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ $gateway.name }} + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ $gateway.cpu.targetAverageUtilization }} +--- +{{- else }} +{{- if (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion)}} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta2 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ $gateway.autoscaleMax }} + minReplicas: {{ $gateway.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ $gateway.name }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ $gateway.cpu.targetAverageUtilization }} +--- +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/deployment.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/deployment.yaml new file mode 100644 index 0000000000..5202916aac --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/deployment.yaml @@ -0,0 +1,451 @@ +{{- define "mesh" }} +{{- if .Values.gatewayAPI.controllerMode }} + discoverySelectors: + - matchLabels: + maistra.io/member-of: "{{ .Release.Namespace }}" +{{- end }} + + # The trust domain corresponds to the trust root of a system. + # Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain + trustDomain: {{ .Values.meshConfig.trustDomain | default .Values.global.trustDomain }} + + # The namespace to treat as the administrative root namespace for Istio configuration. + # When processing a leaf namespace Istio will search for declarations in that namespace first + # and if none are found it will search in the root namespace. Any matching declaration found in the root namespace + # is processed as if it were declared in the leaf namespace. + rootNamespace: {{ .Values.meshConfig.rootNamespace | default .Release.Namespace }} + + {{ $prom := include "prometheus" . | eq "true" }} + {{ $sdMetrics := include "sd-metrics" . | eq "true" }} + {{ $sdLogs := include "sd-logs" . | eq "true" }} + {{- if or $prom $sdMetrics $sdLogs }} + defaultProviders: + {{- if or $prom $sdMetrics }} + metrics: + {{ if $prom }}- prometheus{{ end }} + {{ if $sdMetrics }}- stackdriver{{ end }} + {{- end }} + {{- if $sdLogs }} + accessLogging: + - stackdriver + {{- end }} + {{- end }} + + defaultConfig: + {{- if .Values.global.meshID }} + meshId: "{{ .Values.global.meshID }}" + {{- end }} + {{- with (.Values.global.proxy.variant | default .Values.global.variant) }} + image: + imageType: {{. | quote}} + {{- end }} + tracing: + {{- if eq .Values.global.proxy.tracer "lightstep" }} + lightstep: + # Address of the LightStep Satellite pool + address: {{ .Values.global.tracer.lightstep.address }} + # Access Token used to communicate with the Satellite pool + accessToken: {{ .Values.global.tracer.lightstep.accessToken }} + {{- else if eq .Values.global.proxy.tracer "zipkin" }} + zipkin: + # Address of the Zipkin collector + address: {{ ((.Values.global.tracer).zipkin).address | default (print "zipkin." .Release.Namespace ":9411") }} + {{- else if eq .Values.global.proxy.tracer "datadog" }} + datadog: + # Address of the Datadog Agent + address: {{ .Values.global.tracer.datadog.address | default "$(HOST_IP):8126" }} + {{- else if eq .Values.global.proxy.tracer "stackdriver" }} + stackdriver: + # enables trace output to stdout. + {{- if $.Values.global.tracer.stackdriver.debug }} + debug: {{ $.Values.global.tracer.stackdriver.debug }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfAttributes }} + # The global default max number of attributes per span. + maxNumberOfAttributes: {{ $.Values.global.tracer.stackdriver.maxNumberOfAttributes | default "200" }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfAnnotations }} + # The global default max number of annotation events per span. + maxNumberOfAnnotations: {{ $.Values.global.tracer.stackdriver.maxNumberOfAnnotations | default "200" }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfMessageEvents }} + # The global default max number of message events per span. + maxNumberOfMessageEvents: {{ $.Values.global.tracer.stackdriver.maxNumberOfMessageEvents | default "200" }} + {{- end }} + {{- else if eq .Values.global.proxy.tracer "openCensusAgent" }} + {{/* Fill in openCensusAgent configuration from meshConfig so it isn't overwritten below */}} +{{ toYaml $.Values.meshConfig.defaultConfig.tracing | indent 8 }} + {{- else }} + {} + {{- end }} + {{- if .Values.global.remotePilotAddress }} + {{- if .Values.pilot.enabled }} + discoveryAddress: {{ printf "istiod-remote.%s.svc" .Release.Namespace }}:15012 + {{- else }} + discoveryAddress: {{ printf "istiod.%s.svc" .Release.Namespace }}:15012 + {{- end }} + {{- else }} + discoveryAddress: istiod-{{ .Values.revision | default "default" }}.{{.Release.Namespace}}.svc:15012 + {{- end }} +{{- end }} + +{{/* We take the mesh config above, defined with individual values.yaml, and merge with .Values.meshConfig */}} +{{/* The intent here is that meshConfig.foo becomes the API, rather than re-inventing the API in values.yaml */}} +{{- $originalMesh := include "mesh" . | fromYaml }} +{{- $mesh := mergeOverwrite $originalMesh .Values.meshConfig }} +{{- $gateway := index .Values "gateways" "istio-egressgateway" }} +{{- if eq $gateway.injectionTemplate "" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra.io/gateway: {{ $gateway.name | default "istio-egressgateway" }}.{{ $gateway.namespace | default .Release.Namespace }} + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: +{{- if not $gateway.autoscaleEnabled }} +{{- if $gateway.replicaCount }} + replicas: {{ $gateway.replicaCount }} +{{- end }} +{{- end }} + selector: + matchLabels: +{{ $gateway.labels | toYaml | indent 6 }} + strategy: + rollingUpdate: + maxSurge: {{ $gateway.rollingMaxSurge }} + maxUnavailable: {{ $gateway.rollingMaxUnavailable }} + template: + metadata: + labels: + maistra.io/gateway: {{ $gateway.name | default "istio-egressgateway" }}.{{ $gateway.namespace | default .Release.Namespace }} + maistra-control-plane: {{ .Release.Namespace }} +{{ $gateway.labels | toYaml | indent 8 }} +{{- if eq .Release.Namespace "istio-system"}} + heritage: Tiller + release: istio + chart: gateways +{{- end }} + service.istio.io/canonical-name: {{ $gateway.name }} + {{- if not (eq .Values.revision "") }} + service.istio.io/canonical-revision: {{ .Values.revision }} + {{- else}} + service.istio.io/canonical-revision: latest + {{- end }} + istio.io/rev: {{ .Values.revision | default "default" }} + sidecar.istio.io/inject: "false" + annotations: + istio.io/rev: {{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.enablePrometheusMerge }} + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + prometheus.io/path: "/stats/prometheus" + {{- end }} + sidecar.istio.io/inject: "false" +{{- if $gateway.podAnnotations }} +{{ toYaml $gateway.podAnnotations | indent 8 }} +{{ end }} + spec: +{{- if not $gateway.runAsRoot }} + securityContext: + runAsUser: {{ $gateway.runAsUser }} + runAsGroup: {{ $gateway.runAsGroup }} + runAsNonRoot: true + fsGroup: {{ $gateway.fsGroup }} +{{- end }} + serviceAccountName: {{ $gateway.name }}-service-account +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} +{{- if .Values.global.proxy.enableCoreDump }} + initContainers: + - name: enable-core-dump +{{- if contains "/" .Values.global.proxy.image }} + image: "{{ .Values.global.proxy.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.global.proxy.image | default "proxyv2" }}:{{ .Values.global.tag }}{{with (.Values.global.proxy.variant | default .Values.global.variant)}}-{{.}}{{end}}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + command: + - /bin/sh + args: + - -c + - sysctl -w kernel.core_pattern=/var/lib/istio/data/core.proxy && ulimit -c unlimited + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + privileged: true +{{- end }} + containers: + - name: istio-proxy +{{- if contains "/" .Values.global.proxy.image }} + image: "{{ .Values.global.proxy.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.global.proxy.image | default "proxyv2" }}:{{ .Values.global.tag }}{{with (.Values.global.proxy.variant | default .Values.global.variant)}}-{{.}}{{end}}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + ports: + {{- range $key, $val := $gateway.ports }} + - name: {{ $val.name }} + containerPort: {{ $val.targetPort | default $val.port }} + protocol: {{ $val.protocol | default "TCP" }} + {{- end }} + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - router + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + {{- if .Values.global.proxy.logLevel }} + - --proxyLogLevel={{ .Values.global.proxy.logLevel }} + {{- end}} + {{- if .Values.global.proxy.componentLogLevel }} + - --proxyComponentLogLevel={{ .Values.global.proxy.componentLogLevel }} + {{- end}} + {{- if .Values.global.logging.level }} + - --log_output_level={{ .Values.global.logging.level }} + {{- end}} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if not $gateway.runAsRoot }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- end }} + readinessProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 1 + resources: +{{- if $gateway.resources }} +{{ toYaml $gateway.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + env: +{{- if $gateway.namespace }} +{{- if ne $gateway.namespace .Release.Namespace }} + - name: PROXY_CONFIG + value: |- +{{ toYaml $mesh.defaultConfig | trim | indent 14 }} +{{- end }} +{{- end }} + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + {{- end }} + - name: NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: HOST_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: ISTIO_META_WORKLOAD_NAME + value: {{ $gateway.name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/{{ .Release.Namespace }}/deployments/{{ $gateway.name }} + {{- if $.Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ $.Values.global.meshID }}" + {{- else if .Values.meshConfig.trustDomain }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.meshConfig.trustDomain }}" + {{- end }} + {{- if .Values.meshConfig.trustDomain }} + - name: TRUST_DOMAIN + value: "{{ .Values.meshConfig.trustDomain }}" + {{- end }} + {{- if not $gateway.runAsRoot }} + - name: ISTIO_META_UNPRIVILEGED_POD + value: "true" + {{- end }} + {{- range $key, $val := $gateway.env }} + - name: {{ $key }} + value: "{{ $val }}" + {{- end }} + {{- range $key, $value := .Values.meshConfig.defaultConfig.proxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- $network_set := index $gateway.env "ISTIO_META_NETWORK" }} + {{- if and (not $network_set) .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + - name: ISTIO_META_CLUSTER_ID + value: "{{ $.Values.global.multiCluster.clusterName | default `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + - name: istio-envoy + mountPath: /etc/istio/proxy + - name: config-volume + mountPath: /etc/istio/config +{{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert +{{- end }} +{{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + mountPath: /var/run/secrets/tokens + readOnly: true +{{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + mountPath: /etc/certs + readOnly: true + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + - name: podinfo + mountPath: /etc/istio/pod + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- range $gateway.configVolumes }} + {{- if .mountPath }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- end }} +{{- if $gateway.additionalContainers }} +{{ toYaml $gateway.additionalContainers | indent 8 }} +{{- end }} + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: {} + name: credential-socket + - emptyDir: {} + name: workload-certs +{{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert +{{- end }} + - name: podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - name: istio-envoy + emptyDir: {} + - name: istio-data + emptyDir: {} +{{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} +{{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + secretName: istio.istio-egressgateway-service-account + optional: true + {{- end }} + - name: config-volume + configMap: + name: istio-{{ .Values.revision | default "default" }} + optional: true + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + secret: + secretName: {{ .secretName | quote }} + optional: true + {{- end }} + {{- range $gateway.configVolumes }} + - name: {{ .name }} + configMap: + name: {{ .configMapName | quote }} + optional: true + {{- end }} + affinity: +{{ include "nodeaffinity" (dict "global" .Values.global "nodeSelector" $gateway.nodeSelector) | trim | indent 8 }} + {{- include "podAntiAffinity" $gateway | indent 6 }} +{{- if $gateway.tolerations }} + tolerations: +{{ toYaml $gateway.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/injected-deployment.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/injected-deployment.yaml new file mode 100644 index 0000000000..b06c72004f --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/injected-deployment.yaml @@ -0,0 +1,144 @@ +{{- $gateway := index .Values "gateways" "istio-egressgateway" }} +{{- if ne $gateway.injectionTemplate "" }} +{{/* This provides a minimal gateway, ready to be injected. + Any settings from values.gateways should be here - these are options specific to the gateway. + Global settings, like the image, various env vars and volumes, etc will be injected. + The normal Deployment is not suitable for this, as the original pod spec will override the injection template. */}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $gateway.name | default "istio-egressgateway" }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: +{{- if not $gateway.autoscaleEnabled }} +{{- if $gateway.replicaCount }} + replicas: {{ $gateway.replicaCount }} +{{- end }} +{{- end }} + selector: + matchLabels: +{{ $gateway.labels | toYaml | indent 6 }} + strategy: + rollingUpdate: + maxSurge: {{ $gateway.rollingMaxSurge }} + maxUnavailable: {{ $gateway.rollingMaxUnavailable }} + template: + metadata: + labels: + maistra-control-plane: {{ .Release.Namespace }} +{{ $gateway.labels | toYaml | indent 8 }} +{{- if eq .Release.Namespace "istio-system"}} + heritage: Tiller + release: istio + chart: gateways +{{- end }} + sidecar.istio.io/inject: "true" + {{- with .Values.revision }} + istio.io/rev: {{ . }} + {{- end }} + annotations: + {{- if .Values.meshConfig.enablePrometheusMerge }} + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + prometheus.io/path: "/stats/prometheus" + {{- end }} + sidecar.istio.io/inject: "true" + inject.istio.io/templates: "{{ $gateway.injectionTemplate }}" +{{- if $gateway.podAnnotations }} +{{ toYaml $gateway.podAnnotations | indent 8 }} +{{ end }} + spec: +{{- if not $gateway.runAsRoot }} + securityContext: + runAsUser: {{ $gateway.runAsUser }} + runAsGroup: {{ $gateway.runAsGroup }} + runAsNonRoot: true + fsGroup: {{ $gateway.fsGroup }} +{{- end }} + serviceAccountName: {{ $gateway.name | default "istio-egressgateway" }}-service-account +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} + containers: + - name: istio-proxy + image: auto +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + ports: + {{- range $key, $val := $gateway.ports }} + - containerPort: {{ $val.targetPort | default $val.port }} + protocol: {{ $val.protocol | default "TCP" }} + {{- end }} + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + {{- if not $gateway.runAsRoot }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- end }} + resources: +{{- if $gateway.resources }} +{{ toYaml $gateway.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + env: + {{- if not $gateway.runAsRoot }} + - name: ISTIO_META_UNPRIVILEGED_POD + value: "true" + {{- end }} + {{- range $key, $val := $gateway.env }} + - name: {{ $key }} + value: {{ $val | quote }} + {{- end }} + volumeMounts: + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- range $gateway.configVolumes }} + {{- if .mountPath }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- end }} +{{- if $gateway.additionalContainers }} +{{ toYaml $gateway.additionalContainers | indent 8 }} +{{- end }} + volumes: + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + secret: + secretName: {{ .secretName | quote }} + optional: true + {{- end }} + {{- range $gateway.configVolumes }} + - name: {{ .name }} + configMap: + name: {{ .configMapName | quote }} + optional: true + {{- end }} + affinity: +{{ include "nodeaffinity" (dict "global" .Values.global "nodeSelector" $gateway.nodeSelector) | trim | indent 8 }} + {{- include "podAntiAffinity" $gateway | indent 6 }} +{{- if $gateway.tolerations }} + tolerations: +{{ toYaml $gateway.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/poddisruptionbudget.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..9b146c4ad0 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.global.defaultPodDisruptionBudget.enabled }} +{{ $gateway := index .Values "gateways" "istio-egressgateway" }} +{{- if (semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion) }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | trim | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + minAvailable: 1 + selector: + matchLabels: +{{ $gateway.labels | toYaml | trim | indent 6 }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/role.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/role.yaml new file mode 100644 index 0000000000..60f8485f74 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/role.yaml @@ -0,0 +1,15 @@ +{{ $gateway := index .Values "gateways" "istio-egressgateway" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $gateway.name }}-sds + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] +--- diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/rolebindings.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/rolebindings.yaml new file mode 100644 index 0000000000..cdd79e2f8a --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/rolebindings.yaml @@ -0,0 +1,18 @@ +{{ $gateway := index .Values "gateways" "istio-egressgateway" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $gateway.name }}-sds + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $gateway.name }}-sds +subjects: +- kind: ServiceAccount + name: {{ $gateway.name }}-service-account +--- diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/service.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/service.yaml new file mode 100644 index 0000000000..031849d414 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/service.yaml @@ -0,0 +1,46 @@ +{{ $gateway := index .Values "gateways" "istio-egressgateway" }} +{{- if not $gateway.customService }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + annotations: + {{- range $key, $val := $gateway.serviceAnnotations }} + {{ $key }}: {{ $val | quote }} + {{- end }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: +{{- if $gateway.loadBalancerIP }} + loadBalancerIP: "{{ $gateway.loadBalancerIP }}" +{{- end }} +{{- if $gateway.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml $gateway.loadBalancerSourceRanges | indent 4 }} +{{- end }} +{{- if $gateway.externalTrafficPolicy }} + externalTrafficPolicy: {{$gateway.externalTrafficPolicy }} +{{- end }} + type: {{ $gateway.type }} + selector: +{{ $gateway.labels | toYaml | indent 4 }} + ports: + + {{- range $key, $val := $gateway.ports }} + - + {{- range $pkey, $pval := $val }} + {{ $pkey}}: {{ $pval }} + {{- end }} + {{- end }} + + {{ range $app := $gateway.egressPorts }} + - + port: {{ $app.port }} + name: {{ $app.name }} + {{- end }} +--- +{{ end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/templates/serviceaccount.yaml b/resources/helm/v2.5/gateways/istio-egress/templates/serviceaccount.yaml new file mode 100644 index 0000000000..02636bfd21 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/templates/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{ $gateway := index .Values "gateways" "istio-egressgateway" }} +apiVersion: v1 +kind: ServiceAccount +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +metadata: + name: {{ $gateway.name }}-service-account + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | trim | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} + {{- with $gateway.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/resources/helm/v2.5/gateways/istio-egress/values.yaml b/resources/helm/v2.5/gateways/istio-egress/values.yaml new file mode 100644 index 0000000000..a09dd8aaa7 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-egress/values.yaml @@ -0,0 +1,361 @@ +# Standalone istio egress gateway. +# Should be installed in a separate namespace, to minimize access to config +gateways: + istio-egressgateway: + name: istio-egressgateway + ports: + - port: 80 + targetPort: 8080 + name: http2 + protocol: TCP + - port: 443 + name: https + targetPort: 8443 + protocol: TCP + + labels: + app: istio-egressgateway + istio: egressgateway + + # Scalability tuning + # replicaCount: 1 + rollingMaxSurge: 100% + rollingMaxUnavailable: 25% + autoscaleEnabled: true + autoscaleMin: 1 + autoscaleMax: 5 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 2000m + memory: 1024Mi + cpu: + targetAverageUtilization: 80 + + serviceAnnotations: {} + podAnnotations: {} + type: ClusterIP # change to NodePort or LoadBalancer if need be + + secretVolumes: + - name: egressgateway-certs + secretName: istio-egressgateway-certs + mountPath: /etc/istio/egressgateway-certs + - name: egressgateway-ca-certs + secretName: istio-egressgateway-ca-certs + mountPath: /etc/istio/egressgateway-ca-certs + + configVolumes: [] + additionalContainers: [] + + serviceAccount: + # Annotations to add to the service account + annotations: {} + + ### Advanced options ############ + # TODO: convert to real options, env should not be exposed + env: {} + # Set this to "external" if and only if you want the egress gateway to + # act as a transparent SNI gateway that routes mTLS/TLS traffic to + # external services defined using service entries, where the service + # entry has resolution set to DNS, has one or more endpoints with + # network field set to "external". By default its set to "" so that + # the egress gateway sees the same set of endpoints as the sidecars + # preserving backward compatibility + # ISTIO_META_REQUESTED_NETWORK_VIEW: "" + + nodeSelector: {} + tolerations: [] + + # Specify the pod anti-affinity that allows you to constrain which nodes + # your pod is eligible to be scheduled based on labels on pods that are + # already running on the node rather than based on labels on nodes. + # There are currently two types of anti-affinity: + # "requiredDuringSchedulingIgnoredDuringExecution" + # "preferredDuringSchedulingIgnoredDuringExecution" + # which denote "hard" vs. "soft" requirements, you can define your values + # in "podAntiAffinityLabelSelector" and "podAntiAffinityTermLabelSelector" + # correspondingly. + # For example: + # podAntiAffinityLabelSelector: + # - key: security + # operator: In + # values: S1,S2 + # topologyKey: "kubernetes.io/hostname" + # This pod anti-affinity rule says that the pod requires not to be scheduled + # onto a node if that node is already running a pod with label having key + # "security" and value "S1". + podAntiAffinityLabelSelector: [] + podAntiAffinityTermLabelSelector: [] + + # whether to run the gateway in a privileged container + runAsRoot: false + + # The injection template to use for the gateway. If not set, no injection will be performed. + injectionTemplate: "" + +# Revision is set as 'version' label and part of the resource names when installing multiple control planes. +revision: "" + +# For Helm compatibility. +ownerName: "" + +global: + # set the default set of namespaces to which services, service entries, virtual services, destination + # rules should be exported to. Currently only one value can be provided in this list. This value + # should be one of the following two options: + # * implies these objects are visible to all namespaces, enabling any sidecar to talk to any other sidecar. + # . implies these objects are visible to only to sidecars in the same namespace, or if imported as a Sidecar.egress.host + defaultConfigVisibilitySettings: [] + + # Default node selector to be applied to all deployments so that all pods can be + # constrained to run a particular nodes. Each component can overwrite these default + # values by adding its node selector block in the relevant section below and setting + # the desired values. + defaultNodeSelector: {} + + # enable pod disruption budget for the control plane, which is used to + # ensure Istio control plane components are gradually upgraded or recovered. + defaultPodDisruptionBudget: + enabled: true + + # A minimal set of requested resources to applied to all deployments so that + # Horizontal Pod Autoscaler will be able to function (if set). + # Each component can overwrite these default values by adding its own resources + # block in the relevant section below and setting the desired resources values. + defaultResources: + requests: + cpu: 10m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + + # Default node tolerations to be applied to all deployments so that all pods can be + # scheduled to a particular nodes with matching taints. Each component can overwrite + # these default values by adding its tolerations block in the relevant section below + # and setting the desired values. + # Configure this field in case that all pods of Istio control plane are expected to + # be scheduled to particular nodes with specified taints. + defaultTolerations: [] + + # Default hub for Istio images. + # Releases are published to docker hub under 'istio' project. + # Dev builds from prow are on gcr.io + hub: gcr.io/istio-testing + + # Default tag for Istio images. + tag: latest + + # Specify image pull policy if default behavior isn't desired. + # Default behavior: latest images will be Always else IfNotPresent. + imagePullPolicy: "" + + # ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace + # to use for pulling any images in pods that reference this ServiceAccount. + # For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing) + # ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects. + # Must be set for any cluster configured with private docker registry. + imagePullSecrets: [] + # - private-registry-key + + # To output all istio components logs in json format by adding --log_as_json argument to each container argument + logAsJson: false + + # Specify pod scheduling arch(amd64, ppc64le, s390x, arm64) and weight as follows: + # 0 - Never scheduled + # 1 - Least preferred + # 2 - No preference + # 3 - Most preferred + arch: {} + + # Comma-separated minimum per-scope logging level of messages to output, in the form of :,: + # The control plane has different scopes depending on component, but can configure default log level across all components + # If empty, default scope and level will be used as configured in code + logging: + level: "default:info" + + # Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and + # system-node-critical, it is better to configure this in order to make sure your Istio pods + # will not be killed because of low priority class. + # Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + # for more detail. + priorityClassName: "" + + proxy: + image: proxyv2 + + # CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value + # cluster domain. Default value is "cluster.local". + clusterDomain: "cluster.local" + + # Per Component log level for proxy, applies to gateways and sidecars. If a component level is + # not set, then the global "logLevel" will be used. + componentLogLevel: "misc:error" + + # If set, newly injected sidecars will have core dumps enabled. + enableCoreDump: false + + # Log level for proxy, applies to gateways and sidecars. + # Expected values are: trace|debug|info|warning|error|critical|off + logLevel: warning + + tracer: zipkin + + ############################################################################################## + # The following values are found in other charts. To effectively modify these values, make # + # make sure they are consistent across your Istio helm charts # + ############################################################################################## + + # The customized CA address to retrieve certificates for the pods in the cluster. + # CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint. + caAddress: "" + + # Used to locate istiod. + istioNamespace: istio-system + + # Configure the policy for validating JWT. + # Currently, two options are supported: "third-party-jwt" and "first-party-jwt". + jwtPolicy: "third-party-jwt" + + # Mesh ID means Mesh Identifier. It should be unique within the scope where + # meshes will interact with each other, but it is not required to be + # globally/universally unique. For example, if any of the following are true, + # then two meshes must have different Mesh IDs: + # - Meshes will have their telemetry aggregated in one place + # - Meshes will be federated together + # - Policy will be written referencing one mesh from the other + # + # If an administrator expects that any of these conditions may become true in + # the future, they should ensure their meshes have different Mesh IDs + # assigned. + # + # Within a multicluster mesh, each cluster must be (manually or auto) + # configured to have the same Mesh ID value. If an existing cluster 'joins' a + # multicluster mesh, it will need to be migrated to the new mesh ID. Details + # of migration TBD, and it may be a disruptive operation to change the Mesh + # ID post-install. + # + # If the mesh admin does not specify a value, Istio will use the value of the + # mesh's Trust Domain. The best practice is to select a proper Trust Domain + # value. + meshID: "" + + # Use the user-specified, secret volume mounted key and certs for Pilot and workloads. + mountMtlsCerts: false + + multiCluster: + # Set to true to connect two kubernetes clusters via their respective + # ingressgateway services when pods in each cluster cannot directly + # talk to one another. All clusters should be using Istio mTLS and must + # have a shared root CA for this model to work. + enabled: false + # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection + # to properly label proxies + clusterName: "" + + # Network defines the network this cluster belong to. This name + # corresponds to the networks in the map of mesh networks. + network: "" + + # Configure the certificate provider for control plane communication. + # Currently, two providers are supported: "kubernetes" and "istiod". + # As some platforms may not have kubernetes signing APIs, + # Istiod is the default + pilotCertProvider: istiod + + sds: + # The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3. + # When a CSR is sent from Citadel Agent to the CA (e.g. Citadel), this aud is to make sure the + # JWT is intended for the CA. + token: + aud: istio-ca + + sts: + # The service port used by Security Token Service (STS) server to handle token exchange requests. + # Setting this port to a non-zero value enables STS server. + servicePort: 0 + + # whether to use autoscaling/v2 template for HPA settings + # for internal usage only, not to be configured by users. + autoscalingv2API: true + + # Configure TLS parameters for listeners + tls: + # List of supported cipher suites, e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + cipherSuites: [] + # List of supported ECDH curves, e.g. CurveP384 + ecdhCurves: [] + # min supported protocol version, e.g. TLSv1_2 + minProtocolVersion: "" + # max supported protocol version, e.g. TLSv1_3 + maxProtocolVersion: "" + + # Configuration for each of the supported tracers + tracer: + # Configuration for envoy to send trace data to LightStep. + # Disabled by default. + # address: the : of the satellite pool + # accessToken: required for sending data to the pool + # + datadog: + # Host:Port for submitting traces to the Datadog agent. + address: "$(HOST_IP):8126" + lightstep: + address: "" # example: lightstep-satellite:443 + accessToken: "" # example: abcdefg1234567 + stackdriver: + # enables trace output to stdout. + debug: false + # The global default max number of message events per span. + maxNumberOfMessageEvents: 200 + # The global default max number of annotation events per span. + maxNumberOfAnnotations: 200 + # The global default max number of attributes per span. + maxNumberOfAttributes: 200 + zipkin: + # Host:Port for reporting trace data in zipkin format. If not specified, will default to + # zipkin service (port 9411) in the same namespace as the other istio components. + address: "" + +meshConfig: + enablePrometheusMerge: true + + # The trust domain corresponds to the trust root of a system + # Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain + trustDomain: "cluster.local" + + defaultConfig: + proxyMetadata: + ISTIO_META_DNS_CAPTURE: "true" + ISTIO_META_DNS_AUTO_ALLOCATE: "true" + PROXY_XDS_VIA_AGENT: "true" + tracing: + # tlsSettings: + # mode: DISABLE # DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + # clientCertificate: # example: /etc/istio/tracer/cert-chain.pem + # privateKey: # example: /etc/istio/tracer/key.pem + # caCertificates: # example: /etc/istio/tracer/root-cert.pem + # sni: # example: tracer.somedomain + # subjectAltNames: [] + # - tracer.somedomain + +gatewayAPI: + enabled: false + controllerMode: false + +telemetry: + enabled: true + v2: + enabled: true + prometheus: + enabled: true + configOverride: + gateway: {} + inboundSidecar: {} + outboundSidecar: {} + stackdriver: + enabled: false + configOverride: {} + disableOutbound: false diff --git a/resources/helm/v2.5/gateways/istio-ingress/Chart.yaml b/resources/helm/v2.5/gateways/istio-ingress/Chart.yaml new file mode 100644 index 0000000000..0314ba11a8 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +name: istio-ingress +# This version is never actually shipped. istio/release-builder will replace it at build-time +# with the appropriate version +version: 1.0.0 +appVersion: 1.0.0 +tillerVersion: ">=2.7.2" +description: Helm chart for deploying Istio gateways +keywords: + - istio + - ingressgateway + - gateways +sources: + - http://github.com/istio/istio +engine: gotpl +icon: https://istio.io/latest/favicons/android-192x192.png diff --git a/resources/helm/v2.5/gateways/istio-ingress/NOTES.txt b/resources/helm/v2.5/gateways/istio-ingress/NOTES.txt new file mode 100644 index 0000000000..221ee56053 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/NOTES.txt @@ -0,0 +1,43 @@ + +Changes: +- separate namespace allows: +-- easier reconfig of just the gateway +-- TLS secrets and domain name management is isolated, for better security +-- simplified configuration +-- multiple versions of the ingress can be used, to minimize upgrade risks + +- the new chart uses the default namespace service account, and doesn't require +additional RBAC permissions. + +- simplified label and chart structure. +- ability to run a pilot dedicated for the gateway, isolated from the main pilot. This is more robust, safer on upgrades +and allows a bit more flexibility. +- the dedicated pilot-per-ingress is required if the gateway needs to support k8s-style ingress. + +# Port and basic host configuration + +In order to configure the Service object, the install/upgrade needs to provide a list of all ports. +In the past, this was done when installing/upgrading full istio, and involved some duplication - ports configured +both in upgrade, Gateway and VirtualService. + +The new Ingress chart uses a 'values.yaml' (see user-example-ingress), which auto-generates Service ports, +Gateways and basic VirtualService. It is still possible to only configure the ports in Service, and do manual +config for the rest. + +All internal services ( telemetry, pilot debug ports, mesh expansion ) can now be configured via the new mechanism. + +# Migration from istio-system + +Istio 1.0 includes the gateways in istio-system. Since the external IP is associated +with the Service and bound to the namespace, it is recommended to: + +1. Install the new gateway in a new namespace. +2. Copy any TLS certificate to the new namespace, and configure the domains. +3. Checking the new gateway work - for example by overriding the IP in /etc/hosts +4. Modify the DNS server to add the A record of the new namespace +5. Check traffic +6. Delete the A record corresponding to the gateway in istio-system +7. Upgrade istio-system, disabling the ingressgateway +8. Delete the domain TLS certs from istio-system. + +If using certmanager, all Certificate and associated configs must be moved as well. diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/_affinity.tpl b/resources/helm/v2.5/gateways/istio-ingress/templates/_affinity.tpl new file mode 100644 index 0000000000..fc1ec54077 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/_affinity.tpl @@ -0,0 +1,104 @@ +{{/* affinity - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ */}} + +{{ define "nodeaffinity" }} +nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityRequiredDuringScheduling" . }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityPreferredDuringScheduling" . }} +{{- end }} + +{{- define "nodeAffinityRequiredDuringScheduling" }} + {{- $nodeSelector := default .global.defaultNodeSelector .nodeSelector -}} + {{- if or .global.arch $nodeSelector }} + nodeSelectorTerms: + - matchExpressions: + {{- if .global.arch }} + - key: kubernetes.io/arch + operator: In + values: + {{- range $key, $val := .global.arch }} + {{- if gt ($val | int) 0 }} + - {{ $key | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $val := $nodeSelector }} + - key: {{ $key }} + operator: In + values: + - {{ $val | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "nodeAffinityPreferredDuringScheduling" }} + {{- range $key, $val := .global.arch }} + {{- if gt ($val | int) 0 }} + - weight: {{ $val | int }} + preference: + matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - {{ $key | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinity" }} +{{- if or .podAntiAffinityLabelSelector .podAntiAffinityTermLabelSelector}} + podAntiAffinity: + {{- if .podAntiAffinityLabelSelector }} + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityRequiredDuringScheduling" . }} + {{- end }} + {{- if .podAntiAffinityTermLabelSelector }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityPreferredDuringScheduling" . }} + {{- end }} +{{- end }} +{{- end }} + +{{- define "podAntiAffinityRequiredDuringScheduling" }} + {{- range $index, $item := .podAntiAffinityLabelSelector }} + - labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + {{- if $item.namespaces }} + namespaces: + {{- $ns := split "," $item.namespaces }} + {{- range $i, $n := $ns }} + - {{ $n | quote }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinityPreferredDuringScheduling" }} + {{- range $index, $item := .podAntiAffinityTermLabelSelector }} + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + weight: 100 + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/_helpers.tpl b/resources/helm/v2.5/gateways/istio-ingress/templates/_helpers.tpl new file mode 100644 index 0000000000..ccf8a077f1 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/_helpers.tpl @@ -0,0 +1,35 @@ +{{/* Prometheus is enabled if its enabled and there are no config overrides set */}} +{{ define "prometheus" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.prometheus.enabled + (not (or + .Values.telemetry.v2.prometheus.configOverride.gateway + .Values.telemetry.v2.prometheus.configOverride.inboundSidecar + .Values.telemetry.v2.prometheus.configOverride.outboundSidecar + )) }} +{{- end }} + +{{/* SD has metrics and logging split. Metrics are enabled if SD is enabled and there are no config overrides set */}} +{{ define "sd-metrics" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} + +{{/* SD has metrics and logging split. */}} +{{ define "sd-logs" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + (has .Values.telemetry.v2.stackdriver.outboundAccessLogging (list "" "ERRORS_ONLY")) + (has .Values.telemetry.v2.stackdriver.inboundAccessLogging (list "" "ALL")) + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/autoscale.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/autoscale.yaml new file mode 100644 index 0000000000..2eafd20f51 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/autoscale.yaml @@ -0,0 +1,58 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if and $gateway.autoscaleEnabled $gateway.autoscaleMin $gateway.autoscaleMax }} +{{- if not .Values.global.autoscalingv2API }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ $gateway.autoscaleMax }} + minReplicas: {{ $gateway.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ $gateway.name }} + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ $gateway.cpu.targetAverageUtilization }} +--- +{{- else }} +{{- if (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion)}} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta2 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ $gateway.autoscaleMax }} + minReplicas: {{ $gateway.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ $gateway.name }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ $gateway.cpu.targetAverageUtilization }} +--- +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/deployment.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/deployment.yaml new file mode 100644 index 0000000000..d15af404cd --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/deployment.yaml @@ -0,0 +1,451 @@ +{{- define "mesh" }} +{{- if .Values.gatewayAPI.controllerMode }} + discoverySelectors: + - matchLabels: + maistra.io/member-of: "{{ .Release.Namespace }}" +{{- end }} + + # The trust domain corresponds to the trust root of a system. + # Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain + trustDomain: {{ .Values.meshConfig.trustDomain | default .Values.global.trustDomain }} + + # The namespace to treat as the administrative root namespace for Istio configuration. + # When processing a leaf namespace Istio will search for declarations in that namespace first + # and if none are found it will search in the root namespace. Any matching declaration found in the root namespace + # is processed as if it were declared in the leaf namespace. + rootNamespace: {{ .Values.meshConfig.rootNamespace | default .Release.Namespace }} + + {{ $prom := include "prometheus" . | eq "true" }} + {{ $sdMetrics := include "sd-metrics" . | eq "true" }} + {{ $sdLogs := include "sd-logs" . | eq "true" }} + {{- if or $prom $sdMetrics $sdLogs }} + defaultProviders: + {{- if or $prom $sdMetrics }} + metrics: + {{ if $prom }}- prometheus{{ end }} + {{ if $sdMetrics }}- stackdriver{{ end }} + {{- end }} + {{- if $sdLogs }} + accessLogging: + - stackdriver + {{- end }} + {{- end }} + + defaultConfig: + {{- if .Values.global.meshID }} + meshId: "{{ .Values.global.meshID }}" + {{- end }} + {{- with (.Values.global.proxy.variant | default .Values.global.variant) }} + image: + imageType: {{. | quote}} + {{- end }} + tracing: + {{- if eq .Values.global.proxy.tracer "lightstep" }} + lightstep: + # Address of the LightStep Satellite pool + address: {{ .Values.global.tracer.lightstep.address }} + # Access Token used to communicate with the Satellite pool + accessToken: {{ .Values.global.tracer.lightstep.accessToken }} + {{- else if eq .Values.global.proxy.tracer "zipkin" }} + zipkin: + # Address of the Zipkin collector + address: {{ ((.Values.global.tracer).zipkin).address | default (print "zipkin." .Release.Namespace ":9411") }} + {{- else if eq .Values.global.proxy.tracer "datadog" }} + datadog: + # Address of the Datadog Agent + address: {{ .Values.global.tracer.datadog.address | default "$(HOST_IP):8126" }} + {{- else if eq .Values.global.proxy.tracer "stackdriver" }} + stackdriver: + # enables trace output to stdout. + {{- if $.Values.global.tracer.stackdriver.debug }} + debug: {{ $.Values.global.tracer.stackdriver.debug }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfAttributes }} + # The global default max number of attributes per span. + maxNumberOfAttributes: {{ $.Values.global.tracer.stackdriver.maxNumberOfAttributes | default "200" }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfAnnotations }} + # The global default max number of annotation events per span. + maxNumberOfAnnotations: {{ $.Values.global.tracer.stackdriver.maxNumberOfAnnotations | default "200" }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfMessageEvents }} + # The global default max number of message events per span. + maxNumberOfMessageEvents: {{ $.Values.global.tracer.stackdriver.maxNumberOfMessageEvents | default "200" }} + {{- end }} + {{- else if eq .Values.global.proxy.tracer "openCensusAgent" }} + {{/* Fill in openCensusAgent configuration from meshConfig so it isn't overwritten below */}} +{{ toYaml $.Values.meshConfig.defaultConfig.tracing | indent 8 }} + {{- else }} + {} + {{- end }} + {{- if .Values.global.remotePilotAddress }} + {{- if .Values.pilot.enabled }} + discoveryAddress: {{ printf "istiod-remote.%s.svc" .Release.Namespace }}:15012 + {{- else }} + discoveryAddress: {{ printf "istiod.%s.svc" .Release.Namespace }}:15012 + {{- end }} + {{- else }} + discoveryAddress: istiod-{{ .Values.revision | default "default" }}.{{.Release.Namespace}}.svc:15012 + {{- end }} +{{- end }} + +{{/* We take the mesh config above, defined with individual values.yaml, and merge with .Values.meshConfig */}} +{{/* The intent here is that meshConfig.foo becomes the API, rather than re-inventing the API in values.yaml */}} +{{- $originalMesh := include "mesh" . | fromYaml }} +{{- $mesh := mergeOverwrite $originalMesh .Values.meshConfig }} +{{- $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if eq $gateway.injectionTemplate "" }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra.io/gateway: {{ $gateway.name | default "istio-ingressgateway" }}.{{ $gateway.namespace | default .Release.Namespace }} + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: +{{- if not $gateway.autoscaleEnabled }} +{{- if $gateway.replicaCount }} + replicas: {{ $gateway.replicaCount }} +{{- end }} +{{- end }} + selector: + matchLabels: +{{ $gateway.labels | toYaml | indent 6 }} + strategy: + rollingUpdate: + maxSurge: {{ $gateway.rollingMaxSurge }} + maxUnavailable: {{ $gateway.rollingMaxUnavailable }} + template: + metadata: + labels: + maistra.io/gateway: {{ $gateway.name | default "istio-ingressgateway" }}.{{ $gateway.namespace | default .Release.Namespace }} + maistra-control-plane: {{ .Release.Namespace }} +{{ $gateway.labels | toYaml | indent 8 }} +{{- if eq .Release.Namespace "istio-system"}} + heritage: Tiller + release: istio + chart: gateways +{{- end }} + service.istio.io/canonical-name: {{ $gateway.name }} + {{- if not (eq .Values.revision "") }} + service.istio.io/canonical-revision: {{ .Values.revision }} + {{- else}} + service.istio.io/canonical-revision: latest + {{- end }} + istio.io/rev: {{ .Values.revision | default "default" }} + sidecar.istio.io/inject: "false" + annotations: + istio.io/rev: {{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.enablePrometheusMerge }} + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + prometheus.io/path: "/stats/prometheus" + {{- end }} + sidecar.istio.io/inject: "false" +{{- if $gateway.podAnnotations }} +{{ toYaml $gateway.podAnnotations | indent 8 }} +{{ end }} + spec: +{{- if not $gateway.runAsRoot }} + securityContext: + runAsUser: {{ $gateway.runAsUser }} + runAsGroup: {{ $gateway.runAsGroup }} + runAsNonRoot: true + fsGroup: {{ $gateway.fsGroup }} +{{- end }} + serviceAccountName: {{ $gateway.name }}-service-account +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} +{{- if .Values.global.proxy.enableCoreDump }} + initContainers: + - name: enable-core-dump +{{- if contains "/" .Values.global.proxy.image }} + image: "{{ .Values.global.proxy.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.global.proxy.image | default "proxyv2" }}:{{ .Values.global.tag }}{{with (.Values.global.proxy.variant | default .Values.global.variant)}}-{{.}}{{end}}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + command: + - /bin/sh + args: + - -c + - sysctl -w kernel.core_pattern=/var/lib/istio/data/core.proxy && ulimit -c unlimited + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + privileged: true +{{- end }} + containers: + - name: istio-proxy +{{- if contains "/" .Values.global.proxy.image }} + image: "{{ .Values.global.proxy.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.global.proxy.image | default "proxyv2" }}:{{ .Values.global.tag }}{{with (.Values.global.proxy.variant | default .Values.global.variant)}}-{{.}}{{end}}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + ports: + {{- range $key, $val := $gateway.ports }} + - name: {{ $val.name }} + containerPort: {{ $val.targetPort | default $val.port }} + protocol: {{ $val.protocol | default "TCP" }} + {{- end }} + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - router + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + {{- if .Values.global.proxy.logLevel }} + - --proxyLogLevel={{ .Values.global.proxy.logLevel }} + {{- end}} + {{- if .Values.global.proxy.componentLogLevel }} + - --proxyComponentLogLevel={{ .Values.global.proxy.componentLogLevel }} + {{- end}} + {{- if .Values.global.logging.level }} + - --log_output_level={{ .Values.global.logging.level }} + {{- end}} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if not $gateway.runAsRoot }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- end }} + readinessProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 1 + resources: +{{- if $gateway.resources }} +{{ toYaml $gateway.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + env: +{{- if $gateway.namespace }} +{{- if ne $gateway.namespace .Release.Namespace }} + - name: PROXY_CONFIG + value: |- +{{ toYaml $mesh.defaultConfig | trim | indent 14 }} +{{- end }} +{{- end }} + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + {{- end }} + - name: NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + - name: HOST_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: ISTIO_META_WORKLOAD_NAME + value: {{ $gateway.name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/{{ .Release.Namespace }}/deployments/{{ $gateway.name }} + {{- if $.Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ $.Values.global.meshID }}" + {{- else if .Values.meshConfig.trustDomain }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.meshConfig.trustDomain }}" + {{- end }} + {{- if .Values.meshConfig.trustDomain }} + - name: TRUST_DOMAIN + value: "{{ .Values.meshConfig.trustDomain }}" + {{- end }} + {{- if not $gateway.runAsRoot }} + - name: ISTIO_META_UNPRIVILEGED_POD + value: "true" + {{- end }} + {{- range $key, $val := $gateway.env }} + - name: {{ $key }} + value: "{{ $val }}" + {{- end }} + {{- range $key, $value := .Values.meshConfig.defaultConfig.proxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- $network_set := index $gateway.env "ISTIO_META_NETWORK" }} + {{- if and (not $network_set) .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + - name: ISTIO_META_CLUSTER_ID + value: "{{ $.Values.global.multiCluster.clusterName | default `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + - name: istio-envoy + mountPath: /etc/istio/proxy + - name: config-volume + mountPath: /etc/istio/config +{{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert +{{- end }} +{{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + mountPath: /var/run/secrets/tokens + readOnly: true +{{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + mountPath: /etc/certs + readOnly: true + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + - name: podinfo + mountPath: /etc/istio/pod + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- range $gateway.configVolumes }} + {{- if .mountPath }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- end }} +{{- if $gateway.additionalContainers }} +{{ toYaml $gateway.additionalContainers | indent 8 }} +{{- end }} + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: {} + name: credential-socket + - emptyDir: {} + name: workload-certs +{{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert +{{- end }} + - name: podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - name: istio-envoy + emptyDir: {} + - name: istio-data + emptyDir: {} +{{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} +{{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + secretName: istio.istio-ingressgateway-service-account + optional: true + {{- end }} + - name: config-volume + configMap: + name: istio-{{ .Values.revision | default "default" }} + optional: true + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + secret: + secretName: {{ .secretName | quote }} + optional: true + {{- end }} + {{- range $gateway.configVolumes }} + - name: {{ .name }} + configMap: + name: {{ .configMapName | quote }} + optional: true + {{- end }} + affinity: +{{ include "nodeaffinity" (dict "global" .Values.global "nodeSelector" $gateway.nodeSelector) | trim | indent 8 }} + {{- include "podAntiAffinity" $gateway | indent 6 }} +{{- if $gateway.tolerations }} + tolerations: +{{ toYaml $gateway.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/gateways.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/gateways.yaml new file mode 100644 index 0000000000..22dad422c2 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/gateways.yaml @@ -0,0 +1,34 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if and (.Values.global.k8sIngress.enabled) ($gateway.enabled) (eq $gateway.name "istio-ingressgateway") }} +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: istio-autogenerated-k8s-ingress + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ $gateway.name }} + release: {{ .Release.Name }} +spec: + selector: + istio: {{ .Values.global.k8sIngress.gatewayName }} + servers: + - port: + number: 80 + protocol: HTTP2 + name: http2 + hosts: + - "*" +{{ if .Values.global.k8sIngress.enableHttps }} + - port: + number: 443 + protocol: HTTPS + name: https + tls: + mode: SIMPLE + serverCertificate: /etc/istio/ingressgateway-certs/tls.crt + privateKey: /etc/istio/ingressgateway-certs/tls.key + hosts: + - "*" +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/injected-deployment.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/injected-deployment.yaml new file mode 100644 index 0000000000..10d3d51e6c --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/injected-deployment.yaml @@ -0,0 +1,144 @@ +{{- $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if ne $gateway.injectionTemplate "" }} +{{/* This provides a minimal gateway, ready to be injected. + Any settings from values.gateways should be here - these are options specific to the gateway. + Global settings, like the image, various env vars and volumes, etc will be injected. + The normal Deployment is not suitable for this, as the original pod spec will override the injection template. */}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ $gateway.name | default "istio-ingressgateway" }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: +{{- if not $gateway.autoscaleEnabled }} +{{- if $gateway.replicaCount }} + replicas: {{ $gateway.replicaCount }} +{{- end }} +{{- end }} + selector: + matchLabels: +{{ $gateway.labels | toYaml | indent 6 }} + strategy: + rollingUpdate: + maxSurge: {{ $gateway.rollingMaxSurge }} + maxUnavailable: {{ $gateway.rollingMaxUnavailable }} + template: + metadata: + labels: + maistra-control-plane: {{ .Release.Namespace }} +{{ $gateway.labels | toYaml | indent 8 }} +{{- if eq .Release.Namespace "istio-system"}} + heritage: Tiller + release: istio + chart: gateways +{{- end }} + sidecar.istio.io/inject: "true" + {{- with .Values.revision }} + istio.io/rev: {{ . }} + {{- end }} + annotations: + {{- if .Values.meshConfig.enablePrometheusMerge }} + prometheus.io/port: "15020" + prometheus.io/scrape: "true" + prometheus.io/path: "/stats/prometheus" + {{- end }} + sidecar.istio.io/inject: "true" + inject.istio.io/templates: "{{ $gateway.injectionTemplate }}" +{{- if $gateway.podAnnotations }} +{{ toYaml $gateway.podAnnotations | indent 8 }} +{{ end }} + spec: +{{- if not $gateway.runAsRoot }} + securityContext: + runAsUser: {{ $gateway.runAsUser }} + runAsGroup: {{ $gateway.runAsGroup }} + runAsNonRoot: true + fsGroup: {{ $gateway.fsGroup }} +{{- end }} + serviceAccountName: {{ $gateway.name | default "istio-ingressgateway" }}-service-account +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} + containers: + - name: istio-proxy + image: auto +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + ports: + {{- range $key, $val := $gateway.ports }} + - containerPort: {{ $val.targetPort | default $val.port }} + protocol: {{ $val.protocol | default "TCP" }} + {{- end }} + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + {{- if not $gateway.runAsRoot }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: true + {{- end }} + resources: +{{- if $gateway.resources }} +{{ toYaml $gateway.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + env: + {{- if not $gateway.runAsRoot }} + - name: ISTIO_META_UNPRIVILEGED_POD + value: "true" + {{- end }} + {{- range $key, $val := $gateway.env }} + - name: {{ $key }} + value: {{ $val | quote }} + {{- end }} + volumeMounts: + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- range $gateway.configVolumes }} + {{- if .mountPath }} + - name: {{ .name }} + mountPath: {{ .mountPath | quote }} + readOnly: true + {{- end }} + {{- end }} +{{- if $gateway.additionalContainers }} +{{ toYaml $gateway.additionalContainers | indent 8 }} +{{- end }} + volumes: + {{- range $gateway.secretVolumes }} + - name: {{ .name }} + secret: + secretName: {{ .secretName | quote }} + optional: true + {{- end }} + {{- range $gateway.configVolumes }} + - name: {{ .name }} + configMap: + name: {{ .configMapName | quote }} + optional: true + {{- end }} + affinity: +{{ include "nodeaffinity" (dict "global" .Values.global "nodeSelector" $gateway.nodeSelector) | trim | indent 8 }} + {{- include "podAntiAffinity" $gateway | indent 6 }} +{{- if $gateway.tolerations }} + tolerations: +{{ toYaml $gateway.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/istio-ingressgateway-route.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/istio-ingressgateway-route.yaml new file mode 100644 index 0000000000..7a50d576fe --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/istio-ingressgateway-route.yaml @@ -0,0 +1,24 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if and $gateway.enabled $gateway.routeConfig.enabled }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: {{ $gateway.name | default "istio-ingressgateway" }} +{{- if or (not $gateway.namespace) (eq $gateway.name "istio-ingressgateway") }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} +{{- else }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} +{{- end }} + labels: + maistra-version: "2.5.0" + release: {{ .Release.Name }} + {{- range $key, $val := $gateway.labels }} + {{ $key }}: {{ $val }} + {{- end }} +spec: + to: + kind: Service + name: {{ $gateway.name | default "istio-ingressgateway" }} + port: + targetPort: 8080 +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/networkpolicy.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/networkpolicy.yaml new file mode 100644 index 0000000000..c739fed294 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/networkpolicy.yaml @@ -0,0 +1,22 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ $gateway.name }} +{{- if not $gateway.namespace }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} +{{- else }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} +{{- end }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + annotations: + "maistra.io/internal": "true" +spec: + podSelector: + matchLabels: +{{ $gateway.labels | toYaml | indent 6 }} + ingress: + - {} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/poddisruptionbudget.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..01ba0aa10f --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.global.defaultPodDisruptionBudget.enabled }} +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if (semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion) }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | trim | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + minAvailable: 1 + selector: + matchLabels: +{{ $gateway.labels | toYaml | trim | indent 6 }} +{{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/role.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/role.yaml new file mode 100644 index 0000000000..c37497528b --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/role.yaml @@ -0,0 +1,15 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $gateway.name }}-sds + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] +--- diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/rolebindings.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/rolebindings.yaml new file mode 100644 index 0000000000..c2001b5141 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/rolebindings.yaml @@ -0,0 +1,18 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $gateway.name }}-sds + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $gateway.name }}-sds +subjects: +- kind: ServiceAccount + name: {{ $gateway.name }}-service-account +--- diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/service.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/service.yaml new file mode 100644 index 0000000000..52d7e4799f --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/service.yaml @@ -0,0 +1,46 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if not $gateway.customService }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $gateway.name }} + namespace: {{ $gateway.namespace | default .Release.Namespace }} + annotations: + {{- range $key, $val := $gateway.serviceAnnotations }} + {{ $key }}: {{ $val | quote }} + {{- end }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: +{{- if $gateway.loadBalancerIP }} + loadBalancerIP: "{{ $gateway.loadBalancerIP }}" +{{- end }} +{{- if $gateway.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml $gateway.loadBalancerSourceRanges | indent 4 }} +{{- end }} +{{- if $gateway.externalTrafficPolicy }} + externalTrafficPolicy: {{$gateway.externalTrafficPolicy }} +{{- end }} + type: {{ $gateway.type }} + selector: +{{ $gateway.labels | toYaml | indent 4 }} + ports: + + {{- range $key, $val := $gateway.ports }} + - + {{- range $pkey, $pval := $val }} + {{ $pkey}}: {{ $pval }} + {{- end }} + {{- end }} + + {{ range $app := $gateway.ingressPorts }} + - + port: {{ $app.port }} + name: {{ $app.name }} + {{- end }} +--- +{{ end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/templates/serviceaccount.yaml b/resources/helm/v2.5/gateways/istio-ingress/templates/serviceaccount.yaml new file mode 100644 index 0000000000..c74212ac11 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/templates/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{ $gateway := index .Values "gateways" "istio-ingressgateway" }} +apiVersion: v1 +kind: ServiceAccount +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +metadata: + name: {{ $gateway.name }}-service-account + namespace: {{ $gateway.namespace | default .Release.Namespace }} + labels: + maistra-version: "2.5.0" +{{ $gateway.labels | toYaml | trim | indent 4 }} + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} + {{- with $gateway.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} diff --git a/resources/helm/v2.5/gateways/istio-ingress/values.yaml b/resources/helm/v2.5/gateways/istio-ingress/values.yaml new file mode 100644 index 0000000000..34af267bf2 --- /dev/null +++ b/resources/helm/v2.5/gateways/istio-ingress/values.yaml @@ -0,0 +1,390 @@ +# A-la-carte istio ingress gateway. +# Must be installed in a separate namespace, to minimize access to secrets. + +gateways: + istio-ingressgateway: + name: istio-ingressgateway + labels: + app: istio-ingressgateway + istio: ingressgateway + ports: + ## You can add custom gateway ports in user values overrides, but it must include those ports since helm replaces. + # Note that AWS ELB will by default perform health checks on the first port + # on this list. Setting this to the health check port will ensure that health + # checks always work. https://github.com/istio/istio/issues/12503 + - port: 15021 + targetPort: 15021 + name: status-port + protocol: TCP + - port: 80 + targetPort: 8080 + name: http2 + protocol: TCP + - port: 443 + targetPort: 8443 + name: https + protocol: TCP + + # Scalability tuning + # replicaCount: 1 + rollingMaxSurge: 100% + rollingMaxUnavailable: 25% + autoscaleEnabled: true + autoscaleMin: 1 + autoscaleMax: 5 + + cpu: + targetAverageUtilization: 80 + + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 2000m + memory: 1024Mi + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + serviceAnnotations: {} + + # To generate an internal load balancer: + # --set serviceAnnotations.cloud.google.com/load-balancer-type=internal + #serviceAnnotations: + # cloud.google.com/load-balancer-type: "internal" + + podAnnotations: {} + type: ClusterIP + + ############## + secretVolumes: + - name: ingressgateway-certs + secretName: istio-ingressgateway-certs + mountPath: /etc/istio/ingressgateway-certs + - name: ingressgateway-ca-certs + secretName: istio-ingressgateway-ca-certs + mountPath: /etc/istio/ingressgateway-ca-certs + + customService: false + externalTrafficPolicy: "" + + ingressPorts: [] + additionalContainers: [] + configVolumes: [] + + serviceAccount: + # Annotations to add to the service account + annotations: {} + + ### Advanced options ############ + env: {} + nodeSelector: {} + tolerations: [] + + # Specify the pod anti-affinity that allows you to constrain which nodes + # your pod is eligible to be scheduled based on labels on pods that are + # already running on the node rather than based on labels on nodes. + # There are currently two types of anti-affinity: + # "requiredDuringSchedulingIgnoredDuringExecution" + # "preferredDuringSchedulingIgnoredDuringExecution" + # which denote "hard" vs. "soft" requirements, you can define your values + # in "podAntiAffinityLabelSelector" and "podAntiAffinityTermLabelSelector" + # correspondingly. + # For example: + # podAntiAffinityLabelSelector: + # - key: security + # operator: In + # values: S1,S2 + # topologyKey: "kubernetes.io/hostname" + # This pod anti-affinity rule says that the pod requires not to be scheduled + # onto a node if that node is already running a pod with label having key + # "security" and value "S1". + podAntiAffinityLabelSelector: [] + podAntiAffinityTermLabelSelector: [] + + # whether to run the gateway in a privileged container + runAsRoot: false + + # specifies whether to create a Route resource (route.openshift.io/v1) for the istio-ingressgateway deployment + routeConfig: + enabled: true + + # The injection template to use for the gateway. If not set, no injection will be performed. + injectionTemplate: "" + +# Revision is set as 'version' label and part of the resource names when installing multiple control planes. +revision: "" + +# For Helm compatibility. +ownerName: "" + +global: + # set the default set of namespaces to which services, service entries, virtual services, destination + # rules should be exported to. Currently only one value can be provided in this list. This value + # should be one of the following two options: + # * implies these objects are visible to all namespaces, enabling any sidecar to talk to any other sidecar. + # . implies these objects are visible to only to sidecars in the same namespace, or if imported as a Sidecar.egress.host + defaultConfigVisibilitySettings: [] + + # Default node selector to be applied to all deployments so that all pods can be + # constrained to run a particular nodes. Each component can overwrite these default + # values by adding its node selector block in the relevant section below and setting + # the desired values. + defaultNodeSelector: {} + + # enable pod disruption budget for the control plane, which is used to + # ensure Istio control plane components are gradually upgraded or recovered. + defaultPodDisruptionBudget: + enabled: true + + # A minimal set of requested resources to applied to all deployments so that + # Horizontal Pod Autoscaler will be able to function (if set). + # Each component can overwrite these default values by adding its own resources + # block in the relevant section below and setting the desired resources values. + defaultResources: + requests: + cpu: 10m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + + # Default node tolerations to be applied to all deployments so that all pods can be + # scheduled to a particular nodes with matching taints. Each component can overwrite + # these default values by adding its tolerations block in the relevant section below + # and setting the desired values. + # Configure this field in case that all pods of Istio control plane are expected to + # be scheduled to particular nodes with specified taints. + defaultTolerations: [] + + # Default hub for Istio images. + # Releases are published to docker hub under 'istio' project. + # Dev builds from prow are on gcr.io + hub: gcr.io/istio-testing + + # Default tag for Istio images. + tag: latest + + # Variant of the image to use. + # Currently supported are: [debug, distroless] + variant: "" + + # Specify image pull policy if default behavior isn't desired. + # Default behavior: latest images will be Always else IfNotPresent. + imagePullPolicy: "" + + # ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace + # to use for pulling any images in pods that reference this ServiceAccount. + # For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing) + # ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects. + # Must be set for any cluster configured with private docker registry. + imagePullSecrets: [] + # - private-registry-key + + # To output all istio components logs in json format by adding --log_as_json argument to each container argument + logAsJson: false + + # Specify pod scheduling arch(amd64, ppc64le, s390x, arm64) and weight as follows: + # 0 - Never scheduled + # 1 - Least preferred + # 2 - No preference + # 3 - Most preferred + arch: {} + + # Comma-separated minimum per-scope logging level of messages to output, in the form of :,: + # The control plane has different scopes depending on component, but can configure default log level across all components + # If empty, default scope and level will be used as configured in code + logging: + level: "default:info" + + # Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and + # system-node-critical, it is better to configure this in order to make sure your Istio pods + # will not be killed because of low priority class. + # Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + # for more detail. + priorityClassName: "" + + # Whether to enable the Kubernetes Ingress feature. + k8sIngress: + enabled: false + + proxy: + image: proxyv2 + + # CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value + # cluster domain. Default value is "cluster.local". + clusterDomain: "cluster.local" + + # Per Component log level for proxy, applies to gateways and sidecars. If a component level is + # not set, then the global "logLevel" will be used. + componentLogLevel: "misc:error" + + # If set, newly injected sidecars will have core dumps enabled. + enableCoreDump: false + + # Log level for proxy, applies to gateways and sidecars. + # Expected values are: trace|debug|info|warning|error|critical|off + logLevel: warning + + tracer: zipkin + + ############################################################################################## + # The following values are found in other charts. To effectively modify these values, make # + # make sure they are consistent across your Istio helm charts # + ############################################################################################## + + # The customized CA address to retrieve certificates for the pods in the cluster. + # CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint. + caAddress: "" + + # Used to locate istiod. + istioNamespace: istio-system + + # Configure the policy for validating JWT. + # Currently, two options are supported: "third-party-jwt" and "first-party-jwt". + jwtPolicy: "third-party-jwt" + + # Mesh ID means Mesh Identifier. It should be unique within the scope where + # meshes will interact with each other, but it is not required to be + # globally/universally unique. For example, if any of the following are true, + # then two meshes must have different Mesh IDs: + # - Meshes will have their telemetry aggregated in one place + # - Meshes will be federated together + # - Policy will be written referencing one mesh from the other + # + # If an administrator expects that any of these conditions may become true in + # the future, they should ensure their meshes have different Mesh IDs + # assigned. + # + # Within a multicluster mesh, each cluster must be (manually or auto) + # configured to have the same Mesh ID value. If an existing cluster 'joins' a + # multicluster mesh, it will need to be migrated to the new mesh ID. Details + # of migration TBD, and it may be a disruptive operation to change the Mesh + # ID post-install. + # + # If the mesh admin does not specify a value, Istio will use the value of the + # mesh's Trust Domain. The best practice is to select a proper Trust Domain + # value. + meshID: "" + + # Use the user-specified, secret volume mounted key and certs for Pilot and workloads. + mountMtlsCerts: false + + multiCluster: + # Set to true to connect two kubernetes clusters via their respective + # ingressgateway services when pods in each cluster cannot directly + # talk to one another. All clusters should be using Istio mTLS and must + # have a shared root CA for this model to work. + enabled: false + # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection + # to properly label proxies + clusterName: "" + # The suffix for global service names + globalDomainSuffix: "global" + # Enable envoy filter to translate `globalDomainSuffix` to cluster local suffix for cross cluster communication + includeEnvoyFilter: true + + # Network defines the network this cluster belong to. This name + # corresponds to the networks in the map of mesh networks. + network: "" + + # Configure the certificate provider for control plane communication. + # Currently, two providers are supported: "kubernetes" and "istiod". + # As some platforms may not have kubernetes signing APIs, + # Istiod is the default + pilotCertProvider: istiod + + sds: + # The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3. + # When a CSR is sent from Citadel Agent to the CA (e.g. Citadel), this aud is to make sure the + # JWT is intended for the CA. + token: + aud: istio-ca + + sts: + # The service port used by Security Token Service (STS) server to handle token exchange requests. + # Setting this port to a non-zero value enables STS server. + servicePort: 0 + + # whether to use autoscaling/v2 template for HPA settings + # for internal usage only, not to be configured by users. + autoscalingv2API: true + + # Configure TLS parameters for listeners + tls: + # List of supported cipher suites, e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + cipherSuites: [] + # List of supported ECDH curves, e.g. CurveP384 + ecdhCurves: [] + # min supported protocol version, e.g. TLSv1_2 + minProtocolVersion: "" + # max supported protocol version, e.g. TLSv1_3 + maxProtocolVersion: "" + + # Configuration for each of the supported tracers + tracer: + # Configuration for envoy to send trace data to LightStep. + # Disabled by default. + # address: the : of the satellite pool + # accessToken: required for sending data to the pool + # + datadog: + # Host:Port for submitting traces to the Datadog agent. + address: "$(HOST_IP):8126" + lightstep: + address: "" # example: lightstep-satellite:443 + accessToken: "" # example: abcdefg1234567 + stackdriver: + # enables trace output to stdout. + debug: false + # The global default max number of message events per span. + maxNumberOfMessageEvents: 200 + # The global default max number of annotation events per span. + maxNumberOfAnnotations: 200 + # The global default max number of attributes per span. + maxNumberOfAttributes: 200 + zipkin: + # Host:Port for reporting trace data in zipkin format. If not specified, will default to + # zipkin service (port 9411) in the same namespace as the other istio components. + address: "" + +meshConfig: + enablePrometheusMerge: true + + # The trust domain corresponds to the trust root of a system + # Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain + trustDomain: "cluster.local" + + defaultConfig: + proxyMetadata: + ISTIO_META_DNS_CAPTURE: "true" + ISTIO_META_DNS_AUTO_ALLOCATE: "true" + PROXY_XDS_VIA_AGENT: "true" + tracing: + # tlsSettings: + # mode: DISABLE # DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + # clientCertificate: # example: /etc/istio/tracer/cert-chain.pem + # privateKey: # example: /etc/istio/tracer/key.pem + # caCertificates: # example: /etc/istio/tracer/root-cert.pem + # sni: # example: tracer.somedomain + # subjectAltNames: [] + # - tracer.somedomain + +gatewayAPI: + enabled: false + controllerMode: false + +telemetry: + enabled: true + v2: + enabled: true + prometheus: + enabled: true + configOverride: + gateway: {} + inboundSidecar: {} + outboundSidecar: {} + stackdriver: + enabled: false + configOverride: {} + disableOutbound: false diff --git a/resources/helm/v2.5/global.yaml b/resources/helm/v2.5/global.yaml new file mode 100644 index 0000000000..aeb52868e4 --- /dev/null +++ b/resources/helm/v2.5/global.yaml @@ -0,0 +1,461 @@ +# Global and common settings for installing Istio. + +# This file is configured for a small scale production cluster. +# Use custom settings to tune up the CPU and scaling. +# Additional values overrides can be used. + +# Each individual component will use values from this file, with defaults and 'advanced' settings included in +# its own chart's values.yaml. + +# TODO: trim this file to commonly used settings, leave 'advanced' in the individual values.yaml (they can +# still be overridden by users, but won't show in basic documentation. + +# This doesn't match istio defaults, which are more geared towards tests and bookinfo. + +global: + # Used to locate istiod. + istioNamespace: istio-system + + # Default hub for Istio images. + # Releases are published to docker hub under 'istio' project. + # Dev builds from prow are on gcr.io + hub: gcr.io/istio-testing + + # Default tag for Istio images. + tag: latest + + # Comma-separated minimum per-scope logging level of messages to output, in the form of :,: + # The control plane has different scopes depending on component, but can configure default log level across all components + # If empty, default scope and level will be used as configured in code + logging: + level: "default:info" + + # To output all istio components logs in json format by adding --log_as_json argument to each container argument + logAsJson: false + + # Enabled by default in master for maximising testing. + istiod: + enableAnalysis: false + # `centralIstiod` flag will be deprecated in favor of `externalIstiod` to better support external control plane model. + # central istiod controls all remote clusters: disabled by default + centralIstiod: false + # external istiod controls all remote clusters: disabled by default + externalIstiod: false + + # Manage network policies that allows communication between namespace members and control plane + # If false, operator does not create any NetworkPolicy resource, and users are responsible for managing them + manageNetworkPolicy: true + + proxy: + image: proxyv2 + + # cluster domain. Default value is "cluster.local". + clusterDomain: "cluster.local" + + # Resources for the sidecar. + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 2000m + memory: 1024Mi + + # Log level for proxy, applies to gateways and sidecars. + # Expected values are: trace|debug|info|warning|error|critical|off + logLevel: warning + + # Per Component log level for proxy, applies to gateways and sidecars. If a component level is + # not set, then the global "logLevel" will be used. + componentLogLevel: "misc:error" + + #If set to true, istio-proxy container will have privileged securityContext + privileged: false + + # If set, newly injected sidecars will have core dumps enabled. + enableCoreDump: false + + # Default port for Pilot agent health checks. A value of 0 will disable health checking. + statusPort: 15021 + + # The initial delay for readiness probes in seconds. + readinessInitialDelaySeconds: 1 + + # The period between readiness probes in seconds. + readinessPeriodSeconds: 2 + + # The number of successive failed probes before indicating readiness failure. + readinessFailureThreshold: 30 + + # istio egress capture allowlist + # https://istio.io/docs/tasks/traffic-management/egress.html#calling-external-services-directly + # example: includeIPRanges: "172.30.0.0/16,172.20.0.0/16" + # would only capture egress traffic on those two IP Ranges, all other outbound traffic would + # be allowed by the sidecar + includeIPRanges: "*" + excludeIPRanges: "" + excludeOutboundPorts: "" + + # istio ingress capture allowlist + # examples: + # Redirect only selected ports: --includeInboundPorts="80,8080" + excludeInboundPorts: "" + includeInboundPorts: "*" + + # This controls the 'policy' in the sidecar injector. + autoInject: enabled + + # Specify which tracer to use. One of: zipkin, lightstep, datadog, stackdriver. + # If using stackdriver tracer outside GCP, set env GOOGLE_APPLICATION_CREDENTIALS to the GCP credential file. + tracer: "zipkin" + + proxy_init: + # Base name for the proxy_init container, used to configure iptables. + image: proxyv2 + resources: + limits: + cpu: 2000m + memory: 1024Mi + requests: + cpu: 10m + memory: 10Mi + + # Specify image pull policy if default behavior isn't desired. + # Default behavior: latest images will be Always else IfNotPresent. + imagePullPolicy: "" + + # Use the user-specified, secret volume mounted key and certs for Pilot and workloads. + mountMtlsCerts: false + + # Configuration for each of the supported tracers + tracer: + # Configuration for envoy to send trace data to LightStep. + # Disabled by default. + # address: the : of the satellite pool + # accessToken: required for sending data to the pool + # + lightstep: + address: "" # example: lightstep-satellite:443 + accessToken: "" # example: abcdefg1234567 + zipkin: + # Host:Port for reporting trace data in zipkin format. If not specified, will default to + # zipkin service (port 9411) in the same namespace as the other istio components. + address: "" + datadog: + # Host:Port for submitting traces to the Datadog agent. + address: "$(HOST_IP):8126" + stackdriver: + # enables trace output to stdout. + debug: false + # The global default max number of attributes per span. + maxNumberOfAttributes: 200 + # The global default max number of annotation events per span. + maxNumberOfAnnotations: 200 + # The global default max number of message events per span. + maxNumberOfMessageEvents: 200 + # Default mtls policy. If true, mtls between services will be enabled by default. + mtls: + # Default setting for service-to-service mtls. Can be set explicitly using + # destination rules or service annotations. + enabled: false + # If set to true, and a given service does not have a corresponding DestinationRule configured, + # or its DestinationRule does not have TLSSettings specified, Istio configures client side + # TLS configuration automatically, based on the server side mTLS authentication policy and the + # availibity of sidecars. + auto: true + + # ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace + # to use for pulling any images in pods that reference this ServiceAccount. + # For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing) + # ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects. + # Must be set for any cluster configured with private docker registry. + imagePullSecrets: [] + # - private-registry-key + + # Specify pod scheduling arch(amd64, ppc64le, s390x) and weight as follows: + # 0 - Never scheduled + # 1 - Least preferred + # 2 - No preference + # 3 - Most preferred + arch: + amd64: 2 + s390x: 2 + ppc64le: 2 + arm64: 2 + + # Whether to restrict the applications namespace the controller manages; + # If not set, controller watches all namespaces + oneNamespace: false + + # Default node selector to be applied to all deployments so that all pods can be + # constrained to run a particular nodes. Each component can overwrite these default + # values by adding its node selector block in the relevant section below and setting + # the desired values. + defaultNodeSelector: {} + + # Default node tolerations to be applied to all deployments so that all pods can be + # scheduled to a particular nodes with matching taints. Each component can overwrite + # these default values by adding its tolerations block in the relevant section below + # and setting the desired values. + # Configure this field in case that all pods of Istio control plane are expected to + # be scheduled to particular nodes with specified taints. + defaultTolerations: [] + + # Whether to perform server-side validation of configuration. + configValidation: true + + # Custom DNS config for the pod to resolve names of services in other + # clusters. Use this to add additional search domains, and other settings. + # see + # https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#dns-config + # This does not apply to gateway pods as they typically need a different + # set of DNS settings than the normal application pods (e.g., in + # multicluster scenarios). + # NOTE: If using templates, follow the pattern in the commented example below. + #podDNSSearchNamespaces: + #- global + #- "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global" + + # If set to true, the pilot and citadel mtls will be exposed on the + # ingress gateway + meshExpansion: + enabled: false + # If set to true, the pilot and citadel mtls and the plain text pilot ports + # will be exposed on an internal gateway + useILB: false + + multiCluster: + # Set to true to connect two kubernetes clusters via their respective + # ingressgateway services when pods in each cluster cannot directly + # talk to one another. All clusters should be using Istio mTLS and must + # have a shared root CA for this model to work. + enabled: false + # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection + # to properly label proxies + clusterName: "" + # The suffix for global service names + globalDomainSuffix: "global" + # Enable envoy filter to translate `globalDomainSuffix` to cluster local suffix for cross cluster communication + includeEnvoyFilter: true + + # A minimal set of requested resources to applied to all deployments so that + # Horizontal Pod Autoscaler will be able to function (if set). + # Each component can overwrite these default values by adding its own resources + # block in the relevant section below and setting the desired resources values. + defaultResources: + requests: + cpu: 10m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + + # enable pod disruption budget for the control plane, which is used to + # ensure Istio control plane components are gradually upgraded or recovered. + defaultPodDisruptionBudget: + enabled: true + # The values aren't mutable due to a current PodDisruptionBudget limitation + # minAvailable: 1 + + # Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and + # system-node-critical, it is better to configure this in order to make sure your Istio pods + # will not be killed because of low priority class. + # Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + # for more detail. + priorityClassName: "" + + # Use the Mesh Control Protocol (MCP) for configuring Istiod. Requires an MCP source. + useMCP: false + + # Mesh ID means Mesh Identifier. It should be unique within the scope where + # meshes will interact with each other, but it is not required to be + # globally/universally unique. For example, if any of the following are true, + # then two meshes must have different Mesh IDs: + # - Meshes will have their telemetry aggregated in one place + # - Meshes will be federated together + # - Policy will be written referencing one mesh from the other + # + # If an administrator expects that any of these conditions may become true in + # the future, they should ensure their meshes have different Mesh IDs + # assigned. + # + # Within a multicluster mesh, each cluster must be (manually or auto) + # configured to have the same Mesh ID value. If an existing cluster 'joins' a + # multicluster mesh, it will need to be migrated to the new mesh ID. Details + # of migration TBD, and it may be a disruptive operation to change the Mesh + # ID post-install. + # + # If the mesh admin does not specify a value, Istio will use the value of the + # mesh's Trust Domain. The best practice is to select a proper Trust Domain + # value. + meshID: "" + + # The namespace where globally shared configurations should be present. + # DestinationRules that apply to the entire mesh (e.g., enabling mTLS), + # default Sidecar configs, etc. should be added to this namespace. + # configRootNamespace: istio-config + + # set the default set of namespaces to which services, service entries, virtual services, destination + # rules should be exported to. Currently only one value can be provided in this list. This value + # should be one of the following two options: + # * implies these objects are visible to all namespaces, enabling any sidecar to talk to any other sidecar. + # . implies these objects are visible to only to sidecars in the same namespace, or if imported as a Sidecar.egress.host + defaultConfigVisibilitySettings: [] +# - '*' + omitSidecarInjectorConfigMap: false + sds: + token: + aud: istio-ca + + sts: + # The service port used by Security Token Service (STS) server to handle token exchange requests. + # Setting this port to a non-zero value enables STS server. + servicePort: 0 + + # The customized CA address to retrieve certificates for the pods in the cluster. + # CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint. + caAddress: "" + + caCertConfigMapName: "istio-ca-root-cert" + + # Configure the mesh networks to be used by the Split Horizon EDS. + # + # The following example defines two networks with different endpoints association methods. + # For `network1` all endpoints that their IP belongs to the provided CIDR range will be + # mapped to network1. The gateway for this network example is specified by its public IP + # address and port. + # The second network, `network2`, in this example is defined differently with all endpoints + # retrieved through the specified Multi-Cluster registry being mapped to network2. The + # gateway is also defined differently with the name of the gateway service on the remote + # cluster. The public IP for the gateway will be determined from that remote service (only + # LoadBalancer gateway service type is currently supported, for a NodePort type gateway service, + # it still need to be configured manually). + # + # meshNetworks: + # network1: + # endpoints: + # - fromCidr: "192.168.0.1/24" + # gateways: + # - address: 1.1.1.1 + # port: 80 + # network2: + # endpoints: + # - fromRegistry: reg1 + # gateways: + # - registryServiceName: istio-ingressgateway.istio-system.svc.cluster.local + # port: 443 + # + meshNetworks: {} + + # Network defines the network this cluster belong to. This name + # corresponds to the networks in the map of mesh networks. + network: "" + + # Configure whether Operator manages webhook configurations. The current behavior + # of Istiod is to manage its own webhook configurations. + # When this option is set as true, Istio Operator, instead of webhooks, manages the + # webhook configurations. When this option is set as false, webhooks manage their + # own webhook configurations. + operatorManageWebhooks: false + + # configure remote pilot and istiod service and endpoint + remotePilotAddress: "" + + # Configure the certificate provider for control plane communication. + # Currently, two providers are supported: "kubernetes" and "istiod". + # As some platforms may not have kubernetes signing APIs, + # Istiod is the default + pilotCertProvider: istiod + + # Configure the policy for validating JWT. + # Currently, two options are supported: "third-party-jwt" and "first-party-jwt". + jwtPolicy: "third-party-jwt" + + # Configure TLS parameters for listeners + tls: + # List of supported cipher suites, e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + cipherSuites: [] + # List of supported ECDH curves, e.g. CurveP384 + ecdhCurves: [] + # min supported protocol version, e.g. TLSv1_2 + maxProtocolVersion: "" + # max supported protocol version, e.g. TLSv1_3 + minProtocolVersion: "" + + # Deprecated, use meshConfig.trustDomain + trustDomain: "" + +# Internal setting - used when generating helm templates for kustomize. +# clusterResources controls the inclusion of cluster-wide resources when generating the charts/installing. +# For backward compat, it is set to 'true', resulting in the old-style installation. +# When set to 'false', all cluster-wide resources will be omitted, and are expected to be installed +# at the same time with the CRDs. +clusterResources: true + +meshConfig: + enablePrometheusMerge: true + defaultConfig: + proxyMetadata: + # required so proxy handles dns requests, which are delegated to istiod + ISTIO_META_DNS_CAPTURE: "true" + # required so that DNS resolves hosts defined as serviceentries + ISTIO_META_DNS_AUTO_ALLOCATE: "true" + # required to enable dns capture + PROXY_XDS_VIA_AGENT: "true" + tracing: +# tlsSettings: +# mode: DISABLE # DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL +# clientCertificate: # example: /etc/istio/tracer/cert-chain.pem +# privateKey: # example: /etc/istio/tracer/key.pem +# caCertificates: # example: /etc/istio/tracer/root-cert.pem +# sni: # example: tracer.somedomain +# subjectAltNames: [] + # - tracer.somedomain + +base: + validationURL: "" + +telemetry: + enabled: true + v2: + # For Null VM case now. + # This also enables metadata exchange. + enabled: true + metadataExchange: + # Indicates whether to enable WebAssembly runtime for metadata exchange filter. + wasmEnabled: false + # Indicate if prometheus stats filter is enabled or not + prometheus: + enabled: true + # Indicates whether to enable WebAssembly runtime for stats filter. + wasmEnabled: false + # overrides stats EnvoyFilter configuration. + configOverride: + gateway: {} + inboundSidecar: {} + outboundSidecar: {} + # stackdriver filter settings. + stackdriver: + enabled: false + logging: false + monitoring: false + topology: false + disableOutbound: false + # configOverride parts give you the ability to override the low level configuration params passed to envoy filter. + + configOverride: {} + # e.g. + # enable_mesh_edges_reporting: true + # disable_server_access_logging: false + # meshEdgesReportingDuration: 500s + # disable_host_header_fallback: true + # Access Log Policy Filter Settings. This enables filtering of access logs from stackdriver. + accessLogPolicy: + enabled: false + # To reduce the number of successful logs, default log window duration is + # set to 12 hours. + logWindowDuration: "43200s" + +gatewayAPI: + enabled: false + controllerMode: false diff --git a/resources/helm/v2.5/install-OpenShift.md b/resources/helm/v2.5/install-OpenShift.md new file mode 100644 index 0000000000..0417c07a31 --- /dev/null +++ b/resources/helm/v2.5/install-OpenShift.md @@ -0,0 +1,43 @@ +# Installing Istio on OpenShift using Helm + +> Note: Be aware of the [platform setup required for OpenShift](https://istio.io/latest/docs/setup/platform-setup/openshift/) when installing Istio. + +To install with Helm, you must first create the namespace that you wish to install in if the namespace does not exist already. The default namespace used is `istio-system` and can be created as follows: + +```console +kubectl create namespace istio-system +``` + +The installation process using the Helm charts is as follows: + +1) `base` chart creates cluster-wide CRDs, cluster bindings and cluster resources. It is possible to change the namespace from `istio-system` but it is not recommended. + +```console +helm install istio-base -n istio-system manifests/charts/base +``` + +2) `istio-cni` chart installs the CNI plugin. This should be installed after the `base` chart and prior to `istiod` chart. Need to add `--set istio_cni.enabled=true` to the `istiod` install to enable its usage. + +```console +helm install istio-cni -n kube-system manifests/charts/istio-cni --set cni.cniBinDir="/var/lib/cni/bin" --set cni.cniConfDir="/etc/cni/multus/net.d" --set cni.chained=false --set cni.cniConfFileName="istio-cni.conf" --set cni.excludeNamespaces[0]="istio-system" --set cni.excludeNamespaces[1]="kube-system" --set cni.repair.enabled=false --set cni.logLevel=info +``` + +3) `istio-control/istio-discovery` chart installs a revision of istiod. + +```console + helm install -n istio-system istio-17 manifests/charts/istio-control/istio-discovery --set istio_cni.enabled=true --set global.jwtPolicy=first-party-jwt --set sidecarInjectorWebhook.injectedAnnotations."k8s\.v1\.cni\.cncf\.io/networks"="istio-cni" +``` + +4) `gateways` charts install a load balancer with `ingress` and `egress`. + +Ingress secrets and access should be separated from the control plane. + +```console +helm install -n istio-system istio-ingress manifests/charts/gateways/istio-ingress --set global.jwtPolicy=first-party-jwt +``` + +Egress secrets and access should be separated from the control plane. + +```console +helm install -n istio-system istio-egress manifests/charts/gateways/istio-egress --set global.jwtPolicy=first-party-jwt +``` diff --git a/resources/helm/v2.5/istio-control/istio-discovery/Chart.yaml b/resources/helm/v2.5/istio-control/istio-discovery/Chart.yaml new file mode 100644 index 0000000000..b0f169b7b5 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +name: istiod +# This version is never actually shipped. istio/release-builder will replace it at build-time +# with the appropriate version +version: 1.0.0 +appVersion: 1.0.0 +tillerVersion: ">=2.7.2" +description: Helm chart for istio control plane +keywords: + - istio + - istiod + - istio-discovery +sources: + - https://github.com/istio/istio +engine: gotpl +icon: https://istio.io/latest/favicons/android-192x192.png diff --git a/resources/helm/v2.5/istio-control/istio-discovery/README.md b/resources/helm/v2.5/istio-control/istio-discovery/README.md new file mode 100644 index 0000000000..9d4d07a426 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/README.md @@ -0,0 +1,59 @@ +# Istiod Helm Chart + +This chart installs an Istiod deployment. + +## Setup Repo Info + +```console +helm repo add istio https://istio-release.storage.googleapis.com/charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +Before installing, ensure CRDs are installed in the cluster (from the `istio/base` chart). + +To install the chart with the release name `istiod`: + +```console +kubectl create namespace istio-system +helm install istiod istio/istiod --namespace istio-system +``` + +## Uninstalling the Chart + +To uninstall/delete the `istiod` deployment: + +```console +helm delete istiod --namespace istio-system +``` + +## Configuration + +To view support configuration options and documentation, run: + +```console +helm show values istio/istiod +``` + +### Examples + +#### Configuring mesh configuration settings + +Any [Mesh Config](https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/) options can be configured like below: + +```yaml +meshConfig: + accessLogFile: /dev/stdout +``` + +#### Revisions + +Control plane revisions allow deploying multiple versions of the control plane in the same cluster. +This allows safe [canary upgrades](https://istio.io/latest/docs/setup/upgrade/canary/) + +```yaml +revision: my-revision-name +``` diff --git a/resources/helm/v2.5/istio-control/istio-discovery/files/gateway-injection-template.yaml b/resources/helm/v2.5/istio-control/istio-discovery/files/gateway-injection-template.yaml new file mode 100644 index 0000000000..acaf6d9aa4 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/files/gateway-injection-template.yaml @@ -0,0 +1,240 @@ +{{- $containers := list }} +{{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} +metadata: + labels: + maistra-version: "2.5.0" + service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} + service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} + annotations: { + istio.io/rev: {{ .Revision | default "default" | quote }}, + {{- if eq (len $containers) 1 }} + kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", + kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", + {{ end }} + } +spec: + containers: + - name: istio-proxy + {{- if contains "/" .Values.global.proxy.image }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + ports: + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - router + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} + - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} + - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.lifecycle }} + lifecycle: + {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} + {{- end }} + env: + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ valueOrDefault .Values.revision "default" }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {{- $first := true }} + {{- range $index1, $c := .Spec.Containers }} + {{- range $index2, $p := $c.Ports }} + {{- if (structToJSON $p) }} + {{if not $first}},{{end}}{{ structToJSON $p }} + {{- $first = false }} + {{- end }} + {{- end}} + {{- end}} + ] + - name: ISTIO_META_APP_CONTAINERS + value: "{{ $containers | join "," }}" + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: "{{ .ProxyConfig.InterceptionMode.String }}" + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- if .DeploymentMeta.Name }} + - name: ISTIO_META_WORKLOAD_NAME + value: "{{ .DeploymentMeta.Name }}" + {{ end }} + {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} + {{- end}} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + readinessProbe: + httpGet: + path: /healthz/ready + port: 15021 + initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} + periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} + timeoutSeconds: 3 + failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + # SDS channel between istioagent and Envoy + - mountPath: /etc/istio/proxy + name: istio-envoy + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - mountPath: /etc/certs/ + name: istio-certs + readOnly: true + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: {} + name: credential-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else}} + - emptyDir: {} + name: workload-certs + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-envoy + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + optional: true + {{ if eq .Spec.ServiceAccountName "" }} + secretName: istio.default + {{ else -}} + secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} + {{ end -}} + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if eq (env "ENABLE_LEGACY_FSGROUP_INJECTION" "false") "true" }} + securityContext: + {{- if .ProxyGID }} + fsGroup: {{ .ProxyGID }} + {{- end }} + {{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/files/grpc-agent.yaml b/resources/helm/v2.5/istio-control/istio-discovery/files/grpc-agent.yaml new file mode 100644 index 0000000000..be900ea892 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/files/grpc-agent.yaml @@ -0,0 +1,321 @@ +{{- define "resources" }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} + requests: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" + {{ end }} + {{- end }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + limits: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" + {{ end }} + {{- end }} + {{- else }} + {{- if .Values.global.proxy.resources }} + {{ toYaml .Values.global.proxy.resources | indent 6 }} + {{- end }} + {{- end }} +{{- end }} +{{- $containers := list }} +{{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} +metadata: + labels: + maistra-version: "2.5.0" + {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} + service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} + service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} + annotations: { + istio.io/rev: {{ .Revision | default "default" }}, + {{- if ge (len $containers) 1 }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} + kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", + {{- end }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} + kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", + {{- end }} + {{- end }} + sidecar.istio.io/rewriteAppHTTPProbers: "false", + } +spec: + containers: + - name: istio-proxy + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + ports: + - containerPort: 15020 + protocol: TCP + name: mesh-metrics + args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} + - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} + - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + lifecycle: + postStart: + exec: + command: + - pilot-agent + - wait + - --url=http://localhost:15020/healthz/ready + env: + - name: ISTIO_META_GENERATOR + value: grpc + - name: OUTPUT_CERTS + value: /var/lib/istio/data + {{- if eq (env "PILOT_ENABLE_INBOUND_PASSTHROUGH" "true") "false" }} + - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION + value: "true" + {{- end }} + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {{- $first := true }} + {{- range $index1, $c := .Spec.Containers }} + {{- range $index2, $p := $c.Ports }} + {{- if (structToJSON $p) }} + {{if not $first}},{{end}}{{ structToJSON $p }} + {{- $first = false }} + {{- end }} + {{- end}} + {{- end}} + ] + - name: ISTIO_META_APP_CONTAINERS + value: "{{ $containers | join "," }}" + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- if .DeploymentMeta.Name }} + - name: ISTIO_META_WORKLOAD_NAME + value: "{{ .DeploymentMeta.Name }}" + {{ end }} + {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} + {{- end}} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + # grpc uses xds:/// to resolve – no need to resolve VIP + - name: ISTIO_META_DNS_CAPTURE + value: "false" + - name: DISABLE_ENVOY + value: "true" + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} + readinessProbe: + httpGet: + path: /healthz/ready + port: 15020 + initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} + periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} + timeoutSeconds: 3 + failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} + resources: + {{ template "resources" . }} + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + # UDS channel between istioagent and gRPC client for XDS/SDS + - mountPath: /etc/istio/proxy + name: istio-xds + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - mountPath: /etc/certs/ + name: istio-certs + readOnly: true + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} + {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 6 }} + {{ end }} + {{- end }} +{{- range $index, $container := .Spec.Containers }} +{{ if not (eq $container.Name "istio-proxy") }} + - name: {{ $container.Name }} + env: + - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" + value: "true" + - name: "GRPC_XDS_BOOTSTRAP" + value: "/etc/istio/proxy/grpc-bootstrap.json" + volumeMounts: + - mountPath: /var/lib/istio/data + name: istio-data + # UDS channel between istioagent and gRPC client for XDS/SDS + - mountPath: /etc/istio/proxy + name: istio-xds + {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} +{{- end }} +{{- end }} + volumes: + - emptyDir: + name: workload-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else }} + - emptyDir: + name: workload-certs + {{- end }} + {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - name: custom-bootstrap-volume + configMap: + name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-xds + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + optional: true + {{ if eq .Spec.ServiceAccountName "" }} + secretName: istio.default + {{ else -}} + secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} + {{ end -}} + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} + {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 4 }} + {{ end }} + {{ end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if eq (env "ENABLE_LEGACY_FSGROUP_INJECTION" "false") "true" }} + securityContext: + fsGroup: 1337 + {{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/files/grpc-simple.yaml b/resources/helm/v2.5/istio-control/istio-discovery/files/grpc-simple.yaml new file mode 100644 index 0000000000..a4f9d3fc14 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/files/grpc-simple.yaml @@ -0,0 +1,67 @@ +metadata: + labels: + maistra-version: "2.5.0" + annotations: + sidecar.istio.io/rewriteAppHTTPProbers: "false" +spec: + initContainers: + - name: grpc-bootstrap-init + image: busybox:1.28 + volumeMounts: + - mountPath: /var/lib/grpc/data/ + name: grpc-io-proxyless-bootstrap + env: + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ISTIO_NAMESPACE + value: | + {{ .Release.Namespace }} + command: + - sh + - "-c" + - |- + NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" + SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" + echo ' + { + "xds_servers": [ + { + "server_uri": "'${SERVER_URI}'", + "channel_creds": [{"type": "insecure"}], + "server_features" : ["xds_v3"] + } + ], + "node": { + "id": "'${NODE_ID}'", + "metadata": { + "GENERATOR": "grpc" + } + } + }' > /var/lib/grpc/data/bootstrap.json + containers: + {{- range $index, $container := .Spec.Containers }} + - name: {{ $container.Name }} + env: + - name: GRPC_XDS_BOOTSTRAP + value: /var/lib/grpc/data/bootstrap.json + - name: GRPC_GO_LOG_VERBOSITY_LEVEL + value: "99" + - name: GRPC_GO_LOG_SEVERITY_LEVEL + value: info + volumeMounts: + - mountPath: /var/lib/grpc/data/ + name: grpc-io-proxyless-bootstrap + {{- end }} + volumes: + - name: grpc-io-proxyless-bootstrap + emptyDir: {} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/files/injection-template.yaml b/resources/helm/v2.5/istio-control/istio-discovery/files/injection-template.yaml new file mode 100644 index 0000000000..a6806a6bba --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/files/injection-template.yaml @@ -0,0 +1,417 @@ +{{- define "resources" }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} + requests: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" + {{ end }} + {{- end }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + limits: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" + {{ end }} + {{- end }} + {{- else }} + {{- if .Values.global.proxy.resources }} + {{ toYaml .Values.global.proxy.resources | indent 6 }} + {{- end }} + {{- end }} +{{- end }} +{{- $containers := list }} +{{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} +metadata: + labels: + maistra-version: "2.5.0" + security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} + {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} + networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} + {{- end }} + service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} + service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} + annotations: { + istio.io/rev: {{ .Revision | default "default" | quote }}, + {{- if ge (len $containers) 1 }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} + kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", + {{- end }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} + kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", + {{- end }} + {{- end }} +{{- if .Values.istio_cni.enabled }} + {{- if not .Values.istio_cni.chained }} + k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) .Values.istio_cni.istio_cni_network }}', + {{- end }} + sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", + {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} + {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} + {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}traffic.sidecar.istio.io/includeInboundPorts: "{{.}}",{{ end }} + traffic.sidecar.istio.io/excludeInboundPorts: "15090,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", + {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} + traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", + {{- end }} + {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} + traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", + {{- end }} + {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} + {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} +{{- end }} + } +spec: + {{- $holdProxy := or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts }} + containers: + - name: istio-proxy + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + ports: + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} + - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} + - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.lifecycle }} + lifecycle: + {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} + {{- else if $holdProxy }} + lifecycle: + postStart: + exec: + command: + - pilot-agent + - wait + {{- end }} + env: + {{- if eq (env "PILOT_ENABLE_INBOUND_PASSTHROUGH" "true") "false" }} + - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION + value: "true" + {{- end }} + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ valueOrDefault .Values.revision "default" }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {{- $first := true }} + {{- range $index1, $c := .Spec.Containers }} + {{- range $index2, $p := $c.Ports }} + {{- if (structToJSON $p) }} + {{if not $first}},{{end}}{{ structToJSON $p }} + {{- $first = false }} + {{- end }} + {{- end}} + {{- end}} + ] + - name: ISTIO_META_APP_CONTAINERS + value: "{{ $containers | join "," }}" + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- if .DeploymentMeta.Name }} + - name: ISTIO_META_WORKLOAD_NAME + value: "{{ .DeploymentMeta.Name }}" + {{ end }} + {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} + {{- end}} + {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - name: ISTIO_BOOTSTRAP_OVERRIDE + value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" + {{- end }} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} + {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.maistra.io/proxyEnv` }} + {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.maistra.io/proxyEnv`) }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} + readinessProbe: + httpGet: + path: /healthz/ready + port: 15021 + initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} + periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} + timeoutSeconds: 3 + failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} + {{ end -}} + securityContext: + {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} + allowPrivilegeEscalation: true + capabilities: + add: + - NET_ADMIN + drop: + - ALL + - KILL + - MKNOD + - SETGID + - SETUID + privileged: true + readOnlyRootFilesystem: {{ ne (annotation .ObjectMeta `sidecar.istio.io/enableCoreDump` .Values.global.proxy.enableCoreDump) "true" }} + {{- if .ProxyUID }} + runAsGroup: {{ .ProxyUID }} + {{- end }} + runAsNonRoot: false + runAsUser: 0 + {{- else }} + allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} + capabilities: + {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} + add: + {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} + - NET_ADMIN + {{- end }} + {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} + - NET_BIND_SERVICE + {{- end }} + {{- end }} + drop: + - ALL + - KILL + - MKNOD + - SETGID + - SETUID + privileged: {{ .Values.global.proxy.privileged }} + readOnlyRootFilesystem: {{ ne (annotation .ObjectMeta `sidecar.istio.io/enableCoreDump` .Values.global.proxy.enableCoreDump) "true" }} + {{- if .ProxyUID }} + runAsGroup: {{ .ProxyUID }} + {{- end }} + {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} + runAsNonRoot: false + runAsUser: 0 + {{- else -}} + runAsNonRoot: true + {{- if .ProxyUID }} + runAsUser: {{ .ProxyUID }} + {{- end }} + {{- end }} + {{- end }} + resources: + {{ template "resources" . }} + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + {{- if eq .Values.global.pilotCertProvider "kubernetes" }} + - mountPath: /var/run/secrets/istio/kubernetes + name: kube-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - mountPath: /etc/istio/custom-bootstrap + name: custom-bootstrap-volume + {{- end }} + # SDS channel between istioagent and Envoy + - mountPath: /etc/istio/proxy + name: istio-envoy + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - mountPath: /etc/certs/ + name: istio-certs + readOnly: true + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} + - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} + name: lightstep-certs + readOnly: true + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} + {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 6 }} + {{ end }} + {{- end }} + volumes: + - emptyDir: + name: workload-socket + - emptyDir: + name: credential-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else }} + - emptyDir: + name: workload-certs + {{- end }} + {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - name: custom-bootstrap-volume + configMap: + name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-envoy + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if eq .Values.global.pilotCertProvider "kubernetes" }} + - name: kube-ca-cert + configMap: + name: kube-root-ca.crt + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + optional: true + {{ if eq .Spec.ServiceAccountName "" }} + secretName: istio.default + {{ else -}} + secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} + {{ end -}} + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} + {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 4 }} + {{ end }} + {{ end }} + {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} + - name: lightstep-certs + secret: + optional: true + secretName: lightstep.cacert + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + {{- if eq (env "ENABLE_LEGACY_FSGROUP_INJECTION" "false") "true" }} + securityContext: + {{- if .ProxyGID }} + fsGroup: {{ .ProxyGID }} + {{- end }} + {{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/files/kube-gateway.yaml b/resources/helm/v2.5/istio-control/istio-discovery/files/kube-gateway.yaml new file mode 100644 index 0000000000..4f9ea7cc94 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/files/kube-gateway.yaml @@ -0,0 +1,293 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{.ServiceAccount | quote}} + namespace: {{.Namespace | quote}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + annotations: + {{- toJsonMap (omit .Annotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + maistra-version: "2.5.0" + {{- toJsonMap .Labels | nindent 4 }} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: {{.Name}} + uid: "{{.UID}}" +spec: + selector: + matchLabels: + istio.io/gateway-name: {{.Name}} + template: + metadata: + annotations: + {{- toJsonMap + (omit .Annotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") + (strdict "istio.io/rev" (.Revision | default "default")) + (strdict + "prometheus.io/path" "/stats/prometheus" + "prometheus.io/port" "15020" + "prometheus.io/scrape" "true" + ) | nindent 8 }} + labels: + maistra-version: "2.5.0" + maistra-control-plane: {{ .Release.Namespace }} + {{- toJsonMap + (strdict + "sidecar.istio.io/inject" "false" + "service.istio.io/canonical-name" .DeploymentName + "service.istio.io/canonical-revision" "latest" + ) + .Labels + (strdict "istio.io/gateway-name" .Name) | nindent 8}} + spec: + {{- if .KubeVersion122 }} + {{/* safe since 1.22: https://github.com/kubernetes/kubernetes/pull/103326. */}} + securityContext: + sysctls: + - name: net.ipv4.ip_unprivileged_port_start + value: "0" + {{- end }} + serviceAccountName: {{.ServiceAccount | quote}} + containers: + - name: istio-proxy + image: "{{ .ProxyImage }}" + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + ports: + - containerPort: 15021 + name: status-port + protocol: TCP + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - router + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} + - --proxyComponentLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} + - --log_output_level + - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.lifecycle }} + lifecycle: + {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} + {{- end }} + env: + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: "[]" + - name: ISTIO_META_APP_CONTAINERS + value: "" + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: "{{ .ProxyConfig.InterceptionMode.String }}" + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + - name: ISTIO_META_WORKLOAD_NAME + value: {{.DeploymentName|quote}} + - name: ISTIO_META_OWNER + value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- with (index .Labels "topology.istio.io/network") }} + - name: ISTIO_META_REQUESTED_NETWORK_VIEW + value: {{.|quote}} + {{- end }} + startupProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 1 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 4 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + # SDS channel between istioagent and Envoy + - mountPath: /etc/istio/proxy + name: istio-envoy + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: {} + name: credential-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else}} + - emptyDir: {} + name: workload-certs + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-envoy + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + {{ toJsonMap (omit .Annotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + maistra-version: "2.5.0" + maistra-control-plane: {{ .Release.Namespace }} + {{ toJsonMap .Labels | nindent 4}} + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: {{.Name}} + uid: {{.UID}} +spec: + ports: + {{- range $key, $val := .Ports }} + - name: {{ $val.Name | quote }} + port: {{ $val.Port }} + protocol: TCP + appProtocol: {{ $val.AppProtocol }} + {{- end }} + selector: + istio.io/gateway-name: {{.Name}} + {{- if .Spec.Addresses }} + loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} + {{- end }} + type: {{ index .Annotations "networking.istio.io/service-type" | default "LoadBalancer" | quote }} +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/files/waypoint.yaml b/resources/helm/v2.5/istio-control/istio-discovery/files/waypoint.yaml new file mode 100644 index 0000000000..2e5d7a783c --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/files/waypoint.yaml @@ -0,0 +1,243 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{.ServiceAccount | quote}} + namespace: {{.Namespace | quote}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + annotations: + {{- toJsonMap (omit .Annotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + maistra-version: "2.5.0" + {{- toJsonMap .Labels | nindent 4 }} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: "{{.Name}}" + uid: "{{.UID}}" +spec: + selector: + matchLabels: + istio.io/gateway-name: "{{.Name}}" + template: + metadata: + annotations: + {{- toJsonMap + (omit .Annotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") + (strdict "istio.io/rev" (.Revision | default "default")) + (strdict + "ambient.istio.io/redirection" "disabled" + "prometheus.io/path" "/stats/prometheus" + "prometheus.io/port" "15020" + "prometheus.io/scrape" "true" + ) | nindent 8 }} + labels: + maistra-version: "2.5.0" + maistra-control-plane: {{ .Release.Namespace }} + {{- toJsonMap + (strdict + "sidecar.istio.io/inject" "false" + "service.istio.io/canonical-name" .DeploymentName + "service.istio.io/canonical-revision" "latest" + ) + .Labels + (strdict + "istio.io/gateway-name" .Name + "gateway.istio.io/managed" "istio.io-mesh-controller" + ) | nindent 8}} + spec: + terminationGracePeriodSeconds: 2 + serviceAccountName: {{.ServiceAccount | quote}} + containers: + - args: + - proxy + - waypoint + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --serviceCluster + - {{.ServiceAccount}}.$(POD_NAMESPACE) + - --proxyLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} + - --proxyComponentLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} + - --log_output_level + - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + env: + - name: ISTIO_META_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_INTERCEPTION_MODE + value: REDIRECT + - name: ISTIO_META_WORKLOAD_NAME + value: {{.DeploymentName}} + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + image: {{.ProxyImage}} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + name: istio-proxy + resources: + limits: + cpu: "2" + memory: 1Gi + requests: + cpu: 100m + memory: 128Mi + startupProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 1 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 4 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 1 + securityContext: + privileged: true + runAsGroup: 1337 + runAsUser: 0 + capabilities: + add: + - NET_ADMIN + - NET_RAW + volumeMounts: + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + - mountPath: /var/lib/istio/data + name: istio-data + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + - mountPath: /etc/istio/pod + name: istio-podinfo + volumes: + - emptyDir: + medium: Memory + name: istio-envoy + - emptyDir: + medium: Memory + name: go-proxy-envoy + - emptyDir: {} + name: istio-data + - emptyDir: {} + name: go-proxy-data + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + - fieldRef: + fieldPath: metadata.annotations + path: annotations + name: istio-podinfo + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: istio-ca + expirationSeconds: 43200 + path: istio-token + - configMap: + name: istio-ca-root-cert + name: istiod-ca-cert + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + {{ toJsonMap (omit .Annotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + maistra-version: "2.5.0" + maistra-control-plane: {{ .Release.Namespace }} + {{ toJsonMap .Labels | nindent 4}} + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: "{{.Name}}" + uid: "{{.UID}}" +spec: + ports: + - name: https-hbone + port: 15008 + protocol: TCP + appProtocol: https + selector: + istio.io/gateway-name: "{{.Name}}" +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/NOTES.txt b/resources/helm/v2.5/istio-control/istio-discovery/templates/NOTES.txt new file mode 100644 index 0000000000..03cb8192f9 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/NOTES.txt @@ -0,0 +1,56 @@ +"istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}" successfully installed! + +To learn more about the release, try: + $ helm status {{ .Release.Name }} + $ helm get all {{ .Release.Name }} + +Next steps: + * Deploy a Gateway: https://istio.io/latest/docs/setup/additional-setup/gateway/ + * Try out our tasks to get started on common configurations: + * https://istio.io/latest/docs/tasks/traffic-management + * https://istio.io/latest/docs/tasks/security/ + * https://istio.io/latest/docs/tasks/policy-enforcement/ + * https://istio.io/latest/docs/tasks/policy-enforcement/ + * Review the list of actively supported releases, CVE publications and our hardening guide: + * https://istio.io/latest/docs/releases/supported-releases/ + * https://istio.io/latest/news/security/ + * https://istio.io/latest/docs/ops/best-practices/security/ + +For further documentation see https://istio.io website + +{{- + $deps := dict + "global.outboundTrafficPolicy" "meshConfig.outboundTrafficPolicy" + "global.certificates" "meshConfig.certificates" + "global.localityLbSetting" "meshConfig.localityLbSetting" + "global.policyCheckFailOpen" "meshConfig.policyCheckFailOpen" + "global.enableTracing" "meshConfig.enableTracing" + "global.proxy.accessLogFormat" "meshConfig.accessLogFormat" + "global.proxy.accessLogFile" "meshConfig.accessLogFile" + "global.proxy.concurrency" "meshConfig.defaultConfig.concurrency" + "global.proxy.envoyAccessLogService" "meshConfig.defaultConfig.envoyAccessLogService" + "global.proxy.envoyAccessLogService.enabled" "meshConfig.enableEnvoyAccessLogService" + "global.proxy.envoyMetricsService" "meshConfig.defaultConfig.envoyMetricsService" + "global.proxy.protocolDetectionTimeout" "meshConfig.protocolDetectionTimeout" + "global.proxy.holdApplicationUntilProxyStarts" "meshConfig.defaultConfig.holdApplicationUntilProxyStarts" + "pilot.ingress" "meshConfig.ingressService, meshConfig.ingressControllerMode, and meshConfig.ingressClass" + "global.mtls.enabled" "the PeerAuthentication resource" + "global.mtls.auto" "meshConfig.enableAutoMtls" + "global.tracer.lightstep.address" "meshConfig.defaultConfig.tracing.lightstep.address" + "global.tracer.lightstep.accessToken" "meshConfig.defaultConfig.tracing.lightstep.accessToken" + "global.tracer.zipkin.address" "meshConfig.defaultConfig.tracing.zipkin.address" + "global.tracer.stackdriver.debug" "meshConfig.defaultConfig.tracing.stackdriver.debug" + "global.tracer.stackdriver.maxNumberOfAttributes" "meshConfig.defaultConfig.tracing.stackdriver.maxNumberOfAttributes" + "global.tracer.stackdriver.maxNumberOfAnnotations" "meshConfig.defaultConfig.tracing.stackdriver.maxNumberOfAnnotations" + "global.tracer.stackdriver.maxNumberOfMessageEvents" "meshConfig.defaultConfig.tracing.stackdriver.maxNumberOfMessageEvents" + "global.tracer.datadog.address" "meshConfig.defaultConfig.tracing.datadog.address" + "global.meshExpansion.enabled" "Gateway and other Istio networking resources, such as in samples/multicluster/" + "istiocoredns.enabled" "the in-proxy DNS capturing (ISTIO_META_DNS_CAPTURE)" +}} +{{- range $dep, $replace := $deps }} +{{- /* Complex logic to turn the string above into a null-safe traversal like ((.Values.global).certificates */}} +{{- $res := tpl (print "{{" (repeat (split "." $dep | len) "(") ".Values." (replace "." ")." $dep) ")}}") $}} +{{- if not (eq $res "")}} +WARNING: {{$dep|quote}} is deprecated; use {{$replace|quote}} instead. +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/_affinity.tpl b/resources/helm/v2.5/istio-control/istio-discovery/templates/_affinity.tpl new file mode 100644 index 0000000000..a3db2bac3a --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/_affinity.tpl @@ -0,0 +1,93 @@ +{{/* affinity - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ */}} + +{{ define "nodeaffinity" }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityRequiredDuringScheduling" . }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityPreferredDuringScheduling" . }} +{{- end }} + +{{- define "nodeAffinityRequiredDuringScheduling" }} + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + {{- range $key, $val := .global.arch }} + {{- if gt ($val | int) 0 }} + - {{ $key | quote }} + {{- end }} + {{- end }} + {{- $nodeSelector := default .global.defaultNodeSelector .nodeSelector -}} + {{- range $key, $val := $nodeSelector }} + - key: {{ $key }} + operator: In + values: + - {{ $val | quote }} + {{- end }} +{{- end }} + +{{- define "nodeAffinityPreferredDuringScheduling" }} + {{- range $key, $val := .global.arch }} + {{- if gt ($val | int) 0 }} + - weight: {{ $val | int }} + preference: + matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - {{ $key | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinity" }} +{{- if or .podAntiAffinityLabelSelector .podAntiAffinityTermLabelSelector}} + podAntiAffinity: + {{- if .podAntiAffinityLabelSelector }} + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityRequiredDuringScheduling" . }} + {{- end }} + {{- if .podAntiAffinityTermLabelSelector }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityPreferredDuringScheduling" . }} + {{- end }} +{{- end }} +{{- end }} + +{{- define "podAntiAffinityRequiredDuringScheduling" }} + {{- range $index, $item := .podAntiAffinityLabelSelector }} + - labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinityPreferredDuringScheduling" }} + {{- range $index, $item := .podAntiAffinityTermLabelSelector }} + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + weight: 100 + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/_helpers.tpl b/resources/helm/v2.5/istio-control/istio-discovery/templates/_helpers.tpl new file mode 100644 index 0000000000..ccf8a077f1 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/_helpers.tpl @@ -0,0 +1,35 @@ +{{/* Prometheus is enabled if its enabled and there are no config overrides set */}} +{{ define "prometheus" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.prometheus.enabled + (not (or + .Values.telemetry.v2.prometheus.configOverride.gateway + .Values.telemetry.v2.prometheus.configOverride.inboundSidecar + .Values.telemetry.v2.prometheus.configOverride.outboundSidecar + )) }} +{{- end }} + +{{/* SD has metrics and logging split. Metrics are enabled if SD is enabled and there are no config overrides set */}} +{{ define "sd-metrics" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} + +{{/* SD has metrics and logging split. */}} +{{ define "sd-logs" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + (has .Values.telemetry.v2.stackdriver.outboundAccessLogging (list "" "ERRORS_ONLY")) + (has .Values.telemetry.v2.stackdriver.inboundAccessLogging (list "" "ALL")) + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/autoscale.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/autoscale.yaml new file mode 100644 index 0000000000..58bc0e2de6 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/autoscale.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.pilot.autoscaleEnabled .Values.pilot.autoscaleMin .Values.pilot.autoscaleMax }} +{{- if not .Values.global.autoscalingv2API }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ .Values.pilot.autoscaleMax }} + minReplicas: {{ .Values.pilot.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: istiod-{{ .Values.revision | default "default" }} + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.pilot.cpu.targetAverageUtilization }} +--- +{{- else }} +{{- if (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion)}} +apiVersion: autoscaling/v2 +{{- else }} +apiVersion: autoscaling/v2beta2 +{{- end }} +kind: HorizontalPodAutoscaler +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ .Values.pilot.autoscaleMax }} + minReplicas: {{ .Values.pilot.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: istiod-{{ .Values.revision | default "default" }} + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.pilot.cpu.targetAverageUtilization }} +--- +{{- end }} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/clusterrole.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/clusterrole.yaml new file mode 100644 index 0000000000..1b0a82649c --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/clusterrole.yaml @@ -0,0 +1,142 @@ +{{ $mcsAPIGroup := or .Values.pilot.env.MCS_API_GROUP "multicluster.x-k8s.io" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: istiod-clusterrole-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +rules: + # sidecar injection controller + + # configuration validation webhook controller + + # istio configuration + # removing CRD permissions can break older versions of Istio running alongside this control plane (https://github.com/istio/istio/issues/29382) + # please proceed with caution + - apiGroups: ["config.istio.io", "security.istio.io", "networking.istio.io", "authentication.istio.io", "rbac.istio.io", "telemetry.istio.io", "extensions.istio.io"] + verbs: ["get", "watch", "list"] + resources: ["*"] +{{- if .Values.global.istiod.enableAnalysis }} + - apiGroups: ["config.istio.io", "security.istio.io", "networking.istio.io", "authentication.istio.io", "rbac.istio.io", "telemetry.istio.io", "extensions.istio.io"] + verbs: ["update"] + # TODO: should be on just */status but wildcard is not supported + resources: ["*"] +{{- end }} + - apiGroups: ["networking.istio.io"] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + resources: [ "workloadentries" ] + - apiGroups: ["networking.istio.io"] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + resources: [ "workloadentries/status" ] + + # auto-detect installed CRD definitions + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "watch"] + + # discovery and routing + - apiGroups: [""] + resources: ["pods", "nodes", "services", "namespaces", "endpoints"] + verbs: ["get", "list", "watch"] + - apiGroups: ["discovery.k8s.io"] + resources: ["endpointslices"] + verbs: ["get", "list", "watch"] + + # ingress controller +{{- if .Values.global.istiod.enableAnalysis }} + - apiGroups: ["extensions", "networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions", "networking.k8s.io"] + resources: ["ingresses/status"] + verbs: ["*"] +{{- end}} + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses", "ingressclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses/status"] + verbs: ["*"] + + # required for CA's namespace controller + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["create", "get", "list", "watch", "update"] + + # Istiod and bootstrap. +{{- $omitCertProvidersForClusterRole := list "istiod" "custom" "none"}} +{{- if or .Values.pilot.env.EXTERNAL_CA (not (has .Values.global.pilotCertProvider $omitCertProvidersForClusterRole)) }} +{{- end}} + + # Used by Istiod to verify the JWT tokens + + # Used by Istiod to verify gateway SDS + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] + + # Use for Kubernetes Service APIs + - apiGroups: ["networking.x-k8s.io", "gateway.networking.k8s.io"] + resources: ["*"] + verbs: ["get", "watch", "list"] + - apiGroups: ["networking.x-k8s.io", "gateway.networking.k8s.io"] + resources: ["*"] # TODO: should be on just */status but wildcard is not supported + verbs: ["update", "patch"] + - apiGroups: ["gateway.networking.k8s.io"] + resources: ["gatewayclasses"] + verbs: ["create", "update", "patch", "delete"] + + # Needed for multicluster secret reading, possibly ingress certs in the future + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] + + # Maistra specific + - apiGroups: ["maistra.io"] + resources: ["servicemeshmemberrolls"] + verbs: ["get", "list", "watch"] + - apiGroups: ["route.openshift.io"] + resources: ["routes", "routes/custom-host"] + verbs: ["get", "list", "watch", "create", "delete", "update"] + + # Used for MCS serviceexport management + - apiGroups: ["{{ $mcsAPIGroup }}"] + resources: ["serviceexports"] + verbs: [ "get", "watch", "list", "create", "delete"] + + # Used for MCS serviceimport management + - apiGroups: ["{{ $mcsAPIGroup }}"] + resources: ["serviceimports"] + verbs: ["get", "watch", "list"] + # Allow use of blockOwnerDeletion in ownerReferences pointing to Pods (see OSSM-1321) + - apiGroups: [""] + resources: ["pods/finalizers"] + verbs: ["update"] +{{- if .Values.global.istiod.enableAnalysis }} + - apiGroups: ["apps"] + verbs: ["get", "watch", "list"] + resources: [ "deployments" ] +{{- end }} +--- +{{- if not (eq (toString .Values.pilot.env.PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER) "false") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: istiod-gateway-controller-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +rules: + - apiGroups: ["apps"] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + resources: [ "deployments" ] + - apiGroups: [""] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + resources: [ "services" ] + - apiGroups: [""] + verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ] + resources: [ "serviceaccounts"] +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/clusterrolebinding.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..ba62880324 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/clusterrolebinding.yaml @@ -0,0 +1,37 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if .Values.global.clusterWide }}ClusterRoleBinding{{ else }}RoleBinding{{ end }} +metadata: + {{ if not .Values.global.clusterWide }}namespace: {{ .Release.Namespace }}{{ end }} + name: istiod-clusterrole-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istiod-clusterrole-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} +subjects: + - kind: ServiceAccount + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} +--- +{{- if not (eq (toString .Values.pilot.env.PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER) "false") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: {{ if .Values.global.clusterWide }}ClusterRoleBinding{{ else }}RoleBinding{{ end }} +metadata: + {{ if not .Values.global.clusterWide }}namespace: {{ .Release.Namespace }}{{ end }} + name: istiod-gateway-controller-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istiod-gateway-controller-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} +subjects: +- kind: ServiceAccount + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/configmap-jwks.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/configmap-jwks.yaml new file mode 100644 index 0000000000..1f35442d5f --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/configmap-jwks.yaml @@ -0,0 +1,13 @@ +{{- if .Values.pilot.jwksResolverExtraRootCA }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: pilot-jwks-extra-cacerts-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +data: + extra.pem: {{ .Values.pilot.jwksResolverExtraRootCA | quote }} +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/configmap.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/configmap.yaml new file mode 100644 index 0000000000..fd63dc5a63 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/configmap.yaml @@ -0,0 +1,125 @@ +{{- define "mesh" }} +{{- if .Values.gatewayAPI.controllerMode }} + discoverySelectors: + - matchLabels: + maistra.io/member-of: "{{ .Release.Namespace }}" +{{- end }} + + # The trust domain corresponds to the trust root of a system. + # Refer to https://github.com/spiffe/spiffe/blob/master/standards/SPIFFE-ID.md#21-trust-domain + trustDomain: {{ .Values.meshConfig.trustDomain | default .Values.global.trustDomain }} + + # The namespace to treat as the administrative root namespace for Istio configuration. + # When processing a leaf namespace Istio will search for declarations in that namespace first + # and if none are found it will search in the root namespace. Any matching declaration found in the root namespace + # is processed as if it were declared in the leaf namespace. + rootNamespace: {{ .Values.meshConfig.rootNamespace | default .Release.Namespace }} + + {{ $prom := include "prometheus" . | eq "true" }} + {{ $sdMetrics := include "sd-metrics" . | eq "true" }} + {{ $sdLogs := include "sd-logs" . | eq "true" }} + {{- if or $prom $sdMetrics $sdLogs }} + defaultProviders: + {{- if or $prom $sdMetrics }} + metrics: + {{ if $prom }}- prometheus{{ end }} + {{ if $sdMetrics }}- stackdriver{{ end }} + {{- end }} + {{- if $sdLogs }} + accessLogging: + - stackdriver + {{- end }} + {{- end }} + + defaultConfig: + {{- if .Values.global.meshID }} + meshId: "{{ .Values.global.meshID }}" + {{- end }} + {{- with (.Values.global.proxy.variant | default .Values.global.variant) }} + image: + imageType: {{. | quote}} + {{- end }} + tracing: + {{- if eq .Values.global.proxy.tracer "lightstep" }} + lightstep: + # Address of the LightStep Satellite pool + address: {{ .Values.global.tracer.lightstep.address }} + # Access Token used to communicate with the Satellite pool + accessToken: {{ .Values.global.tracer.lightstep.accessToken }} + {{- else if eq .Values.global.proxy.tracer "zipkin" }} + zipkin: + # Address of the Zipkin collector + address: {{ ((.Values.global.tracer).zipkin).address | default (print "zipkin." .Release.Namespace ":9411") }} + {{- else if eq .Values.global.proxy.tracer "datadog" }} + datadog: + # Address of the Datadog Agent + address: {{ .Values.global.tracer.datadog.address | default "$(HOST_IP):8126" }} + {{- else if eq .Values.global.proxy.tracer "stackdriver" }} + stackdriver: + # enables trace output to stdout. + {{- if $.Values.global.tracer.stackdriver.debug }} + debug: {{ $.Values.global.tracer.stackdriver.debug }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfAttributes }} + # The global default max number of attributes per span. + maxNumberOfAttributes: {{ $.Values.global.tracer.stackdriver.maxNumberOfAttributes | default "200" }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfAnnotations }} + # The global default max number of annotation events per span. + maxNumberOfAnnotations: {{ $.Values.global.tracer.stackdriver.maxNumberOfAnnotations | default "200" }} + {{- end }} + {{- if $.Values.global.tracer.stackdriver.maxNumberOfMessageEvents }} + # The global default max number of message events per span. + maxNumberOfMessageEvents: {{ $.Values.global.tracer.stackdriver.maxNumberOfMessageEvents | default "200" }} + {{- end }} + {{- else if eq .Values.global.proxy.tracer "openCensusAgent" }} + {{/* Fill in openCensusAgent configuration from meshConfig so it isn't overwritten below */}} +{{ toYaml $.Values.meshConfig.defaultConfig.tracing | indent 8 }} + {{- else }} + {} + {{- end }} + {{- if .Values.global.remotePilotAddress }} + {{- if .Values.pilot.enabled }} + discoveryAddress: {{ printf "istiod-remote.%s.svc" .Release.Namespace }}:15012 + {{- else }} + discoveryAddress: {{ printf "istiod.%s.svc" .Release.Namespace }}:15012 + {{- end }} + {{- else }} + discoveryAddress: istiod-{{ .Values.revision | default "default" }}.{{.Release.Namespace}}.svc:15012 + {{- end }} +{{- end }} + +{{/* We take the mesh config above, defined with individual values.yaml, and merge with .Values.meshConfig */}} +{{/* The intent here is that meshConfig.foo becomes the API, rather than re-inventing the API in values.yaml */}} +{{- $originalMesh := include "mesh" . | fromYaml }} +{{- $mesh := mergeOverwrite $originalMesh .Values.meshConfig }} + +{{- if .Values.pilot.configMap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: istio-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} + release: {{ .Release.Name }} +data: + + # Configuration file for the mesh networks to be used by the Split Horizon EDS. + meshNetworks: |- + {{- if .Values.global.meshNetworks }} + networks: +{{ toYaml .Values.global.meshNetworks | trim | indent 6 }} + {{- else }} + networks: {} + {{- end }} + + mesh: |- +{{- if .Values.meshConfig }} +{{ $mesh | toYaml | indent 4 }} +{{- else }} +{{- include "mesh" . }} +{{- end }} +--- +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/deployment.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/deployment.yaml new file mode 100644 index 0000000000..0f46aa18c2 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/deployment.yaml @@ -0,0 +1,347 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + istio: pilot + release: {{ .Release.Name }} +{{- range $key, $val := .Values.pilot.deploymentLabels }} + {{ $key }}: "{{ $val }}" +{{- end }} +spec: +{{- if not .Values.pilot.autoscaleEnabled }} +{{- if .Values.pilot.replicaCount }} + replicas: {{ .Values.pilot.replicaCount }} +{{- end }} +{{- end }} + strategy: + rollingUpdate: + maxSurge: {{ .Values.pilot.rollingMaxSurge }} + maxUnavailable: {{ .Values.pilot.rollingMaxUnavailable }} + selector: + matchLabels: + app: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + {{- if ne .Values.revision "" }} + app: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + {{- else }} + istio: pilot + {{- end }} + template: + metadata: + labels: + maistra-control-plane: {{ .Release.Namespace }} + app: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + sidecar.istio.io/inject: "false" + {{- if ne .Values.revision "" }} + istio: istiod + {{- else }} + istio: pilot + {{- end }} + {{- range $key, $val := .Values.pilot.podLabels }} + {{ $key }}: "{{ $val }}" + {{- end }} + {{- if .Values.pilot.podLabels }} +{{ toYaml .Values.pilot.podLabels | indent 8 }} + {{- end }} + annotations: + {{- if .Values.meshConfig.enablePrometheusMerge }} + prometheus.io/port: "15014" + prometheus.io/scrape: "true" + {{- end }} + ambient.istio.io/redirection: disabled + sidecar.istio.io/inject: "false" + {{- if .Values.pilot.podAnnotations }} +{{ toYaml .Values.pilot.podAnnotations | indent 8 }} + {{- end }} + spec: +{{- if .Values.pilot.nodeSelector }} + nodeSelector: +{{ toYaml .Values.pilot.nodeSelector | indent 8 }} +{{- end }} +{{- with .Values.pilot.affinity }} + affinity: +{{- toYaml . | nindent 8 }} +{{- end }} +{{- with .Values.pilot.tolerations }} + tolerations: +{{- toYaml . | nindent 8 }} +{{- end }} + serviceAccountName: istiod-{{ .Values.revision | default "default" }} +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} + containers: + - name: discovery + workingDir: "/" +{{- if contains "/" .Values.pilot.image }} + image: "{{ .Values.pilot.image }}" +{{- else }} + image: "{{ .Values.pilot.hub | default .Values.global.hub }}/{{ .Values.pilot.image | default "pilot" }}:{{ .Values.pilot.tag | default .Values.global.tag }}{{with (.Values.pilot.variant | default .Values.global.variant)}}-{{.}}{{end}}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + args: + - "discovery" +{{- if .Values.pilot.extraArgs }} + {{- range .Values.pilot.extraArgs }} + - {{ . | quote }} + {{- end }} +{{- end }} +{{- if not .Values.global.clusterWide }} + - --memberRollName=default + - --enableNodeAccess=false + - --enableCRDScan=false + - --enableIngressClassName=false +{{- end}} + - --monitoringAddr=:15014 +{{- if .Values.global.logging.level }} + - --log_output_level={{ .Values.global.logging.level }} +{{- end}} +{{- if .Values.global.logAsJson }} + - --log_as_json +{{- end }} + - --domain + - {{ .Values.global.proxy.clusterDomain }} +{{- if .Values.global.oneNamespace }} + - "-a" + - {{ .Release.Namespace }} +{{- end }} +{{- if .Values.pilot.plugins }} + - --plugins={{ .Values.pilot.plugins }} +{{- end }} + - --keepaliveMaxServerConnectionAge + - "{{ .Values.pilot.keepaliveMaxServerConnectionAge }}" + ports: + - containerPort: 8080 + protocol: TCP + - containerPort: 15010 + protocol: TCP + - name: webhook + containerPort: 15017 + protocol: TCP + - containerPort: 8188 + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: 8080 + initialDelaySeconds: 1 + periodSeconds: 3 + timeoutSeconds: 5 + env: +{{- $iorEnabled := "true" }} +{{- $gateway := index .Values "gateways" "istio-ingressgateway" }} +{{- if or (not .Values.gateways.enabled) (not $gateway) (not $gateway.ior_enabled) }} +{{- $iorEnabled = "false" }} +{{- end }} + - name: ENABLE_IOR + value: "{{ $iorEnabled }}" + - name: PILOT_CA_CERT_CONFIG_MAP_NAME + value: "{{ .Values.global.caCertConfigMapName }}" +{{- if .Values.gatewayAPI.enabled }} + - name: PILOT_ENABLE_GATEWAY_API + value: "true" + - name: PILOT_ENABLE_GATEWAY_API_STATUS + value: "true" + - name: PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER + value: "true" +{{- if .Values.gatewayAPI.controllerMode }} + - name: PILOT_ENABLE_GATEWAY_CONTROLLER_MODE + value: "true" + - name: PILOT_GATEWAY_API_DEFAULT_GATEWAYCLASS + value: "ocp" + - name: PILOT_GATEWAY_API_CONTROLLER_NAME + value: "openshift.io/gateway-controller" + - name: PILOT_GATEWAY_API_DEPLOYMENT_DEFAULT_LABELS + value: "{\"gateway.openshift.io/inject\":\"true\"}" +{{- end }} +{{- else }} + - name: PILOT_ENABLE_GATEWAY_API + value: "false" + - name: PILOT_ENABLE_GATEWAY_API_STATUS + value: "false" + - name: PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER + value: "false" +{{- end }} + - name: PRIORITIZED_LEADER_ELECTION + value: "false" + - name: VALIDATION_WEBHOOK_CONFIG_NAME + value: "" + - name: INJECTION_WEBHOOK_CONFIG_NAME + value: "" + - name: REVISION + value: "{{ .Values.revision | default `default` }}" + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.serviceAccountName + - name: KUBECONFIG + value: /var/run/secrets/remote/config + {{- if .Values.pilot.env }} + {{- range $key, $val := .Values.pilot.env }} + - name: {{ $key }} + value: "{{ $val }}" + {{- end }} + {{- end }} +{{- if semverCompare "<1.19" .Capabilities.KubeVersion.GitVersion }} + - name: ENABLE_LEGACY_FSGROUP_INJECTION + value: "true" +{{- end }} + - name: PILOT_ENABLE_FEDERATION + value: "{{ .Values.pilot.enableFederation }}" +{{- if .Values.pilot.traceSampling }} + - name: PILOT_TRACE_SAMPLING + value: "{{ .Values.pilot.traceSampling }}" +{{- end }} + - name: PILOT_ENABLE_PROTOCOL_SNIFFING_FOR_OUTBOUND + value: "{{ .Values.pilot.enableProtocolSniffingForOutbound }}" + - name: PILOT_ENABLE_PROTOCOL_SNIFFING_FOR_INBOUND + value: "{{ .Values.pilot.enableProtocolSniffingForInbound }}" + - name: ISTIOD_ADDR + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + - name: PILOT_ENABLE_STATUS + value: "{{ .Values.global.istiod.enableAnalysis }}" + - name: PILOT_ENABLE_ANALYSIS + value: "{{ .Values.global.istiod.enableAnalysis }}" + - name: CLUSTER_ID + value: "{{ $.Values.global.multiCluster.clusterName | default `Kubernetes` }}" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory +{{- if .Values.global.tls }} +{{- if .Values.global.tls.minProtocolVersion }} + - name: TLS_MIN_PROTOCOL_VERSION + value: {{ .Values.global.tls.minProtocolVersion }} +{{- end }} +{{- if .Values.global.tls.maxProtocolVersion }} + - name: TLS_MAX_PROTOCOL_VERSION + value: {{ .Values.global.tls.maxProtocolVersion }} +{{- end }} +{{- if .Values.global.tls.cipherSuites }} + - name: TLS_CIPHER_SUITES + value: {{ .Values.global.tls.cipherSuites }} +{{- end }} +{{- if .Values.global.tls.ecdhCurves }} + - name: TLS_ECDH_CURVES + value: {{ .Values.global.tls.ecdhCurves }} +{{- end }} +{{- end }} + resources: +{{- if .Values.pilot.resources }} +{{ toYaml .Values.pilot.resources | trim | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | trim | indent 12 }} +{{- end }} + securityContext: + capabilities: + drop: + - ALL +{{- if .Values.pilot.seccompProfile }} + seccompProfile: +{{ toYaml .Values.pilot.seccompProfile | trim | indent 14 }} +{{- end }} + volumeMounts: +{{- if .Values.pilot.extraVolumeMounts }} +{{ toYaml .Values.pilot.extraVolumeMounts | indent 10 }} +{{- end }} + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + mountPath: /var/run/secrets/tokens + readOnly: true + {{- end }} + - name: local-certs + mountPath: /var/run/secrets/istio-dns + - name: cacerts + mountPath: /etc/cacerts + readOnly: true + - name: istio-kubeconfig + mountPath: /var/run/secrets/remote + readOnly: true + {{- if .Values.pilot.jwksResolverExtraRootCA }} + - name: extracacerts + mountPath: /cacerts + {{- end }} + - name: istio-csr-dns-cert + mountPath: /var/run/secrets/istiod/tls + readOnly: true + - name: istio-csr-ca-configmap + mountPath: /var/run/secrets/istiod/ca + readOnly: true + affinity: +{{ include "nodeaffinity" (dict "global" .Values.global "nodeSelector" .Values.pilot.nodeSelector) }} +{{ include "podAntiAffinity" .Values.pilot }} +{{- if .Values.pilot.tolerations }} + tolerations: +{{ toYaml .Values.pilot.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} + volumes: + # Technically not needed on this pod - but it helps debugging/testing SDS + # Should be removed after everything works. + - emptyDir: + medium: Memory + name: local-certs + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: {{ .Values.global.sds.token.aud }} + expirationSeconds: 43200 + path: istio-token + {{- end }} + # Optional: user-generated root + - name: cacerts + secret: + secretName: cacerts + optional: true + - name: istio-kubeconfig + secret: + secretName: istio-kubeconfig + optional: true + # Optional: istio-csr dns pilot certs + - name: istio-csr-dns-cert + secret: + secretName: istiod-tls + optional: true + - name: istio-csr-ca-configmap + configMap: + name: "{{ .Values.global.caCertConfigMapName }}" + defaultMode: 420 + optional: true + {{- if .Values.pilot.jwksResolverExtraRootCA }} + - name: extracacerts + configMap: + name: pilot-jwks-extra-cacerts-{{ .Values.revision | default "default" }} + {{- end }} + +{{- if .Values.pilot.extraVolumes }} +{{ toYaml .Values.pilot.extraVolumes | indent 6 }} +{{- end }} +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/federation.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/federation.yaml new file mode 100644 index 0000000000..40d4208f3e --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/federation.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} + app: istiod + istio: pilot + release: {{ .Release.Name }} +spec: + host: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc.cluster.local + trafficPolicy: + portLevelSettings: + - port: + number: 8188 + tls: + mode: SIMPLE +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/istiod-injector-configmap.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/istiod-injector-configmap.yaml new file mode 100644 index 0000000000..f764819924 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/istiod-injector-configmap.yaml @@ -0,0 +1,67 @@ +{{- if not .Values.global.omitSidecarInjectorConfigMap }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: istio-sidecar-injector-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} + release: {{ .Release.Name }} +data: +{{/* Scope the values to just top level fields used in the template, to reduce the size. */}} + values: |- +{{ pick .Values "global" "istio_cni" "sidecarInjectorWebhook" "revision" | toPrettyJson | indent 4 }} + + # To disable injection: use omitSidecarInjectorConfigMap, which disables the webhook patching + # and istiod webhook functionality. + # + # New fields should not use Values - it is a 'primary' config object, users should be able + # to fine tune it or use it with kube-inject. + config: |- + # defaultTemplates defines the default template to use for pods that do not explicitly specify a template + defaultTemplates: [sidecar] + policy: {{ .Values.global.proxy.autoInject }} + alwaysInjectSelector: +{{ toYaml .Values.sidecarInjectorWebhook.alwaysInjectSelector | trim | indent 6 }} + neverInjectSelector: +{{ toYaml .Values.sidecarInjectorWebhook.neverInjectSelector | trim | indent 6 }} + injectedAnnotations: + {{- range $key, $val := .Values.sidecarInjectorWebhook.injectedAnnotations }} + "{{ $key }}": {{ $val | quote }} + {{- end }} + {{- /* If someone ends up with this new template, but an older Istiod image, they will attempt to render this template + which will fail with "Pod injection failed: template: inject:1: function "Istio_1_9_Required_Template_And_Version_Mismatched" not defined". + This should make it obvious that their installation is broken. + */}} + template: {{ `{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}` | quote }} + templates: +{{- if not (hasKey .Values.sidecarInjectorWebhook.templates "sidecar") }} + sidecar: | +{{ .Files.Get "files/injection-template.yaml" | trim | indent 8 }} +{{- end }} +{{- if not (hasKey .Values.sidecarInjectorWebhook.templates "gateway") }} + gateway: | +{{ .Files.Get "files/gateway-injection-template.yaml" | trim | indent 8 }} +{{- end }} +{{- if not (hasKey .Values.sidecarInjectorWebhook.templates "grpc-simple") }} + grpc-simple: | +{{ .Files.Get "files/grpc-simple.yaml" | trim | indent 8 }} +{{- end }} +{{- if not (hasKey .Values.sidecarInjectorWebhook.templates "grpc-agent") }} + grpc-agent: | +{{ .Files.Get "files/grpc-agent.yaml" | trim | indent 8 }} +{{- end }} +{{- if not (hasKey .Values.sidecarInjectorWebhook.templates "waypoint") }} + waypoint: | +{{ .Files.Get "files/waypoint.yaml" | trim | indent 8 }} +{{- end }} +{{- if not (hasKey .Values.sidecarInjectorWebhook.templates "kube-gateway") }} + kube-gateway: | +{{ .Files.Get "files/kube-gateway.yaml" | trim | indent 8 }} +{{- end }} +{{- with .Values.sidecarInjectorWebhook.templates }} +{{ toYaml . | trim | indent 6 }} +{{- end }} + +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/meshclusterrole.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/meshclusterrole.yaml new file mode 100644 index 0000000000..0ab0f054b7 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/meshclusterrole.yaml @@ -0,0 +1,18 @@ +# Dedicated cluster role - istiod will use fewer dangerous permissions ( secret access in particular ). +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: istiod-internal-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +rules: + # for k8s service account token authentication + - apiGroups: ["authentication.k8s.io"] + resources: ["tokenreviews"] + verbs: ["create"] + # for istiod to check if the proxy has permissions to read secrets + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/meshclusterrolebinding.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/meshclusterrolebinding.yaml new file mode 100644 index 0000000000..105a3fea71 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/meshclusterrolebinding.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: istiod-internal-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istiod-internal-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} +subjects: + - kind: ServiceAccount + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/mutatingwebhook.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/mutatingwebhook.yaml new file mode 100644 index 0000000000..852c96ffbd --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/mutatingwebhook.yaml @@ -0,0 +1,79 @@ +{{- /* Core defines the common configuration used by all webhook segments */}} +{{- define "core" }} +{{- /* Kubernetes unfortunately requires a unique name for the webhook in some newer versions, so we assign +a unique prefix to each. */}} +- name: {{.Prefix}}sidecar-injector.istio.io + clientConfig: + {{- if .Values.istiodRemote.injectionURL }} + url: "{{ .Values.istiodRemote.injectionURL }}" + {{- else }} + service: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + path: "{{ .Values.istiodRemote.injectionPath }}" + port: 443 + {{- end }} + caBundle: "" + sideEffects: None + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + failurePolicy: Fail + admissionReviewVersions: ["v1beta1", "v1"] +{{- end }} +{{- /* Installed for each revision - not installed for cluster resources ( cluster roles, bindings, crds) */}} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: istiod-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} + app: sidecar-injector + release: {{ .Release.Name }} +webhooks: + {{- include "core" (mergeOverwrite (deepCopy .) (dict "Prefix" "") ) }} + namespaceSelector: + matchExpressions: + - key: maistra.io/member-of + operator: In + values: + - {{ .Release.Namespace }} + - key: maistra.io/ignore-namespace + operator: DoesNotExist + - key: istio-injection + operator: NotIn + values: + - disabled + - key: istio-env + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: app + operator: NotIn + values: + - "istiod" +{{- if .Values.sidecarInjectorWebhook.objectSelector.enabled }} +{{- if eq .Values.global.proxy.autoInject "enabled" }} + - key: "sidecar.istio.io/inject" + operator: NotIn + values: + - "false" +{{- else }} + - key: "sidecar.istio.io/inject" + operator: In + values: + - "true" +{{- end }} +{{- end }} +{{- if .Values.gatewayAPI.controllerMode }} + {{- include "core" (mergeOverwrite (deepCopy .) (dict "Prefix" "gateways.") ) }} + objectSelector: + matchExpressions: + - key: "gateway.openshift.io/inject" + operator: In + values: + - "true" +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/networkpolicy.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/networkpolicy.yaml new file mode 100644 index 0000000000..dd86e94140 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/networkpolicy.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + istio: pilot + istio.io/rev: {{ .Values.revision | default "default" }} + release: {{ .Release.Name }} + annotations: + "maistra.io/internal": "true" +spec: + podSelector: + matchLabels: + app: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + ingress: + - ports: + port: webhook diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/poddisruptionbudget.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..7f3a73f73e --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/poddisruptionbudget.yaml @@ -0,0 +1,28 @@ +{{- if .Values.global.defaultPodDisruptionBudget.enabled }} +{{- if (semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion) }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + istio.io/rev: {{ .Values.revision | default "default" }} + release: {{ .Release.Name }} + istio: pilot +spec: + minAvailable: 1 + selector: + matchLabels: + app: istiod + {{- if ne .Values.revision "" }} + istio.io/rev: {{ .Values.revision }} + {{- else }} + istio: pilot + {{- end }} +--- +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/revision-tags.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/revision-tags.yaml new file mode 100644 index 0000000000..ccd58718f1 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/revision-tags.yaml @@ -0,0 +1,139 @@ +# Adapted from istio-discovery/templates/mutatingwebhook.yaml +# Removed paths for legacy and default selectors since a revision tag +# is inherently created from a specific revision +{{- $whv := dict + "revision" .Values.revision + "injectionPath" .Values.istiodRemote.injectionPath + "injectionURL" .Values.istiodRemote.injectionURL + "namespace" .Release.Namespace }} +{{- define "core" }} +{{- /* Kubernetes unfortunately requires a unique name for the webhook in some newer versions, so we assign +a unique prefix to each. */}} +- name: {{.Prefix}}sidecar-injector.istio.io + clientConfig: + {{- if .injectionURL }} + url: "{{ .injectionURL }}" + {{- else }} + service: + name: istiod{{- if not (eq .revision "") }}-{{ .revision }}{{- end }} + namespace: {{ .namespace }} + path: "{{ .injectionPath }}" + port: 443 + {{- end }} + sideEffects: None + rules: + - operations: [ "CREATE" ] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] + failurePolicy: Fail + admissionReviewVersions: ["v1beta1", "v1"] +{{- end }} +{{- range $tagName := $.Values.revisionTags }} +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: +{{- if eq $.Release.Namespace "istio-system"}} + name: istio-revision-tag-{{ $tagName }} +{{- else }} + name: istio-revision-tag-{{ $tagName }}-{{ $.Release.Namespace }} +{{- end }} + labels: + maistra-version: "2.5.0" + istio.io/tag: {{ $tagName }} + istio.io/rev: {{ $.Values.revision | default "default" }} + app: sidecar-injector + release: {{ $.Release.Name }} +webhooks: +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "rev.namespace.") ) }} + namespaceSelector: + matchExpressions: + - key: istio.io/rev + operator: In + values: + - "{{ $tagName }}" + - key: istio-injection + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "rev.object.") ) }} + namespaceSelector: + matchExpressions: + - key: istio.io/rev + operator: DoesNotExist + - key: istio-injection + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + - key: istio.io/rev + operator: In + values: + - "{{ $tagName }}" + +{{- /* When the tag is "default" we want to create webhooks for the default revision */}} +{{- /* These webhooks should be kept in sync with istio-discovery/templates/mutatingwebhook.yaml */}} +{{- if (eq $tagName "default") }} + +{{- /* Case 1: Namespace selector enabled, and object selector is not injected */}} +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "namespace.") ) }} + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: In + values: + - enabled + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + +{{- /* Case 2: no namespace label, but object selector is enabled (and revision label is not, which has priority) */}} +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "object.") ) }} + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: In + values: + - "true" + - key: istio.io/rev + operator: DoesNotExist + +{{- if $.Values.sidecarInjectorWebhook.enableNamespacesByDefault }} +{{- /* Special case 3: no labels at all */}} +{{- include "core" (mergeOverwrite (deepCopy $whv) (dict "Prefix" "auto.") ) }} + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist + - key: "kubernetes.io/metadata.name" + operator: "NotIn" + values: ["kube-system","kube-public","kube-node-lease","local-path-storage"] + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist +{{- end }} + +{{- end }} +--- +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/role.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/role.yaml new file mode 100644 index 0000000000..183011f926 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/role.yaml @@ -0,0 +1,39 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: istiod-internal-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + annotations: + "maistra.io/internal": "true" + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +rules: +# permissions to verify the webhook is ready and rejecting +# invalid config. We use --server-dry-run so no config is persisted. +- apiGroups: ["networking.istio.io"] + verbs: ["create"] + resources: ["gateways"] + +# For storing CA secret +- apiGroups: [""] + resources: ["secrets"] + # TODO lock this down to istio-ca-cert if not using the DNS cert mesh config + verbs: ["create", "get", "watch", "list", "update", "delete"] + +# For status controller, so it can delete the distribution report configmap +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["delete"] + +# For gateway deployment controller +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "update", "patch", "create"] + +# For MeshFederation support +- apiGroups: ["federation.maistra.io"] + resources: ["servicemeshpeers", "servicemeshpeers/status", "exportedservicesets", "exportedservicesets/status", "importedservicesets", "importedservicesets/status"] + verbs: ["get", "list", "watch", "patch", "update"] + diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/rolebinding.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/rolebinding.yaml new file mode 100644 index 0000000000..9a1c00eae0 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/rolebinding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: istiod-internal-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + annotations: + "maistra.io/internal": "true" + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: istiod-internal-{{ .Values.revision | default "default" }} +subjects: + - kind: ServiceAccount + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/service.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/service.yaml new file mode 100644 index 0000000000..b735aec602 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/service.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Service +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + {{- if .Values.pilot.serviceAnnotations }} + annotations: +{{ toYaml .Values.pilot.serviceAnnotations | indent 4 }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} + app: istiod + istio: pilot + release: {{ .Release.Name }} +spec: + ports: + - port: 15010 + name: grpc-xds # plaintext + protocol: TCP + - port: 15012 + name: https-dns # mTLS with k8s-signed cert + protocol: TCP + - port: 443 + name: https-webhook # validation and injection + targetPort: 15017 + protocol: TCP + - port: 15014 + name: http-monitoring # prometheus stats + protocol: TCP + - port: 8188 + name: http-discovery # federation discovery + protocol: TCP + selector: + app: istiod + {{- if ne .Values.revision "" }} + istio.io/rev: {{ .Values.revision }} + {{- else }} + # Label used by the 'default' service. For versioned deployments we match with app and version. + # This avoids default deployment picking the canary + istio: pilot + {{- end }} +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/serviceaccount.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/serviceaccount.yaml new file mode 100644 index 0000000000..2f0af044b0 --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ServiceAccount + {{- if .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +metadata: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} +--- diff --git a/resources/helm/v2.5/istio-control/istio-discovery/templates/validatingwebhookconfiguration.yaml b/resources/helm/v2.5/istio-control/istio-discovery/templates/validatingwebhookconfiguration.yaml new file mode 100644 index 0000000000..812c674a7a --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/templates/validatingwebhookconfiguration.yaml @@ -0,0 +1,77 @@ +{{- if .Values.global.configValidation }} +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + name: istio-validator-{{ .Values.revision | default "default" }}-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istiod + release: {{ .Release.Name }} + istio: istiod + istio.io/rev: {{ .Values.revision | default "default" }} +webhooks: + # Webhook handling per-revision validation. Mostly here so we can determine whether webhooks + # are rejecting invalid configs on a per-revision basis. + - name: rev.validation.istio.io + clientConfig: + # Should change from base but cannot for API compat + {{- if .Values.base.validationURL }} + url: {{ .Values.base.validationURL }} + {{- else }} + service: + name: istiod-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + path: "/validate" + {{- end }} + namespaceSelector: + matchExpressions: + - key: maistra.io/member-of + operator: In + values: + - {{ .Release.Namespace }} + objectSelector: + matchExpressions: + - key: maistra-version + operator: DoesNotExist + rules: + - operations: + - CREATE + - UPDATE + apiGroups: + - authentication.maistra.io + apiVersions: + - "*" + resources: + - "*" + - operations: + - CREATE + - UPDATE + apiGroups: + - rbac.maistra.io + apiVersions: + - "*" + resources: + - "*" + - operations: + - CREATE + - UPDATE + apiGroups: + - security.istio.io + - networking.istio.io + - telemetry.istio.io + - extensions.istio.io + {{- if .Values.base.validateGateway }} + - gateway.networking.k8s.io + {{- end }} + apiVersions: + - "*" + resources: + - "*" + # Fail open until the validation webhook is ready. The webhook controller + # will update this to `Fail` and patch in the `caBundle` when the webhook + # endpoint is ready. + failurePolicy: Fail + sideEffects: None + admissionReviewVersions: ["v1beta1", "v1"] +--- +{{- end }} diff --git a/resources/helm/v2.5/istio-control/istio-discovery/values.yaml b/resources/helm/v2.5/istio-control/istio-discovery/values.yaml new file mode 100644 index 0000000000..bc5e33e7ce --- /dev/null +++ b/resources/helm/v2.5/istio-control/istio-discovery/values.yaml @@ -0,0 +1,566 @@ +#.Values.pilot for discovery and mesh wide config + +## Discovery Settings +pilot: + enableFederation: true + autoscaleEnabled: true + autoscaleMin: 1 + autoscaleMax: 5 + replicaCount: 1 + rollingMaxSurge: 100% + rollingMaxUnavailable: 25% + + hub: "" + tag: "" + variant: "" + + # Can be a full hub/image:tag + image: pilot + traceSampling: 1.0 + extraArgs: [] + extraVolumeMounts: [] + extraVolumes: [] + + # Resources for a small pilot install + resources: + requests: + cpu: 500m + memory: 2048Mi + + # Set to `type: RuntimeDefault` to use the default profile if available. + seccompProfile: {} + + env: {} + + cpu: + targetAverageUtilization: 80 + + # if protocol sniffing is enabled for outbound + enableProtocolSniffingForOutbound: false + # if protocol sniffing is enabled for inbound + enableProtocolSniffingForInbound: false + + nodeSelector: {} + podLabels: {} + podAnnotations: {} + serviceAnnotations: {} + + tolerations: [] + + # Specify the pod anti-affinity that allows you to constrain which nodes + # your pod is eligible to be scheduled based on labels on pods that are + # already running on the node rather than based on labels on nodes. + # There are currently two types of anti-affinity: + # "requiredDuringSchedulingIgnoredDuringExecution" + # "preferredDuringSchedulingIgnoredDuringExecution" + # which denote "hard" vs. "soft" requirements, you can define your values + # in "podAntiAffinityLabelSelector" and "podAntiAffinityTermLabelSelector" + # correspondingly. + # For example: + # podAntiAffinityLabelSelector: + # - key: security + # operator: In + # values: S1,S2 + # topologyKey: "kubernetes.io/hostname" + # This pod anti-affinity rule says that the pod requires not to be scheduled + # onto a node if that node is already running a pod with label having key + # "security" and value "S1". + podAntiAffinityLabelSelector: [] + podAntiAffinityTermLabelSelector: [] + + # You can use jwksResolverExtraRootCA to provide a root certificate + # in PEM format. This will then be trusted by pilot when resolving + # JWKS URIs. + jwksResolverExtraRootCA: "" + + # This is used to set the source of configuration for + # the associated address in configSource, if nothing is specified + # the default MCP is assumed. + configSource: + subscribedResources: [] + + plugins: [] + + # The following is used to limit how long a sidecar can be connected + # to a pilot. It balances out load across pilot instances at the cost of + # increasing system churn. + keepaliveMaxServerConnectionAge: 30m + + # Additional labels to apply to the deployment. + deploymentLabels: {} + + ## Mesh config settings + + # Install the mesh config map, generated from values.yaml. + # If false, pilot wil use default values (by default) or user-supplied values. + configMap: true + + # Additional labels to apply on the pod level for monitoring and logging configuration. + podLabels: {} + +sidecarInjectorWebhook: + objectSelector: + enabled: false + + # You can use the field called alwaysInjectSelector and neverInjectSelector which will always inject the sidecar or + # always skip the injection on pods that match that label selector, regardless of the global policy. + # See https://istio.io/docs/setup/kubernetes/additional-setup/sidecar-injection/#more-control-adding-exceptions + neverInjectSelector: [] + alwaysInjectSelector: [] + + # injectedAnnotations are additional annotations that will be added to the pod spec after injection + # This is primarily to support PSP annotations. For example, if you defined a PSP with the annotations: + # + # annotations: + # apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default + # apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default + # + # The PSP controller would add corresponding annotations to the pod spec for each container. However, this happens before + # the inject adds additional containers, so we must specify them explicitly here. With the above example, we could specify: + # injectedAnnotations: + # container.apparmor.security.beta.kubernetes.io/istio-init: runtime/default + # container.apparmor.security.beta.kubernetes.io/istio-proxy: runtime/default + injectedAnnotations: {} + + # This enables injection of sidecar in all namespaces, + # with the exception of namespaces with "istio-injection:disabled" annotation + # Only one environment should have this enabled. + enableNamespacesByDefault: false + + rewriteAppHTTPProbe: true + + # Templates defines a set of custom injection templates that can be used. For example, defining: + # + # templates: + # hello: | + # metadata: + # labels: + # hello: world + # + # Then starting a pod with the `inject.istio.io/templates: hello` annotation, will result in the pod + # being injected with the hello=world labels. + # This is intended for advanced configuration only; most users should use the built in template + templates: {} + + # Default templates specifies a set of default templates that are used in sidecar injection. + # By default, a template `sidecar` is always provided, which contains the template of default sidecar. + # To inject other additional templates, define it using the `templates` option, and add it to + # the default templates list. + # For example: + # + # templates: + # hello: | + # metadata: + # labels: + # hello: world + # + # defaultTemplates: ["sidecar", "hello"] + # defaultTemplates: [] +istiodRemote: + # Sidecar injector mutating webhook configuration clientConfig.url value. + # For example: https://$remotePilotAddress:15017/inject + # The host should not refer to a service running in the cluster; use a service reference by specifying + # the clientConfig.service field instead. + injectionURL: "" + + # Sidecar injector mutating webhook configuration path value for the clientConfig.service field. + # Override to pass env variables, for example: /inject/cluster/remote/net/network2 + injectionPath: "/inject" +telemetry: + enabled: true + v2: + # For Null VM case now. + # This also enables metadata exchange. + enabled: true + metadataExchange: + # Indicates whether to enable WebAssembly runtime for metadata exchange filter. + wasmEnabled: false + # Indicate if prometheus stats filter is enabled or not + prometheus: + enabled: true + # Indicates whether to enable WebAssembly runtime for stats filter. + wasmEnabled: false + # overrides stats EnvoyFilter configuration. + configOverride: + gateway: {} + inboundSidecar: {} + outboundSidecar: {} + # stackdriver filter settings. + stackdriver: + enabled: false + logging: false + monitoring: false + topology: false # deprecated. setting this to true will have no effect, as this option is no longer supported. + disableOutbound: false + # configOverride parts give you the ability to override the low level configuration params passed to envoy filter. + + configOverride: {} + # e.g. + # disable_server_access_logging: false + # disable_host_header_fallback: true + # Access Log Policy Filter Settings. This enables filtering of access logs from stackdriver. + accessLogPolicy: + enabled: false + # To reduce the number of successful logs, default log window duration is + # set to 12 hours. + logWindowDuration: "43200s" +# Revision is set as 'version' label and part of the resource names when installing multiple control planes. +revision: "" + +# Revision tags are aliases to Istio control plane revisions +revisionTags: [] + +# For Helm compatibility. +ownerName: "" + +# meshConfig defines runtime configuration of components, including Istiod and istio-agent behavior +# See https://istio.io/docs/reference/config/istio.mesh.v1alpha1/ for all available options +meshConfig: + enablePrometheusMerge: true + +global: + # Used to locate istiod. + istioNamespace: istio-system + # List of cert-signers to allow "approve" action in the istio cluster role + # + # certSigners: + # - clusterissuers.cert-manager.io/istio-ca + certSigners: [] + # enable pod disruption budget for the control plane, which is used to + # ensure Istio control plane components are gradually upgraded or recovered. + defaultPodDisruptionBudget: + enabled: true + # The values aren't mutable due to a current PodDisruptionBudget limitation + # minAvailable: 1 + + # A minimal set of requested resources to applied to all deployments so that + # Horizontal Pod Autoscaler will be able to function (if set). + # Each component can overwrite these default values by adding its own resources + # block in the relevant section below and setting the desired resources values. + defaultResources: + requests: + cpu: 10m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + + # Default node tolerations to be applied to all deployments so that all pods can be + # scheduled to a particular nodes with matching taints. Each component can overwrite + # these default values by adding its tolerations block in the relevant section below + # and setting the desired values. + # Configure this field in case that all pods of Istio control plane are expected to + # be scheduled to particular nodes with specified taints. + defaultTolerations: [] + + # Default node selector key-value pairs to set in the pod's nodeAffinity field + defaultNodeSelector: {} + + # Specify pod scheduling arch(amd64, ppc64le, s390x) and weight as follows: + # 0 - Never scheduled + # 1 - Least preferred + # 2 - No preference + # 3 - Most preferred + arch: + amd64: 2 + s390x: 2 + ppc64le: 2 + + # Default hub for Istio images. + # Releases are published to docker hub under 'istio' project. + # Dev builds from prow are on gcr.io + hub: gcr.io/istio-testing + # Default tag for Istio images. + tag: latest + # Variant of the image to use. + # Currently supported are: [debug, distroless] + variant: "" + + # Specify image pull policy if default behavior isn't desired. + # Default behavior: latest images will be Always else IfNotPresent. + imagePullPolicy: "" + + # ImagePullSecrets for all ServiceAccount, list of secrets in the same namespace + # to use for pulling any images in pods that reference this ServiceAccount. + # For components that don't use ServiceAccounts (i.e. grafana, servicegraph, tracing) + # ImagePullSecrets will be added to the corresponding Deployment(StatefulSet) objects. + # Must be set for any cluster configured with private docker registry. + imagePullSecrets: [] + # - private-registry-key + + # Enabled by default in master for maximising testing. + istiod: + enableAnalysis: false + + # To output all istio components logs in json format by adding --log_as_json argument to each container argument + logAsJson: false + + # Comma-separated minimum per-scope logging level of messages to output, in the form of :,: + # The control plane has different scopes depending on component, but can configure default log level across all components + # If empty, default scope and level will be used as configured in code + logging: + level: "default:info" + + omitSidecarInjectorConfigMap: false + + # Whether to restrict the applications namespace the controller manages; + # If not set, controller watches all namespaces + oneNamespace: false + + # Configure whether Operator manages webhook configurations. The current behavior + # of Istiod is to manage its own webhook configurations. + # When this option is set as true, Istio Operator, instead of webhooks, manages the + # webhook configurations. When this option is set as false, webhooks manage their + # own webhook configurations. + operatorManageWebhooks: false + + # Custom DNS config for the pod to resolve names of services in other + # clusters. Use this to add additional search domains, and other settings. + # see + # https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#dns-config + # This does not apply to gateway pods as they typically need a different + # set of DNS settings than the normal application pods (e.g., in + # multicluster scenarios). + # NOTE: If using templates, follow the pattern in the commented example below. + #podDNSSearchNamespaces: + #- global + #- "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global" + + # Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and + # system-node-critical, it is better to configure this in order to make sure your Istio pods + # will not be killed because of low priority class. + # Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + # for more detail. + priorityClassName: "" + + proxy: + image: proxyv2 + + # This controls the 'policy' in the sidecar injector. + autoInject: enabled + + # CAUTION: It is important to ensure that all Istio helm charts specify the same clusterDomain value + # cluster domain. Default value is "cluster.local". + clusterDomain: "cluster.local" + + # Per Component log level for proxy, applies to gateways and sidecars. If a component level is + # not set, then the global "logLevel" will be used. + componentLogLevel: "misc:error" + + # If set, newly injected sidecars will have core dumps enabled. + enableCoreDump: false + + # istio ingress capture allowlist + # examples: + # Redirect only selected ports: --includeInboundPorts="80,8080" + excludeInboundPorts: "" + includeInboundPorts: "*" + + # istio egress capture allowlist + # https://istio.io/docs/tasks/traffic-management/egress.html#calling-external-services-directly + # example: includeIPRanges: "172.30.0.0/16,172.20.0.0/16" + # would only capture egress traffic on those two IP Ranges, all other outbound traffic would + # be allowed by the sidecar + includeIPRanges: "*" + excludeIPRanges: "" + includeOutboundPorts: "" + excludeOutboundPorts: "" + + # Log level for proxy, applies to gateways and sidecars. + # Expected values are: trace|debug|info|warning|error|critical|off + logLevel: warning + + #If set to true, istio-proxy container will have privileged securityContext + privileged: false + + # The number of successive failed probes before indicating readiness failure. + readinessFailureThreshold: 30 + + # The initial delay for readiness probes in seconds. + readinessInitialDelaySeconds: 1 + + # The period between readiness probes. + readinessPeriodSeconds: 2 + + # Resources for the sidecar. + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 2000m + memory: 1024Mi + + # Default port for Pilot agent health checks. A value of 0 will disable health checking. + statusPort: 15021 + + # Specify which tracer to use. One of: zipkin, lightstep, datadog, stackdriver. + # If using stackdriver tracer outside GCP, set env GOOGLE_APPLICATION_CREDENTIALS to the GCP credential file. + tracer: "zipkin" + + proxy_init: + # Base name for the proxy_init container, used to configure iptables. + image: proxyv2 + + # configure remote pilot and istiod service and endpoint + remotePilotAddress: "" + + ############################################################################################## + # The following values are found in other charts. To effectively modify these values, make # + # make sure they are consistent across your Istio helm charts # + ############################################################################################## + + # The customized CA address to retrieve certificates for the pods in the cluster. + # CSR clients such as the Istio Agent and ingress gateways can use this to specify the CA endpoint. + # If not set explicitly, default to the Istio discovery address. + caAddress: "" + + # Configure a remote cluster data plane controlled by an external istiod. + # When set to true, istiod is not deployed locally and only a subset of the other + # discovery charts are enabled. + externalIstiod: false + + # Configure a remote cluster as the config cluster for an external istiod. + configCluster: false + + # Configure the policy for validating JWT. + # Currently, two options are supported: "third-party-jwt" and "first-party-jwt". + jwtPolicy: "third-party-jwt" + + # Mesh ID means Mesh Identifier. It should be unique within the scope where + # meshes will interact with each other, but it is not required to be + # globally/universally unique. For example, if any of the following are true, + # then two meshes must have different Mesh IDs: + # - Meshes will have their telemetry aggregated in one place + # - Meshes will be federated together + # - Policy will be written referencing one mesh from the other + # + # If an administrator expects that any of these conditions may become true in + # the future, they should ensure their meshes have different Mesh IDs + # assigned. + # + # Within a multicluster mesh, each cluster must be (manually or auto) + # configured to have the same Mesh ID value. If an existing cluster 'joins' a + # multicluster mesh, it will need to be migrated to the new mesh ID. Details + # of migration TBD, and it may be a disruptive operation to change the Mesh + # ID post-install. + # + # If the mesh admin does not specify a value, Istio will use the value of the + # mesh's Trust Domain. The best practice is to select a proper Trust Domain + # value. + meshID: "" + + # Configure the mesh networks to be used by the Split Horizon EDS. + # + # The following example defines two networks with different endpoints association methods. + # For `network1` all endpoints that their IP belongs to the provided CIDR range will be + # mapped to network1. The gateway for this network example is specified by its public IP + # address and port. + # The second network, `network2`, in this example is defined differently with all endpoints + # retrieved through the specified Multi-Cluster registry being mapped to network2. The + # gateway is also defined differently with the name of the gateway service on the remote + # cluster. The public IP for the gateway will be determined from that remote service (only + # LoadBalancer gateway service type is currently supported, for a NodePort type gateway service, + # it still need to be configured manually). + # + # meshNetworks: + # network1: + # endpoints: + # - fromCidr: "192.168.0.1/24" + # gateways: + # - address: 1.1.1.1 + # port: 80 + # network2: + # endpoints: + # - fromRegistry: reg1 + # gateways: + # - registryServiceName: istio-ingressgateway.istio-system.svc.cluster.local + # port: 443 + # + meshNetworks: {} + + # Use the user-specified, secret volume mounted key and certs for Pilot and workloads. + mountMtlsCerts: false + + # Default mtls policy. If true, mtls between services will be enabled by default. + mtls: + # Default setting for service-to-service mtls. Can be set explicitly using + # destination rules or service annotations. + enabled: false + # If set to true, and a given service does not have a corresponding DestinationRule configured, + # or its DestinationRule does not have TLSSettings specified, Istio configures client side + # TLS configuration automatically, based on the server side mTLS authentication policy and the + # availibity of sidecars. + auto: true + + multiCluster: + # Set to true to connect two kubernetes clusters via their respective + # ingressgateway services when pods in each cluster cannot directly + # talk to one another. All clusters should be using Istio mTLS and must + # have a shared root CA for this model to work. + enabled: false + # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection + # to properly label proxies + clusterName: "" + + # Network defines the network this cluster belong to. This name + # corresponds to the networks in the map of mesh networks. + network: "" + + # Configure the certificate provider for control plane communication. + # Currently, two providers are supported: "kubernetes" and "istiod". + # As some platforms may not have kubernetes signing APIs, + # Istiod is the default + pilotCertProvider: istiod + + sds: + # The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3. + # When a CSR is sent from Istio Agent to the CA (e.g. Istiod), this aud is to make sure the + # JWT is intended for the CA. + token: + aud: istio-ca + + sts: + # The service port used by Security Token Service (STS) server to handle token exchange requests. + # Setting this port to a non-zero value enables STS server. + servicePort: 0 + + # Configure TLS parameters for listeners + tls: + # List of supported cipher suites, e.g. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + cipherSuites: [] + # List of supported ECDH curves, e.g. CurveP384 + ecdhCurves: [] + # min supported protocol version, e.g. TLSv1_2 + minProtocolVersion: "" + # max supported protocol version, e.g. TLSv1_3 + maxProtocolVersion: "" + + # The name of the CA for workload certificates. + # For example, when caName=GkeWorkloadCertificate, GKE workload certificates + # will be used as the certificates for workloads. + # The default value is "" and when caName="", the CA will be configured by other + # mechanisms (e.g., environmental variable CA_PROVIDER). + caName: "" + + # whether to use autoscaling/v2 template for HPA settings + # for internal usage only, not to be configured by users. + autoscalingv2API: true + +gateways: {} + +base: + validationURL: "" + # For istioctl usage to disable istio config crds in base + enableIstioConfigCRDs: true + + # If enabled, gateway-api types will be validated using the standard upstream validation logic. + # This is an alternative to deploying the standalone validation server the project provides. + # This is disabled by default, as the cluster may already have a validation server; while technically + # it works to have multiple redundant validations, this adds complexity and operational risks. + # Users should consider enabling this if they want full gateway-api validation but don't have other validation servers. + validateGateway: false + +gatewayAPI: + enabled: false + controllerMode: false diff --git a/resources/helm/v2.5/istio-init/files/authorizationpolicies.security.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/authorizationpolicies.security.istio.io.crd.yaml new file mode 100644 index 0000000000..d6647b8fa0 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/authorizationpolicies.security.istio.io.crd.yaml @@ -0,0 +1,389 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + istio: security + release: istio + name: authorizationpolicies.security.istio.io +spec: + group: security.istio.io + names: + categories: + - istio-io + - security-istio-io + kind: AuthorizationPolicy + listKind: AuthorizationPolicyList + plural: authorizationpolicies + singular: authorizationpolicy + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration for access control on workloads. See more + details at: https://istio.io/docs/reference/config/security/authorization-policy.html' + oneOf: + - not: + anyOf: + - required: + - provider + - required: + - provider + properties: + action: + description: Optional. + enum: + - ALLOW + - DENY + - AUDIT + - CUSTOM + type: string + provider: + description: Specifies detailed configuration of the CUSTOM action. + properties: + name: + description: Specifies the name of the extension provider. + type: string + type: object + rules: + description: Optional. + items: + properties: + from: + description: Optional. + items: + properties: + source: + description: Source specifies the source of a request. + properties: + ipBlocks: + description: Optional. + items: + type: string + type: array + namespaces: + description: Optional. + items: + type: string + type: array + notIpBlocks: + description: Optional. + items: + type: string + type: array + notNamespaces: + description: Optional. + items: + type: string + type: array + notPrincipals: + description: Optional. + items: + type: string + type: array + notRemoteIpBlocks: + description: Optional. + items: + type: string + type: array + notRequestPrincipals: + description: Optional. + items: + type: string + type: array + principals: + description: Optional. + items: + type: string + type: array + remoteIpBlocks: + description: Optional. + items: + type: string + type: array + requestPrincipals: + description: Optional. + items: + type: string + type: array + type: object + type: object + type: array + to: + description: Optional. + items: + properties: + operation: + description: Operation specifies the operation of a request. + properties: + hosts: + description: Optional. + items: + type: string + type: array + methods: + description: Optional. + items: + type: string + type: array + notHosts: + description: Optional. + items: + type: string + type: array + notMethods: + description: Optional. + items: + type: string + type: array + notPaths: + description: Optional. + items: + type: string + type: array + notPorts: + description: Optional. + items: + type: string + type: array + paths: + description: Optional. + items: + type: string + type: array + ports: + description: Optional. + items: + type: string + type: array + type: object + type: object + type: array + when: + description: Optional. + items: + properties: + key: + description: The name of an Istio attribute. + type: string + notValues: + description: Optional. + items: + type: string + type: array + values: + description: Optional. + items: + type: string + type: array + type: object + type: array + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration for access control on workloads. See more + details at: https://istio.io/docs/reference/config/security/authorization-policy.html' + oneOf: + - not: + anyOf: + - required: + - provider + - required: + - provider + properties: + action: + description: Optional. + enum: + - ALLOW + - DENY + - AUDIT + - CUSTOM + type: string + provider: + description: Specifies detailed configuration of the CUSTOM action. + properties: + name: + description: Specifies the name of the extension provider. + type: string + type: object + rules: + description: Optional. + items: + properties: + from: + description: Optional. + items: + properties: + source: + description: Source specifies the source of a request. + properties: + ipBlocks: + description: Optional. + items: + type: string + type: array + namespaces: + description: Optional. + items: + type: string + type: array + notIpBlocks: + description: Optional. + items: + type: string + type: array + notNamespaces: + description: Optional. + items: + type: string + type: array + notPrincipals: + description: Optional. + items: + type: string + type: array + notRemoteIpBlocks: + description: Optional. + items: + type: string + type: array + notRequestPrincipals: + description: Optional. + items: + type: string + type: array + principals: + description: Optional. + items: + type: string + type: array + remoteIpBlocks: + description: Optional. + items: + type: string + type: array + requestPrincipals: + description: Optional. + items: + type: string + type: array + type: object + type: object + type: array + to: + description: Optional. + items: + properties: + operation: + description: Operation specifies the operation of a request. + properties: + hosts: + description: Optional. + items: + type: string + type: array + methods: + description: Optional. + items: + type: string + type: array + notHosts: + description: Optional. + items: + type: string + type: array + notMethods: + description: Optional. + items: + type: string + type: array + notPaths: + description: Optional. + items: + type: string + type: array + notPorts: + description: Optional. + items: + type: string + type: array + paths: + description: Optional. + items: + type: string + type: array + ports: + description: Optional. + items: + type: string + type: array + type: object + type: object + type: array + when: + description: Optional. + items: + properties: + key: + description: The name of an Istio attribute. + type: string + notValues: + description: Optional. + items: + type: string + type: array + values: + description: Optional. + items: + type: string + type: array + type: object + type: array + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/destinationrules.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/destinationrules.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..c881d79704 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/destinationrules.networking.istio.io.crd.yaml @@ -0,0 +1,2844 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: destinationrules.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: DestinationRule + listKind: DestinationRuleList + plural: destinationrules + shortNames: + - dr + singular: destinationrule + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The name of a service from the service registry + jsonPath: .spec.host + name: Host + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting load balancing, outlier detection, + etc. See more details at: https://istio.io/docs/reference/config/networking/destination-rule.html' + properties: + exportTo: + description: A list of namespaces to which this destination rule is + exported. + items: + type: string + type: array + host: + description: The name of a service from the service registry. + type: string + subsets: + items: + properties: + labels: + additionalProperties: + type: string + type: object + name: + description: Name of the subset. + type: string + trafficPolicy: + description: Traffic policies that apply to this subset. + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection should + be upgraded to http2 for the associated destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, this + is DestinationRule-level and will override mesh + wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection + should be upgraded to http2 for the associated + destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests + to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream + connection pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per + connection to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and + TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP + connections to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE + on the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between + keep-alive probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer + algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP + header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP + query parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev + hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend + hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' + separated, e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities + to traffic distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, + this is DestinationRule-level and will override + mesh wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered + list of labels used to sort endpoints to + do priority based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of + Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host + is ejected from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a + host is ejected from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep + analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish + local origin failures from external errors. + type: boolean + type: object + port: + properties: + number: + type: integer + type: object + tls: + description: TLS related settings for connections + to the upstream service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server + during TLS handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + type: array + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + tunnel: + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream + connection is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream + connection is tunneled. + type: integer + type: object + type: object + type: object + type: array + trafficPolicy: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection should be upgraded + to http2 for the associated destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query parameter. + type: string + maglev: + description: The Maglev load balancer implements consistent + hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer implements + consistent hashing to backend hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities to traffic + distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, this is DestinationRule-level + and will override mesh wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list of labels + used to sort endpoints to do priority based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local origin + failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection should + be upgraded to http2 for the associated destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, this + is DestinationRule-level and will override mesh + wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + port: + properties: + number: + type: integer + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + type: array + tls: + description: TLS related settings for connections to the upstream + service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during TLS + handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + tunnel: + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream connection + is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream connection + is tunneled. + type: integer + type: object + type: object + workloadSelector: + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: The name of a service from the service registry + jsonPath: .spec.host + name: Host + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting load balancing, outlier detection, + etc. See more details at: https://istio.io/docs/reference/config/networking/destination-rule.html' + properties: + exportTo: + description: A list of namespaces to which this destination rule is + exported. + items: + type: string + type: array + host: + description: The name of a service from the service registry. + type: string + subsets: + items: + properties: + labels: + additionalProperties: + type: string + type: object + name: + description: Name of the subset. + type: string + trafficPolicy: + description: Traffic policies that apply to this subset. + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection should + be upgraded to http2 for the associated destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, this + is DestinationRule-level and will override mesh + wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection + should be upgraded to http2 for the associated + destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests + to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream + connection pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per + connection to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and + TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP + connections to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE + on the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between + keep-alive probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer + algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP + header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP + query parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev + hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend + hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' + separated, e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities + to traffic distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, + this is DestinationRule-level and will override + mesh wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered + list of labels used to sort endpoints to + do priority based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of + Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host + is ejected from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a + host is ejected from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep + analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish + local origin failures from external errors. + type: boolean + type: object + port: + properties: + number: + type: integer + type: object + tls: + description: TLS related settings for connections + to the upstream service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server + during TLS handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + type: array + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + tunnel: + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream + connection is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream + connection is tunneled. + type: integer + type: object + type: object + type: object + type: array + trafficPolicy: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection should be upgraded + to http2 for the associated destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query parameter. + type: string + maglev: + description: The Maglev load balancer implements consistent + hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer implements + consistent hashing to backend hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities to traffic + distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, this is DestinationRule-level + and will override mesh wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list of labels + used to sort endpoints to do priority based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local origin + failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: Specify if http1.1 connection should + be upgraded to http2 for the associated destination. + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + probes: + type: integer + time: + type: string + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + - required: + - simple + - properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + minimumRingSize: {} + required: + - consistentHash + properties: + consistentHash: + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + type: integer + type: object + minimumRingSize: + description: Deprecated. + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: enable locality load balancing, this + is DestinationRule-level and will override mesh + wide settings in entirety. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmupDurationSecs: + description: Represents the warmup duration of Service. + type: string + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + nullable: true + type: integer + consecutiveLocalOriginFailures: + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + maxEjectionPercent: + format: int32 + type: integer + minHealthPercent: + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + port: + properties: + number: + type: integer + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + type: object + type: array + tls: + description: TLS related settings for connections to the upstream + service. + properties: + caCertificates: + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + type: string + insecureSkipVerify: + nullable: true + type: boolean + mode: + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during TLS + handshake. + type: string + subjectAltNames: + items: + type: string + type: array + type: object + tunnel: + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream connection + is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream connection + is tunneled. + type: integer + type: object + type: object + workloadSelector: + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/envoyfilters.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/envoyfilters.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..f14e3272ea --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/envoyfilters.networking.istio.io.crd.yaml @@ -0,0 +1,242 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: envoyfilters.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: EnvoyFilter + listKind: EnvoyFilterList + plural: envoyfilters + singular: envoyfilter + scope: Namespaced + versions: + - name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Customizing Envoy configuration generated by Istio. See + more details at: https://istio.io/docs/reference/config/networking/envoy-filter.html' + properties: + configPatches: + description: One or more patches with match conditions. + items: + properties: + applyTo: + enum: + - INVALID + - LISTENER + - FILTER_CHAIN + - NETWORK_FILTER + - HTTP_FILTER + - ROUTE_CONFIGURATION + - VIRTUAL_HOST + - HTTP_ROUTE + - CLUSTER + - EXTENSION_CONFIG + - BOOTSTRAP + - LISTENER_FILTER + type: string + match: + description: Match on listener/route configuration/cluster. + oneOf: + - not: + anyOf: + - required: + - listener + - required: + - routeConfiguration + - required: + - cluster + - required: + - listener + - required: + - routeConfiguration + - required: + - cluster + properties: + cluster: + description: Match on envoy cluster attributes. + properties: + name: + description: The exact name of the cluster to match. + type: string + portNumber: + description: The service port for which this cluster + was generated. + type: integer + service: + description: The fully qualified service name for this + cluster. + type: string + subset: + description: The subset associated with the service. + type: string + type: object + context: + description: The specific config generation context to match + on. + enum: + - ANY + - SIDECAR_INBOUND + - SIDECAR_OUTBOUND + - GATEWAY + type: string + listener: + description: Match on envoy listener attributes. + properties: + filterChain: + description: Match a specific filter chain in a listener. + properties: + applicationProtocols: + description: Applies only to sidecars. + type: string + destinationPort: + description: The destination_port value used by + a filter chain's match condition. + type: integer + filter: + description: The name of a specific filter to apply + the patch to. + properties: + name: + description: The filter name to match on. + type: string + subFilter: + properties: + name: + description: The filter name to match on. + type: string + type: object + type: object + name: + description: The name assigned to the filter chain. + type: string + sni: + description: The SNI value used by a filter chain's + match condition. + type: string + transportProtocol: + description: Applies only to `SIDECAR_INBOUND` context. + type: string + type: object + listenerFilter: + description: Match a specific listener filter. + type: string + name: + description: Match a specific listener by its name. + type: string + portName: + type: string + portNumber: + type: integer + type: object + proxy: + description: Match on properties associated with a proxy. + properties: + metadata: + additionalProperties: + type: string + type: object + proxyVersion: + type: string + type: object + routeConfiguration: + description: Match on envoy HTTP route configuration attributes. + properties: + gateway: + type: string + name: + description: Route configuration name to match on. + type: string + portName: + description: Applicable only for GATEWAY context. + type: string + portNumber: + type: integer + vhost: + properties: + name: + type: string + route: + description: Match a specific route within the virtual + host. + properties: + action: + description: Match a route with specific action + type. + enum: + - ANY + - ROUTE + - REDIRECT + - DIRECT_RESPONSE + type: string + name: + type: string + type: object + type: object + type: object + type: object + patch: + description: The patch to apply along with the operation. + properties: + filterClass: + description: Determines the filter insertion order. + enum: + - UNSPECIFIED + - AUTHN + - AUTHZ + - STATS + type: string + operation: + description: Determines how the patch should be applied. + enum: + - INVALID + - MERGE + - ADD + - REMOVE + - INSERT_BEFORE + - INSERT_AFTER + - INSERT_FIRST + - REPLACE + type: string + value: + description: The JSON config of the object being patched. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + type: array + priority: + description: Priority defines the order in which patch sets are applied + within a context. + format: int32 + type: integer + workloadSelector: + properties: + labels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/exportedservicesets.federation.maistra.io.crd.yaml b/resources/helm/v2.5/istio-init/files/exportedservicesets.federation.maistra.io.crd.yaml new file mode 100644 index 0000000000..3d41697961 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/exportedservicesets.federation.maistra.io.crd.yaml @@ -0,0 +1,222 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: "2.5.0" + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: exportedservicesets.federation.maistra.io +spec: + group: federation.maistra.io + names: + kind: ExportedServiceSet + listKind: ExportedServiceSetList + plural: exportedservicesets + singular: exportedserviceset + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ExportedServiceSet is the Schema for configuring exported services. + It must be created in the same namespace as the control plane. The name + of the ExportedServiceSet resource must match the name of a ServiceMeshPeer + resource defining the remote mesh to which the services will be exported. + This implies there will be at most one ExportedServiceSet resource per peer + and control plane. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines rules for matching services to be exported. + properties: + exportRules: + description: ExportRules are the rules that determine which services + are exported from the mesh. The list is processed in order and + the first spec in the list that applies to a service is the one + that will be applied. This allows more specific selectors to be + placed before more general selectors. + items: + properties: + labelSelector: + description: LabelSelector provides a mechanism for selecting + services to export by using a label selector to match Service + resources for export. + properties: + aliases: + description: 'Aliases is a map of aliases to apply to exported + services. If a name is not found in the map, the original + service name is exported. A ''*'' will match any name. + The Aliases list will be processed in order, with the + first match found being applied to the exported service. + Examples: */foo->*/bar will match foo service in any namesapce, + exporting it as bar from its original namespace. */foo->bar/bar + will match foo service in any namespace, exporting it + as bar/bar. foo/*->bar/* will match any service in foo + namespace, exporting it from the bar namespace with its + original name */*->bar/* will match any service and export + it from the bar namespace with its original name. */*->*/* + is the same as not specifying anything' + items: + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: array + namespace: + description: Namespace specifies to which namespace the + selector applies. An empty value applies to all namespaces + in the mesh. + type: string + selector: + description: Selector used to select Service resources in + the namespace/mesh. An empty selector selects all services. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists + or DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + type: object + nameSelector: + description: NameSelector provides a simple name matcher for + exporting services in the mesh. + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: + description: Type of rule. One of NameSelector or LabelSelector. + type: string + required: + - type + type: object + type: array + type: object + status: + properties: + exportedServices: + description: Exports provides details about the services exported + by this mesh. + items: + description: PeerServiceMapping represents the name mapping between + an exported service and its local counterpart. + properties: + exportedName: + description: ExportedName represents the fully qualified domain + name (FQDN) of an exported service. For an exporting mesh, + this is the name that is exported to the remote mesh. For + an importing mesh, this would be the name of the service exported + by the remote mesh. + type: string + localService: + description: LocalService represents the service in the local + (i.e. this) mesh. For an exporting mesh, this would be the + service being exported. For an importing mesh, this would + be the imported service. + properties: + hostname: + description: Hostname represents fully qualified domain + name (FQDN) used to access the service. + type: string + name: + description: Name represents the simple name of the service, + e.g. the metadata.name field of a kubernetes Service. + type: string + namespace: + description: Namespace represents the namespace within which + the service resides. + type: string + required: + - hostname + - name + - namespace + type: object + required: + - exportedName + - localService + type: object + type: array + x-kubernetes-list-map-keys: + - exportedName + x-kubernetes-list-type: map + required: + - exportedServices + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/gateways.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/gateways.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..8878f46f2a --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/gateways.networking.istio.io.crd.yaml @@ -0,0 +1,258 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: gateways.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gw + singular: gateway + scope: Namespaced + versions: + - name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting edge load balancer. See more details + at: https://istio.io/docs/reference/config/networking/gateway.html' + properties: + selector: + additionalProperties: + type: string + type: object + servers: + description: A list of server specifications. + items: + properties: + bind: + type: string + defaultEndpoint: + type: string + hosts: + description: One or more hosts exposed by this gateway. + items: + type: string + type: array + name: + description: An optional name of the server, when set must be + unique across all servers. + type: string + port: + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + tls: + description: Set of TLS related options that govern the server's + behavior. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL`. + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + type: string + httpsRedirect: + type: boolean + maxProtocolVersion: + description: 'Optional: Maximum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: 'Optional: Minimum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + items: + type: string + type: array + verifyCertificateHash: + items: + type: string + type: array + verifyCertificateSpki: + items: + type: string + type: array + type: object + type: object + type: array + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting edge load balancer. See more details + at: https://istio.io/docs/reference/config/networking/gateway.html' + properties: + selector: + additionalProperties: + type: string + type: object + servers: + description: A list of server specifications. + items: + properties: + bind: + type: string + defaultEndpoint: + type: string + hosts: + description: One or more hosts exposed by this gateway. + items: + type: string + type: array + name: + description: An optional name of the server, when set must be + unique across all servers. + type: string + port: + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + tls: + description: Set of TLS related options that govern the server's + behavior. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL`. + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + type: string + httpsRedirect: + type: boolean + maxProtocolVersion: + description: 'Optional: Maximum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: 'Optional: Minimum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + items: + type: string + type: array + verifyCertificateHash: + items: + type: string + type: array + verifyCertificateSpki: + items: + type: string + type: array + type: object + type: object + type: array + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/importedservicesets.federation.maistra.io.crd.yaml b/resources/helm/v2.5/istio-init/files/importedservicesets.federation.maistra.io.crd.yaml new file mode 100644 index 0000000000..7295e5f821 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/importedservicesets.federation.maistra.io.crd.yaml @@ -0,0 +1,172 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: "2.5.0" + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: importedservicesets.federation.maistra.io +spec: + group: federation.maistra.io + names: + kind: ImportedServiceSet + listKind: ImportedServiceSetList + plural: importedservicesets + singular: importedserviceset + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ImportedServiceSet is the Schema for configuring imported services. + It must be created in the same namespace as the control plane. The name + of the ImportedServiceSet resource must match the name of a ServiceMeshPeer + resource defining the remote mesh from which the services will be imported. + This implies there will be at most one ImportedServiceSet resource per peer + and control plane. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines rules for matching services to be imported. + properties: + domainSuffix: + description: 'DomainSuffix specifies the domain suffix to be applies + to imported services. If no domain suffix is specified, imported + services will be named as follows: ..svc.-imports.local + If a domain suffix is specified, imported services will be named + as follows: ..' + type: string + importRules: + description: ImportRules are the rules that determine which services + are imported to the mesh. The list is processed in order and the + first spec in the list that applies to a service is the one that + will be applied. This allows more specific selectors to be placed + before more general selectors. + items: + properties: + domainSuffix: + description: DomainSuffix applies the specified suffix to services + imported by this rule. The behavior is identical to that + of ImportedServiceSetSpec.DomainSuffix. + type: string + importAsLocal: + description: ImportAsLocal imports the service as a local service + in the mesh. For example, if an exported service, foo/bar + is imported as some-ns/service, the service will be imported + as service.some-ns.svc.cluster.local in the some-ns namespace. If + a service of this name already exists in the mesh, the imported + service's endpoints will be aggregated with any other workloads + associated with the service. This setting overrides DomainSuffix. + type: boolean + nameSelector: + description: NameSelector provides a simple name matcher for + importing services in the mesh. + properties: + alias: + properties: + name: + type: string + namespace: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + type: + description: Type of rule. Only NameSelector type is supported. + type: string + required: + - type + type: object + type: array + locality: + description: Locality within which imported services should be associated. + properties: + region: + description: Region within which imported services are located. + type: string + subzone: + description: Subzone within which imported services are located. If + Subzone is specified, Zone must also be specified. + type: string + zone: + description: Zone within which imported services are located. If + Zone is specified, Region must also be specified. + type: string + type: object + type: object + status: + properties: + importedServices: + description: Imports provides details about the services imported + by this mesh. + items: + description: PeerServiceMapping represents the name mapping between + an exported service and its local counterpart. + properties: + exportedName: + description: ExportedName represents the fully qualified domain + name (FQDN) of an exported service. For an exporting mesh, + this is the name that is exported to the remote mesh. For + an importing mesh, this would be the name of the service exported + by the remote mesh. + type: string + localService: + description: LocalService represents the service in the local + (i.e. this) mesh. For an exporting mesh, this would be the + service being exported. For an importing mesh, this would + be the imported service. + properties: + hostname: + description: Hostname represents fully qualified domain + name (FQDN) used to access the service. + type: string + name: + description: Name represents the simple name of the service, + e.g. the metadata.name field of a kubernetes Service. + type: string + namespace: + description: Namespace represents the namespace within which + the service resides. + type: string + required: + - hostname + - name + - namespace + type: object + required: + - exportedName + - localService + type: object + type: array + x-kubernetes-list-map-keys: + - exportedName + x-kubernetes-list-type: map + required: + - importedServices + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/peerauthentications.security.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/peerauthentications.security.istio.io.crd.yaml new file mode 100644 index 0000000000..c13e42efc7 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/peerauthentications.security.istio.io.crd.yaml @@ -0,0 +1,92 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + istio: security + release: istio + name: peerauthentications.security.istio.io +spec: + group: security.istio.io + names: + categories: + - istio-io + - security-istio-io + kind: PeerAuthentication + listKind: PeerAuthenticationList + plural: peerauthentications + shortNames: + - pa + singular: peerauthentication + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Defines the mTLS mode used for peer authentication. + jsonPath: .spec.mtls.mode + name: Mode + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: PeerAuthentication defines how traffic will be tunneled (or + not) to the sidecar. + properties: + mtls: + description: Mutual TLS settings for workload. + properties: + mode: + description: Defines the mTLS mode used for peer authentication. + enum: + - UNSET + - DISABLE + - PERMISSIVE + - STRICT + type: string + type: object + portLevelMtls: + additionalProperties: + properties: + mode: + description: Defines the mTLS mode used for peer authentication. + enum: + - UNSET + - DISABLE + - PERMISSIVE + - STRICT + type: string + type: object + description: Port specific mutual TLS settings. + type: object + selector: + description: The selector determines the workloads to apply the ChannelAuthentication + on. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/proxyconfigs.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/proxyconfigs.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..c9dfd17476 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/proxyconfigs.networking.istio.io.crd.yaml @@ -0,0 +1,65 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: proxyconfigs.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: ProxyConfig + listKind: ProxyConfigList + plural: proxyconfigs + singular: proxyconfig + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Provides configuration for individual workloads. See more + details at: https://istio.io/docs/reference/config/networking/proxy-config.html' + properties: + concurrency: + description: The number of worker threads to run. + nullable: true + type: integer + environmentVariables: + additionalProperties: + type: string + description: Additional environment variables for the proxy. + type: object + image: + description: Specifies the details of the proxy image. + properties: + imageType: + description: The image type of the image. + type: string + type: object + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/requestauthentications.security.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/requestauthentications.security.istio.io.crd.yaml new file mode 100644 index 0000000000..f17f66cf9d --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/requestauthentications.security.istio.io.crd.yaml @@ -0,0 +1,195 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + istio: security + release: istio + name: requestauthentications.security.istio.io +spec: + group: security.istio.io + names: + categories: + - istio-io + - security-istio-io + kind: RequestAuthentication + listKind: RequestAuthenticationList + plural: requestauthentications + shortNames: + - ra + singular: requestauthentication + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: RequestAuthentication defines what request authentication + methods are supported by a workload. + properties: + jwtRules: + description: Define the list of JWTs that can be validated at the + selected workloads' proxy. + items: + properties: + audiences: + items: + type: string + type: array + forwardOriginalToken: + description: If set to true, the original token will be kept + for the upstream request. + type: boolean + fromHeaders: + description: List of header locations from which JWT is expected. + items: + properties: + name: + description: The HTTP header name. + type: string + prefix: + description: The prefix that should be stripped before + decoding the token. + type: string + type: object + type: array + fromParams: + description: List of query parameters from which JWT is expected. + items: + type: string + type: array + issuer: + description: Identifies the issuer that issued the JWT. + type: string + jwks: + description: JSON Web Key Set of public keys to validate signature + of the JWT. + type: string + jwks_uri: + type: string + jwksUri: + type: string + outputClaimToHeaders: + description: This field specifies a list of operations to copy + the claim to HTTP headers on a successfully verified token. + items: + properties: + claim: + description: The name of the claim to be copied from. + type: string + header: + description: The name of the header to be created. + type: string + type: object + type: array + outputPayloadToHeader: + type: string + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: RequestAuthentication defines what request authentication + methods are supported by a workload. + properties: + jwtRules: + description: Define the list of JWTs that can be validated at the + selected workloads' proxy. + items: + properties: + audiences: + items: + type: string + type: array + forwardOriginalToken: + description: If set to true, the original token will be kept + for the upstream request. + type: boolean + fromHeaders: + description: List of header locations from which JWT is expected. + items: + properties: + name: + description: The HTTP header name. + type: string + prefix: + description: The prefix that should be stripped before + decoding the token. + type: string + type: object + type: array + fromParams: + description: List of query parameters from which JWT is expected. + items: + type: string + type: array + issuer: + description: Identifies the issuer that issued the JWT. + type: string + jwks: + description: JSON Web Key Set of public keys to validate signature + of the JWT. + type: string + jwks_uri: + type: string + jwksUri: + type: string + outputClaimToHeaders: + description: This field specifies a list of operations to copy + the claim to HTTP headers on a successfully verified token. + items: + properties: + claim: + description: The name of the claim to be copied from. + type: string + header: + description: The name of the header to be created. + type: string + type: object + type: array + outputPayloadToHeader: + type: string + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/serviceentries.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/serviceentries.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..1c8a05f64a --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/serviceentries.networking.istio.io.crd.yaml @@ -0,0 +1,274 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: serviceentries.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: ServiceEntry + listKind: ServiceEntryList + plural: serviceentries + shortNames: + - se + singular: serviceentry + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The hosts associated with the ServiceEntry + jsonPath: .spec.hosts + name: Hosts + type: string + - description: Whether the service is external to the mesh or part of the mesh + (MESH_EXTERNAL or MESH_INTERNAL) + jsonPath: .spec.location + name: Location + type: string + - description: Service resolution mode for the hosts (NONE, STATIC, or DNS) + jsonPath: .spec.resolution + name: Resolution + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting service registry. See more details + at: https://istio.io/docs/reference/config/networking/service-entry.html' + properties: + addresses: + description: The virtual IP addresses associated with the service. + items: + type: string + type: array + endpoints: + description: One or more endpoints associated with the service. + items: + properties: + address: + type: string + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + type: object + locality: + description: The locality associated with the endpoint. + type: string + network: + type: string + ports: + additionalProperties: + type: integer + description: Set of ports associated with the endpoint. + type: object + serviceAccount: + type: string + weight: + description: The load balancing weight associated with the endpoint. + type: integer + type: object + type: array + exportTo: + description: A list of namespaces to which this service is exported. + items: + type: string + type: array + hosts: + description: The hosts associated with the ServiceEntry. + items: + type: string + type: array + location: + enum: + - MESH_EXTERNAL + - MESH_INTERNAL + type: string + ports: + description: The ports associated with the external service. + items: + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + type: array + resolution: + description: Service resolution mode for the hosts. + enum: + - NONE + - STATIC + - DNS + - DNS_ROUND_ROBIN + type: string + subjectAltNames: + items: + type: string + type: array + workloadSelector: + description: Applicable only for MESH_INTERNAL services. + properties: + labels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: The hosts associated with the ServiceEntry + jsonPath: .spec.hosts + name: Hosts + type: string + - description: Whether the service is external to the mesh or part of the mesh + (MESH_EXTERNAL or MESH_INTERNAL) + jsonPath: .spec.location + name: Location + type: string + - description: Service resolution mode for the hosts (NONE, STATIC, or DNS) + jsonPath: .spec.resolution + name: Resolution + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting service registry. See more details + at: https://istio.io/docs/reference/config/networking/service-entry.html' + properties: + addresses: + description: The virtual IP addresses associated with the service. + items: + type: string + type: array + endpoints: + description: One or more endpoints associated with the service. + items: + properties: + address: + type: string + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + type: object + locality: + description: The locality associated with the endpoint. + type: string + network: + type: string + ports: + additionalProperties: + type: integer + description: Set of ports associated with the endpoint. + type: object + serviceAccount: + type: string + weight: + description: The load balancing weight associated with the endpoint. + type: integer + type: object + type: array + exportTo: + description: A list of namespaces to which this service is exported. + items: + type: string + type: array + hosts: + description: The hosts associated with the ServiceEntry. + items: + type: string + type: array + location: + enum: + - MESH_EXTERNAL + - MESH_INTERNAL + type: string + ports: + description: The ports associated with the external service. + items: + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + type: array + resolution: + description: Service resolution mode for the hosts. + enum: + - NONE + - STATIC + - DNS + - DNS_ROUND_ROBIN + type: string + subjectAltNames: + items: + type: string + type: array + workloadSelector: + description: Applicable only for MESH_INTERNAL services. + properties: + labels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/servicemeshpeers.federation.maistra.io.crd.yaml b/resources/helm/v2.5/istio-init/files/servicemeshpeers.federation.maistra.io.crd.yaml new file mode 100644 index 0000000000..1d054c1b4a --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/servicemeshpeers.federation.maistra.io.crd.yaml @@ -0,0 +1,354 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: "2.5.0" + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: servicemeshpeers.federation.maistra.io +spec: + group: federation.maistra.io + names: + categories: + - maistra-io + kind: ServiceMeshPeer + listKind: ServiceMeshPeerList + plural: servicemeshpeers + singular: servicemeshpeer + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ServiceMeshPeer is the Schema for joining two meshes together. The + resource name will be used to identify the 'cluster' to which imported services + belong. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServiceMeshPeerSpec configures details required to support + federation with another service mesh. + properties: + gateways: + description: Gateways configures the gateways used to facilitate ingress + and egress with the other mesh. + properties: + egress: + description: Gateway through which outbound federated service + traffic will travel. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + ingress: + description: Gateway through which inbound federated service traffic + will travel. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: object + remote: + description: Remote configures details related to the remote mesh + with which this mesh is federating. + properties: + addresses: + description: Addresses are the addresses to which discovery and + service requests should be sent (i.e. the addresses of ingress + gateways on the remote mesh). These may be specified as resolveable + DNS names or IP addresses. + items: + type: string + type: array + discoveryPort: + description: DiscoveryPort is the port on which the addresses + are handling discovery requests. Defaults to 8188, if unspecified. + format: int32 + type: integer + servicePort: + description: ServicePort is the port on which the addresses are + handling service requests. Defaults to 15443, if unspecified. + format: int32 + type: integer + type: object + security: + description: Security configures details for securing communication + with the other mesh. + properties: + certificateChain: + description: Name of ConfigMap containing certificate chain to + be used to validate the remote. This is also used to validate + certificates used by the remote services (both client and server + certificates). The name of the entry should be root-cert.pem. If + unspecified, it will look for a ConfigMap named -ca-root-cert, + e.g. if this resource is named mesh1, it will look for a ConfigMap + named mesh1-ca-root-cert. + properties: + apiGroup: + description: APIGroup is the group for the resource being + referenced. If APIGroup is not specified, the specified + Kind must be in the core API group. For any other third-party + types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + clientID: + description: ClientID of the remote mesh. This is used to authenticate + incoming requrests from the remote mesh's discovery client. + type: string + trustDomain: + description: TrustDomain of remote mesh. + type: string + type: object + type: object + status: + description: ServiceMeshPeerStatus provides information related to the + other mesh. + properties: + discoveryStatus: + description: DiscoveryStatus represents the discovery status of each + pilot/istiod pod in the mesh. + properties: + active: + description: Active represents the pilot/istiod pods actively + watching the other mesh for discovery. + items: + description: PodPeerDiscoveryStatus provides discovery details + related to a specific pilot/istiod pod. + properties: + pod: + description: Pod is the pod name to which these details + apply. This maps to a a pilot/istiod pod. + type: string + remotes: + description: Remotes represents details related to the inbound + connections from remote meshes. + items: + description: DiscoveryRemoteStatus represents details + related to an inbound connection from a remote mesh. + properties: + connected: + description: Connected identfies an active connection + with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time + a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time + the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned + the last time the connection with the remote mesh + was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an + event was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time + a full sync was performed with the remote mesh. + format: date-time + type: string + source: + description: Source represents the source of the remote + watch. + type: string + required: + - connected + - source + type: object + type: array + x-kubernetes-list-map-keys: + - source + x-kubernetes-list-type: map + watch: + description: Watch represents details related to the outbound + connection to the remote mesh. + properties: + connected: + description: Connected identfies an active connection + with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time + a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time + the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned + the last time the connection with the remote mesh + was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an event + was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time a + full sync was performed with the remote mesh. + format: date-time + type: string + required: + - connected + type: object + required: + - pod + type: object + nullable: true + type: array + x-kubernetes-list-map-keys: + - pod + x-kubernetes-list-type: map + inactive: + description: Inactive represents the pilot/istiod pods not actively + watching the other mesh for discovery. + items: + description: PodPeerDiscoveryStatus provides discovery details + related to a specific pilot/istiod pod. + properties: + pod: + description: Pod is the pod name to which these details + apply. This maps to a a pilot/istiod pod. + type: string + remotes: + description: Remotes represents details related to the inbound + connections from remote meshes. + items: + description: DiscoveryRemoteStatus represents details + related to an inbound connection from a remote mesh. + properties: + connected: + description: Connected identfies an active connection + with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time + a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time + the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned + the last time the connection with the remote mesh + was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an + event was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time + a full sync was performed with the remote mesh. + format: date-time + type: string + source: + description: Source represents the source of the remote + watch. + type: string + required: + - connected + - source + type: object + type: array + x-kubernetes-list-map-keys: + - source + x-kubernetes-list-type: map + watch: + description: Watch represents details related to the outbound + connection to the remote mesh. + properties: + connected: + description: Connected identfies an active connection + with the remote mesh. + type: boolean + lastConnected: + description: LastConnected represents the last time + a connection with the remote mesh was successful. + format: date-time + type: string + lastDisconnect: + description: LastDisconnect represents the last time + the connection with the remote mesh was disconnected. + format: date-time + type: string + lastDisconnectStatus: + description: LastDisconnectStatus is the status returned + the last time the connection with the remote mesh + was terminated. + type: string + lastEvent: + description: LastEvent represents the last time an event + was received from the remote mesh. + format: date-time + type: string + lastFullSync: + description: LastFullSync represents the last time a + full sync was performed with the remote mesh. + format: date-time + type: string + required: + - connected + type: object + required: + - pod + type: object + nullable: true + type: array + x-kubernetes-list-map-keys: + - pod + x-kubernetes-list-type: map + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/servicemeshpolicies.authentication.maistra.io.crd.yaml b/resources/helm/v2.5/istio-init/files/servicemeshpolicies.authentication.maistra.io.crd.yaml new file mode 100644 index 0000000000..262e8d6f5d --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/servicemeshpolicies.authentication.maistra.io.crd.yaml @@ -0,0 +1,729 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-citadel + chart: istio + heritage: Tiller + release: istio + name: servicemeshpolicies.authentication.maistra.io +spec: + group: authentication.maistra.io + names: + categories: + - istio-io + - authentication-istio-io + kind: ServiceMeshPolicy + listKind: ServiceMeshPolicyList + plural: servicemeshpolicies + singular: servicemeshpolicy + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + properties: + spec: + description: 'Authentication policy for Istio services. See more details + at: https://istio.io/docs/reference/config/istio.authentication.v1alpha1.html' + properties: + originIsOptional: + type: boolean + origins: + description: List of authentication methods that can be used for origin + authentication. + items: + properties: + jwt: + description: Jwt params for the method. + properties: + audiences: + items: + format: string + type: string + type: array + issuer: + description: Identifies the issuer that issued the JWT. + format: string + type: string + jwks: + description: JSON Web Key Set of public keys to validate signature + of the JWT. + format: string + type: string + jwks_uri: + format: string + type: string + jwksUri: + format: string + type: string + jwt_headers: + description: JWT is sent in a request header. + items: + format: string + type: string + type: array + jwtHeaders: + description: JWT is sent in a request header. + items: + format: string + type: string + type: array + jwtParams: + description: JWT is sent in a query parameter. + items: + format: string + type: string + type: array + trigger_rules: + items: + properties: + excluded_paths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + excludedPaths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + included_paths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + includedPaths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + type: object + type: array + triggerRules: + items: + properties: + excluded_paths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + excludedPaths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + included_paths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + includedPaths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + type: object + type: array + type: object + type: object + type: array + peerIsOptional: + type: boolean + peers: + description: List of authentication methods that can be used for peer + authentication. + items: + oneOf: + - required: + - mtls + - required: + - jwt + properties: + jwt: + properties: + audiences: + items: + format: string + type: string + type: array + issuer: + description: Identifies the issuer that issued the JWT. + format: string + type: string + jwks: + description: JSON Web Key Set of public keys to validate signature + of the JWT. + format: string + type: string + jwks_uri: + format: string + type: string + jwksUri: + format: string + type: string + jwt_headers: + description: JWT is sent in a request header. + items: + format: string + type: string + type: array + jwtHeaders: + description: JWT is sent in a request header. + items: + format: string + type: string + type: array + jwtParams: + description: JWT is sent in a query parameter. + items: + format: string + type: string + type: array + trigger_rules: + items: + properties: + excluded_paths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + excludedPaths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + included_paths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + includedPaths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + type: object + type: array + triggerRules: + items: + properties: + excluded_paths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + excludedPaths: + description: List of paths to be excluded from the request. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + included_paths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + includedPaths: + description: List of paths that the request must include. + items: + oneOf: + - required: + - exact + - required: + - prefix + - required: + - suffix + - required: + - regex + properties: + exact: + description: exact string match. + format: string + type: string + prefix: + description: prefix-based match. + format: string + type: string + regex: + description: ECMAscript style regex-based match + as defined by [EDCA-262](http://en.cppreference.com/w/cpp/regex/ecmascript). + format: string + type: string + suffix: + description: suffix-based match. + format: string + type: string + type: object + type: array + type: object + type: array + type: object + mtls: + description: Set if mTLS is used. + properties: + allowTls: + description: WILL BE DEPRECATED, if set, will translates to + `TLS_PERMISSIVE` mode. + type: boolean + mode: + description: Defines the mode of mTLS authentication. + enum: + - STRICT + - PERMISSIVE + type: string + type: object + type: object + type: array + principalBinding: + description: Define whether peer or origin identity should be use for + principal. + enum: + - USE_PEER + - USE_ORIGIN + type: string + targets: + description: List rules to select workloads that the policy should be + applied on. + items: + properties: + labels: + additionalProperties: + format: string + type: string + type: object + name: + description: The name must be a short name from the service registry. + format: string + type: string + ports: + description: Specifies the ports. + items: + oneOf: + - required: + - number + - required: + - name + properties: + name: + format: string + type: string + number: + type: integer + type: object + type: array + type: object + type: array + type: object + type: object + versions: + - name: v1 + served: true + storage: true \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/servicemeshrbacconfigs.rbac.maistra.io.crd.yaml b/resources/helm/v2.5/istio-init/files/servicemeshrbacconfigs.rbac.maistra.io.crd.yaml new file mode 100644 index 0000000000..bab6bd6951 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/servicemeshrbacconfigs.rbac.maistra.io.crd.yaml @@ -0,0 +1,84 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + heritage: Tiller + istio: rbac + release: istio + name: servicemeshrbacconfigs.rbac.maistra.io +spec: + group: rbac.maistra.io + names: + categories: + - istio-io + - rbac-istio-io + kind: ServiceMeshRbacConfig + plural: servicemeshrbacconfigs + singular: servicemeshrbacconfig + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + properties: + spec: + description: 'Configuration for Role Based Access Control. See more details + at: https://istio.io/docs/reference/config/authorization/istio.rbac.v1alpha1.html' + properties: + enforcementMode: + enum: + - ENFORCED + - PERMISSIVE + type: string + exclusion: + description: A list of services or namespaces that should not be enforced + by Istio RBAC policies. + properties: + namespaces: + description: A list of namespaces. + items: + format: string + type: string + type: array + services: + description: A list of services. + items: + format: string + type: string + type: array + type: object + inclusion: + description: A list of services or namespaces that should be enforced + by Istio RBAC policies. + properties: + namespaces: + description: A list of namespaces. + items: + format: string + type: string + type: array + services: + description: A list of services. + items: + format: string + type: string + type: array + type: object + mode: + description: Istio RBAC mode. + enum: + - "OFF" + - "ON" + - ON_WITH_INCLUSION + - ON_WITH_EXCLUSION + type: string + type: object + type: object + versions: + - name: v1 + served: true + storage: true \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/sidecars.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/sidecars.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..4d6bbd8582 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/sidecars.networking.istio.io.crd.yaml @@ -0,0 +1,370 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: sidecars.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: Sidecar + listKind: SidecarList + plural: sidecars + singular: sidecar + scope: Namespaced + versions: + - name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting network reachability of a sidecar. + See more details at: https://istio.io/docs/reference/config/networking/sidecar.html' + properties: + egress: + items: + properties: + bind: + type: string + captureMode: + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + hosts: + items: + type: string + type: array + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + type: object + type: array + ingress: + items: + properties: + bind: + description: The IP(IPv4 or IPv6) to which the listener should + be bound. + type: string + captureMode: + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + defaultEndpoint: + type: string + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + tls: + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL`. + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + type: string + httpsRedirect: + type: boolean + maxProtocolVersion: + description: 'Optional: Maximum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: 'Optional: Minimum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + items: + type: string + type: array + verifyCertificateHash: + items: + type: string + type: array + verifyCertificateSpki: + items: + type: string + type: array + type: object + type: object + type: array + outboundTrafficPolicy: + description: Configuration for the outbound traffic policy. + properties: + egressProxy: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + mode: + enum: + - REGISTRY_ONLY + - ALLOW_ANY + type: string + type: object + workloadSelector: + properties: + labels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting network reachability of a sidecar. + See more details at: https://istio.io/docs/reference/config/networking/sidecar.html' + properties: + egress: + items: + properties: + bind: + type: string + captureMode: + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + hosts: + items: + type: string + type: array + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + type: object + type: array + ingress: + items: + properties: + bind: + description: The IP(IPv4 or IPv6) to which the listener should + be bound. + type: string + captureMode: + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + defaultEndpoint: + type: string + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + type: integer + type: object + tls: + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL`. + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + type: string + httpsRedirect: + type: boolean + maxProtocolVersion: + description: 'Optional: Maximum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: 'Optional: Minimum TLS protocol version.' + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + items: + type: string + type: array + verifyCertificateHash: + items: + type: string + type: array + verifyCertificateSpki: + items: + type: string + type: array + type: object + type: object + type: array + outboundTrafficPolicy: + description: Configuration for the outbound traffic policy. + properties: + egressProxy: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + mode: + enum: + - REGISTRY_ONLY + - ALLOW_ANY + type: string + type: object + workloadSelector: + properties: + labels: + additionalProperties: + type: string + type: object + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/telemetries.telemetry.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/telemetries.telemetry.istio.io.crd.yaml new file mode 100644 index 0000000000..e31ecf4cff --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/telemetries.telemetry.istio.io.crd.yaml @@ -0,0 +1,270 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + istio: telemetry + release: istio + name: telemetries.telemetry.istio.io +spec: + group: telemetry.istio.io + names: + categories: + - istio-io + - telemetry-istio-io + kind: Telemetry + listKind: TelemetryList + plural: telemetries + shortNames: + - telemetry + singular: telemetry + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Telemetry configuration for workloads. See more details + at: https://istio.io/docs/reference/config/telemetry.html' + properties: + accessLogging: + description: Optional. + items: + properties: + disabled: + description: Controls logging. + nullable: true + type: boolean + filter: + description: Optional. + properties: + expression: + description: CEL expression for selecting when requests/connections + should be logged. + type: string + type: object + match: + description: Allows tailoring of logging behavior to specific + conditions. + properties: + mode: + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + providers: + description: Optional. + items: + properties: + name: + description: Required. + type: string + type: object + type: array + type: object + type: array + metrics: + description: Optional. + items: + properties: + overrides: + description: Optional. + items: + properties: + disabled: + description: Optional. + nullable: true + type: boolean + match: + description: Match allows provides the scope of the override. + oneOf: + - not: + anyOf: + - required: + - metric + - required: + - customMetric + - required: + - metric + - required: + - customMetric + properties: + customMetric: + description: Allows free-form specification of a metric. + type: string + metric: + description: One of the well-known Istio Standard + Metrics. + enum: + - ALL_METRICS + - REQUEST_COUNT + - REQUEST_DURATION + - REQUEST_SIZE + - RESPONSE_SIZE + - TCP_OPENED_CONNECTIONS + - TCP_CLOSED_CONNECTIONS + - TCP_SENT_BYTES + - TCP_RECEIVED_BYTES + - GRPC_REQUEST_MESSAGES + - GRPC_RESPONSE_MESSAGES + type: string + mode: + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + tagOverrides: + additionalProperties: + properties: + operation: + description: Operation controls whether or not to + update/add a tag, or to remove it. + enum: + - UPSERT + - REMOVE + type: string + value: + description: Value is only considered if the operation + is `UPSERT`. + type: string + type: object + description: Optional. + type: object + type: object + type: array + providers: + description: Optional. + items: + properties: + name: + description: Required. + type: string + type: object + type: array + reportingInterval: + description: Optional. + type: string + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + tracing: + description: Optional. + items: + properties: + customTags: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - literal + - required: + - environment + - required: + - header + - required: + - literal + - required: + - environment + - required: + - header + properties: + environment: + description: Environment adds the value of an environment + variable to each span. + properties: + defaultValue: + description: Optional. + type: string + name: + description: Name of the environment variable from + which to extract the tag value. + type: string + type: object + header: + properties: + defaultValue: + description: Optional. + type: string + name: + description: Name of the header from which to extract + the tag value. + type: string + type: object + literal: + description: Literal adds the same, hard-coded value to + each span. + properties: + value: + description: The tag value to use. + type: string + type: object + type: object + description: Optional. + type: object + disableSpanReporting: + description: Controls span reporting. + nullable: true + type: boolean + match: + description: Allows tailoring of behavior to specific conditions. + properties: + mode: + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + providers: + description: Optional. + items: + properties: + name: + description: Required. + type: string + type: object + type: array + randomSamplingPercentage: + nullable: true + type: number + useRequestIdForTraceSampling: + nullable: true + type: boolean + type: object + type: array + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/virtualservices.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/virtualservices.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..3742daf315 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/virtualservices.networking.istio.io.crd.yaml @@ -0,0 +1,1592 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: virtualservices.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: VirtualService + listKind: VirtualServiceList + plural: virtualservices + shortNames: + - vs + singular: virtualservice + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The names of gateways and sidecars that should apply these routes + jsonPath: .spec.gateways + name: Gateways + type: string + - description: The destination hosts to which traffic is being sent + jsonPath: .spec.hosts + name: Hosts + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting label/content routing, sni routing, + etc. See more details at: https://istio.io/docs/reference/config/networking/virtual-service.html' + properties: + exportTo: + description: A list of namespaces to which this virtual service is + exported. + items: + type: string + type: array + gateways: + description: The names of gateways and sidecars that should apply + these routes. + items: + type: string + type: array + hosts: + description: The destination hosts to which traffic is being sent. + items: + type: string + type: array + http: + description: An ordered list of route rules for HTTP traffic. + items: + properties: + corsPolicy: + description: Cross-Origin Resource Sharing policy (CORS). + properties: + allowCredentials: + nullable: true + type: boolean + allowHeaders: + items: + type: string + type: array + allowMethods: + description: List of HTTP methods allowed to access the + resource. + items: + type: string + type: array + allowOrigin: + description: The list of origins that are allowed to perform + CORS requests. + items: + type: string + type: array + allowOrigins: + description: String patterns that match allowed origins. + items: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + type: array + exposeHeaders: + items: + type: string + type: array + maxAge: + type: string + type: object + delegate: + properties: + name: + description: Name specifies the name of the delegate VirtualService. + type: string + namespace: + description: Namespace specifies the namespace where the + delegate VirtualService resides. + type: string + type: object + directResponse: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + properties: + body: + description: Specifies the content of the response body. + oneOf: + - not: + anyOf: + - required: + - string + - required: + - bytes + - required: + - string + - required: + - bytes + properties: + bytes: + description: response body as base64 encoded bytes. + format: binary + type: string + string: + type: string + type: object + status: + description: Specifies the HTTP response status to be returned. + type: integer + type: object + fault: + description: Fault injection policy to apply on HTTP traffic + at the client side. + properties: + abort: + oneOf: + - not: + anyOf: + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + properties: + grpcStatus: + description: GRPC status code to use to abort the request. + type: string + http2Error: + type: string + httpStatus: + description: HTTP status code to use to abort the Http + request. + format: int32 + type: integer + percentage: + description: Percentage of requests to be aborted with + the error code provided. + properties: + value: + format: double + type: number + type: object + type: object + delay: + oneOf: + - not: + anyOf: + - required: + - fixedDelay + - required: + - exponentialDelay + - required: + - fixedDelay + - required: + - exponentialDelay + properties: + exponentialDelay: + type: string + fixedDelay: + description: Add a fixed delay before forwarding the + request. + type: string + percent: + description: Percentage of requests on which the delay + will be injected (0-100). + format: int32 + type: integer + percentage: + description: Percentage of requests on which the delay + will be injected. + properties: + value: + format: double + type: number + type: object + type: object + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + match: + items: + properties: + authority: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + headers: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + type: object + ignoreUriCase: + description: Flag to specify whether the URI matching + should be case-insensitive. + type: boolean + method: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + name: + description: The name assigned to a match. + type: string + port: + description: Specifies the ports on the host that is being + addressed. + type: integer + queryParams: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + description: Query parameters for matching. + type: object + scheme: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + sourceLabels: + additionalProperties: + type: string + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + statPrefix: + description: The human readable prefix to use when emitting + statistics for this route. + type: string + uri: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + withoutHeaders: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + description: withoutHeader has the same syntax with the + header, but has opposite meaning. + type: object + type: object + type: array + mirror: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + mirror_percent: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + nullable: true + type: integer + mirrorPercent: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + nullable: true + type: integer + mirrorPercentage: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + properties: + value: + format: double + type: number + type: object + name: + description: The name assigned to the route for debugging purposes. + type: string + redirect: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + oneOf: + - not: + anyOf: + - required: + - port + - required: + - derivePort + - required: + - port + - required: + - derivePort + properties: + authority: + type: string + derivePort: + enum: + - FROM_PROTOCOL_DEFAULT + - FROM_REQUEST_PORT + type: string + port: + description: On a redirect, overwrite the port portion of + the URL with this value. + type: integer + redirectCode: + type: integer + scheme: + description: On a redirect, overwrite the scheme portion + of the URL with this value. + type: string + uri: + type: string + type: object + retries: + description: Retry policy for HTTP requests. + properties: + attempts: + description: Number of retries to be allowed for a given + request. + format: int32 + type: integer + perTryTimeout: + description: Timeout per attempt for a given request, including + the initial call and any retries. + type: string + retryOn: + description: Specifies the conditions under which retry + takes place. + type: string + retryRemoteLocalities: + description: Flag to specify whether the retries should + retry to other localities. + nullable: true + type: boolean + type: object + rewrite: + description: Rewrite HTTP URIs and Authority headers. + properties: + authority: + description: rewrite the Authority/Host header with this + value. + type: string + uri: + type: string + type: object + route: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + items: + properties: + destination: + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + type: object + type: array + timeout: + description: Timeout for HTTP requests, default is disabled. + type: string + type: object + type: array + tcp: + description: An ordered list of route rules for opaque TCP traffic. + items: + properties: + match: + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + type: integer + sourceLabels: + additionalProperties: + type: string + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + sourceSubnet: + description: IPv4 or IPv6 ip address of source with optional + subnet. + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + type: object + type: array + type: object + type: array + tls: + items: + properties: + match: + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + type: integer + sniHosts: + description: SNI (server name indicator) to match on. + items: + type: string + type: array + sourceLabels: + additionalProperties: + type: string + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + type: object + type: array + type: object + type: array + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: The names of gateways and sidecars that should apply these routes + jsonPath: .spec.gateways + name: Gateways + type: string + - description: The destination hosts to which traffic is being sent + jsonPath: .spec.hosts + name: Hosts + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting label/content routing, sni routing, + etc. See more details at: https://istio.io/docs/reference/config/networking/virtual-service.html' + properties: + exportTo: + description: A list of namespaces to which this virtual service is + exported. + items: + type: string + type: array + gateways: + description: The names of gateways and sidecars that should apply + these routes. + items: + type: string + type: array + hosts: + description: The destination hosts to which traffic is being sent. + items: + type: string + type: array + http: + description: An ordered list of route rules for HTTP traffic. + items: + properties: + corsPolicy: + description: Cross-Origin Resource Sharing policy (CORS). + properties: + allowCredentials: + nullable: true + type: boolean + allowHeaders: + items: + type: string + type: array + allowMethods: + description: List of HTTP methods allowed to access the + resource. + items: + type: string + type: array + allowOrigin: + description: The list of origins that are allowed to perform + CORS requests. + items: + type: string + type: array + allowOrigins: + description: String patterns that match allowed origins. + items: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + type: array + exposeHeaders: + items: + type: string + type: array + maxAge: + type: string + type: object + delegate: + properties: + name: + description: Name specifies the name of the delegate VirtualService. + type: string + namespace: + description: Namespace specifies the namespace where the + delegate VirtualService resides. + type: string + type: object + directResponse: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + properties: + body: + description: Specifies the content of the response body. + oneOf: + - not: + anyOf: + - required: + - string + - required: + - bytes + - required: + - string + - required: + - bytes + properties: + bytes: + description: response body as base64 encoded bytes. + format: binary + type: string + string: + type: string + type: object + status: + description: Specifies the HTTP response status to be returned. + type: integer + type: object + fault: + description: Fault injection policy to apply on HTTP traffic + at the client side. + properties: + abort: + oneOf: + - not: + anyOf: + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + properties: + grpcStatus: + description: GRPC status code to use to abort the request. + type: string + http2Error: + type: string + httpStatus: + description: HTTP status code to use to abort the Http + request. + format: int32 + type: integer + percentage: + description: Percentage of requests to be aborted with + the error code provided. + properties: + value: + format: double + type: number + type: object + type: object + delay: + oneOf: + - not: + anyOf: + - required: + - fixedDelay + - required: + - exponentialDelay + - required: + - fixedDelay + - required: + - exponentialDelay + properties: + exponentialDelay: + type: string + fixedDelay: + description: Add a fixed delay before forwarding the + request. + type: string + percent: + description: Percentage of requests on which the delay + will be injected (0-100). + format: int32 + type: integer + percentage: + description: Percentage of requests on which the delay + will be injected. + properties: + value: + format: double + type: number + type: object + type: object + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + match: + items: + properties: + authority: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + headers: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + type: object + ignoreUriCase: + description: Flag to specify whether the URI matching + should be case-insensitive. + type: boolean + method: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + name: + description: The name assigned to a match. + type: string + port: + description: Specifies the ports on the host that is being + addressed. + type: integer + queryParams: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + description: Query parameters for matching. + type: object + scheme: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + sourceLabels: + additionalProperties: + type: string + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + statPrefix: + description: The human readable prefix to use when emitting + statistics for this route. + type: string + uri: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + withoutHeaders: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax). + type: string + type: object + description: withoutHeader has the same syntax with the + header, but has opposite meaning. + type: object + type: object + type: array + mirror: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + mirror_percent: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + nullable: true + type: integer + mirrorPercent: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + nullable: true + type: integer + mirrorPercentage: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + properties: + value: + format: double + type: number + type: object + name: + description: The name assigned to the route for debugging purposes. + type: string + redirect: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + oneOf: + - not: + anyOf: + - required: + - port + - required: + - derivePort + - required: + - port + - required: + - derivePort + properties: + authority: + type: string + derivePort: + enum: + - FROM_PROTOCOL_DEFAULT + - FROM_REQUEST_PORT + type: string + port: + description: On a redirect, overwrite the port portion of + the URL with this value. + type: integer + redirectCode: + type: integer + scheme: + description: On a redirect, overwrite the scheme portion + of the URL with this value. + type: string + uri: + type: string + type: object + retries: + description: Retry policy for HTTP requests. + properties: + attempts: + description: Number of retries to be allowed for a given + request. + format: int32 + type: integer + perTryTimeout: + description: Timeout per attempt for a given request, including + the initial call and any retries. + type: string + retryOn: + description: Specifies the conditions under which retry + takes place. + type: string + retryRemoteLocalities: + description: Flag to specify whether the retries should + retry to other localities. + nullable: true + type: boolean + type: object + rewrite: + description: Rewrite HTTP URIs and Authority headers. + properties: + authority: + description: rewrite the Authority/Host header with this + value. + type: string + uri: + type: string + type: object + route: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + items: + properties: + destination: + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + type: object + type: array + timeout: + description: Timeout for HTTP requests, default is disabled. + type: string + type: object + type: array + tcp: + description: An ordered list of route rules for opaque TCP traffic. + items: + properties: + match: + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + type: integer + sourceLabels: + additionalProperties: + type: string + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + sourceSubnet: + description: IPv4 or IPv6 ip address of source with optional + subnet. + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + type: object + type: array + type: object + type: array + tls: + items: + properties: + match: + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + type: integer + sniHosts: + description: SNI (server name indicator) to match on. + items: + type: string + type: array + sourceLabels: + additionalProperties: + type: string + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + type: object + type: array + type: object + type: array + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/wasmplugins.extensions.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/wasmplugins.extensions.istio.io.crd.yaml new file mode 100644 index 0000000000..5267eee5f0 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/wasmplugins.extensions.istio.io.crd.yaml @@ -0,0 +1,140 @@ +# DO NOT EDIT - Generated by Cue OpenAPI generator based on Istio APIs. +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: wasmplugins.extensions.istio.io +spec: + group: extensions.istio.io + names: + categories: + - istio-io + - extensions-istio-io + kind: WasmPlugin + listKind: WasmPluginList + plural: wasmplugins + singular: wasmplugin + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Extend the functionality provided by the Istio proxy through + WebAssembly filters. See more details at: https://istio.io/docs/reference/config/proxy_extensions/wasm-plugin.html' + properties: + imagePullPolicy: + enum: + - UNSPECIFIED_POLICY + - IfNotPresent + - Always + type: string + imagePullSecret: + description: Credentials to use for OCI image pulling. + type: string + match: + description: Specifies the criteria to determine which traffic is + passed to WasmPlugin. + items: + properties: + mode: + description: Criteria for selecting traffic by their direction. + enum: + - UNDEFINED + - CLIENT + - SERVER + - CLIENT_AND_SERVER + type: string + ports: + description: Criteria for selecting traffic by their destination + port. + items: + properties: + number: + type: integer + type: object + type: array + type: object + type: array + phase: + description: Determines where in the filter chain this `WasmPlugin` + is to be injected. + enum: + - UNSPECIFIED_PHASE + - AUTHN + - AUTHZ + - STATS + type: string + pluginConfig: + description: The configuration that will be passed on to the plugin. + type: object + x-kubernetes-preserve-unknown-fields: true + pluginName: + type: string + priority: + description: Determines ordering of `WasmPlugins` in the same `phase`. + nullable: true + type: integer + selector: + properties: + matchLabels: + additionalProperties: + type: string + type: object + type: object + sha256: + description: SHA256 checksum that will be used to verify Wasm module + or OCI container. + type: string + url: + description: URL of a Wasm module or OCI container. + type: string + verificationKey: + type: string + vmConfig: + description: Configuration for a Wasm VM. + properties: + env: + description: Specifies environment variables to be injected to + this VM. + items: + properties: + name: + type: string + value: + description: Value for the environment variable. + type: string + valueFrom: + enum: + - INLINE + - HOST + type: string + type: object + type: array + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/workloadentries.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/workloadentries.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..5967554ebb --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/workloadentries.networking.istio.io.crd.yaml @@ -0,0 +1,130 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + "helm.sh/resource-policy": keep + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: workloadentries.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: WorkloadEntry + listKind: WorkloadEntryList + plural: workloadentries + shortNames: + - we + singular: workloadentry + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Address associated with the network endpoint. + jsonPath: .spec.address + name: Address + type: string + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting VMs onboarded into the mesh. See + more details at: https://istio.io/docs/reference/config/networking/workload-entry.html' + properties: + address: + type: string + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + type: object + locality: + description: The locality associated with the endpoint. + type: string + network: + type: string + ports: + additionalProperties: + type: integer + description: Set of ports associated with the endpoint. + type: object + serviceAccount: + type: string + weight: + description: The load balancing weight associated with the endpoint. + type: integer + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Address associated with the network endpoint. + jsonPath: .spec.address + name: Address + type: string + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting VMs onboarded into the mesh. See + more details at: https://istio.io/docs/reference/config/networking/workload-entry.html' + properties: + address: + type: string + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + type: object + locality: + description: The locality associated with the endpoint. + type: string + network: + type: string + ports: + additionalProperties: + type: integer + description: Set of ports associated with the endpoint. + type: object + serviceAccount: + type: string + weight: + description: The load balancing weight associated with the endpoint. + type: integer + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-init/files/workloadgroups.networking.istio.io.crd.yaml b/resources/helm/v2.5/istio-init/files/workloadgroups.networking.istio.io.crd.yaml new file mode 100644 index 0000000000..43aef8d6a1 --- /dev/null +++ b/resources/helm/v2.5/istio-init/files/workloadgroups.networking.istio.io.crd.yaml @@ -0,0 +1,324 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + maistra-version: "2.5.0" + app: istio-pilot + chart: istio + heritage: Tiller + release: istio + name: workloadgroups.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: WorkloadGroup + listKind: WorkloadGroupList + plural: workloadgroups + shortNames: + - wg + singular: workloadgroup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Describes a collection of workload instances. See more details + at: https://istio.io/docs/reference/config/networking/workload-group.html' + properties: + metadata: + description: Metadata that will be used for all corresponding `WorkloadEntries`. + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + probe: + description: '`ReadinessProbe` describes the configuration the user + must provide for healthchecking on their workload.' + oneOf: + - not: + anyOf: + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + properties: + exec: + description: Health is determined by how the command that is executed + exited. + properties: + command: + description: Command to run. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. + format: int32 + type: integer + httpGet: + properties: + host: + description: Host name to connect to, defaults to the pod + IP. + type: string + httpHeaders: + description: Headers the proxy will pass on to make the request. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + description: Port on which the endpoint lives. + type: integer + scheme: + type: string + type: object + initialDelaySeconds: + description: Number of seconds after the container has started + before readiness probes are initiated. + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. + format: int32 + type: integer + tcpSocket: + description: Health is determined by if the proxy is able to connect. + properties: + host: + type: string + port: + type: integer + type: object + timeoutSeconds: + description: Number of seconds after which the probe times out. + format: int32 + type: integer + type: object + template: + description: Template to be used for the generation of `WorkloadEntry` + resources that belong to this `WorkloadGroup`. + properties: + address: + type: string + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + type: object + locality: + description: The locality associated with the endpoint. + type: string + network: + type: string + ports: + additionalProperties: + type: integer + description: Set of ports associated with the endpoint. + type: object + serviceAccount: + type: string + weight: + description: The load balancing weight associated with the endpoint. + type: integer + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + properties: + metadata: + description: Metadata that will be used for all corresponding `WorkloadEntries`. + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + probe: + description: '`ReadinessProbe` describes the configuration the user + must provide for healthchecking on their workload.' + oneOf: + - not: + anyOf: + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + properties: + exec: + description: Health is determined by how the command that is executed + exited. + properties: + command: + description: Command to run. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. + format: int32 + type: integer + httpGet: + properties: + host: + description: Host name to connect to, defaults to the pod + IP. + type: string + httpHeaders: + description: Headers the proxy will pass on to make the request. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + description: Port on which the endpoint lives. + type: integer + scheme: + type: string + type: object + initialDelaySeconds: + description: Number of seconds after the container has started + before readiness probes are initiated. + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. + format: int32 + type: integer + tcpSocket: + description: Health is determined by if the proxy is able to connect. + properties: + host: + type: string + port: + type: integer + type: object + timeoutSeconds: + description: Number of seconds after which the probe times out. + format: int32 + type: integer + type: object + template: + description: Template to be used for the generation of `WorkloadEntry` + resources that belong to this `WorkloadGroup`. + properties: + address: + type: string + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + type: object + locality: + description: The locality associated with the endpoint. + type: string + network: + type: string + ports: + additionalProperties: + type: integer + description: Set of ports associated with the endpoint. + type: object + serviceAccount: + type: string + weight: + description: The load balancing weight associated with the endpoint. + type: integer + type: object + type: object + status: + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-telemetry/grafana/Chart.yaml b/resources/helm/v2.5/istio-telemetry/grafana/Chart.yaml new file mode 100644 index 0000000000..32df002be6 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +description: A Helm chart for Kubernetes +name: grafana +version: 1.1.0 +appVersion: 1.1.0 +tillerVersion: ">=2.7.2" +keywords: + - istio-addon diff --git a/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-extension-dashboard.json b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-extension-dashboard.json new file mode 100644 index 0000000000..445a8a329d --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-extension-dashboard.json @@ -0,0 +1,850 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "collapsed": false, + "datasource": "Prometheus", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 3, + "panels": [], + "title": "Wasm VMs", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": { + "align": null + }, + "links": [], + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 1 + }, + "hiddenSeries": false, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(envoy_wasm_envoy_wasm_runtime_null_active)", + "interval": "", + "legendFormat": "native", + "refId": "A" + }, + { + "expr": "avg(envoy_wasm_envoy_wasm_runtime_v8_active)", + "interval": "", + "legendFormat": "v8", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Active", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:123", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:124", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 1 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(envoy_wasm_envoy_wasm_runtime_null_created)", + "interval": "", + "legendFormat": "native", + "refId": "A" + }, + { + "expr": "avg(envoy_wasm_envoy_wasm_runtime_v8_created)", + "interval": "", + "legendFormat": "v8", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Created", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:68", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:69", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 9 + }, + "id": 7, + "panels": [], + "title": "Wasm Module Remote Load", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 10 + }, + "hiddenSeries": false, + "id": 11, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(envoy_wasm_remote_load_cache_entries)", + "interval": "", + "legendFormat": "entries", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cache Entry", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:178", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:179", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 10 + }, + "hiddenSeries": false, + "id": 8, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(envoy_wasm_remote_load_cache_hits)", + "interval": "", + "legendFormat": "hits", + "refId": "A" + }, + { + "expr": "avg(envoy_wasm_remote_load_cache_misses)", + "interval": "", + "legendFormat": "misses", + "refId": "B" + }, + { + "expr": "avg(envoy_wasm_remote_load_cache_negative_hits)", + "interval": "", + "legendFormat": "negative hits", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Cache Visit", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:233", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:234", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 10 + }, + "hiddenSeries": false, + "id": 10, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(envoy_wasm_remote_load_fetch_failures)", + "interval": "", + "legendFormat": "failures", + "refId": "A" + }, + { + "expr": "avg(envoy_wasm_remote_load_fetch_successes)", + "interval": "", + "legendFormat": "successes", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Remote Fetch", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:288", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:289", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": "Prometheus", + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 18 + }, + "id": 71, + "panels": [], + "title": "Proxy Resource Usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 19 + }, + "hiddenSeries": false, + "id": 72, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{container=\"istio-proxy\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:396", + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:397", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 19 + }, + "hiddenSeries": false, + "id": 73, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.2.1", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "vCPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:447", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "$$hashKey": "object:448", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": false, + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Istio Wasm Extension Dashboard", + "uid": "7PAV7ctGz", + "version": 17 +} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-mesh-dashboard.json b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-mesh-dashboard.json new file mode 100644 index 0000000000..90ef9bfe43 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-mesh-dashboard.json @@ -0,0 +1,1744 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "content": "
\n
\n Istio\n
\n
\n Istio is an open platform that provides a uniform way to secure,\n connect, and \n monitor microservices.\n
\n Need help? Join the Istio community.\n
\n
", + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "height": "50px", + "id": 13, + "links": [], + "mode": "html", + "style": { + "font-size": "18pt" + }, + "title": "", + "transparent": true, + "type": "text" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 3 + }, + "id": 20, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{reporter=\"source\"}[1m])), 0.001)", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Global Request Volume", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 80, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": false + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 3 + }, + "id": 21, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(rate(istio_requests_total{reporter=\"source\", response_code!~\"5.*\"}[1m])) / sum(rate(istio_requests_total{reporter=\"source\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "95, 99, 99.5", + "title": "Global Success Rate (non-5xx responses)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 3 + }, + "id": 22, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=\"source\", response_code=~\"4.*\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "4xxs", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 3 + }, + "id": 23, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=\"source\", response_code=~\"5.*\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "5xxs", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 6 + }, + "id": 113, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"VirtualService\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"VirtualService\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Virtual Services", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 6 + }, + "id": 114, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"DestinationRule\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"DestinationRule\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Destination Rules", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 6 + }, + "id": 115, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"Gateway\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"Gateway\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Gateways", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 6 + }, + "id": 116, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"WorkloadEntry\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"WorkloadEntry\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Workload Entries", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 0, + "y": 6 + }, + "id": 117, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"ServiceEntry\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"ServiceEntry\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Service Entries", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 6, + "y": 6 + }, + "id": 90, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"PeerAuthentication\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"PeerAuthentication\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "PeerAuthentication Policies", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 12, + "y": 6 + }, + "id": 91, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"RequestAuthentication\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"RequestAuthentication\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "RequestAuthentication Policies", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 3, + "w": 6, + "x": 18, + "y": 6 + }, + "id": 92, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(pilot_k8s_cfg_events{type=\"AuthorizationPolicy\", event=\"add\"}) - (max(pilot_k8s_cfg_events{type=\"AuthorizationPolicy\", event=\"delete\"}) or max(up * 0))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "", + "timeFrom": null, + "timeShift": null, + "title": "Authorization Policies", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "columns": [], + "datasource": "Prometheus", + "fontSize": "100%", + "gridPos": { + "h": 21, + "w": 24, + "x": 0, + "y": 9 + }, + "hideTimeOverride": false, + "id": 73, + "links": [], + "pageSize": null, + "repeat": null, + "repeatDirection": "v", + "scroll": true, + "showHeader": true, + "sort": { + "col": 5, + "desc": true + }, + "styles": [ + { + "alias": "Workload", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "Workload dashboard", + "linkUrl": "/dashboard/db/istio-workload-dashboard?var-namespace=${__cell_3:raw}&var-workload=${__cell_2:raw}", + "pattern": "destination_workload", + "preserveFormat": false, + "sanitize": false, + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Time", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Requests", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #A", + "thresholds": [], + "type": "number", + "unit": "ops" + }, + { + "alias": "P50 Latency", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #B", + "thresholds": [], + "type": "number", + "unit": "s" + }, + { + "alias": "P90 Latency", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #C", + "thresholds": [], + "type": "number", + "unit": "s" + }, + { + "alias": "P99 Latency", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #D", + "thresholds": [], + "type": "number", + "unit": "s" + }, + { + "alias": "Success Rate", + "colorMode": "cell", + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #E", + "thresholds": [ + ".95", + " 1.00" + ], + "type": "number", + "unit": "percentunit" + }, + { + "alias": "Workload", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "$__cell dashboard", + "linkUrl": "/dashboard/db/istio-workload-dashboard?var-workload=${__cell_2:raw}&var-namespace=${__cell_3:raw}", + "pattern": "destination_workload_var", + "thresholds": [], + "type": "number", + "unit": "short" + }, + { + "alias": "Service", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "$__cell dashboard", + "linkUrl": "/dashboard/db/istio-service-dashboard?var-service=${__cell_1:raw}", + "pattern": "destination_service", + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "destination_workload_namespace", + "thresholds": [], + "type": "hidden", + "unit": "short" + } + ], + "targets": [ + { + "expr": "label_join(sum(rate(istio_requests_total{reporter=\"source\", response_code=\"200\"}[1m])) by (destination_workload, destination_workload_namespace, destination_service), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload}}.{{ destination_workload_namespace }}", + "refId": "A" + }, + { + "expr": "label_join((histogram_quantile(0.50, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"source\"}[1m])) by (le, destination_workload, destination_workload_namespace)) / 1000) or histogram_quantile(0.50, sum(rate(istio_request_duration_seconds_bucket{reporter=\"source\"}[1m])) by (le, destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload}}.{{ destination_workload_namespace }}", + "refId": "B" + }, + { + "expr": "label_join((histogram_quantile(0.90, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"source\"}[1m])) by (le, destination_workload, destination_workload_namespace)) / 1000) or histogram_quantile(0.90, sum(rate(istio_request_duration_seconds_bucket{reporter=\"source\"}[1m])) by (le, destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}", + "refId": "C" + }, + { + "expr": "label_join((histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"source\"}[1m])) by (le, destination_workload, destination_workload_namespace)) / 1000) or histogram_quantile(0.99, sum(rate(istio_request_duration_seconds_bucket{reporter=\"source\"}[1m])) by (le, destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}", + "refId": "D" + }, + { + "expr": "label_join((sum(rate(istio_requests_total{reporter=\"source\", response_code!~\"5.*\"}[1m])) by (destination_workload, destination_workload_namespace) / sum(rate(istio_requests_total{reporter=\"source\"}[1m])) by (destination_workload, destination_workload_namespace)), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}", + "refId": "E" + } + ], + "timeFrom": null, + "title": "HTTP/GRPC Workloads", + "transform": "table", + "type": "table" + }, + { + "columns": [], + "datasource": "Prometheus", + "fontSize": "100%", + "gridPos": { + "h": 18, + "w": 24, + "x": 0, + "y": 30 + }, + "hideTimeOverride": false, + "id": 109, + "links": [], + "pageSize": null, + "repeatDirection": "v", + "scroll": true, + "showHeader": true, + "sort": { + "col": 5, + "desc": true + }, + "styles": [ + { + "alias": "Workload", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": false, + "linkTargetBlank": false, + "linkTooltip": "$__cell dashboard", + "linkUrl": "/dashboard/db/istio-workload-dashboard?var-namespace=${__cell_3:raw}&var-workload=${__cell_2:raw}", + "pattern": "destination_workload", + "preserveFormat": false, + "sanitize": false, + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Bytes Sent", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #A", + "thresholds": [ + "" + ], + "type": "number", + "unit": "Bps" + }, + { + "alias": "Bytes Received", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Value #B", + "thresholds": [], + "type": "number", + "unit": "Bps" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "Time", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Workload", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "$__cell dashboard", + "linkUrl": "/dashboard/db/istio-workload-dashboard?var-namespace=${__cell_3:raw}&var-workload=${__cell_2:raw}", + "pattern": "destination_workload_var", + "thresholds": [], + "type": "string", + "unit": "short" + }, + { + "alias": "", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "pattern": "destination_workload_namespace", + "thresholds": [], + "type": "hidden", + "unit": "short" + }, + { + "alias": "Service", + "colorMode": null, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "decimals": 2, + "link": true, + "linkTooltip": "$__cell dashboard", + "linkUrl": "/dashboard/db/istio-service-dashboard?var-service=${__cell_1:raw}", + "pattern": "destination_service", + "thresholds": [], + "type": "number", + "unit": "short" + } + ], + "targets": [ + { + "expr": "label_join(sum(rate(istio_tcp_received_bytes_total{reporter=\"source\"}[1m])) by (destination_workload, destination_workload_namespace, destination_service), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}", + "refId": "A" + }, + { + "expr": "label_join(sum(rate(istio_tcp_sent_bytes_total{reporter=\"source\"}[1m])) by (destination_workload, destination_workload_namespace, destination_service), \"destination_workload_var\", \".\", \"destination_workload\", \"destination_workload_namespace\")", + "format": "table", + "hide": false, + "instant": true, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}", + "refId": "B" + } + ], + "timeFrom": null, + "title": "TCP Workloads", + "transform": "table", + "type": "table" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 24, + "x": 0, + "y": 48 + }, + "id": 111, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(istio_build) by (component, tag)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ component }}: {{ tag }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Istio Components by Version", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 18, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Istio Mesh Dashboard", + "uid": "G8wLrJIZk", + "version": 5 +} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-performance-dashboard.json b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-performance-dashboard.json new file mode 100644 index 0000000000..0cedbd8cda --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-performance-dashboard.json @@ -0,0 +1,1334 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "links": [], + "panels": [ + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 21, + "panels": [ + { + "content": "The charts on this dashboard are intended to show Istio main components cost in terms of resources utilization under steady load.\n\n- **vCPU / 1k rps:** shows vCPU utilization by the main Istio components normalized by 1000 requests/second. When idle or low traffic, this chart will be blank. The curve for istio-proxy refers to the services sidecars only.\n- **vCPU:** vCPU utilization by Istio components, not normalized.\n- **Memory:** memory footprint for the components. Telemetry and policy are normalized by 1k rps, and no data is shown when there is no traffic. For ingress and istio-proxy, the data is per instance.\n- **Bytes transferred / sec:** shows the number of bytes flowing through each Istio component.\n\n\n", + "gridPos": { + "h": 6, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 19, + "links": [], + "mode": "markdown", + "timeFrom": null, + "timeShift": null, + "title": "Performance Dashboard README", + "transparent": true, + "type": "text" + } + ], + "title": "Performance Dashboard Notes", + "type": "row" + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 6, + "panels": [], + "title": "vCPU Usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 2 + }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(sum(irate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m])) / (round(sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m])), 0.001)/1000))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "istio-ingressgateway", + "refId": "A" + }, + { + "expr": "(sum(irate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))/ (round(sum(irate(istio_requests_total[1m])), 0.001)/1000))/ (sum(irate(istio_requests_total{source_workload=\"istio-ingressgateway\"}[1m])) >bool 10)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "istio-proxy", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "vCPU / 1k rps", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 2 + }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_usage_seconds_total{pod=~\"istio-ingressgateway-.*\",container=\"istio-proxy\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "istio-ingressgateway", + "refId": "A" + }, + { + "expr": "sum(rate(container_cpu_usage_seconds_total{namespace!=\"istio-system\",container=\"istio-proxy\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "istio-proxy", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "vCPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 10 + }, + "id": 13, + "panels": [], + "title": "Memory and Data Rates", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 11 + }, + "id": 902, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{pod=~\"istio-ingressgateway-.*\"}) / count(container_memory_working_set_bytes{pod=~\"istio-ingressgateway-.*\",container!=\"POD\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "per istio-ingressgateway", + "refId": "A" + }, + { + "expr": "sum(container_memory_working_set_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"}) / count(container_memory_working_set_bytes{namespace!=\"istio-system\",container=\"istio-proxy\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "per istio proxy", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 11 + }, + "id": 11, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(istio_response_bytes_sum{source_workload=\"istio-ingressgateway\", reporter=\"source\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "istio-ingressgateway", + "refId": "A" + }, + { + "expr": "sum(irate(istio_response_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m])) + sum(irate(istio_request_bytes_sum{source_workload_namespace!=\"istio-system\", reporter=\"source\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "istio-proxy", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes transferred / sec", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 19 + }, + "id": 17, + "panels": [], + "title": "Istio Component Versions", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 20 + }, + "id": 15, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(istio_build) by (component, tag)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ component }}: {{ tag }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Istio Components by Version", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 71, + "panels": [], + "title": "Proxy Resource Usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 32 + }, + "id": 72, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_working_set_bytes{container=\"istio-proxy\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 32 + }, + "id": 73, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_usage_seconds_total{container=\"istio-proxy\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "vCPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 32 + }, + "id": 702, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_fs_usage_bytes{container=\"istio-proxy\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "none", + "label": "", + "logBase": 1024, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 39 + }, + "id": 69, + "panels": [], + "title": "Istiod Resource Usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 40 + }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_virtual_memory_bytes{app=\"istiod\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 2, + "legendFormat": "Virtual Memory", + "refId": "I", + "step": 2 + }, + { + "expr": "process_resident_memory_bytes{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Resident Memory", + "refId": "H", + "step": 2 + }, + { + "expr": "go_memstats_heap_sys_bytes{app=\"istiod\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "heap sys", + "refId": "A" + }, + { + "expr": "go_memstats_heap_alloc_bytes{app=\"istiod\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "heap alloc", + "refId": "D" + }, + { + "expr": "go_memstats_alloc_bytes{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Alloc", + "refId": "F", + "step": 2 + }, + { + "expr": "go_memstats_heap_inuse_bytes{app=\"istiod\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Heap in-use", + "refId": "E", + "step": 2 + }, + { + "expr": "go_memstats_stack_inuse_bytes{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Stack in-use", + "refId": "G", + "step": 2 + }, + { + "expr": "sum(container_memory_working_set_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"})", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "C", + "step": 2 + }, + { + "expr": "container_memory_working_set_bytes{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{ container }} (k8s)", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 40 + }, + "id": 602, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Total (k8s)", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(rate(container_cpu_usage_seconds_total{container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}[1m])) by (container)", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{ container }} (k8s)", + "refId": "B", + "step": 2 + }, + { + "expr": "irate(process_cpu_seconds_total{app=\"istiod\"}[1m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "pilot (self-reported)", + "refId": "C", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "vCPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 40 + }, + "id": 74, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_open_fds{app=\"istiod\"}", + "format": "time_series", + "hide": true, + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Open FDs (pilot)", + "refId": "A" + }, + { + "expr": "container_fs_usage_bytes{ container=~\"discovery|istio-proxy\", pod=~\"istiod-.*\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ container }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "none", + "label": "", + "logBase": 1024, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 40 + }, + "id": 402, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Number of Goroutines", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Goroutines", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "10s", + "schemaVersion": 18, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Istio Performance Dashboard", + "uid": "vu8e0VWZk", + "version": 22 +} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-service-dashboard.json b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-service-dashboard.json new file mode 100644 index 0000000000..b92e199f1d --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-service-dashboard.json @@ -0,0 +1,3033 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1595591291797, + "links": [], + "panels": [ + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 106, + "panels": [ + { + "content": "
\nSERVICE: $service\n
", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 89, + "links": [], + "mode": "html", + "options": { + "content": "
\nSERVICE: $service\n
", + "mode": "html" + }, + "pluginVersion": "7.1.0", + "title": "", + "transparent": true, + "type": "text" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 4 + }, + "id": 12, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{reporter=~\"$qrep\",destination_service=~\"$service\"}[5m])), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Client Request Volume", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 80, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": false + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 4 + }, + "id": 14, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=~\"$qrep\",destination_service=~\"$service\",response_code!~\"5.*\"}[5m])) / sum(irate(istio_requests_total{reporter=~\"$qrep\",destination_service=~\"$service\"}[5m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "95, 99, 99.5", + "title": "Client Success Rate (non-5xx responses)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 4 + }, + "hiddenSeries": false, + "id": 87, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\",destination_service=~\"$service\"}[1m])) by (le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\",destination_service=~\"$service\"}[1m])) by (le))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "P50", + "refId": "A" + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\",destination_service=~\"$service\"}[1m])) by (le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\",destination_service=~\"$service\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "P90", + "refId": "B" + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\",destination_service=~\"$service\"}[1m])) by (le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\",destination_service=~\"$service\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "P99", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Client Request Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "Bps", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 4 + }, + "id": 84, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", destination_service=~\"$service\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "TCP Received Bytes", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 8 + }, + "id": 97, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{reporter=\"destination\",destination_service=~\"$service\"}[5m])), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Server Request Volume", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 80, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": false + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 8 + }, + "id": 98, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=\"destination\",destination_service=~\"$service\",response_code!~\"5.*\"}[5m])) / sum(irate(istio_requests_total{reporter=\"destination\",destination_service=~\"$service\"}[5m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "95, 99, 99.5", + "title": "Server Success Rate (non-5xx responses)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 8 + }, + "hiddenSeries": false, + "id": 99, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\",destination_service=~\"$service\"}[1m])) by (le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\",destination_service=~\"$service\"}[1m])) by (le))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "P50", + "refId": "A" + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\",destination_service=~\"$service\"}[1m])) by (le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\",destination_service=~\"$service\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "P90", + "refId": "B" + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\",destination_service=~\"$service\"}[1m])) by (le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\",destination_service=~\"$service\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "P99", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Server Request Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "Bps", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 8 + }, + "id": 100, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_service=~\"$service\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "TCP Sent Bytes", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + ], + "title": "General", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 104, + "panels": [ + { + "content": "
\nCLIENT WORKLOADS\n
", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 45, + "links": [], + "mode": "html", + "options": { + "content": "
\nCLIENT WORKLOADS\n
", + "mode": "html" + }, + "pluginVersion": "7.1.0", + "title": "", + "transparent": true, + "type": "text" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 5 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{connection_security_policy=\"mutual_tls\",destination_service=~\"$service\",reporter=~\"$qrep\",source_workload=~\"$srcwl\",source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace, response_code), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }} : {{ response_code }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_requests_total{connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", reporter=~\"$qrep\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace, response_code), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }} : {{ response_code }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Requests By Source And Response Code", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 5 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\",response_code!~\"5.*\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace) / sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\",response_code!~\"5.*\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace) / sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Success Rate (non-5xx responses) By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.01", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 11 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Request Duration By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 11 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Request Size By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 11 + }, + "hiddenSeries": false, + "id": 68, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Response Size By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 17 + }, + "hiddenSeries": false, + "id": 80, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Received from Incoming TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 17 + }, + "hiddenSeries": false, + "id": 82, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=~\"$qrep\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=~\"$qrep\", destination_service=~\"$service\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Sent to Incoming TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Client Workloads", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 102, + "panels": [ + { + "content": "
\nSERVICE WORKLOADS\n
", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 69, + "links": [], + "mode": "html", + "options": { + "content": "
\nSERVICE WORKLOADS\n
", + "mode": "html" + }, + "pluginVersion": "7.1.0", + "title": "", + "transparent": true, + "type": "text" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 6 + }, + "hiddenSeries": false, + "id": 90, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{connection_security_policy=\"mutual_tls\",destination_service=~\"$service\",reporter=\"destination\",destination_workload=~\"$dstwl\",destination_workload_namespace=~\"$dstns\"}[5m])) by (destination_workload, destination_workload_namespace, response_code), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} : {{ response_code }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_requests_total{connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", reporter=\"destination\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[5m])) by (destination_workload, destination_workload_namespace, response_code), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} : {{ response_code }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Requests By Destination Workload And Response Code", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 6 + }, + "hiddenSeries": false, + "id": 91, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\",response_code!~\"5.*\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[5m])) by (destination_workload, destination_workload_namespace) / sum(irate(istio_requests_total{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[5m])) by (destination_workload, destination_workload_namespace)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(irate(istio_requests_total{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\",response_code!~\"5.*\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[5m])) by (destination_workload, destination_workload_namespace) / sum(irate(istio_requests_total{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[5m])) by (destination_workload, destination_workload_namespace)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Success Rate (non-5xx responses) By Destination Workload", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.01", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 12 + }, + "hiddenSeries": false, + "id": 94, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Request Duration By Service Workload", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 12 + }, + "hiddenSeries": false, + "id": 95, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Request Size By Service Workload", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 12 + }, + "hiddenSeries": false, + "id": 96, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace }} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Response Size By Service Workload", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 18 + }, + "hiddenSeries": false, + "id": 92, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=\"destination\", connection_security_policy=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace}} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=\"destination\", connection_security_policy!=\"mutual_tls\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{ destination_workload_namespace}}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Received from Incoming TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 18 + }, + "hiddenSeries": false, + "id": 93, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=\"destination\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{destination_workload_namespace }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=\"destination\", destination_service=~\"$service\", destination_workload=~\"$dstwl\", destination_workload_namespace=~\"$dstns\"}[1m])) by (destination_workload, destination_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_workload }}.{{destination_workload_namespace }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Sent to Incoming TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Service Workloads", + "type": "row" + } + ], + "refresh": "1m", + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Service", + "multi": false, + "name": "service", + "options": [], + "query": "query_result(sum(istio_requests_total{}) by (destination_service) or sum(istio_tcp_sent_bytes_total{}) by (destination_service))", + "refresh": 1, + "regex": "/.*destination_service=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "destination", + "value": "destination" + }, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Reporter", + "multi": true, + "name": "qrep", + "query": "source,destination", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "custom", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Client Cluster", + "multi": true, + "name": "srccluster", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=~\"$qrep\", destination_service=\"$service\"}) by (source_cluster) or sum(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_service=~\"$service\"}) by (source_cluster))", + "refresh": 1, + "regex": "/.*cluster=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Client Workload Namespace", + "multi": true, + "name": "srcns", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=~\"$qrep\", destination_service=\"$service\"}) by (source_workload_namespace) or sum(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_service=~\"$service\"}) by (source_workload_namespace))", + "refresh": 1, + "regex": "/.*namespace=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 3, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Client Workload", + "multi": true, + "name": "srcwl", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=~\"$qrep\", destination_service=~\"$service\", source_workload_namespace=~\"$srcns\"}) by (source_workload) or sum(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_service=~\"$service\", source_workload_namespace=~\"$srcns\"}) by (source_workload))", + "refresh": 1, + "regex": "/.*workload=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 4, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Service Workload Cluster", + "multi": true, + "name": "dstcluster", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=\"destination\", destination_service=\"$service\"}) by (destination_cluster) or sum(istio_tcp_sent_bytes_total{reporter=\"destination\", destination_service=~\"$service\"}) by (destination_cluster))", + "refresh": 1, + "regex": "/.*cluster=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Service Workload Namespace", + "multi": true, + "name": "dstns", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=\"destination\", destination_service=\"$service\"}) by (destination_workload_namespace) or sum(istio_tcp_sent_bytes_total{reporter=\"destination\", destination_service=~\"$service\"}) by (destination_workload_namespace))", + "refresh": 1, + "regex": "/.*namespace=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 3, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Service Workload", + "multi": true, + "name": "dstwl", + "options": [], + "query": "query_result( sum(istio_requests_total{reporter=\"destination\", destination_service=~\"$service\", destination_cluster=~\"$dstcluster\", destination_workload_namespace=~\"$dstns\"}) by (destination_workload) or sum(istio_tcp_sent_bytes_total{reporter=\"destination\", destination_service=~\"$service\", destination_cluster=~\"$dstcluster\", destination_workload_namespace=~\"$dstns\"}) by (destination_workload))", + "refresh": 1, + "regex": "/.*workload=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 4, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Istio Service Dashboard", + "uid": "LJ_uJAvmk", + "version": 1 +} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-workload-dashboard.json b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-workload-dashboard.json new file mode 100644 index 0000000000..dd17f22132 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/istio-workload-dashboard.json @@ -0,0 +1,2671 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 0, + "iteration": 1531345461465, + "links": [], + "panels": [ + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 95, + "panels": [ + { + "content": "
\nWORKLOAD: $workload.$namespace\n
", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 89, + "links": [], + "mode": "html", + "options": { + "content": "
\nWORKLOAD: $workload.$namespace\n
", + "mode": "html" + }, + "pluginVersion": "7.1.0", + "title": "", + "transparent": true, + "type": "text" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "ops", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 8, + "x": 0, + "y": 4 + }, + "id": 12, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{reporter=~\"$qrep\",destination_workload_namespace=~\"$namespace\",destination_workload=~\"$workload\"}[5m])), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "refId": "A", + "step": 4 + } + ], + "thresholds": "", + "title": "Incoming Request Volume", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": null, + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "percentunit", + "gauge": { + "maxValue": 100, + "minValue": 80, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": false + }, + "gridPos": { + "h": 4, + "w": 8, + "x": 8, + "y": 4 + }, + "id": 14, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=~\"$qrep\",destination_workload_namespace=~\"$namespace\",destination_workload=~\"$workload\",response_code!~\"5.*\"}[5m])) / sum(irate(istio_requests_total{reporter=~\"$qrep\",destination_workload_namespace=~\"$namespace\",destination_workload=~\"$workload\"}[5m]))", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": "95, 99, 99.5", + "title": "Incoming Success Rate (non-5xx responses)", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 4, + "w": 8, + "x": 16, + "y": 4 + }, + "hiddenSeries": false, + "id": 87, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\",destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\"}[1m])) by (le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\",destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\"}[1m])) by (le))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "P50", + "refId": "A" + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\",destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\"}[1m])) by (le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\",destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "P90", + "refId": "B" + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\",destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\"}[1m])) by (le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\",destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\"}[1m])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "P99", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Request Duration", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "Bps", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 0, + "y": 8 + }, + "id": 84, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\"}[1m])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "TCP Server Traffic", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "#299c46", + "rgba(237, 129, 40, 0.89)", + "#d44a3a" + ], + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "format": "Bps", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 4, + "w": 12, + "x": 12, + "y": 8 + }, + "id": 85, + "interval": null, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "textMode": "auto" + }, + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": true, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(irate(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\"}[1m])) + sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": "", + "title": "TCP Client Traffic", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "avg" + } + ], + "title": "General", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 93, + "panels": [ + { + "content": "
\nINBOUND WORKLOADS\n
", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 45, + "links": [], + "mode": "html", + "options": { + "content": "
\nINBOUND WORKLOADS\n
", + "mode": "html" + }, + "pluginVersion": "7.1.0", + "title": "", + "transparent": true, + "type": "text" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 16 + }, + "hiddenSeries": false, + "id": 25, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{connection_security_policy=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", reporter=~\"$qrep\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace, response_code), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }} : {{ response_code }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_requests_total{connection_security_policy!=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", reporter=~\"$qrep\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace, response_code), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }} : {{ response_code }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Requests By Source And Response Code", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 16 + }, + "hiddenSeries": false, + "id": 26, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\",response_code!~\"5.*\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace) / sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\",response_code!~\"5.*\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace) / sum(irate(istio_requests_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[5m])) by (source_workload, source_workload_namespace)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Success Rate (non-5xx responses) By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.01", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 22 + }, + "hiddenSeries": false, + "id": 27, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Request Duration By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 22 + }, + "hiddenSeries": false, + "id": 28, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Incoming Request Size By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 22 + }, + "hiddenSeries": false, + "id": 68, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload=~\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{source_workload}}.{{source_workload_namespace}} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Response Size By Source", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 80, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{reporter=~\"$qrep\", connection_security_policy!=\"mutual_tls\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Received from Incoming TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 82, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy=\"mutual_tls\", reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=~\"$qrep\", destination_workload_namespace=~\"$namespace\", destination_workload=~\"$workload\", source_workload=~\"$srcwl\", source_workload_namespace=~\"$srcns\"}[1m])) by (source_workload, source_workload_namespace), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ source_workload }}.{{ source_workload_namespace}}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Sent to Incoming TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Inbound Workloads", + "type": "row" + }, + { + "collapsed": true, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 2 + }, + "id": 91, + "panels": [ + { + "content": "
\nOUTBOUND SERVICES\n
", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 69, + "links": [], + "mode": "html", + "options": { + "content": "
\nOUTBOUND SERVICES\n
", + "mode": "html" + }, + "pluginVersion": "7.1.0", + "title": "", + "transparent": true, + "type": "text" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 0, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 17 + }, + "hiddenSeries": false, + "id": 70, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_requests_total{destination_principal=~\"spiffe.*\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", reporter=\"source\", destination_service=~\"$dstsvc\"}[5m])) by (destination_service, response_code), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} : {{ response_code }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_requests_total{destination_principal!~\"spiffe.*\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", reporter=\"source\", destination_service=~\"$dstsvc\"}[5m])) by (destination_service, response_code), 0.001)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} : {{ response_code }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Outgoing Requests By Destination And Response Code", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 17 + }, + "hiddenSeries": false, + "id": 71, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(istio_requests_total{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\",response_code!~\"5.*\", destination_service=~\"$dstsvc\"}[5m])) by (destination_service) / sum(irate(istio_requests_total{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[5m])) by (destination_service)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "sum(irate(istio_requests_total{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\",response_code!~\"5.*\", destination_service=~\"$dstsvc\"}[5m])) by (destination_service) / sum(irate(istio_requests_total{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[5m])) by (destination_service)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Outgoing Success Rate (non-5xx responses) By Destination", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percentunit", + "label": null, + "logBase": 1, + "max": "1.01", + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 23 + }, + "hiddenSeries": false, + "id": 72, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": false, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.50, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.50, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.90, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.90, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.95, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.95, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "(histogram_quantile(0.99, sum(irate(istio_request_duration_milliseconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le)) / 1000) or histogram_quantile(0.99, sum(irate(istio_request_duration_seconds_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Outgoing Request Duration By Destination", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 23 + }, + "hiddenSeries": false, + "id": 73, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_request_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Outgoing Request Size By Destination", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 23 + }, + "hiddenSeries": false, + "id": 74, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "hideEmpty": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P50 (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P90 (🔐mTLS)", + "refId": "B", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P95 (🔐mTLS)", + "refId": "C", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P99 (🔐mTLS)", + "refId": "D", + "step": 2 + }, + { + "expr": "histogram_quantile(0.50, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P50", + "refId": "E", + "step": 2 + }, + { + "expr": "histogram_quantile(0.90, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P90", + "refId": "F", + "step": 2 + }, + { + "expr": "histogram_quantile(0.95, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P95", + "refId": "G", + "step": 2 + }, + { + "expr": "histogram_quantile(0.99, sum(irate(istio_response_bytes_bucket{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service, le))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} P99", + "refId": "H", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Response Size By Destination", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 0, + "y": 29 + }, + "hiddenSeries": false, + "id": 76, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy=\"mutual_tls\", reporter=\"source\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_received_bytes_total{connection_security_policy!=\"mutual_tls\", reporter=\"source\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_service }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Sent on Outgoing TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 6, + "w": 12, + "x": 12, + "y": 29 + }, + "hiddenSeries": false, + "id": 78, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pluginVersion": "7.1.0", + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{reporter=\"source\", connection_security_policy=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_service }} (🔐mTLS)", + "refId": "A", + "step": 2 + }, + { + "expr": "round(sum(irate(istio_tcp_sent_bytes_total{reporter=\"source\", connection_security_policy!=\"mutual_tls\", source_workload_namespace=~\"$namespace\", source_workload=~\"$workload\", destination_service=~\"$dstsvc\"}[1m])) by (destination_service), 0.001)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ destination_service }}", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Bytes Received from Outgoing TCP Connection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "title": "Outbound Services", + "type": "row" + } + ], + "refresh": "1m", + "schemaVersion": 26, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Namespace", + "multi": false, + "name": "namespace", + "options": [], + "query": "query_result(sum(istio_requests_total) by (destination_workload_namespace) or sum(istio_tcp_sent_bytes_total) by (destination_workload_namespace))", + "refresh": 1, + "regex": "/.*_namespace=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Workload", + "multi": false, + "name": "workload", + "options": [], + "query": "query_result((sum(istio_requests_total{destination_workload_namespace=~\"$namespace\"}) by (destination_workload) or sum(istio_requests_total{source_workload_namespace=~\"$namespace\"}) by (source_workload)) or (sum(istio_tcp_sent_bytes_total{destination_workload_namespace=~\"$namespace\"}) by (destination_workload) or sum(istio_tcp_sent_bytes_total{source_workload_namespace=~\"$namespace\"}) by (source_workload)))", + "refresh": 1, + "regex": "/.*workload=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": { + "selected": true, + "text": "destination", + "value": "destination" + }, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": false, + "label": "Reporter", + "multi": true, + "name": "qrep", + "query": "source,destination", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "custom", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Inbound Workload Namespace", + "multi": true, + "name": "srcns", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=~\"$qrep\", destination_workload=\"$workload\", destination_workload_namespace=~\"$namespace\"}) by (source_workload_namespace) or sum(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_workload=\"$workload\", destination_workload_namespace=~\"$namespace\"}) by (source_workload_namespace))", + "refresh": 1, + "regex": "/.*namespace=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 2, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Inbound Workload", + "multi": true, + "name": "srcwl", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=~\"$qrep\", destination_workload=\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload_namespace=~\"$srcns\"}) by (source_workload) or sum(istio_tcp_sent_bytes_total{reporter=~\"$qrep\", destination_workload=\"$workload\", destination_workload_namespace=~\"$namespace\", source_workload_namespace=~\"$srcns\"}) by (source_workload))", + "refresh": 1, + "regex": "/.*workload=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 3, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "", + "hide": 0, + "includeAll": true, + "label": "Destination Service", + "multi": true, + "name": "dstsvc", + "options": [], + "query": "query_result(sum(istio_requests_total{reporter=\"source\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\"}) by (destination_service) or sum(istio_tcp_sent_bytes_total{reporter=\"source\", source_workload=~\"$workload\", source_workload_namespace=~\"$namespace\"}) by (destination_service))", + "refresh": 1, + "regex": "/.*destination_service=\"([^\"]*).*/", + "skipUrlSync": false, + "sort": 4, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Istio Workload Dashboard", + "uid": "UbsSZTDik", + "version": 1 +} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/dashboards/pilot-dashboard.json b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/pilot-dashboard.json new file mode 100644 index 0000000000..82f7306392 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/dashboards/pilot-dashboard.json @@ -0,0 +1,1749 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": false, + "gnetId": null, + "graphTooltip": 1, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 60, + "panels": [], + "title": "Deployed Versions", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 5, + "w": 24, + "x": 0, + "y": 1 + }, + "id": 56, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(istio_build{component=\"pilot\"}) by (tag)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ tag }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pilot Versions", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 6 + }, + "id": 62, + "panels": [], + "title": "Resource Usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 7 + }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "process_virtual_memory_bytes{app=\"istiod\"}", + "format": "time_series", + "instant": false, + "intervalFactor": 2, + "legendFormat": "Virtual Memory", + "refId": "I", + "step": 2 + }, + { + "expr": "process_resident_memory_bytes{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Resident Memory", + "refId": "H", + "step": 2 + }, + { + "expr": "go_memstats_heap_sys_bytes{app=\"istiod\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "heap sys", + "refId": "A" + }, + { + "expr": "go_memstats_heap_alloc_bytes{app=\"istiod\"}", + "format": "time_series", + "hide": true, + "intervalFactor": 2, + "legendFormat": "heap alloc", + "refId": "D" + }, + { + "expr": "go_memstats_alloc_bytes{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Alloc", + "refId": "F", + "step": 2 + }, + { + "expr": "go_memstats_heap_inuse_bytes{app=\"istiod\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Heap in-use", + "refId": "E", + "step": 2 + }, + { + "expr": "go_memstats_stack_inuse_bytes{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Stack in-use", + "refId": "G", + "step": 2 + }, + { + "expr": "container_memory_working_set_bytes{container=~\"discovery\", pod=~\"istiod-.*|istio-pilot-.*\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Discovery (container)", + "refId": "B", + "step": 2 + }, + { + "expr": "container_memory_working_set_bytes{container=~\"istio-proxy\", pod=~\"istiod-.*|istio-pilot-.*\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Sidecar (container)", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Memory", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 7 + }, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_cpu_usage_seconds_total{container=\"discovery\", pod=~\"istiod-.*|istio-pilot-.*\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Discovery (container)", + "refId": "A" + }, + { + "expr": "irate(process_cpu_seconds_total{app=\"istiod\"}[1m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Discovery (process)", + "refId": "C", + "step": 2 + }, + { + "expr": "sum(irate(container_cpu_usage_seconds_total{container=\"istio-proxy\", pod=~\"istiod-.*|istio-pilot-.*\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "Sidecar (container)", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "CPU", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 12, + "y": 7 + }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "container_fs_usage_bytes{container=\"discovery\", pod=~\"istiod-.*|istio-pilot-.*\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Discovery", + "refId": "B", + "step": 2 + }, + { + "expr": "container_fs_usage_bytes{container=\"istio-proxy\", pod=~\"istiod-.*|istio-pilot-.*\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Sidecar", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Disk", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "decimals": null, + "format": "none", + "label": "", + "logBase": 1024, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 6, + "x": 18, + "y": 7 + }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "go_goroutines{app=\"istiod\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Number of Goroutines", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Goroutines", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 14 + }, + "id": 58, + "panels": [], + "title": "Pilot Push Information", + "type": "row" + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Shows the rate of pilot pushes", + "fill": 1, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 15 + }, + "id": 622, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "paceLength": 10, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(pilot_xds_pushes{type=\"cds\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Cluster", + "refId": "C" + }, + { + "expr": "sum(irate(pilot_xds_pushes{type=\"eds\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Endpoints", + "refId": "D" + }, + { + "expr": "sum(irate(pilot_xds_pushes{type=\"lds\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Listeners", + "refId": "A" + }, + { + "expr": "sum(irate(pilot_xds_pushes{type=\"rds\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Routes", + "refId": "E" + }, + { + "expr": "sum(irate(pilot_xds_pushes{type=\"sds\"}[1m]))", + "interval": "", + "legendFormat": "Secrets", + "refId": "B" + }, + { + "expr": "sum(irate(pilot_xds_pushes{type=\"nds\"}[1m]))", + "interval": "", + "legendFormat": "Nametables", + "refId": "F" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pilot Pushes", + "tooltip": { + "shared": false, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [ + "total" + ] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": "0", + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Captures a variety of pilot errors", + "fill": 1, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 15 + }, + "id": 67, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(pilot_xds_cds_reject{app=\"istiod\"}) or (absent(pilot_xds_cds_reject{app=\"istiod\"}) - 1)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Rejected CDS Configs", + "refId": "C" + }, + { + "expr": "sum(pilot_xds_eds_reject{app=\"istiod\"}) or (absent(pilot_xds_eds_reject{app=\"istiod\"}) - 1)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Rejected EDS Configs", + "refId": "D" + }, + { + "expr": "sum(pilot_xds_rds_reject{app=\"istiod\"}) or (absent(pilot_xds_rds_reject{app=\"istiod\"}) - 1)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Rejected RDS Configs", + "refId": "A" + }, + { + "expr": "sum(pilot_xds_lds_reject{app=\"istiod\"}) or (absent(pilot_xds_lds_reject{app=\"istiod\"}) - 1)", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Rejected LDS Configs", + "refId": "B" + }, + { + "expr": "sum(rate(pilot_xds_write_timeout{app=\"istiod\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Write Timeouts", + "refId": "F" + }, + { + "expr": "sum(rate(pilot_total_xds_internal_errors{app=\"istiod\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Internal Errors", + "refId": "H" + }, + { + "expr": "sum(rate(pilot_total_xds_rejects{app=\"istiod\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Config Rejection Rate", + "refId": "E" + }, + { + "expr": "sum(rate(pilot_xds_push_context_errors{app=\"istiod\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Push Context Errors", + "refId": "K" + }, + { + "expr": "sum(rate(pilot_xds_write_timeout{app=\"istiod\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Push Timeouts", + "refId": "G" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Pilot Errors", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Shows the total time it takes to push a config update to a proxy", + "fill": 1, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 15 + }, + "id": 624, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "histogram_quantile(0.5, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "p50 ", + "refId": "A" + }, + { + "expr": "histogram_quantile(0.9, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "p90", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "p99", + "refId": "C" + }, + { + "expr": "histogram_quantile(0.999, sum(rate(pilot_proxy_convergence_time_bucket[1m])) by (le))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "p99.9", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Proxy Push Time", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 23 + }, + "id": 45, + "legend": { + "avg": false, + "current": false, + "hideEmpty": true, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "pilot_conflict_inbound_listener{app=\"istiod\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Inbound Listeners", + "refId": "B" + }, + { + "expr": "pilot_conflict_outbound_listener_http_over_current_tcp{app=\"istiod\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Outbound Listeners (http over current tcp)", + "refId": "A" + }, + { + "expr": "pilot_conflict_outbound_listener_tcp_over_current_tcp{app=\"istiod\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Outbound Listeners (tcp over current tcp)", + "refId": "C" + }, + { + "expr": "pilot_conflict_outbound_listener_tcp_over_current_http{app=\"istiod\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "Outbound Listeners (tcp over current http)", + "refId": "D" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Conflicts", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 23 + }, + "id": 47, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "avg(pilot_virt_services{app=\"istiod\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Virtual Services", + "refId": "A" + }, + { + "expr": "avg(pilot_services{app=\"istiod\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Services", + "refId": "B" + }, + { + "expr": "sum(pilot_xds{app=\"istiod\"}) by (pod)", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Connected Endpoints {{pod}}", + "refId": "E" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "ADS Monitoring", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 31 + }, + "id": 64, + "panels": [], + "title": "Envoy Information", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Shows details about Envoy proxies in the mesh", + "fill": 1, + "gridPos": { + "h": 8, + "w": 8, + "x": 0, + "y": 32 + }, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(envoy_cluster_upstream_cx_total{cluster_name=\"xds-grpc\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "XDS Connections", + "refId": "C" + }, + { + "expr": "sum(irate(envoy_cluster_upstream_cx_connect_fail{cluster_name=\"xds-grpc\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "XDS Connection Failures", + "refId": "A" + }, + { + "expr": "sum(increase(envoy_server_hot_restart_epoch[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Envoy Restarts", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Envoy Details", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 8, + "w": 8, + "x": 8, + "y": 32 + }, + "id": 41, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(envoy_cluster_upstream_cx_active{cluster_name=\"xds-grpc\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "XDS Active Connections", + "refId": "C", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "XDS Active Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "Shows the size of XDS requests and responses", + "fill": 1, + "gridPos": { + "h": 8, + "w": 8, + "x": 16, + "y": 32 + }, + "id": 42, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "max(rate(envoy_cluster_upstream_cx_rx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "XDS Response Bytes Max", + "refId": "D" + }, + { + "expr": "quantile(0.5, rate(envoy_cluster_upstream_cx_rx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))", + "format": "time_series", + "hide": false, + "intervalFactor": 1, + "legendFormat": "XDS Response Bytes Average", + "refId": "B" + }, + { + "expr": "max(rate(envoy_cluster_upstream_cx_tx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "XDS Request Bytes Max", + "refId": "A" + }, + { + "expr": "quantile(.5, rate(envoy_cluster_upstream_cx_tx_bytes_total{cluster_name=\"xds-grpc\"}[1m]))", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "XDS Request Bytes Average", + "refId": "C" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "XDS Requests Size", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "ops", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "datasource": null, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 40 + }, + "id": 626, + "panels": [], + "title": "Webhooks", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 41 + }, + "hiddenSeries": false, + "id": 629, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(galley_validation_passed[1m]))", + "interval": "", + "legendFormat": "Validations (Success)", + "refId": "A" + }, + { + "expr": "sum(rate(galley_validation_failed[1m]))", + "interval": "", + "legendFormat": "Validation (Failure)", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Configuration Validation", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": null, + "description": "", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 41 + }, + "hiddenSeries": false, + "id": 630, + "legend": { + "avg": false, + "current": false, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(sidecar_injection_success_total[1m]))", + "interval": "", + "legendFormat": "Injections (Success)", + "refId": "A" + }, + { + "expr": "sum(rate(sidecar_injection_failure_total[1m]))", + "interval": "", + "legendFormat": "Injections (Failure)", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Sidecar Injection", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": "5s", + "schemaVersion": 18, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": true, + "text": "default", + "value": "default" + }, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + } + ] + }, + "time": { + "from": "now-5m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Istio Control Plane Dashboard", + "uid": "3--MLVZZk", + "version": 11 +} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/_affinity.tpl b/resources/helm/v2.5/istio-telemetry/grafana/templates/_affinity.tpl new file mode 100644 index 0000000000..f2707b9318 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/_affinity.tpl @@ -0,0 +1,93 @@ +{{/* affinity - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ */}} + +{{- define "nodeaffinity" }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityRequiredDuringScheduling" . }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityPreferredDuringScheduling" . }} +{{- end }} + +{{- define "nodeAffinityRequiredDuringScheduling" }} + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + {{- range $key, $val := .Values.global.arch }} + {{- if gt ($val | int) 0 }} + - {{ $key | quote }} + {{- end }} + {{- end }} + {{- $nodeSelector := default .Values.global.defaultNodeSelector .Values.grafana.nodeSelector -}} + {{- range $key, $val := $nodeSelector }} + - key: {{ $key }} + operator: In + values: + - {{ $val | quote }} + {{- end }} +{{- end }} + +{{- define "nodeAffinityPreferredDuringScheduling" }} + {{- range $key, $val := .Values.global.arch }} + {{- if gt ($val | int) 0 }} + - weight: {{ $val | int }} + preference: + matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - {{ $key | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinity" }} +{{- if or .Values.grafana.podAntiAffinityLabelSelector .Values.grafana.podAntiAffinityTermLabelSelector}} + podAntiAffinity: + {{- if .Values.grafana.podAntiAffinityLabelSelector }} + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityRequiredDuringScheduling" . }} + {{- end }} + {{- if .Values.grafana.podAntiAffinityTermLabelSelector }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityPreferredDuringScheduling" . }} + {{- end }} +{{- end }} +{{- end }} + +{{- define "podAntiAffinityRequiredDuringScheduling" }} + {{- range $index, $item := .Values.grafana.podAntiAffinityLabelSelector }} + - labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinityPreferredDuringScheduling" }} + {{- range $index, $item := .Values.grafana.podAntiAffinityTermLabelSelector }} + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + weight: 100 + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/configmap-dashboards.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/configmap-dashboards.yaml new file mode 100644 index 0000000000..5366aa6c34 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/configmap-dashboards.yaml @@ -0,0 +1,17 @@ +{{- $files := .Files }} +{{- range $path, $bytes := .Files.Glob "dashboards/*.json" }} +{{- $filename := trimSuffix (ext $path) (base $path) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: istio-grafana-configuration-dashboards-{{ $filename }} + namespace: {{ $.Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ $.Release.Name }} + istio: grafana +data: + {{ base $path }}: '{{ $files.Get $path }}' +--- +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/configmap.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/configmap.yaml new file mode 100644 index 0000000000..bff319bcba --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/configmap.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: istio-grafana + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} + istio: grafana +data: + # TODO: this needs to be verified + grafana.ini: | + [analytics] + check_for_updates = true + [grafana_net] + url = https://grafana.net + [log] + mode = console + [paths] + data = /data/grafana + logs = /var/log/grafana + plugins = /var/lib/grafana/plugins + provisioning = /etc/grafana/provisioning + +{{- if .Values.grafana.datasources }} + {{- range $key, $value := .Values.grafana.datasources }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} + +{{- if .Values.grafana.dashboardProviders }} + {{- range $key, $value := .Values.grafana.dashboardProviders }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/deployment.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/deployment.yaml new file mode 100644 index 0000000000..3c828449cf --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/deployment.yaml @@ -0,0 +1,230 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grafana + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} +spec: + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + replicas: {{ .Values.grafana.replicaCount }} + revisionHistoryLimit: 10 + selector: + matchLabels: + app: grafana + template: + metadata: + labels: + maistra-control-plane: {{ .Release.Namespace }} + app: grafana + annotations: + checksum/config: d2485b1ee9f9be63381c231826a43742bb10ebac2964bdc3f22a100eab9d032c + checksum/dashboards-json-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b + checksum/sc-dashboard-provider-config: 01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b + sidecar.istio.io/inject: "false" + {{- if .Values.grafana.podAnnotations }} +{{ toYaml .Values.grafana.podAnnotations | indent 8 }} + {{- end }} + spec: +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} +{{- if .Values.global.imagePullSecrets }} + imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} + serviceAccountName: grafana + containers: + # OAuth proxy + - name: grafana-proxy +{{- if contains "/" .Values.global.oauthproxy.image }} + image: {{ .Values.global.oauthproxy.image }} +{{- else }} + image: {{ .Values.global.oauthproxy.hub }}/{{ .Values.global.oauthproxy.image }}:{{ .Values.global.oauthproxy.tag }} +{{- end }} + imagePullPolicy: {{ .Values.global.oauthproxy.imagePullPolicy }} + ports: + - containerPort: 3001 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + httpGet: + path: /oauth/healthz + port: https + scheme: HTTPS + timeoutSeconds: 1 + resources: +{{- if .Values.global.oauthproxy.resources }} +{{ toYaml .Values.global.oauthproxy.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/tls/private + name: secret-grafana-tls + - mountPath: /etc/proxy/htpasswd + name: secret-htpasswd + - mountPath: /etc/proxy/secrets + name: secret-grafana-proxy + - mountPath: /etc/pki/ca-trust/extracted/pem/ + name: trusted-ca-bundle + readOnly: true + args: + - -provider=openshift + - -https-address=:3001 + - -http-address= + - -email-domain=* + - -upstream=http://localhost:3000 + - -htpasswd-file=/etc/proxy/htpasswd/auth + - -display-htpasswd-form=false + - '-openshift-sar={"namespace": "{{ .Release.Namespace }}", "resource": "pods", "verb": "get"}' + - -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token + - -openshift-service-account=grafana + - -cookie-secret-file=/etc/proxy/secrets/session_secret + - -tls-cert=/etc/tls/private/tls.crt + - -tls-key=/etc/tls/private/tls.key + - -openshift-ca=/etc/pki/tls/cert.pem + - -openshift-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + - name: {{ .Chart.Name }} +{{- if contains "/" .Values.grafana.image }} + image: "{{ .Values.grafana.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.grafana.image }}:{{ .Values.global.tag }}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + ports: + - name: service + containerPort: 3000 + protocol: TCP + - name: grafana + containerPort: 3000 + protocol: TCP + livenessProbe: + failureThreshold: 10 + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 60 + timeoutSeconds: 30 + readinessProbe: + httpGet: + path: /api/health + port: 3000 + env: + - name: GRAFANA_PORT + value: "3000" + - name: GF_AUTH_BASIC_ENABLED + value: "false" + - name: GF_AUTH_PROXY_ENABLED + value: "true" + - name: GF_AUTH_PROXY_AUTO_SIGN_UP + value: "true" + - name: GF_AUTH_PROXY_WHITELIST + value: 127.0.0.0/24,::1 + - name: GF_AUTH_PROXY_HEADERS + value: Email:X-Forwarded-Email + - name: GF_AUTH_PROXY_HEADER_NAME + value: X-Forwarded-User + - name: GF_USERS_AUTO_ASSIGN_ORG_ROLE + value: Admin + {{- range $key, $value := $.Values.grafana.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- range $key, $secret := $.Values.grafana.envSecrets }} + - name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ $secret }} + key: {{ $key | quote }} + {{- end }} + resources: +{{- if .Values.grafana.resources }} +{{ toYaml .Values.grafana.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/grafana.ini" + subPath: grafana.ini + - name: data + mountPath: /data/grafana + {{- range $path, $bytes := .Files.Glob "dashboards/*.json" }} + {{- $filename := trimSuffix (ext $path) (base $path) }} + - name: dashboards-istio-{{ $filename }} + mountPath: "/var/lib/grafana/dashboards/istio/{{ base $path }}" + subPath: {{ base $path }} + readOnly: true + {{- end }} + - name: config + mountPath: "/etc/grafana/provisioning/datasources/datasources.yaml" + subPath: datasources.yaml + - name: config + mountPath: "/etc/grafana/provisioning/dashboards/dashboardproviders.yaml" + subPath: dashboardproviders.yaml + affinity: + {{- include "nodeaffinity" . | indent 6 }} + {{- include "podAntiAffinity" . | indent 6 }} +{{- if .Values.grafana.tolerations }} + tolerations: +{{ toYaml .Values.grafana.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} + volumes: + # OAuth proxy + - name: secret-grafana-tls + secret: + defaultMode: 420 + secretName: grafana-tls + - name: secret-htpasswd + secret: + defaultMode: 420 + items: + - key: auth + path: auth + secretName: htpasswd + - name: secret-grafana-proxy + secret: + defaultMode: 420 + secretName: grafana-proxy + - name: trusted-ca-bundle + configMap: + defaultMode: 420 + items: + - key: ca-bundle.crt + path: tls-ca-bundle.pem + name: trusted-ca-bundle + optional: true + - name: config + configMap: + name: istio-grafana + - name: data +{{- if .Values.grafana.persist }} + persistentVolumeClaim: + claimName: istio-grafana-pvc +{{- else }} + emptyDir: {} +{{- end }} +{{- range $path, $bytes := .Files.Glob "dashboards/*.json" }} +{{- $filename := trimSuffix (ext $path) (base $path) }} + - name: dashboards-istio-{{ $filename }} + configMap: + name: istio-grafana-configuration-dashboards-{{ $filename }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/grafana-policy.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/grafana-policy.yaml new file mode 100644 index 0000000000..8912cfedd2 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/grafana-policy.yaml @@ -0,0 +1,20 @@ +{{- if .Values.grafana.enabled }} +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: grafana-ports-mtls-disabled + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + app: grafana + mtls: + mode: PERMISSIVE + portLevelMtls: + {{ .Values.grafana.service.externalPort }}: + mode: DISABLE +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/ingress.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/ingress.yaml new file mode 100644 index 0000000000..45fc1bd396 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/ingress.yaml @@ -0,0 +1,28 @@ +{{- if .Values.grafana.ingress.enabled -}} +{{- range $index, $host := .Values.grafana.ingress.hosts }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: grafana{{ if gt $index 0 }}-{{ $index }}{{ end }} + namespace: {{ $.Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ $.Release.Name }} +{{- if gt (len $.Values.grafana.ingress.annotations) 0 }} + annotations: +{{- range $key, $value := $.Values.grafana.ingress.annotations }} + {{ $key }}: {{ $value | quote }} +{{- end }} +{{- end }} +spec: + host: {{ $host }} + to: + kind: Service + name: grafana + tls: + termination: reencrypt + insecureEdgeTerminationPolicy: Redirect +--- +{{- end }} +{{- end -}} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/networkpolicy.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/networkpolicy.yaml new file mode 100644 index 0000000000..6a44bcf94b --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/networkpolicy.yaml @@ -0,0 +1,19 @@ +# This is to support routes on ocp 3.11 installs +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-grafana-ingress + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} + annotations: + "maistra.io/internal": "true" +spec: + podSelector: + matchLabels: + app: grafana + ingress: + - ports: + port: 3001 diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/pvc.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/pvc.yaml new file mode 100644 index 0000000000..b47e29da89 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/pvc.yaml @@ -0,0 +1,18 @@ +{{- if .Values.grafana.persist }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: istio-grafana-pvc + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} +spec: + storageClassName: {{ .Values.grafana.storageClassName }} + accessModes: + - {{ .Values.grafana.accessMode }} + resources: + requests: + storage: {{ .Values.grafana.persistenceResources.requests.storage | quote }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/secrets.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/secrets.yaml new file mode 100644 index 0000000000..e020cafa83 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/secrets.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +data: + session_secret: "" +kind: Secret +metadata: + name: grafana-proxy + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} +type: Opaque diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/service.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/service.yaml new file mode 100644 index 0000000000..93ec045979 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/service.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: grafana + namespace: {{ .Release.Namespace }} + annotations: + {{- range $key, $val := .Values.grafana.service.annotations }} + {{ $key }}: {{ $val | quote }} + {{- end }} + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} +spec: + type: {{ .Values.grafana.service.type }} + ports: + - port: {{ .Values.grafana.service.externalPort }} + targetPort: 3001 + protocol: TCP + name: {{ .Values.grafana.service.name }} + selector: + app: grafana +{{- if .Values.grafana.service.loadBalancerIP }} + loadBalancerIP: "{{ .Values.grafana.service.loadBalancerIP }}" +{{- end }} + {{if .Values.grafana.service.loadBalancerSourceRanges}} + loadBalancerSourceRanges: + {{range $rangeList := .Values.grafana.service.loadBalancerSourceRanges}} + - {{ $rangeList }} + {{end}} + {{end}} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/templates/serviceaccount.yaml b/resources/helm/v2.5/istio-telemetry/grafana/templates/serviceaccount.yaml new file mode 100644 index 0000000000..51b883ccfc --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana + namespace: {{ .Release.Namespace }} + annotations: + serviceaccounts.openshift.io/oauth-redirectreference.primary: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"grafana"}}' + labels: + maistra-version: "2.5.0" + app: grafana + release: {{ .Release.Name }} diff --git a/resources/helm/v2.5/istio-telemetry/grafana/values.yaml b/resources/helm/v2.5/istio-telemetry/grafana/values.yaml new file mode 100644 index 0000000000..45f7e44e10 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/grafana/values.yaml @@ -0,0 +1,150 @@ +global: + # ImagePullSecrets for control plane ServiceAccount, list of secrets in the same namespace + # to use for pulling any images in pods that reference this ServiceAccount. + # Must be set for any cluster configured with private docker registry. + imagePullSecrets: [] + + # Kubernetes >=v1.11.0 will create two PriorityClass, including system-cluster-critical and + # system-node-critical, it is better to configure this in order to make sure your Istio pods + # will not be killed because of low priority class. + # Refer to https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass + # for more detail. + priorityClassName: "" + + oauthproxy: + image: registry.redhat.io/openshift4/ose-oauth-proxy:latest + +grafana: + enabled: true + replicaCount: 1 + image: grafana + persist: false + storageClassName: "" + accessMode: ReadWriteMany + security: + enabled: false + secretName: grafana + usernameKey: username + passphraseKey: passphrase + persistenceResources: + requests: + storage: "5Gi" # PVC spec.resources.requests.storage default value + + contextPath: /grafana + service: + annotations: + service.alpha.openshift.io/serving-cert-secret-name: grafana-tls + name: http + type: ClusterIP + externalPort: 3000 + loadBalancerIP: "" + loadBalancerSourceRanges: "" + + ingress: + enabled: true + ## Used to create an Ingress record. + hosts: [""] + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + tls: {} + # Secrets must be manually created in the namespace. + # - secretName: grafana-tls + # hosts: + # - grafana.local + + # Optional: prometheus may be deployed in a different namespace + # prometheusNamespace: istio-telemetry + + # Additional datasources. Prometheus included in the config map. + datasources: + datasources.yaml: + apiVersion: 1 + datasources: + - access: proxy + editable: true + isDefault: true + jsonData: + timeInterval: 5s + # XXX: is this still needed? + # we should be using the CA cert in /var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt + tlsSkipVerify: true + name: Prometheus + orgId: 1 + type: prometheus + url: https://prometheus:9090 + basicAuth: true + basicAuthPassword: "" + basicAuthUser: internal + version: 1 + + dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - disableDeletion: false + folder: istio + name: istio + options: + path: /var/lib/grafana/dashboards/istio + orgId: 1 + type: file + + nodeSelector: {} + tolerations: [] + podAnnotations: {} + + env: {} + # Define additional environment variables for configuring grafana. + # @see https://grafana.com/docs/installation/configuration/#using-environment-variables + # Format: env_variable_name: value + # For example: + # GF_SMTP_ENABLED: true + # GF_SMTP_HOST: email-smtp.eu-west-1.amazonaws.com:2587 + # GF_SMTP_FROM_ADDRESS: alerts@mydomain.com + # GF_SMTP_FROM_NAME: Grafana + + envSecrets: {} + # The key name and ENV name must match in the secrets file. + # @see https://grafana.com/docs/installation/configuration/#using-environment-variables + # For example: + # --- + # apiVersion: v1 + # kind: Secret + # metadata: + # name: grafana-secrets + # namespace: istio-system + # data: + # GF_SMTP_USER: bXl1c2Vy + # GF_SMTP_PASSWORD: bXlwYXNzd29yZA== + # type: Opaque + # --- + # env_variable_key_name: secretsName + # --- + # GF_SMTP_USER: grafana-secrets + # GF_SMTP_PASSWORD: grafana-secrets + + resources: {} + + prometheusNamespace: "" + + # Specify the pod anti-affinity that allows you to constrain which nodes + # your pod is eligible to be scheduled based on labels on pods that are + # already running on the node rather than based on labels on nodes. + # There are currently two types of anti-affinity: + # "requiredDuringSchedulingIgnoredDuringExecution" + # "preferredDuringSchedulingIgnoredDuringExecution" + # which denote "hard" vs. "soft" requirements, you can define your values + # in "podAntiAffinityLabelSelector" and "podAntiAffinityTermLabelSelector" + # correspondingly. + # For example: + # podAntiAffinityLabelSelector: + # - key: security + # operator: In + # values: S1,S2 + # topologyKey: "kubernetes.io/hostname" + # This pod anti-affinity rule says that the pod requires not to be scheduled + # onto a node if that node is already running a pod with label having key + # "security" and value "S1". + podAntiAffinityLabelSelector: [] + podAntiAffinityTermLabelSelector: [] diff --git a/resources/helm/v2.5/istio-telemetry/kiali/Chart.yaml b/resources/helm/v2.5/istio-telemetry/kiali/Chart.yaml new file mode 100644 index 0000000000..ab829b3171 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/kiali/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +description: Kiali is an open source project for service mesh observability, refer to https://www.kiali.io for details. +name: kiali +version: 1.18.0 +appVersion: 1.18.0 +tillerVersion: ">=2.7.2" +keywords: + - istio-addon diff --git a/resources/helm/v2.5/istio-telemetry/kiali/templates/kiali-cr.yaml b/resources/helm/v2.5/istio-telemetry/kiali/templates/kiali-cr.yaml new file mode 100644 index 0000000000..541e8c397a --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/kiali/templates/kiali-cr.yaml @@ -0,0 +1,149 @@ +{{- if .Values.kiali.install }} +apiVersion: kiali.io/v1alpha1 +kind: Kiali +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.kiali.resourceName | default "kiali" }} + namespace: {{ .Release.Namespace }} +spec: + version: "v1.65" + installation_tag: "Kiali [{{ .Release.Namespace }}]" + istio_namespace: "{{ .Release.Namespace }}" + + auth: + strategy: "openshift" + + deployment: + accessible_namespaces: [] +{{- if and .Values.kiali.hub .Values.kiali.image }} + image_name: "{{ .Values.kiali.hub }}/{{ .Values.kiali.image }}" +{{- end }} + image_pull_policy: "{{ .Values.global.imagePullPolicy }}" +{{- if .Values.global.imagePullSecrets }} + image_pull_secrets: +{{- range .Values.global.imagePullSecrets }} + - {{ . }} +{{- end }} +{{- end }} +{{- if .Values.kiali.ingress }} +{{- if .Values.kiali.ingress.enabled }} + ingress: + enabled: {{ .Values.kiali.ingress.enabled }} +{{- end }} +{{- end }} + namespace: "{{ .Release.Namespace }}" +{{- if .Values.kiali.dashboard }} +{{- if .Values.kiali.dashboard.viewOnlyMode }} + view_only_mode: {{ .Values.kiali.dashboard.viewOnlyMode }} +{{- end }} +{{- end }} + +{{- if or .Values.kiali.resources .Values.kiali.deployment_resources }} + resources: + {{- if .Values.kiali.resources}} +{{ toYaml .Values.kiali.resources | indent 6 }} + {{- else }} +{{ toYaml .Values.kiali.deployment_resources | indent 6 }} + {{- end }} +{{- end }} + +{{- if or .Values.kiali.tolerations .Values.kiali.deployment_tolerations .Values.global.defaultTolerations }} + tolerations: + {{- if .Values.kiali.tolerations }} +{{ toYaml .Values.kiali.tolerations | indent 6 }} + {{- else if .Values.kiali.deployment_tolerations }} +{{ toYaml .Values.kiali.deployment_tolerations | indent 6 }} + {{- else }} +{{ toYaml .Values.global.defaultTolerations | indent 6 }} + {{- end }} +{{- end }} + +{{- if or .Values.kiali.nodeSelector .Values.kiali.deployment_nodeSelector .Values.global.defaultNodeSelector }} + node_selector: + {{- if .Values.kiali.nodeSelector }} +{{ toYaml .Values.kiali.nodeSelector | indent 6 }} + {{- else if .Values.kiali.deployment_nodeSelector }} +{{ toYaml .Values.kiali.deployment_nodeSelector | indent 6 }} + {{- else }} +{{ toYaml .Values.global.defaultNodeSelector | indent 6 }} + {{- end }} +{{- end }} + + pod_labels: + sidecar.istio.io/inject: "false" + +{{- if or .Values.kiali.affinity .Values.kiali.deployment_affinity }} + affinity: + {{- if .Values.kiali.affinity }} + {{- if .Values.kiali.affinity.nodeAffinity }} + node: +{{ toYaml .Values.kiali.affinity.nodeAffinity | indent 8 }} + {{- end }} + {{- if .Values.kiali.affinity.podAffinity }} + pod: +{{ toYaml .Values.kiali.affinity.podAffinity | indent 8 }} + {{- end }} + {{- if .Values.kiali.affinity.podAntiAffinity }} + pod_anti: +{{ toYaml .Values.kiali.affinity.podAntiAffinity | indent 8 }} + {{- end }} + {{- else }} +{{ toYaml .Values.kiali.deployment_affinity | indent 6 }} + {{- end }} +{{- end }} + + external_services: + custom_dashboards: + namespace_label: kubernetes_namespace + istio: + config_map_name: istio-{{ .Values.revision | default "default" }} + url_service_version: http://istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}:15014/version + istiod_deployment_name: istiod-{{ .Values.revision | default "default" }} + istio_sidecar_injector_config_map_name: istio-sidecar-injector-{{ .Values.revision | default "default" }} + grafana: + auth: + type: "basic" + use_kiali_token: false + username: "internal" + password: "" + enabled: true + in_cluster_url: "https://grafana.{{ .Release.Namespace }}.svc:3000" +{{- if .Values.kiali.dashboard }} +{{- if .Values.kiali.dashboard.grafanaURL }} + url: "{{ .Values.kiali.dashboard.grafanaURL }}" +{{- end }} +{{- end }} + prometheus: + auth: + type: "basic" + use_kiali_token: false + username: "internal" + password: "" + url: "https://prometheus.{{ .Release.Namespace }}.svc:9090" + tracing: + auth: + type: "basic" + use_kiali_token: false + username: "internal" + password: "" + enabled: true +{{- if .Values.kiali.jaegerInClusterURL }} + in_cluster_url: "{{ .Values.kiali.jaegerInClusterURL }}" +{{- else }} + in_cluster_url: "https://{{ .Values.tracing.jaeger.resourceName | default "jaeger" }}-query.{{ .Release.Namespace }}.svc" +{{- end }} + namespace: "{{ .Release.Namespace }}" + service : "" +{{- if .Values.kiali.dashboard }} +{{- if .Values.kiali.dashboard.jaegerURL }} + url: "{{ .Values.kiali.dashboard.jaegerURL }}" +{{- end }} +{{- end }} + use_grpc: false + +{{- if .Values.kiali.contextPath }} + server: + web_root: "{{ .Values.kiali.contextPath }}" +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/kiali/templates/networkpolicy.yaml b/resources/helm/v2.5/istio-telemetry/kiali/templates/networkpolicy.yaml new file mode 100644 index 0000000000..891290e70c --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/kiali/templates/networkpolicy.yaml @@ -0,0 +1,19 @@ +# This is to support routes on ocp 3.11 installs +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-kiali-ingress + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: kiali + release: {{ .Release.Name }} + annotations: + "maistra.io/internal": "true" +spec: + podSelector: + matchLabels: + app: kiali + ingress: + - ports: + port: 20001 diff --git a/resources/helm/v2.5/istio-telemetry/kiali/values.yaml b/resources/helm/v2.5/istio-telemetry/kiali/values.yaml new file mode 100644 index 0000000000..cae701eb98 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/kiali/values.yaml @@ -0,0 +1,2 @@ +kiali: + install: false \ No newline at end of file diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/Chart.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/Chart.yaml new file mode 100644 index 0000000000..cea934b9a6 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +description: A Helm chart for Kubernetes +name: prometheus +version: 1.1.0 +appVersion: 2.8.0 +tillerVersion: ">=2.7.2" +keywords: + - istio-addon diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/_affinity.tpl b/resources/helm/v2.5/istio-telemetry/prometheus/templates/_affinity.tpl new file mode 100644 index 0000000000..ac4dc9c42c --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/_affinity.tpl @@ -0,0 +1,93 @@ +{{/* affinity - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ */}} + +{{- define "nodeaffinity" }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityRequiredDuringScheduling" . }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityPreferredDuringScheduling" . }} +{{- end }} + +{{- define "nodeAffinityRequiredDuringScheduling" }} + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + {{- range $key, $val := .Values.global.arch }} + {{- if gt ($val | int) 0 }} + - {{ $key | quote }} + {{- end }} + {{- end }} + {{- $nodeSelector := default .Values.global.defaultNodeSelector .Values.prometheus.nodeSelector -}} + {{- range $key, $val := $nodeSelector }} + - key: {{ $key }} + operator: In + values: + - {{ $val | quote }} + {{- end }} +{{- end }} + +{{- define "nodeAffinityPreferredDuringScheduling" }} + {{- range $key, $val := .Values.global.arch }} + {{- if gt ($val | int) 0 }} + - weight: {{ $val | int }} + preference: + matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - {{ $key | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinity" }} +{{- if or .Values.prometheus.podAntiAffinityLabelSelector .Values.prometheus.podAntiAffinityTermLabelSelector}} + podAntiAffinity: + {{- if .Values.prometheus.podAntiAffinityLabelSelector }} + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityRequiredDuringScheduling" . }} + {{- end }} + {{- if .Values.prometheus.podAntiAffinityTermLabelSelector }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityPreferredDuringScheduling" . }} + {{- end }} +{{- end }} +{{- end }} + +{{- define "podAntiAffinityRequiredDuringScheduling" }} + {{- range $index, $item := .Values.prometheus.podAntiAffinityLabelSelector }} + - labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinityPreferredDuringScheduling" }} + {{- range $index, $item := .Values.prometheus.podAntiAffinityTermLabelSelector }} + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + weight: 100 + {{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/_sd_namespace.tpl b/resources/helm/v2.5/istio-telemetry/prometheus/templates/_sd_namespace.tpl new file mode 100644 index 0000000000..086eaa9510 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/_sd_namespace.tpl @@ -0,0 +1,8 @@ +{{- define "sdNamespaces" }} +namespaces: + names: + - {{ .Values.global.istioNamespace }} +{{- if gt (len .Values.prometheus.scrapingNamespaces) 0 }} +{{ toYaml .Values.prometheus.scrapingNamespaces | indent 2 }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/clusterrole.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/clusterrole.yaml new file mode 100644 index 0000000000..6e6ce35541 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/clusterrole.yaml @@ -0,0 +1,24 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: prometheus-{{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} +rules: +- apiGroups: ["maistra.io"] + resources: ["servicemeshmemberrolls"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: + - services + - endpoints + - pods + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: + - configmaps + verbs: ["get"] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/clusterrolebindings.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/clusterrolebindings.yaml new file mode 100644 index 0000000000..9c784dda67 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/clusterrolebindings.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: prometheus-{{ .Release.Namespace }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: prometheus-{{ .Release.Namespace }} +subjects: +- kind: ServiceAccount + name: prometheus + namespace: {{ .Release.Namespace }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/configmap.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/configmap.yaml new file mode 100644 index 0000000000..12940a7d09 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/configmap.yaml @@ -0,0 +1,353 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: prometheus + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} +data: + prometheus.yml: |- + global: + evaluation_interval: 1m + scrape_interval: {{ .Values.prometheus.scrapeInterval }} + scrape_timeout: 10s + rule_files: + - /etc/config/recording_rules.yml + - /etc/config/alerting_rules.yml + - /etc/config/rules + - /etc/config/alerts + scrape_configs: + - job_name: prometheus + static_configs: + - targets: + - localhost:9090 + +{{- if not .Values.meshConfig.enablePrometheusMerge }} + # Scrape config for envoy stats + - job_name: 'envoy-stats' + metrics_path: /stats/prometheus + kubernetes_sd_configs: + - role: pod + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: + - source_labels: [__meta_kubernetes_pod_container_port_name] + action: keep + regex: '.*-envoy-prom' + - source_labels: [__meta_kubernetes_pod_ip] + action: replace + regex: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}) + replacement: '[$1]:15090' + target_label: __address__ + - source_labels: [__meta_kubernetes_pod_ip] + action: replace + regex: ((([0-9]+?)(\.|$)){4}) + replacement: $1:15090 + - action: labeldrop + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + + - job_name: 'pilot' + kubernetes_sd_configs: + - role: endpoints + namespaces: + names: + - {{ .Release.Namespace }} + relabel_configs: + - source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: istiod.*;http-monitoring + - source_labels: [__meta_kubernetes_service_label_app] + target_label: app +{{- end }} + + # scrape config for API servers + # config removed + # scrape config for nodes (kubelet) + # config removed + # Scrape config for Kubelet cAdvisor. + # + # This is required for Kubernetes 1.7.3 and later, where cAdvisor metrics + # (those whose names begin with 'container_') have been removed from the + # Kubelet metrics endpoint. This job scrapes the cAdvisor endpoint to + # retrieve those metrics. + # + # In Kubernetes 1.7.0-1.7.2, these metrics are only exposed on the cAdvisor + # HTTP endpoint; use "replacement: /api/v1/nodes/${1}:4194/proxy/metrics" + # in that case (and ensure cAdvisor's HTTP server hasn't been disabled with + # the --cadvisor-port=0 Kubelet flag). + # + # This job is not necessary and should be removed in Kubernetes 1.6 and + # earlier versions, or it will cause the metrics to be scraped twice. + # config removed + + # scrape config for service endpoints. + - job_name: kubernetes-service-endpoints + kubernetes_sd_configs: + - role: endpoints + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scrape + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: kubernetes_node + # MAISTRA-748: Exclude scraping of prometheus itself on the oauth port + - action: drop + source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_pod_container_port_number] + regex: prometheus;3001 + + - job_name: kubernetes-service-endpoints-slow + kubernetes_sd_configs: + - role: endpoints + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scrape_slow + - action: replace + regex: (https?) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_scheme + target_label: __scheme__ + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_path + target_label: __metrics_path__ + - action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + source_labels: + - __address__ + - __meta_kubernetes_service_annotation_prometheus_io_port + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: kubernetes_node + # MAISTRA-748: Exclude scraping of prometheus itself on the oauth port + - action: drop + source_labels: [__meta_kubernetes_service_name, __meta_kubernetes_pod_container_port_number] + regex: prometheus;3001 + scrape_interval: 5m + scrape_timeout: 30s + + - honor_labels: true + job_name: prometheus-pushgateway + kubernetes_sd_configs: + - role: service + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: + - action: keep + regex: pushgateway + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_probe + + - job_name: kubernetes-services + kubernetes_sd_configs: + - role: service + {{- include "sdNamespaces" . | indent 8 }} + metrics_path: /probe + params: + module: + - http_2xx + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_service_annotation_prometheus_io_probe + - source_labels: + - __address__ + target_label: __param_target + - replacement: blackbox + target_label: __address__ + - source_labels: + - __param_target + target_label: instance + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - source_labels: + - __meta_kubernetes_service_name + target_label: kubernetes_name + + - job_name: 'kubernetes-pods' + kubernetes_sd_configs: + - role: pod + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: # If first two labels are present, pod should be scraped by the istio-secure job. + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true +{{- if and .Values.prometheus.provisionPrometheusCert (not .Values.meshConfig.enablePrometheusMerge) }} + - source_labels: [__meta_kubernetes_pod_annotation_sidecar_istio_io_status] + action: drop + regex: (.+) + - source_labels: [__meta_kubernetes_pod_annotation_istio_mtls] + action: drop + regex: (true) +{{- end }} + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip] + action: replace + regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}) + replacement: '[$2]:$1' + target_label: __address__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip] + action: replace + regex: (\d+);((([0-9]+?)(\.|$)){4}) + replacement: $2:$1 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name + - action: drop + regex: Pending|Succeeded|Failed + source_labels: + - __meta_kubernetes_pod_phase + + - job_name: kubernetes-pods-slow + kubernetes_sd_configs: + - role: pod + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: + - action: keep + regex: true + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_scrape_slow + - action: replace + regex: (.+) + source_labels: + - __meta_kubernetes_pod_annotation_prometheus_io_path + target_label: __metrics_path__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip] + action: replace + regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}) + replacement: '[$2]:$1' + target_label: __address__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip] + action: replace + regex: (\d+);((([0-9]+?)(\.|$)){4}) + replacement: $2:$1 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: kubernetes_namespace + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: kubernetes_pod_name + - action: drop + regex: Pending|Succeeded|Failed + source_labels: + - __meta_kubernetes_pod_phase + scrape_interval: 5m + scrape_timeout: 30s + +{{- if and .Values.prometheus.provisionPrometheusCert (not .Values.meshConfig.enablePrometheusMerge) }} + - job_name: 'kubernetes-pods-istio-secure' + scheme: https + tls_config: + ca_file: /etc/istio-certs/root-cert.pem + cert_file: /etc/istio-certs/cert-chain.pem + key_file: /etc/istio-certs/key.pem + insecure_skip_verify: true # prometheus does not support secure naming. + kubernetes_sd_configs: + - role: pod + {{- include "sdNamespaces" . | indent 8 }} + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + # sidecar status annotation is added by sidecar injector and + # istio_workload_mtls_ability can be specifically placed on a pod to indicate its ability to receive mtls traffic. + - source_labels: [__meta_kubernetes_pod_annotation_sidecar_istio_io_status, __meta_kubernetes_pod_annotation_istio_mtls] + action: keep + regex: (([^;]+);([^;]*))|(([^;]*);(true)) + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__] # Only keep address that is host:port + action: keep # otherwise an extra target with ':443' is added for https scheme + regex: ([^:]+):(\d+) + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip] + action: replace + regex: (\d+);(([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}) + replacement: '[$2]:$1' + target_label: __address__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_ip] + action: replace + regex: (\d+);((([0-9]+?)(\.|$)){4}) + replacement: $2:$1 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: kubernetes_namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: kubernetes_pod_name +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/deployment.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/deployment.yaml new file mode 100644 index 0000000000..594a8eade2 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/deployment.yaml @@ -0,0 +1,411 @@ +# TODO: the original template has service account, roles, etc +apiVersion: apps/v1 +kind: Deployment +metadata: + name: prometheus + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} +spec: + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + replicas: {{ .Values.prometheus.replicaCount }} + selector: + matchLabels: + app: prometheus + template: + metadata: + labels: + maistra-control-plane: {{ .Release.Namespace }} + app: prometheus + release: {{ .Release.Name }} + annotations: + sidecar.istio.io/inject: "false" + {{- if .Values.prometheus.podAnnotations }} +{{ toYaml .Values.prometheus.podAnnotations | indent 8 }} + {{- end }} + spec: +{{- if .Values.global.priorityClassName }} + priorityClassName: "{{ .Values.global.priorityClassName }}" +{{- end }} + serviceAccountName: prometheus + initContainers: + - name: init-config-reloader +{{- if contains "/" .Values.prometheusConfigReloader.image }} + image: "{{ .Values.prometheusConfigReloader.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.prometheusConfigReloader.image }}:{{ .Values.global.tag }}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + args: + - '--watch-interval=0' + - '--reload-url=http://localhost:9090/-/reload' + - '--config-file=/etc/prometheus/config/prometheus.yml' + command: + - /bin/prometheus-config-reloader + resources: +{{- if .Values.prometheusConfigReloader.resources }} +{{ toYaml .Values.prometheusConfigReloader.resources | indent 12 }} +{{- else }} + limits: + cpu: 100m + memory: 50Mi + requests: + cpu: 100m + memory: 50Mi +{{- end }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - name: config-volume + mountPath: /etc/prometheus/config + containers: + # OAuth proxy + - name: prometheus-proxy +{{- if contains "/" .Values.global.oauthproxy.image }} + image: {{ .Values.global.oauthproxy.image }} +{{- else }} + image: {{ .Values.global.oauthproxy.hub }}/{{ .Values.global.oauthproxy.image }}:{{ .Values.global.oauthproxy.tag }} +{{- end }} + imagePullPolicy: {{ .Values.global.oauthproxy.imagePullPolicy }} + ports: + - containerPort: 3001 + name: https + protocol: TCP + readinessProbe: + failureThreshold: 3 + periodSeconds: 10 + successThreshold: 1 + httpGet: + path: /oauth/healthz + port: https + scheme: HTTPS + timeoutSeconds: 1 + resources: +{{- if .Values.global.oauthproxy.resources }} +{{ toYaml .Values.global.oauthproxy.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /etc/tls/private + name: secret-prometheus-tls + - mountPath: /etc/proxy/htpasswd + name: secret-htpasswd + - mountPath: /etc/proxy/secrets + name: secret-prometheus-proxy + - mountPath: /etc/pki/ca-trust/extracted/pem/ + name: trusted-ca-bundle + readOnly: true + args: + - -provider=openshift + - -https-address=:3001 + - -http-address= + - -email-domain=* + - -upstream=http://localhost:9090 + - -htpasswd-file=/etc/proxy/htpasswd/auth + - -display-htpasswd-form=false + - '-openshift-sar={"namespace": "{{ .Release.Namespace }}", "resource": "pods", "verb": "get"}' + - -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token + - -openshift-service-account=prometheus + - -cookie-secret-file=/etc/proxy/secrets/session_secret + - -tls-cert=/etc/tls/private/tls.crt + - -tls-key=/etc/tls/private/tls.key + - -openshift-ca=/etc/pki/tls/cert.pem + - -openshift-ca=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt + - name: prometheus +{{- if contains "/" .Values.prometheus.image }} + image: "{{ .Values.prometheus.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.prometheus.image }}:{{ .Values.global.tag }}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + args: + - '--storage.tsdb.retention.time={{ .Values.prometheus.retention }}' + - '--storage.tsdb.path=/prometheus' + - '--config.file=/etc/prometheus/config/prometheus.yml' + - '--web.enable-lifecycle' + ports: + - containerPort: 9090 + name: web + protocol: TCP + livenessProbe: + httpGet: + path: /-/healthy + port: web + scheme: HTTP + readinessProbe: + httpGet: + path: /-/ready + port: web + scheme: HTTP + timeoutSeconds: 3 + periodSeconds: 5 + successThreshold: 1 + failureThreshold: 3 + startupProbe: + httpGet: + path: /-/ready + port: web + scheme: HTTP + timeoutSeconds: 3 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 60 + resources: +{{- if .Values.prometheus.resources }} +{{ toYaml .Values.prometheus.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + volumeMounts: + - name: config-volume + mountPath: /etc/prometheus/config + - name: prometheus-db-volume + mountPath: /prometheus + {{- if and .Values.prometheus.provisionPrometheusCert (not .Values.meshConfig.enablePrometheusMerge) }} + - mountPath: /etc/istio-certs + name: istio-certs + {{- end }} + - name: config-reloader +{{- if contains "/" .Values.prometheusConfigReloader.image }} + image: "{{ .Values.prometheusConfigReloader.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.prometheusConfigReloader.image }}:{{ .Values.global.tag }}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + args: + - "--watch-interval={{ .Values.prometheus.configReloadInterval }}" + - '--reload-url=http://localhost:9090/-/reload' + - '--config-file=/etc/prometheus/config/prometheus.yml' + command: + - /bin/prometheus-config-reloader + resources: +{{- if .Values.prometheusConfigReloader.resources }} +{{ toYaml .Values.prometheusConfigReloader.resources | indent 12 }} +{{- else }} + limits: + cpu: 100m + memory: 50Mi + requests: + cpu: 100m + memory: 50Mi +{{- end }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - name: config-volume + mountPath: /etc/prometheus/config +{{- if and .Values.prometheus.provisionPrometheusCert (not .Values.meshConfig.enablePrometheusMerge) }} + - name: istio-proxy +{{- if contains "/" .Values.global.proxy.image }} + image: "{{ .Values.global.proxy.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.global.proxy.image | default "proxyv2" }}:{{ .Values.global.tag }}" +{{- end }} + ports: + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - "istio-proxy-prometheus" + {{- if .Values.global.proxy.logLevel }} + - --proxyLogLevel={{ .Values.global.proxy.logLevel }} + {{- end}} + {{- if .Values.global.proxy.componentLogLevel }} + - --proxyComponentLogLevel={{ .Values.global.proxy.componentLogLevel }} + {{- end}} + - --controlPlaneAuthPolicy + - NONE + {{- if .Values.global.trustDomain }} + - --trust-domain={{ .Values.global.trustDomain }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + env: + - name: OUTPUT_CERTS + value: "/etc/istio-certs" + - name: JWT_POLICY + value: {{ .Values.global.jwtPolicy }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + # Temp, pending PR to make it default or based on the istiodAddr env + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod-{{ .Values.revision | default "default" }}.{{ .Release.Namespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if .Values.global.trustDomain }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.trustDomain }}" + {{- end }} + - name: ISTIO_META_CLUSTER_ID + value: "{{ .Values.global.multiCluster.clusterName | default `Kubernetes` }}" + {{- range $key, $value := .Values.meshConfig.defaultConfig.proxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + imagePullPolicy: {{ .Values.global.imagePullPolicy | default "Always" }} + readinessProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15020 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 2 + successThreshold: 1 + timeoutSeconds: 1 + resources: +{{- if .Values.global.proxy.resources }} +{{ toYaml .Values.global.proxy.resources | indent 12 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 12 }} +{{- end }} + volumeMounts: + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /etc/istio/proxy + name: istio-envoy + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- end }} + - mountPath: /etc/istio-certs/ + name: istio-certs + - name: istio-config-volume + mountPath: /etc/istio/config +{{- end }} + + volumes: + # OAuth proxy + - name: secret-prometheus-tls + secret: + defaultMode: 420 + secretName: prometheus-tls + - name: secret-htpasswd + secret: + items: + - key: auth + path: auth + defaultMode: 420 + secretName: htpasswd + - name: secret-prometheus-proxy + secret: + defaultMode: 420 + secretName: prometheus-proxy + - name: trusted-ca-bundle + configMap: + defaultMode: 420 + items: + - key: ca-bundle.crt + path: tls-ca-bundle.pem + name: trusted-ca-bundle + optional: true + - name: istio-config-volume + configMap: + name: istio-{{ .Values.revision | default "default" }} + optional: true + - name: config-volume + configMap: + name: prometheus + - name: prometheus-db-volume + emptyDir: {} + +{{- if and .Values.prometheus.provisionPrometheusCert (not .Values.meshConfig.enablePrometheusMerge) }} + - name: istio-certs + emptyDir: + medium: Memory +{{- end }} + +{{- if and .Values.prometheus.provisionPrometheusCert (not .Values.meshConfig.enablePrometheusMerge) }} + - emptyDir: + medium: Memory + name: istio-envoy + {{- if eq .Values.global.jwtPolicy "third-party-jwt" }} + - name: istio-token + projected: + defaultMode: 420 + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + defaultMode: 420 + name: {{ .Values.global.caCertConfigMapName }} + {{- end }} +{{- end }} + + affinity: + {{- include "nodeaffinity" . | indent 6 }} + {{- include "podAntiAffinity" . | indent 6 }} +{{- if .Values.prometheus.tolerations }} + tolerations: +{{ toYaml .Values.prometheus.tolerations | indent 6 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 6 }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/ingress.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/ingress.yaml new file mode 100644 index 0000000000..0d7e800426 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/ingress.yaml @@ -0,0 +1,28 @@ +{{- if .Values.prometheus.ingress.enabled -}} +{{- range $index, $host := .Values.prometheus.ingress.hosts }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: prometheus{{ if gt $index 0 }}-{{ $index }}{{ end }} + namespace: {{ $.Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ $.Release.Name }} +{{- if gt (len $.Values.prometheus.ingress.annotations) 0 }} + annotations: +{{- range $key, $value := $.Values.prometheus.ingress.annotations }} + {{ $key }}: {{ $value | quote }} +{{- end }} +{{- end }} +spec: + host: {{ $host }} + to: + kind: Service + name: prometheus + tls: + termination: reencrypt + insecureEdgeTerminationPolicy: Redirect +--- +{{- end }} +{{- end -}} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/networkpolicy.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/networkpolicy.yaml new file mode 100644 index 0000000000..6a2fc69c32 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/networkpolicy.yaml @@ -0,0 +1,19 @@ +# This is to support routes on ocp 3.11 installs +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-prometheus-ingress + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} + annotations: + "maistra.io/internal": "true" +spec: + podSelector: + matchLabels: + app: prometheus + ingress: + - ports: + port: 3001 diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/secrets.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/secrets.yaml new file mode 100644 index 0000000000..a1d0425f2b --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/secrets.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +data: + session_secret: "" +kind: Secret +metadata: + name: prometheus-proxy + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +type: Opaque diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/service.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/service.yaml new file mode 100644 index 0000000000..bb901ae3a2 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/service.yaml @@ -0,0 +1,50 @@ +apiVersion: v1 +kind: Service +metadata: + name: prometheus + namespace: {{ .Release.Namespace }} + annotations: + prometheus.io/scrape: 'true' + {{- if .Values.prometheus.service }} + {{- range $key, $val := .Values.prometheus.service.annotations }} + {{ $key }}: {{ $val | quote }} + {{- end }} + {{- end }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} +spec: + selector: + app: prometheus + ports: + - name: http-prometheus + protocol: TCP + port: 9090 + targetPort: 3001 + +{{- if .Values.prometheus.service.nodePort }} +{{- if .Values.prometheus.service.nodePort.enabled }} +# Using separate ingress for nodeport, to avoid conflict with pilot e2e test configs. +--- +apiVersion: v1 +kind: Service +metadata: + name: prometheus-nodeport + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + maistra-version: "2.0.1.1" + app: prometheus + release: {{ .Release.Name }} +spec: + type: NodePort + ports: + - port: 9090 + targetPort: 3001 + nodePort: {{ .Values.prometheus.service.nodePort.port }} + name: http-prometheus + selector: + app: prometheus +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/templates/serviceaccount.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/templates/serviceaccount.yaml new file mode 100644 index 0000000000..38c65d7e5d --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ServiceAccount +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +metadata: + name: prometheus + annotations: + serviceaccounts.openshift.io/oauth-redirectreference.primary: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"prometheus"}}' + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: prometheus + release: {{ .Release.Name }} diff --git a/resources/helm/v2.5/istio-telemetry/prometheus/values.yaml b/resources/helm/v2.5/istio-telemetry/prometheus/values.yaml new file mode 100644 index 0000000000..07fd1c8ec1 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/prometheus/values.yaml @@ -0,0 +1,119 @@ +global: + # ImagePullSecrets for control plane ServiceAccount, list of secrets in the same namespace + # to use for pulling any images in pods that reference this ServiceAccount. + # Must be set for any cluster configured with private docker registry. + imagePullSecrets: [] + + oauthproxy: + image: registry.redhat.io/openshift4/ose-oauth-proxy:latest + + proxy: + image: proxyv2 + + multiCluster: + # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection + # to properly label proxies + clusterName: "" + + # Configure the certificate provider for control plane communication. + # Currently, two providers are supported: "kubernetes" and "istiod". + # As some platforms may not have kubernetes signing APIs, + # Istiod is the default + pilotCertProvider: istiod + + sds: + # The JWT token for SDS and the aud field of such JWT. See RFC 7519, section 4.1.3. + # When a CSR is sent from Istio Agent to the CA (e.g. Istiod), this aud is to make sure the + # JWT is intended for the CA. + token: + aud: istio-ca + + # Configure the policy for validating JWT. + # Currently, two options are supported: "third-party-jwt" and "first-party-jwt". + jwtPolicy: "third-party-jwt" + + # A minimal set of requested resources to applied to all deployments so that + # Horizontal Pod Autoscaler will be able to function (if set). + # Each component can overwrite these default values by adding its own resources + # block in the relevant section below and setting the desired resources values. + defaultResources: + requests: + cpu: 10m + # memory: 128Mi + # limits: + # cpu: 100m + # memory: 128Mi + +meshConfig: + enablePrometheusMerge: false + defaultConfig: + proxyMetadata: {} + +prometheus: + enabled: true + ingress: + hosts: [""] + annotations: {} + enabled: false + replicaCount: 1 + hub: docker.io/prom + image: prometheus + tag: v2.21.0 + retention: 6h + + # Controls the frequency of prometheus scraping + scrapeInterval: 15s + # Controls how often the Prometheus reloader will try to trigger configuration changes + configReloadInterval: 10s + + contextPath: /prometheus + + # 1.2 it is disabled by default - it can be enabled for special cases, but would create port + # conflicts. In general it is not recommended to use node ports for services, but use gateways instead. +# service: +# annotations: {} +# nodePort: +# enabled: false +# port: 32090 + + nodeSelector: {} + tolerations: [] + podAnnotations: {} + service: {} + resources: {} + datasources: [] + # Specify the pod anti-affinity that allows you to constrain which nodes + # your pod is eligible to be scheduled based on labels on pods that are + # already running on the node rather than based on labels on nodes. + # There are currently two types of anti-affinity: + # "requiredDuringSchedulingIgnoredDuringExecution" + # "preferredDuringSchedulingIgnoredDuringExecution" + # which denote "hard" vs. "soft" requirements, you can define your values + # in "podAntiAffinityLabelSelector" and "podAntiAffinityTermLabelSelector" + # correspondingly. + # For example: + # podAntiAffinityLabelSelector: + # - key: security + # operator: In + # values: S1,S2 + # topologyKey: "kubernetes.io/hostname" + # This pod anti-affinity rule says that the pod requires not to be scheduled + # onto a node if that node is already running a pod with label having key + # "security" and value "S1". + podAntiAffinityLabelSelector: [] + podAntiAffinityTermLabelSelector: [] + + # Configure whether provisions a certificate to Prometheus through Istio Agent. + # When this option is set as true, a sidecar is deployed along Prometheus to + # provision a certificate through Istio Agent to Prometheus. The provisioned certificate + # is shared with Prometheus through mounted files. + # When this option is set as false, this certificate provisioning mechanism is disabled. + provisionPrometheusCert: true + + scrapingNamespaces: [] + +prometheusConfigReloader: + image: quay.io/prometheus-operator/prometheus-config-reloader:v0.63.0 + resources: {} + +revision: "" \ No newline at end of file diff --git a/resources/helm/v2.5/istio-telemetry/telemetry-common/Chart.yaml b/resources/helm/v2.5/istio-telemetry/telemetry-common/Chart.yaml new file mode 100644 index 0000000000..d94d8048e6 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/telemetry-common/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +name: telemetry-common +version: 1.1.0 +appVersion: 1.1.0 +tillerVersion: ">=2.7.2" +description: Helm chart for common istio telemetry resources +keywords: + - istio +sources: + - http://github.com/maistra/istio +engine: gotpl +icon: https://istio.io/favicons/android-192x192.png diff --git a/resources/helm/v2.5/istio-telemetry/telemetry-common/templates/htpasswd-secret.yaml b/resources/helm/v2.5/istio-telemetry/telemetry-common/templates/htpasswd-secret.yaml new file mode 100644 index 0000000000..60f21bd491 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/telemetry-common/templates/htpasswd-secret.yaml @@ -0,0 +1,15 @@ +{{- if or .Values.tracing.enabled .Values.grafana.enabled .Values.prometheus.enabled .Values.kiali.enabled }} +apiVersion: v1 +data: + auth: "" + rawPassword: "" +kind: Secret +metadata: + name: htpasswd + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +type: Opaque +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/telemetry-common/templates/trusted-ca-bundle-cm.yaml b/resources/helm/v2.5/istio-telemetry/telemetry-common/templates/trusted-ca-bundle-cm.yaml new file mode 100644 index 0000000000..11bb3f1870 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/telemetry-common/templates/trusted-ca-bundle-cm.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: trusted-ca-bundle + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} + config.openshift.io/inject-trusted-cabundle: "true" diff --git a/resources/helm/v2.5/istio-telemetry/telemetry-common/values.yaml b/resources/helm/v2.5/istio-telemetry/telemetry-common/values.yaml new file mode 100644 index 0000000000..e2e5a2313b --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/telemetry-common/values.yaml @@ -0,0 +1,11 @@ +kiali: + enabled: false + +tracing: + enabled: false + +grafana: + enabled: false + +prometheus: + enabled: false \ No newline at end of file diff --git a/resources/helm/v2.5/istio-telemetry/tracing/Chart.yaml b/resources/helm/v2.5/istio-telemetry/tracing/Chart.yaml new file mode 100644 index 0000000000..4a29e471ab --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +description: A Helm chart for tracing +name: tracing +version: 1.1.0 +appVersion: 1.5.1 +tillerVersion: ">=2.7.2" +keywords: + - istio-addon diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/_affinity.tpl b/resources/helm/v2.5/istio-telemetry/tracing/templates/_affinity.tpl new file mode 100644 index 0000000000..d91f409aab --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/_affinity.tpl @@ -0,0 +1,93 @@ +{{/* affinity - https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ */}} + +{{- define "nodeaffinity" }} + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityRequiredDuringScheduling" . }} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "nodeAffinityPreferredDuringScheduling" . }} +{{- end }} + +{{- define "nodeAffinityRequiredDuringScheduling" }} + nodeSelectorTerms: + - matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + {{- range $key, $val := .Values.global.arch }} + {{- if gt ($val | int) 0 }} + - {{ $key | quote }} + {{- end }} + {{- end }} + {{- $nodeSelector := default .Values.global.defaultNodeSelector .Values.tracing.nodeSelector -}} + {{- range $key, $val := $nodeSelector }} + - key: {{ $key }} + operator: In + values: + - {{ $val | quote }} + {{- end }} +{{- end }} + +{{- define "nodeAffinityPreferredDuringScheduling" }} + {{- range $key, $val := .Values.global.arch }} + {{- if gt ($val | int) 0 }} + - weight: {{ $val | int }} + preference: + matchExpressions: + - key: beta.kubernetes.io/arch + operator: In + values: + - {{ $key | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinity" }} +{{- if or .Values.tracing.podAntiAffinityLabelSelector .Values.tracing.podAntiAffinityTermLabelSelector}} + podAntiAffinity: + {{- if .Values.tracing.podAntiAffinityLabelSelector }} + requiredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityRequiredDuringScheduling" . }} + {{- end }} + {{- if or .Values.tracing.podAntiAffinityTermLabelSelector}} + preferredDuringSchedulingIgnoredDuringExecution: + {{- include "podAntiAffinityPreferredDuringScheduling" . }} + {{- end }} +{{- end }} +{{- end }} + +{{- define "podAntiAffinityRequiredDuringScheduling" }} + {{- range $index, $item := .Values.tracing.podAntiAffinityLabelSelector }} + - labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + {{- end }} +{{- end }} + +{{- define "podAntiAffinityPreferredDuringScheduling" }} + {{- range $index, $item := .Values.tracing.podAntiAffinityTermLabelSelector }} + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: {{ $item.key }} + operator: {{ $item.operator }} + {{- if $item.values }} + values: + {{- $vals := split "," $item.values }} + {{- range $i, $v := $vals }} + - {{ $v | quote }} + {{- end }} + {{- end }} + topologyKey: {{ $item.topologyKey }} + weight: 100 + {{- end }} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/jaeger-all-in-one.yaml b/resources/helm/v2.5/istio-telemetry/tracing/templates/jaeger-all-in-one.yaml new file mode 100644 index 0000000000..5216a5a57a --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/jaeger-all-in-one.yaml @@ -0,0 +1,93 @@ +{{ if and (eq .Values.tracing.provider "jaeger") (eq .Values.tracing.jaeger.template "all-in-one") .Values.tracing.jaeger.install }} +apiVersion: jaegertracing.io/v1 +kind: "Jaeger" +metadata: + name: {{ .Values.tracing.jaeger.resourceName | default "jaeger" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} +spec: + strategy: allInOne + + allInOne: + {{- if and .Values.tracing.jaeger.hub .Values.tracing.jaeger.tag .Values.tracing.jaeger.allInOneImage }} + image: {{ .Values.tracing.jaeger.hub }}/{{ .Values.tracing.jaeger.allInOneImage }}:{{ .Values.tracing.jaeger.tag }} + {{- end }} + options: + log-level: debug + query: + base-path: / + +{{- if and .Values.tracing.jaeger.hub .Values.tracing.jaeger.tag .Values.tracing.jaeger.agentImage }} + agent: + image: {{ .Values.tracing.jaeger.hub }}/{{ .Values.tracing.jaeger.agentImage }}:{{ .Values.tracing.jaeger.tag }} +{{- end }} + +{{- if .Values.tracing.jaeger.annotations }} + annotations: + {{- range $key, $value := .Values.tracing.jaeger.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + + storage: + options: + memory: + {{- if .Values.tracing.jaeger.memory.max_traces }} + max-traces: {{ .Values.tracing.jaeger.memory.max_traces }} + {{- else }} + max-traces: 100000 + {{- end }} + + ingress: + enabled: {{ .Values.tracing.ingress.enabled }} + # XXX: should this be parameterized? + security: oauth-proxy +{{- if .Values.tracing.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.tracing.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + openshift: + sar: '{"namespace": "{{ .Release.Namespace }}", "resource": "pods", "verb": "get"}' + htpasswdFile: /etc/proxy/htpasswd/auth + + volumeMounts: + - name: secret-htpasswd + mountPath: /etc/proxy/htpasswd + - name: trusted-ca-bundle + mountPath: /etc/pki/ca-trust/extracted/pem/ + readOnly: true + volumes: + - name: secret-htpasswd + secret: + secretName: htpasswd + - name: trusted-ca-bundle + configMap: + defaultMode: 420 + items: + - key: ca-bundle.crt + path: tls-ca-bundle.pem + name: trusted-ca-bundle + optional: true + resources: +{{- if .Values.tracing.jaeger.resources }} +{{ toYaml .Values.tracing.jaeger.resources | indent 4 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 4 }} +{{- end }} + affinity: + {{- include "nodeaffinity" . | indent 2 }} + +{{- if .Values.tracing.tolerations }} + tolerations: +{{ toYaml .Values.tracing.tolerations | indent 4 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 4 }} +{{- end }} + +{{ end }} diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/jaeger-production-elasticsearch.yaml b/resources/helm/v2.5/istio-telemetry/tracing/templates/jaeger-production-elasticsearch.yaml new file mode 100644 index 0000000000..8a9c6fc053 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/jaeger-production-elasticsearch.yaml @@ -0,0 +1,126 @@ +{{ if and (eq .Values.tracing.provider "jaeger") (eq .Values.tracing.jaeger.template "production-elasticsearch") .Values.tracing.jaeger.install }} +apiVersion: jaegertracing.io/v1 +kind: "Jaeger" +metadata: + name: {{ .Values.tracing.jaeger.resourceName | default "jaeger"}} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} +spec: + strategy: production + + query: + {{- if and .Values.tracing.jaeger.hub .Values.tracing.jaeger.tag .Values.tracing.jaeger.queryImage }} + image: {{ .Values.tracing.jaeger.hub }}/{{ .Values.tracing.jaeger.queryImage }}:{{ .Values.tracing.jaeger.tag }} + {{- end }} + options: + query: + base-path: / + +{{- if and .Values.tracing.jaeger.hub .Values.tracing.jaeger.tag .Values.tracing.jaeger.collectorImage }} + collector: + image: {{ .Values.tracing.jaeger.hub }}/{{ .Values.tracing.jaeger.collectorImage }}:{{ .Values.tracing.jaeger.tag }} +{{- end }} + +{{- if and .Values.tracing.jaeger.hub .Values.tracing.jaeger.tag .Values.tracing.jaeger.agentImage }} + agent: + image: {{ .Values.tracing.jaeger.hub }}/{{ .Values.tracing.jaeger.agentImage }}:{{ .Values.tracing.jaeger.tag }} +{{- end }} + +{{- if .Values.tracing.jaeger.annotations }} + annotations: + {{- range $key, $value := .Values.tracing.jaeger.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + + storage: + type: elasticsearch + elasticsearch: +{{- if .Values.tracing.jaeger.elasticsearch.image }} + image: {{ toYaml .Values.tracing.jaeger.elasticsearch.image }} +{{- end }} +{{- if .Values.tracing.jaeger.elasticsearch.nodeCount }} + nodeCount: {{ toYaml .Values.tracing.jaeger.elasticsearch.nodeCount }} +{{- else }} + nodeCount: 3 +{{- end }} +{{- if .Values.tracing.jaeger.elasticsearch.storage }} + storage: +{{ toYaml .Values.tracing.jaeger.elasticsearch.storage | indent 8 }} +{{- end }} +{{- if .Values.tracing.jaeger.elasticsearch.redundancyPolicy }} + redundancyPolicy: {{ toYaml .Values.tracing.jaeger.elasticsearch.redundancyPolicy }} +{{- end }} +{{- if .Values.tracing.jaeger.elasticsearch.nodeSelector }} + nodeSelector: + {{- range $key, $value := .Values.tracing.jaeger.elasticsearch.nodeSelector }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + resources: +{{- if .Values.tracing.jaeger.elasticsearch.resources }} +{{ toYaml .Values.tracing.jaeger.elasticsearch.resources | indent 8 }} +{{- else }} + requests: + memory: "16Gi" + cpu: "1" +{{- end }} + +{{- if .Values.tracing.jaeger.esIndexCleaner }} + esIndexCleaner: +{{ toYaml .Values.tracing.jaeger.esIndexCleaner | indent 6 }} +{{- end }} + + ingress: + enabled: {{ .Values.tracing.ingress.enabled }} + # XXX: should this be parameterized? + security: oauth-proxy +{{- if .Values.tracing.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.tracing.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + openshift: + sar: '{"namespace": "{{ .Release.Namespace }}", "resource": "pods", "verb": "get"}' + htpasswdFile: /etc/proxy/htpasswd/auth + + volumeMounts: + - name: secret-htpasswd + mountPath: /etc/proxy/htpasswd + - name: trusted-ca-bundle + mountPath: /etc/pki/ca-trust/extracted/pem/ + readOnly: true + volumes: + - name: secret-htpasswd + secret: + secretName: htpasswd + - name: trusted-ca-bundle + configMap: + defaultMode: 420 + items: + - key: ca-bundle.crt + path: tls-ca-bundle.pem + name: trusted-ca-bundle + optional: true + resources: +{{- if .Values.tracing.jaeger.resources }} +{{ toYaml .Values.tracing.jaeger.resources | indent 4 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | indent 4 }} +{{- end }} + affinity: + {{- include "nodeaffinity" . | indent 2 }} + +{{- if .Values.tracing.tolerations }} + tolerations: +{{ toYaml .Values.tracing.tolerations | indent 4 }} +{{- else if .Values.global.defaultTolerations }} + tolerations: +{{ toYaml .Values.global.defaultTolerations | indent 4 }} +{{- end }} + +{{ end }} diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/networkpolicy.yaml b/resources/helm/v2.5/istio-telemetry/tracing/templates/networkpolicy.yaml new file mode 100644 index 0000000000..7a221bb584 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/networkpolicy.yaml @@ -0,0 +1,31 @@ +{{- if (eq .Values.tracing.provider "jaeger") }} +# This is to support routes on ocp 3.11 installs +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-jaeger-ingress + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} + annotations: + "maistra.io/internal": "true" +spec: + podSelector: + matchExpressions: + # the value of this label depends on the deployment strategy used + - key: app.kubernetes.io/component + operator: In + values: + - all-in-one + - query + matchLabels: + app.kubernetes.io/instance: {{ .Values.tracing.jaeger.resourceName | default "jaeger" }} + app.kubernetes.io/part-of: jaeger + app.kubernetes.io/managed-by: jaeger-operator + ingress: + - ports: + port: 8443 + +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/policy-jaeger.yaml b/resources/helm/v2.5/istio-telemetry/tracing/templates/policy-jaeger.yaml new file mode 100644 index 0000000000..02033be17b --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/policy-jaeger.yaml @@ -0,0 +1,54 @@ +{{ if and .Values.tracing.enabled (eq .Values.tracing.provider "jaeger") }} + +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: disable-mtls-jaeger-collector + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + {{- if eq .Values.tracing.jaeger.template "all-in-one"}} + app.kubernetes.io/component: all-in-one + {{- else }} + app.kubernetes.io/component: collector + {{- end }} + app.kubernetes.io/instance: {{ .Values.tracing.jaeger.resourceName | default "jaeger" }} + mtls: + mode: DISABLE +--- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: disable-mtls-jaeger-collector + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} +spec: + host: {{ .Values.tracing.jaeger.resourceName | default "jaeger" }}-collector.{{ .Release.Namespace }}.svc.{{ .Values.global.proxy.clusterDomain }} + trafficPolicy: + tls: + mode: DISABLE +--- +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: disable-mtls-zipkin + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} +spec: + host: zipkin + trafficPolicy: + tls: + mode: DISABLE + +{{ end }} diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/service.yaml b/resources/helm/v2.5/istio-telemetry/tracing/templates/service.yaml new file mode 100644 index 0000000000..a3acc0b482 --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: zipkin + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: {{ .Values.tracing.provider }} + release: {{ .Release.Name }} +spec: + ports: + - port: {{ .Values.tracing.zipkin.queryPort }} + targetPort: {{ .Values.tracing.zipkin.queryPort }} + protocol: TCP + name: {{ .Values.tracing.service.name }} + selector: +{{- if eq .Values.tracing.provider "jaeger" }} + {{- if eq .Values.tracing.jaeger.template "all-in-one"}} + app.kubernetes.io/component: all-in-one + {{- else }} + app.kubernetes.io/component: collector + {{- end }} + app.kubernetes.io/instance: {{ .Values.tracing.jaeger.resourceName | default "jaeger" }} + app.kubernetes.io/part-of: jaeger + app.kubernetes.io/managed-by: jaeger-operator +{{- else }} + app: {{ .Values.tracing.provider }} +{{- end }} diff --git a/resources/helm/v2.5/istio-telemetry/tracing/templates/serviceaccount-jaeger.yaml b/resources/helm/v2.5/istio-telemetry/tracing/templates/serviceaccount-jaeger.yaml new file mode 100644 index 0000000000..c1532994ce --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/templates/serviceaccount-jaeger.yaml @@ -0,0 +1,19 @@ +{{ if and (eq .Values.tracing.provider "jaeger") (eq (.Values.tracing.jaeger.agentStrategy | default "" | lower) "daemonset") .Values.tracing.jaeger.install }} +apiVersion: v1 +kind: ServiceAccount +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +metadata: + name: jaeger-agent + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio-jaeger + chart: {{ template "tracing.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{ end }} diff --git a/resources/helm/v2.5/istio-telemetry/tracing/values.yaml b/resources/helm/v2.5/istio-telemetry/tracing/values.yaml new file mode 100644 index 0000000000..84451c913a --- /dev/null +++ b/resources/helm/v2.5/istio-telemetry/tracing/values.yaml @@ -0,0 +1,91 @@ +# +# addon tracing configuration +# +tracing: + enabled: false + + provider: jaeger + nodeSelector: {} + tolerations: [] + + # Specify the pod anti-affinity that allows you to constrain which nodes + # your pod is eligible to be scheduled based on labels on pods that are + # already running on the node rather than based on labels on nodes. + # There are currently two types of anti-affinity: + # "requiredDuringSchedulingIgnoredDuringExecution" + # "preferredDuringSchedulingIgnoredDuringExecution" + # which denote "hard" vs. "soft" requirements, you can define your values + # in "podAntiAffinityLabelSelector" and "podAntiAffinityTermLabelSelector" + # correspondingly. + # For example: + # podAntiAffinityLabelSelector: + # - key: security + # operator: In + # values: S1,S2 + # topologyKey: "kubernetes.io/hostname" + # This pod anti-affinity rule says that the pod requires not to be scheduled + # onto a node if that node is already running a pod with label having key + # "security" and value "S1". + podAntiAffinityLabelSelector: [] + podAntiAffinityTermLabelSelector: [] + + contextPath: "" + + + jaeger: + template: "" + # include elasticsearch to support default configurations + elasticsearch: {} + install: true + resourceName: jaeger + image: all-in-one + memory: + max_traces: 50000 + resources: {} + # spanStorageType value can be "memory" and "badger" for all-in-one image + spanStorageType: badger + persist: false + storageClassName: "" + accessMode: ReadWriteMany + podAnnotations: {} + + zipkin: + image: zipkin-slim + probeStartupDelay: 10 + livenessProbeStartupDelay: 200 + queryPort: 9411 + resources: + limits: + cpu: 1000m + memory: 2048Mi + requests: + cpu: 150m + memory: 900Mi + javaOptsHeap: 700 + # From: https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml#L51 + # Maximum number of spans to keep in memory. When exceeded, oldest traces (and their spans) will be purged. + # A safe estimate is 1K of memory per span (each span with 2 annotations + 1 binary annotation), plus + # 100 MB for a safety buffer. You'll need to verify in your own environment. + maxSpans: 500000 + node: + cpus: 2 + podAnnotations: {} + + opencensus: + resources: + limits: + cpu: 1 + memory: 2Gi + requests: + cpu: 200m + memory: 400Mi + exporters: + stackdriver: + enable_tracing: true + podAnnotations: {} + + service: + annotations: {} + name: zipkin + type: ClusterIP + externalPort: 80 diff --git a/resources/helm/v2.5/istio_cni/Chart.yaml b/resources/helm/v2.5/istio_cni/Chart.yaml new file mode 100644 index 0000000000..80a1a64c60 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +name: istio_cni +version: 1.1.0 +appVersion: 1.1.0 +tillerVersion: ">=2.7.2" +description: Helm chart for istio-cni deployment +keywords: + - istio + - cni +sources: + - http://github.com/istio/cni +engine: gotpl +icon: https://istio.io/favicons/android-192x192.png diff --git a/resources/helm/v2.5/istio_cni/templates/clusterrole-v2.4.yaml b/resources/helm/v2.5/istio_cni/templates/clusterrole-v2.4.yaml new file mode 100644 index 0000000000..964f691891 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/clusterrole-v2.4.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.cni.enabled (has "v2.4" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.4") }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }} +rules: + - apiGroups: [""] + resources: + - pods + verbs: + - get + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - 'use' +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/clusterrole-v2.5.yaml b/resources/helm/v2.5/istio_cni/templates/clusterrole-v2.5.yaml new file mode 100644 index 0000000000..64dde7129d --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/clusterrole-v2.5.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }} +rules: + - apiGroups: [""] + resources: + - pods + verbs: + - get + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - 'use' +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/clusterrole.yaml b/resources/helm/v2.5/istio_cni/templates/clusterrole.yaml new file mode 100644 index 0000000000..a211311411 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/clusterrole.yaml @@ -0,0 +1,24 @@ +{{ if .Values.cni.enabled }} +{{ if or (eq .Values.cni.instanceVersion "v2.0") (eq .Values.cni.instanceVersion "v2.1") (eq .Values.cni.instanceVersion "v2.2") (eq .Values.cni.instanceVersion "v2.3")}} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + maistra-version: "2.5.0" + name: istio-cni +rules: + - apiGroups: [""] + resources: + - pods + verbs: + - get + - apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - privileged + verbs: + - 'use' +{{ end }} +{{ end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio_cni/templates/clusterrolebinding-v2.4.yaml b/resources/helm/v2.5/istio_cni/templates/clusterrolebinding-v2.4.yaml new file mode 100644 index 0000000000..3c4ac6efb5 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/clusterrolebinding-v2.4.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.cni.enabled (has "v2.4" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.4") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Values.cni.defaultResourceName }} +subjects: + - kind: ServiceAccount + name: {{ .Values.cni.defaultResourceName }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/clusterrolebinding-v2.5.yaml b/resources/helm/v2.5/istio_cni/templates/clusterrolebinding-v2.5.yaml new file mode 100644 index 0000000000..00157efbed --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/clusterrolebinding-v2.5.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Values.cni.defaultResourceName }} +subjects: + - kind: ServiceAccount + name: {{ .Values.cni.defaultResourceName }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/clusterrolebinding.yaml b/resources/helm/v2.5/istio_cni/templates/clusterrolebinding.yaml new file mode 100644 index 0000000000..73626cf5ae --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{ if .Values.cni.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + maistra-version: "2.5.0" + name: istio-cni +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istio-cni +subjects: + - kind: ServiceAccount + name: istio-cni + namespace: {{ .Release.Namespace }} +{{ end }} diff --git a/resources/helm/v2.5/istio_cni/templates/configmap-v2.3.yaml b/resources/helm/v2.5/istio_cni/templates/configmap-v2.3.yaml new file mode 100644 index 0000000000..18c9329947 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/configmap-v2.3.yaml @@ -0,0 +1,28 @@ +{{ if .Values.cni.enabled }} +{{- if and (has "v2.3" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.3") }} +# This ConfigMap is used to configure a self-hosted Istio CNI installation. +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + maistra-version: "2.5.0" + name: istio-cni-config-v2-3 + namespace: {{ .Release.Namespace }} +data: + # The CNI network configuration to add to the plugin chain on each node. The special + # values in this config will be automatically populated. + cni_network_config: |- + { + "cniVersion": "0.3.1", + "name": "v2-3-istio-cni", + "type": "v2-3-istio-cni", + "log_level": {{ quote .Values.cni.logLevel }}, + "log_uds_address": "__LOG_UDS_ADDRESS__", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } +{{- end }} +{{ end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio_cni/templates/configmap-v2.4.yaml b/resources/helm/v2.5/istio_cni/templates/configmap-v2.4.yaml new file mode 100644 index 0000000000..1acd88bb29 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/configmap-v2.4.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.cni.enabled (has "v2.4" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.4") }} +# This ConfigMap is used to configure a self-hosted Istio CNI installation. +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }}-config-v2-4 + namespace: {{ .Release.Namespace }} +data: + # The CNI network configuration to add to the plugin chain on each node. The special + # values in this config will be automatically populated. + cni_network_config: |- + { + "cniVersion": "0.3.1", + "name": "v2-4-istio-cni", + "type": "v2-4-istio-cni", + "log_level": {{ quote .Values.cni.logLevel }}, + "log_uds_address": "__LOG_UDS_ADDRESS__", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/configmap-v2.5.yaml b/resources/helm/v2.5/istio_cni/templates/configmap-v2.5.yaml new file mode 100644 index 0000000000..07844cbb74 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/configmap-v2.5.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +# This ConfigMap is used to configure a self-hosted Istio CNI installation. +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }}-config-v2-5 + namespace: {{ .Release.Namespace }} +data: + # The CNI network configuration to add to the plugin chain on each node. The special + # values in this config will be automatically populated. + cni_network_config: |- + { + "cniVersion": "0.3.1", + "name": "v2-5-istio-cni", + "type": "v2-5-istio-cni", + "log_level": {{ quote .Values.cni.logLevel }}, + "log_uds_address": "__LOG_UDS_ADDRESS__", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/configmap.yaml b/resources/helm/v2.5/istio_cni/templates/configmap.yaml new file mode 100644 index 0000000000..0cc672ebaf --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/configmap.yaml @@ -0,0 +1,54 @@ +{{ if .Values.cni.enabled }} +{{- if or (eq .Values.cni.instanceVersion "v2.0") (eq .Values.cni.instanceVersion "v2.1") (eq .Values.cni.instanceVersion "v2.2")}} +# This ConfigMap is used to configure a self-hosted Istio CNI installation. +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + maistra-version: "2.5.0" + name: istio-cni-config + namespace: {{ .Release.Namespace }} +data: + # The CNI network configuration to add to the plugin chain on each node. The special + # values in this config will be automatically populated. + cni_network_config_v2_0: |- + { + "cniVersion": "0.3.0", + "name": "v2-0-istio-cni", + "type": "v2-0-istio-cni", + "log_level": "info", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "iptables_script": "v2-0-istio-iptables.sh", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } + cni_network_config_v2_1: |- + { + "cniVersion": "0.3.0", + "name": "v2-1-istio-cni", + "type": "v2-1-istio-cni", + "log_level": "info", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "netns_setup_executable": "v2-1-istio-iptables", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } + cni_network_config_v2_2: |- + { + "cniVersion": "0.3.0", + "name": "v2-2-istio-cni", + "type": "v2-2-istio-cni", + "log_level": {{ quote .Values.cni.logLevel }}, + "log_uds_address": "__LOG_UDS_ADDRESS__", + "kubernetes": { + "kubeconfig": "__KUBECONFIG_FILEPATH__", + "cni_bin_dir": "{{ default "/opt/cni/bin" .Values.cni.cniBinDir }}", + "exclude_namespaces": [ "{{ .Release.Namespace }}" ] + } + } +{{- end }} +{{ end }} \ No newline at end of file diff --git a/resources/helm/v2.5/istio_cni/templates/daemonset-v2.3.yaml b/resources/helm/v2.5/istio_cni/templates/daemonset-v2.3.yaml new file mode 100644 index 0000000000..a13145024e --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/daemonset-v2.3.yaml @@ -0,0 +1,129 @@ +{{ if .Values.cni.enabled }} +{{- if and (has "v2.3" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.3") }} +# This manifest installs the Istio install-cni container, as well +# as the Istio CNI plugin and config on +# each master and worker node in a Kubernetes cluster. +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: istio-cni-node-v2-3 + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + k8s-app: istio-cni-node-v2-3 + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + k8s-app: istio-cni-node-v2-3 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + template: + metadata: + labels: + k8s-app: istio-cni-node-v2-3 + release: {{ .Release.Name }} + annotations: + sidecar.istio.io/inject: "false" + # Custom annotations + {{- if .Values.cni.podAnnotations }} +{{ toYaml .Values.cni.podAnnotations | indent 8 }} + {{- end }} + spec: + nodeSelector: + kubernetes.io/os: linux + tolerations: + # Make sure istio-cni-node gets scheduled on all nodes. + - effect: NoSchedule + operator: Exists + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + priorityClassName: system-node-critical + serviceAccountName: istio-cni + # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force + # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. + terminationGracePeriodSeconds: 5 +{{- if .Values.cni.imagePullSecrets }} + imagePullSecrets: +{{- range .Values.cni.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} + containers: + # This container installs the Istio CNI binaries + # and CNI network config file on each node. + - name: install-cni + image: "{{ .Values.cni.image_v2_3 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8000 + initialDelaySeconds: 5 + readinessProbe: + httpGet: + path: /readyz + port: 8000 + command: ["install-cni"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_3 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_3 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: istio-cni-config-v2-3 + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_3 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-3-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-3-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + - mountPath: /var/run/istio-cni + name: cni-log-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} + volumes: + # Used to install CNI. + - name: cni-bin-dir + hostPath: + path: {{ default "/opt/cni/bin" .Values.cni.cniBinDir }} + - name: etc-cni-dir + hostPath: + path: /etc/cni + # Used for UDS log + - name: cni-log-dir + hostPath: + path: /var/run/istio-cni +{{- end }} +{{ end }} diff --git a/resources/helm/v2.5/istio_cni/templates/daemonset-v2.4.yaml b/resources/helm/v2.5/istio_cni/templates/daemonset-v2.4.yaml new file mode 100644 index 0000000000..061e75bf1b --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/daemonset-v2.4.yaml @@ -0,0 +1,127 @@ +{{- if and .Values.cni.enabled (has "v2.4" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.4") }} +# This manifest installs the Istio install-cni container, as well +# as the Istio CNI plugin and config on +# each master and worker node in a Kubernetes cluster. +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: istio-cni-node-v2-4 + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + k8s-app: istio-cni-node-v2-4 + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + k8s-app: istio-cni-node-v2-4 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + template: + metadata: + labels: + k8s-app: istio-cni-node-v2-4 + release: {{ .Release.Name }} + annotations: + sidecar.istio.io/inject: "false" + # Custom annotations + {{- if .Values.cni.podAnnotations }} +{{ toYaml .Values.cni.podAnnotations | indent 8 }} + {{- end }} + spec: + nodeSelector: + kubernetes.io/os: linux + tolerations: + # Make sure istio-cni-node gets scheduled on all nodes. + - effect: NoSchedule + operator: Exists + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + priorityClassName: system-node-critical + serviceAccountName: {{ .Values.cni.defaultResourceName }} + # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force + # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. + terminationGracePeriodSeconds: 5 +{{- if .Values.cni.imagePullSecrets }} + imagePullSecrets: +{{- range .Values.cni.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} + containers: + # This container installs the Istio CNI binaries + # and CNI network config file on each node. + - name: install-cni + image: "{{ .Values.cni.image_v2_4 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8000 + initialDelaySeconds: 5 + readinessProbe: + httpGet: + path: /readyz + port: 8000 + command: ["install-cni"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_4 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_4 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: {{ .Values.cni.defaultResourceName }}-config-v2-4 + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_4 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-4-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-4-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + - mountPath: /var/run/istio-cni + name: cni-log-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} + volumes: + # Used to install CNI. + - name: cni-bin-dir + hostPath: + path: {{ default "/opt/cni/bin" .Values.cni.cniBinDir }} + - name: etc-cni-dir + hostPath: + path: /etc/cni + # Used for UDS log + - name: cni-log-dir + hostPath: + path: /var/run/istio-cni +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/daemonset-v2.5.yaml b/resources/helm/v2.5/istio_cni/templates/daemonset-v2.5.yaml new file mode 100644 index 0000000000..b25fda49e1 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/daemonset-v2.5.yaml @@ -0,0 +1,127 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +# This manifest installs the Istio install-cni container, as well +# as the Istio CNI plugin and config on +# each master and worker node in a Kubernetes cluster. +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: istio-cni-node-v2-5 + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + k8s-app: istio-cni-node-v2-5 + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + k8s-app: istio-cni-node-v2-5 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + template: + metadata: + labels: + k8s-app: istio-cni-node-v2-5 + release: {{ .Release.Name }} + annotations: + sidecar.istio.io/inject: "false" + # Custom annotations + {{- if .Values.cni.podAnnotations }} +{{ toYaml .Values.cni.podAnnotations | indent 8 }} + {{- end }} + spec: + nodeSelector: + kubernetes.io/os: linux + tolerations: + # Make sure istio-cni-node gets scheduled on all nodes. + - effect: NoSchedule + operator: Exists + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + priorityClassName: system-node-critical + serviceAccountName: {{ .Values.cni.defaultResourceName }} + # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force + # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. + terminationGracePeriodSeconds: 5 +{{- if .Values.cni.imagePullSecrets }} + imagePullSecrets: +{{- range .Values.cni.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} + containers: + # This container installs the Istio CNI binaries + # and CNI network config file on each node. + - name: install-cni + image: "{{ .Values.cni.image_v2_5 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8000 + initialDelaySeconds: 5 + readinessProbe: + httpGet: + path: /readyz + port: 8000 + command: ["install-cni"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_5 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_5 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: {{ .Values.cni.defaultResourceName }}-config-v2-5 + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_5 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-5-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-5-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + - mountPath: /var/run/istio-cni + name: cni-log-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} + volumes: + # Used to install CNI. + - name: cni-bin-dir + hostPath: + path: {{ default "/opt/cni/bin" .Values.cni.cniBinDir }} + - name: etc-cni-dir + hostPath: + path: /etc/cni + # Used for UDS log + - name: cni-log-dir + hostPath: + path: /var/run/istio-cni +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/daemonset.yaml b/resources/helm/v2.5/istio_cni/templates/daemonset.yaml new file mode 100644 index 0000000000..43e749bcef --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/daemonset.yaml @@ -0,0 +1,225 @@ +{{ if .Values.cni.enabled }} +{{- if or (eq .Values.cni.instanceVersion "v2.0") (eq .Values.cni.instanceVersion "v2.1") (eq .Values.cni.instanceVersion "v2.2")}} +# This manifest installs the Istio install-cni container, as well +# as the Istio CNI plugin and config on +# each master and worker node in a Kubernetes cluster. +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: istio-cni-node + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + k8s-app: istio-cni-node + release: {{ .Release.Name }} +spec: + selector: + matchLabels: + k8s-app: istio-cni-node + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + template: + metadata: + labels: + k8s-app: istio-cni-node + release: {{ .Release.Name }} + annotations: + sidecar.istio.io/inject: "false" + # Custom annotations + {{- if .Values.cni.podAnnotations }} +{{ toYaml .Values.cni.podAnnotations | indent 8 }} + {{- end }} + spec: + nodeSelector: + kubernetes.io/os: linux + tolerations: + # Make sure istio-cni-node gets scheduled on all nodes. + - effect: NoSchedule + operator: Exists + # Mark the pod as a critical add-on for rescheduling. + - key: CriticalAddonsOnly + operator: Exists + - effect: NoExecute + operator: Exists + priorityClassName: system-node-critical + serviceAccountName: istio-cni + # Minimize downtime during a rolling upgrade or deletion; tell Kubernetes to do a "force + # deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods. + terminationGracePeriodSeconds: 5 +{{- if .Values.cni.imagePullSecrets }} + imagePullSecrets: +{{- range .Values.cni.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} + containers: + # This container installs the Istio CNI binaries + # and CNI network config file on each node. +{{- if and (.Values.cni.supportedReleases) (has "v2.0" .Values.cni.supportedReleases) }} + - name: install-cni-v2-0 + image: "{{ .Values.cni.image_v2_0 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + command: ["/install-cni.sh"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_0 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_0 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: istio-cni-config + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_0 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-0-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-0-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} +{{- end }} +{{- if and (.Values.cni.supportedReleases) (has "v2.1" .Values.cni.supportedReleases) }} + - name: install-cni-v2-1 + image: "{{ .Values.cni.image_v2_1 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + command: ["install-cni"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_1 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_1 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: istio-cni-config + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_1 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-1-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-1-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} +{{- end }} +{{- if and (.Values.cni.supportedReleases) (has "v2.2" .Values.cni.supportedReleases) }} + - name: install-cni-v2-2 + image: "{{ .Values.cni.image_v2_2 }}" + imagePullPolicy: {{ .Values.cni.imagePullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8000 + initialDelaySeconds: 5 + readinessProbe: + httpGet: + path: /readyz + port: 8000 + command: ["install-cni"] + securityContext: + privileged: true + env: +{{- if .Values.cni.cniConfFileName_v2_2 }} + # Name of the CNI config file to create. + - name: CNI_CONF_NAME + value: "{{ .Values.cni.cniConfFileName_v2_2 }}" +{{- end }} + # The CNI network config to install on each node. + - name: CNI_NETWORK_CONFIG + valueFrom: + configMapKeyRef: + name: istio-cni-config + key: "{{ default "cni_network_config" .Values.cni.configMap_v2_2 }}" + - name: CNI_NET_DIR + value: {{ default "/etc/cni/net.d" .Values.cni.cniConfDir }} + # Deploy as a standalone CNI plugin or as chained? + - name: CHAINED_CNI_PLUGIN + value: "{{ .Values.cni.chained }}" + # Directory in which the CNI config file should be created (host path mounted in the container) + - name: MOUNTED_CNI_NET_DIR + value: {{ default "/host/etc/cni/net.d" .Values.cni.mountedCniConfDir }} + # Name of the kubeconfig file used by CNI agent + - name: KUBECFG_FILE_NAME + value: "v2-2-istio-cni.kubeconfig" + # The prefix to add when installing the CNI binaries to the node + - name: CNI_BINARIES_PREFIX + value: "v2-2-" + volumeMounts: + - mountPath: /host/opt/cni/bin + name: cni-bin-dir + - mountPath: /host/etc/cni/ + name: etc-cni-dir + - mountPath: /var/run/istio-cni + name: cni-log-dir + resources: +{{- if .Values.cni.resources }} +{{ toYaml .Values.cni.resources | indent 12 }} +{{- else }} + requests: + cpu: 10m + memory: 100Mi +{{- end }} +{{- end }} + volumes: + # Used to install CNI. + - name: cni-bin-dir + hostPath: + path: {{ default "/opt/cni/bin" .Values.cni.cniBinDir }} + - name: etc-cni-dir + hostPath: + path: /etc/cni + # Used for UDS log + - name: cni-log-dir + hostPath: + path: /var/run/istio-cni +{{- end }} +{{ end }} diff --git a/resources/helm/v2.5/istio_cni/templates/serviceaccount-v2.4.yaml b/resources/helm/v2.5/istio_cni/templates/serviceaccount-v2.4.yaml new file mode 100644 index 0000000000..969e8c85a4 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/serviceaccount-v2.4.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.cni.enabled (has "v2.4" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.4") }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/serviceaccount-v2.5.yaml b/resources/helm/v2.5/istio_cni/templates/serviceaccount-v2.5.yaml new file mode 100644 index 0000000000..7847b0d635 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/serviceaccount-v2.5.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.cni.enabled (has "v2.5" .Values.cni.supportedReleases) (eq .Values.cni.instanceVersion "v2.5") }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + maistra-version: "2.5.0" + name: {{ .Values.cni.defaultResourceName }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/resources/helm/v2.5/istio_cni/templates/serviceaccount.yaml b/resources/helm/v2.5/istio_cni/templates/serviceaccount.yaml new file mode 100644 index 0000000000..c30f616757 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/templates/serviceaccount.yaml @@ -0,0 +1,9 @@ +{{ if .Values.cni.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + maistra-version: "2.5.0" + name: istio-cni + namespace: {{ .Release.Namespace }} +{{ end }} diff --git a/resources/helm/v2.5/istio_cni/values.yaml b/resources/helm/v2.5/istio_cni/values.yaml new file mode 100644 index 0000000000..95f2d26818 --- /dev/null +++ b/resources/helm/v2.5/istio_cni/values.yaml @@ -0,0 +1,3 @@ +cni: + defaultResourceName: ossm-cni + enabled: false diff --git a/resources/helm/v2.5/mesh-config/Chart.yaml b/resources/helm/v2.5/mesh-config/Chart.yaml new file mode 100644 index 0000000000..4b6d5e08ed --- /dev/null +++ b/resources/helm/v2.5/mesh-config/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +name: mesh-config +version: 1.1.0 +appVersion: 1.1.0 +tillerVersion: ">=2.7.2" +description: Helm chart for istio mesh config +keywords: + - istio + - mixer +sources: + - http://github.com/maistra/istio +engine: gotpl +icon: https://istio.io/favicons/android-192x192.png diff --git a/resources/helm/v2.5/mesh-config/templates/_helpers.tpl b/resources/helm/v2.5/mesh-config/templates/_helpers.tpl new file mode 100644 index 0000000000..ccf8a077f1 --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/_helpers.tpl @@ -0,0 +1,35 @@ +{{/* Prometheus is enabled if its enabled and there are no config overrides set */}} +{{ define "prometheus" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.prometheus.enabled + (not (or + .Values.telemetry.v2.prometheus.configOverride.gateway + .Values.telemetry.v2.prometheus.configOverride.inboundSidecar + .Values.telemetry.v2.prometheus.configOverride.outboundSidecar + )) }} +{{- end }} + +{{/* SD has metrics and logging split. Metrics are enabled if SD is enabled and there are no config overrides set */}} +{{ define "sd-metrics" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} + +{{/* SD has metrics and logging split. */}} +{{ define "sd-logs" }} +{{- and + (not .Values.meshConfig.defaultProviders) + .Values.telemetry.enabled .Values.telemetry.v2.enabled .Values.telemetry.v2.stackdriver.enabled + (not (or + .Values.telemetry.v2.stackdriver.configOverride + (has .Values.telemetry.v2.stackdriver.outboundAccessLogging (list "" "ERRORS_ONLY")) + (has .Values.telemetry.v2.stackdriver.inboundAccessLogging (list "" "ALL")) + .Values.telemetry.v2.stackdriver.disableOutbound )) +}} +{{- end }} \ No newline at end of file diff --git a/resources/helm/v2.5/mesh-config/templates/enable-mesh-mtls.yaml b/resources/helm/v2.5/mesh-config/templates/enable-mesh-mtls.yaml new file mode 100644 index 0000000000..7a13acde02 --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/enable-mesh-mtls.yaml @@ -0,0 +1,61 @@ +{{- if .Values.global.mtls.enabled }} +# These policy and destination rules effectively enable mTLS for all services in the mesh. For now, +# they are added to Istio installation yaml for backward compatible. In future, they should be in +# a separated yaml file so that customer can enable mTLS independent from installation. + +# Authentication policy to enable mutual TLS for all services (that have sidecar) in the mesh. +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: "default" + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +spec: + mtls: + mode: STRICT +--- +# Corresponding destination rule to configure client side to use mutual TLS when talking to +# any service (host) in the mesh. +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: "default" + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +spec: + host: "*.{{ .Values.global.proxy.clusterDomain }}" + {{- if .Values.global.defaultConfigVisibilitySettings }} + exportTo: + - '*' + {{- end }} + trafficPolicy: + tls: + mode: ISTIO_MUTUAL +--- +# Destination rule to disable (m)TLS when talking to API server, as API server doesn't have sidecar. +# Customer should add similar destination rules for other services that don't have sidecar. +apiVersion: networking.istio.io/v1beta1 +kind: DestinationRule +metadata: + name: "api-server" + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +spec: + host: "kubernetes.default.svc.{{ .Values.global.proxy.clusterDomain }}" + {{- if .Values.global.defaultConfigVisibilitySettings }} + exportTo: + - '*' + {{- end }} + trafficPolicy: + tls: + mode: DISABLE +{{- end }} diff --git a/resources/helm/v2.5/mesh-config/templates/enable-mesh-permissive.yaml b/resources/helm/v2.5/mesh-config/templates/enable-mesh-permissive.yaml new file mode 100644 index 0000000000..5552fef258 --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/enable-mesh-permissive.yaml @@ -0,0 +1,15 @@ +{{- if (not .Values.global.mtls.enabled) }} +# Authentication policy to enable permissive mode for all services (that have sidecar) in the mesh. +apiVersion: security.istio.io/v1beta1 +kind: PeerAuthentication +metadata: + name: "default" + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +spec: + mtls: + mode: PERMISSIVE +{{- end }} diff --git a/resources/helm/v2.5/mesh-config/templates/networkpolicy.yaml b/resources/helm/v2.5/mesh-config/templates/networkpolicy.yaml new file mode 100644 index 0000000000..3473cc9372 --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/networkpolicy.yaml @@ -0,0 +1,37 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-mesh-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + "maistra.io/member-of": "{{ .Release.Namespace }}" + +--- + +# this will work for all routes into the mesh namespace referencing a labelled pod, but not on ocp 3.11 +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: istio-expose-route-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: istio + release: {{ .Release.Name }} +spec: + podSelector: + matchLabels: + maistra.io/expose-route: "true" + ingress: + - from: + - namespaceSelector: + matchLabels: + network.openshift.io/policy-group: ingress diff --git a/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.16.yaml b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.16.yaml new file mode 100644 index 0000000000..979e3c1c0f --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.16.yaml @@ -0,0 +1,621 @@ +{{- if and .Values.telemetry.enabled .Values.telemetry.v2.enabled }} +{{ $prom := not (include "prometheus" . | eq "true") }} +{{ $sdMetrics := not (include "sd-metrics" . | eq "true") }} +{{ $sdLogs := not (include "sd-logs" . | eq "true") }} +--- +# Note: http stats filter is wasm enabled only in sidecars. +{{- if and .Values.telemetry.v2.prometheus.enabled $prom }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stats-filter-1.16-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.prometheus.configOverride.outboundSidecar }} + { + "debug": "false", + "stat_prefix": "istio" + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.outboundSidecar | indent 18 }} + {{- end }} + vm_config: + vm_id: stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + allow_precompiled: true + code: + local: + filename: /etc/istio/extensions/stats-filter.compiled.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.stats + {{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stats_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.prometheus.configOverride.inboundSidecar }} + { + "debug": "false", + "stat_prefix": "istio", + "disable_host_header_fallback": true + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.inboundSidecar | indent 18 }} + {{- end }} + vm_config: + vm_id: stats_inbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + allow_precompiled: true + code: + local: + filename: /etc/istio/extensions/stats-filter.compiled.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.stats + {{- end }} + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.prometheus.configOverride.gateway }} + { + "debug": "false", + "stat_prefix": "istio", + "disable_host_header_fallback": true + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.gateway | indent 18 }} + {{- end }} + vm_config: + vm_id: stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + allow_precompiled: true + code: + local: + filename: /etc/istio/extensions/stats-filter.compiled.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.stats + {{- end }} +--- +# Note: tcp stats filter is wasm enabled only in sidecars. +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stats-filter-1.16-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stats_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.prometheus.configOverride.inboundSidecar }} + { + "debug": "false", + "stat_prefix": "istio" + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.inboundSidecar | indent 18 }} + {{- end }} + vm_config: + vm_id: tcp_stats_inbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + allow_precompiled: true + code: + local: + filename: /etc/istio/extensions/stats-filter.compiled.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: "envoy.wasm.stats" + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.prometheus.configOverride.outboundSidecar }} + { + "debug": "false", + "stat_prefix": "istio" + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.outboundSidecar | indent 18 }} + {{- end }} + vm_config: + vm_id: tcp_stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + allow_precompiled: true + code: + local: + filename: /etc/istio/extensions/stats-filter.compiled.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: "envoy.wasm.stats" + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.prometheus.configOverride.gateway }} + { + "debug": "false", + "stat_prefix": "istio" + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.gateway | indent 18 }} + {{- end }} + vm_config: + vm_id: tcp_stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + allow_precompiled: true + code: + local: + filename: /etc/istio/extensions/stats-filter.compiled.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: "envoy.wasm.stats" + {{- end }} +--- +{{- end }} +{{/*TODO: this is broken, we do not handle the split quite right! */}} +{{- if and .Values.telemetry.v2.stackdriver.enabled $sdLogs $sdMetrics }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-filter-1.16-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: +{{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +{{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, + "access_logging": "{{ .Values.telemetry.v2.stackdriver.inboundAccessLogging }}", + "disable_host_header_fallback": true, + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "disable_host_header_fallback": true, + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stackdriver-filter-1.16-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + {{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, + "access_logging": "{{ .Values.telemetry.v2.stackdriver.inboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +{{- if .Values.telemetry.v2.accessLogPolicy.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-sampling-accesslog-filter-1.16-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '1\.16.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "istio.stackdriver" + patch: + operation: INSERT_BEFORE + value: + name: istio.access_log + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + { + "log_window_duration": "{{ .Values.telemetry.v2.accessLogPolicy.logWindowDuration }}" + } + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.access_log_policy" } +--- +{{- end }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.17.yaml b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.17.yaml new file mode 100644 index 0000000000..f9ec6309f5 --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.17.yaml @@ -0,0 +1,491 @@ +{{- if and .Values.telemetry.enabled .Values.telemetry.v2.enabled }} +{{ $prom := not (include "prometheus" . | eq "true") }} +{{ $sdMetrics := not (include "sd-metrics" . | eq "true") }} +{{ $sdLogs := not (include "sd-logs" . | eq "true") }} +--- +# Note: http stats filter is wasm enabled only in sidecars. +{{- if and .Values.telemetry.v2.prometheus.enabled $prom }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stats-filter-1.17-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.outboundSidecar }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.outboundSidecar | indent 18 }} + {{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.inboundSidecar }} + { + "disable_host_header_fallback": true + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.inboundSidecar | indent 18 }} + {{- end }} + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.gateway }} + { + "disable_host_header_fallback": true + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.gateway | indent 18 }} + {{- end }} +--- +# Note: tcp stats filter is wasm enabled only in sidecars. +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stats-filter-1.17-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.inboundSidecar }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.inboundSidecar | indent 18 }} + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.outboundSidecar }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.outboundSidecar | indent 18 }} + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.gateway }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.gateway | indent 18 }} + {{- end }} +--- +{{- end }} +{{/*TODO: this is broken, we do not handle the split quite right! */}} +{{- if and .Values.telemetry.v2.stackdriver.enabled $sdLogs $sdMetrics }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-filter-1.17-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: +{{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +{{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, + "access_logging": "{{ .Values.telemetry.v2.stackdriver.inboundAccessLogging }}", + "disable_host_header_fallback": true, + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "disable_host_header_fallback": true, + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stackdriver-filter-1.17-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + {{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, + "access_logging": "{{ .Values.telemetry.v2.stackdriver.inboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +{{- if .Values.telemetry.v2.accessLogPolicy.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-sampling-accesslog-filter-1.17-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '1\.17.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "istio.stackdriver" + patch: + operation: INSERT_BEFORE + value: + name: istio.access_log + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + { + "log_window_duration": "{{ .Values.telemetry.v2.accessLogPolicy.logWindowDuration }}" + } + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.access_log_policy" } +--- +{{- end }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.18.yaml b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.18.yaml new file mode 100644 index 0000000000..bc409aef6c --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.18.yaml @@ -0,0 +1,491 @@ +{{- if and .Values.telemetry.enabled .Values.telemetry.v2.enabled }} +{{ $prom := not (include "prometheus" . | eq "true") }} +{{ $sdMetrics := not (include "sd-metrics" . | eq "true") }} +{{ $sdLogs := not (include "sd-logs" . | eq "true") }} +--- +# Note: http stats filter is wasm enabled only in sidecars. +{{- if and .Values.telemetry.v2.prometheus.enabled $prom }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stats-filter-1.18-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.outboundSidecar }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.outboundSidecar | indent 18 }} + {{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.inboundSidecar }} + { + "disable_host_header_fallback": true + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.inboundSidecar | indent 18 }} + {{- end }} + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.gateway }} + { + "disable_host_header_fallback": true + } + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.gateway | indent 18 }} + {{- end }} +--- +# Note: tcp stats filter is wasm enabled only in sidecars. +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stats-filter-1.18-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.inboundSidecar }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.inboundSidecar | indent 18 }} + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.outboundSidecar }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.outboundSidecar | indent 18 }} + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/stats.PluginConfig + value: + {{- if not .Values.telemetry.v2.prometheus.configOverride.gateway }} + {} + {{- else }} + {{ toJson .Values.telemetry.v2.prometheus.configOverride.gateway | indent 18 }} + {{- end }} +--- +{{- end }} +{{/*TODO: this is broken, we do not handle the split quite right! */}} +{{- if and .Values.telemetry.v2.stackdriver.enabled $sdLogs $sdMetrics }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-filter-1.18-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: +{{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +{{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, + "access_logging": "{{ .Values.telemetry.v2.stackdriver.inboundAccessLogging }}", + "disable_host_header_fallback": true, + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "envoy.filters.http.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "disable_host_header_fallback": true, + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stackdriver-filter-1.18-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + {{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, + "access_logging": "{{ .Values.telemetry.v2.stackdriver.inboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + { + "access_logging": "{{ .Values.telemetry.v2.stackdriver.outboundAccessLogging }}", + "metric_expiry_duration": "3600s" + } + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +{{- if .Values.telemetry.v2.accessLogPolicy.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-sampling-accesslog-filter-1.18-{{ .Values.revision | default "default" }} + {{- if .Values.meshConfig.rootNamespace }} + namespace: {{ .Values.meshConfig.rootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + priority: -1 + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '1\.18.*' + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + subFilter: + name: "istio.stackdriver" + patch: + operation: INSERT_BEFORE + value: + name: istio.access_log + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + configuration: + "@type": "type.googleapis.com/google.protobuf.StringValue" + value: | + { + "log_window_duration": "{{ .Values.telemetry.v2.accessLogPolicy.logWindowDuration }}" + } + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.access_log_policy" } +--- +{{- end }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.6.yaml b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.6.yaml new file mode 100644 index 0000000000..142b18db35 --- /dev/null +++ b/resources/helm/v2.5/mesh-config/templates/telemetryv2_1.6.yaml @@ -0,0 +1,588 @@ +{{- if and .Values.telemetry.enabled .Values.telemetry.v2.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: metadata-exchange-1.6-{{ .Values.revision | default "default" }} + {{- if .Values.global.configRootNamespace }} + namespace: {{ .Values.global.configRootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + configPatches: + - applyTo: HTTP_FILTER + match: + context: ANY # inbound, outbound, and gateway + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + patch: + operation: INSERT_BEFORE + value: + name: istio.metadata_exchange + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + configuration: | + {} + vm_config: + {{- if .Values.telemetry.v2.metadataExchange.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/metadata-exchange-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.metadata_exchange + {{- end }} +--- +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-metadata-exchange-1.6-{{ .Values.revision | default "default" }} + {{- if .Values.global.configRootNamespace }} + namespace: {{ .Values.global.configRootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + configPatches: + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: {} + patch: + operation: INSERT_BEFORE + value: + name: istio.metadata_exchange + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange + value: + protocol: istio-peer-exchange + - applyTo: CLUSTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.6.*' + cluster: {} + patch: + operation: MERGE + value: + filters: + - name: istio.metadata_exchange + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange + value: + protocol: istio-peer-exchange + - applyTo: CLUSTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.6.*' + cluster: {} + patch: + operation: MERGE + value: + filters: + - name: istio.metadata_exchange + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange + value: + protocol: istio-peer-exchange +--- +{{- if .Values.telemetry.v2.prometheus.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stats-filter-1.6-{{ .Values.revision | default "default" }} + {{- if .Values.global.configRootNamespace }} + namespace: {{ .Values.global.configRootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: | + { + "debug": "false", + "stat_prefix": "istio"{{- if .Values.global.multiCluster.clusterName }}, + "metrics": [ + { + "dimensions": { + "source_cluster": "node.metadata['CLUSTER_ID']", + "destination_cluster": "upstream_peer.cluster_id" + } + } + ] + {{- end }} + } + vm_config: + vm_id: stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/stats-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.stats + {{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stats_inbound + configuration: | + { + "debug": "false", + "stat_prefix": "istio"{{- if .Values.global.multiCluster.clusterName }}, + "metrics": [ + { + "dimensions": { + "destination_cluster": "node.metadata['CLUSTER_ID']", + "source_cluster": "downstream_peer.cluster_id" + } + } + ] + {{- end }} + } + vm_config: + vm_id: stats_inbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/stats-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.stats + {{- end }} + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: | + { + "debug": "false", + "stat_prefix": "istio", + "disable_host_header_fallback": true{{- if .Values.global.multiCluster.clusterName }}, + "metrics": [ + { + "dimensions": { + "source_cluster": "node.metadata['CLUSTER_ID']", + "destination_cluster": "upstream_peer.cluster_id" + } + } + ] + {{- end }} + } + vm_config: + vm_id: stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/stats-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: envoy.wasm.stats + {{- end }} +--- +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: tcp-stats-filter-1.6-{{ .Values.revision | default "default" }} + {{- if .Values.global.configRootNamespace }} + namespace: {{ .Values.global.configRootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + configPatches: + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stats_inbound + configuration: | + { + "debug": "false", + "stat_prefix": "istio"{{- if .Values.global.multiCluster.clusterName }}, + "metrics": [ + { + "dimensions": { + "destination_cluster": "node.metadata['CLUSTER_ID']", + "source_cluster": "downstream_peer.cluster_id" + } + } + ] + {{- end }} + } + vm_config: + vm_id: tcp_stats_inbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/stats-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: "envoy.wasm.stats" + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: | + { + "debug": "false", + "stat_prefix": "istio"{{- if .Values.global.multiCluster.clusterName }}, + "metrics": [ + { + "dimensions": { + "source_cluster": "node.metadata['CLUSTER_ID']", + "destination_cluster": "upstream_peer.cluster_id" + } + } + ] + {{- end }} + } + vm_config: + vm_id: tcp_stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/stats-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: "envoy.wasm.stats" + {{- end }} + - applyTo: NETWORK_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + name: istio.stats + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm + value: + config: + root_id: stats_outbound + configuration: | + { + "debug": "false", + "stat_prefix": "istio"{{- if .Values.global.multiCluster.clusterName }}, + "metrics": [ + { + "dimensions": { + "source_cluster": "node.metadata['CLUSTER_ID']", + "destination_cluster": "upstream_peer.cluster_id" + } + } + ] + {{- end }} + } + vm_config: + vm_id: tcp_stats_outbound + {{- if .Values.telemetry.v2.prometheus.wasmEnabled }} + runtime: envoy.wasm.runtime.v8 + code: + local: + filename: /etc/istio/extensions/stats-filter.wasm + {{- else }} + runtime: envoy.wasm.runtime.null + code: + local: + inline_string: "envoy.wasm.stats" + {{- end }} +--- + +{{- end }} + +{{- if .Values.telemetry.v2.stackdriver.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-filter-1.6-{{ .Values.revision | default "default" }} + {{- if .Values.global.configRootNamespace }} + namespace: {{ .Values.global.configRootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + configPatches: +{{- if not .Values.telemetry.v2.stackdriver.disableOutbound }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + {"enable_mesh_edges_reporting": {{ .Values.telemetry.v2.stackdriver.topology }}, "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, "meshEdgesReportingDuration": "600s"} + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +{{- end }} + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_inbound + configuration: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + {"enable_mesh_edges_reporting": {{ .Values.telemetry.v2.stackdriver.topology }}, "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, "meshEdgesReportingDuration": "600s"} + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_inbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } + - applyTo: HTTP_FILTER + match: + context: GATEWAY + proxy: + proxyVersion: '^1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "envoy.router" + patch: + operation: INSERT_BEFORE + value: + name: istio.stackdriver + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + root_id: stackdriver_outbound + configuration: | + {{- if not .Values.telemetry.v2.stackdriver.configOverride }} + {"enable_mesh_edges_reporting": {{ .Values.telemetry.v2.stackdriver.topology }}, "disable_server_access_logging": {{ not .Values.telemetry.v2.stackdriver.logging }}, "meshEdgesReportingDuration": "600s", "disable_host_header_fallback": true} + {{- else }} + {{ toJson .Values.telemetry.v2.stackdriver.configOverride | indent 18 }} + {{- end }} + vm_config: + vm_id: stackdriver_outbound + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: envoy.wasm.null.stackdriver } +--- +{{- if .Values.telemetry.v2.accessLogPolicy.enabled }} +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: stackdriver-sampling-accesslog-filter-1.6-{{ .Values.revision | default "default" }} + {{- if .Values.global.configRootNamespace }} + namespace: {{ .Values.global.configRootNamespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: + maistra-version: "2.5.0" + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_INBOUND + proxy: + proxyVersion: '1\.6.*' + listener: + filterChain: + filter: + name: "envoy.http_connection_manager" + subFilter: + name: "istio.stackdriver" + patch: + operation: INSERT_BEFORE + value: + name: istio.access_log + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + configuration: | + { + "log_window_duration": "{{ .Values.telemetry.v2.accessLogPolicy.logWindowDuration }}" + } + vm_config: + runtime: envoy.wasm.runtime.null + code: + local: { inline_string: "envoy.wasm.access_log_policy" } +--- +{{- end}} +{{- end}} +{{- end}} diff --git a/resources/helm/v2.5/mesh-config/values.yaml b/resources/helm/v2.5/mesh-config/values.yaml new file mode 100644 index 0000000000..ff0d9f288b --- /dev/null +++ b/resources/helm/v2.5/mesh-config/values.yaml @@ -0,0 +1,64 @@ +# meshConfig defines runtime configuration of components, including Istiod and istio-agent behavior +# See https://istio.io/docs/reference/config/istio.mesh.v1alpha1/ for all available options +meshConfig: + # The namespace to treat as the administrative root namespace for Istio configuration. + # When processing a leaf namespace Istio will search for declarations in that namespace first + # and if none are found it will search in the root namespace. Any matching declaration found in the root namespace + # is processed as if it were declared in the leaf namespace. + rootNamespace: + +global: + multiCluster: + # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection + # to properly label proxies + clusterName: "" + + # Default mtls policy. If true, mtls between services will be enabled by default. + mtls: + # Default setting for service-to-service mtls. Can be set explicitly using + # destination rules or service annotations. + enabled: false + # If set to true, and a given service does not have a corresponding DestinationRule configured, + # or its DestinationRule does not have TLSSettings specified, Istio configures client side + # TLS configuration automatically, based on the server side mTLS authentication policy and the + # availibity of sidecars. + auto: true + +telemetry: + enabled: true + v2: + # For Null VM case now. + # This also enables metadata exchange. + enabled: true + metadataExchange: + # Indicates whether to enable WebAssembly runtime for metadata exchange filter. + wasmEnabled: false + # Indicate if prometheus stats filter is enabled or not + prometheus: + enabled: true + # Indicates whether to enable WebAssembly runtime for stats filter. + wasmEnabled: false + # overrides stats EnvoyFilter configuration. + configOverride: + gateway: {} + inboundSidecar: {} + outboundSidecar: {} + # stackdriver filter settings. + stackdriver: + enabled: false + logging: false + monitoring: false + topology: false # deprecated. setting this to true will have no effect, as this option is no longer supported. + disableOutbound: false + # configOverride parts give you the ability to override the low level configuration params passed to envoy filter. + + configOverride: {} + # e.g. + # disable_server_access_logging: false + # disable_host_header_fallback: true + # Access Log Policy Filter Settings. This enables filtering of access logs from stackdriver. + accessLogPolicy: + enabled: false + # To reduce the number of successful logs, default log window duration is + # set to 12 hours. + logWindowDuration: "43200s" diff --git a/resources/helm/v2.5/rls/Chart.yaml b/resources/helm/v2.5/rls/Chart.yaml new file mode 100644 index 0000000000..658a630851 --- /dev/null +++ b/resources/helm/v2.5/rls/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +name: rls +version: 2.1.0 +appVersion: 1.0.0 +tillerVersion: ">=2.7.2-0" +description: Helm chart for Maistra Rate Limiting Server +keywords: + - maistra + - rls +sources: + - http://github.com/maistra/istio +engine: gotpl +icon: https://istio.io/favicons/android-192x192.png diff --git a/resources/helm/v2.5/rls/templates/autoscale.yaml b/resources/helm/v2.5/rls/templates/autoscale.yaml new file mode 100644 index 0000000000..1cb1f8734e --- /dev/null +++ b/resources/helm/v2.5/rls/templates/autoscale.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.rateLimiting.rls.autoscaleEnabled .Values.rateLimiting.rls.autoscaleMin .Values.rateLimiting.rls.autoscaleMax }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: rls-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: rls + release: {{ .Release.Name }} + istio.io/rev: {{ .Values.revision | default "default" }} +spec: + maxReplicas: {{ .Values.rateLimiting.rls.autoscaleMax }} + minReplicas: {{ .Values.rateLimiting.rls.autoscaleMin }} + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: rls-{{ .Values.revision | default "default" }} + metrics: + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.rateLimiting.rls.cpu.targetAverageUtilization }} +--- +{{- end }} diff --git a/resources/helm/v2.5/rls/templates/configmap.yaml b/resources/helm/v2.5/rls/templates/configmap.yaml new file mode 100644 index 0000000000..2e9fe4ab51 --- /dev/null +++ b/resources/helm/v2.5/rls/templates/configmap.yaml @@ -0,0 +1,16 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + labels: + maistra-version: "2.5.0" + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: rls-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} +data: + config.yaml: | +{{- if .Values.rateLimiting.rawRules }} +{{ toYaml .Values.rateLimiting.rawRules | indent 4 }} +{{- end }} diff --git a/resources/helm/v2.5/rls/templates/deployment.yaml b/resources/helm/v2.5/rls/templates/deployment.yaml new file mode 100644 index 0000000000..3ac13a40ef --- /dev/null +++ b/resources/helm/v2.5/rls/templates/deployment.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + maistra-version: "2.5.0" + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: rls-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} +spec: +{{- if not .Values.rateLimiting.rls.autoscaleEnabled }} +{{- if .Values.rateLimiting.rls.replicaCount }} + replicas: {{ .Values.rateLimiting.rls.replicaCount }} +{{- end }} +{{- end }} + selector: + matchLabels: + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: {{ .Values.rateLimiting.rls.rollingMaxSurge }} + maxUnavailable: {{ .Values.rateLimiting.rls.rollingMaxUnavailable }} + template: + metadata: + labels: + maistra-control-plane: {{ .Release.Namespace }} + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + spec: + serviceAccountName: rls-{{ .Values.revision | default "default" }} + containers: + - name: rls + workingDir: "/" +{{- if contains "/" .Values.rateLimiting.rls.image }} + image: "{{ .Values.rateLimiting.rls.image }}" +{{- else }} + image: "{{ .Values.global.hub }}/{{ .Values.rateLimiting.rls.image }}:{{ .Values.global.tag }}" +{{- end }} +{{- if .Values.global.imagePullPolicy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} +{{- end }} + command: + - ratelimit + resources: +{{- if .Values.rateLimiting.rls.resources }} +{{ toYaml .Values.rateLimiting.rls.resources | trim | indent 10 }} +{{- else }} +{{ toYaml .Values.global.defaultResources | trim | indent 10 }} +{{- end }} + env: + - name: USE_STATSD + value: "false" + - name: RUNTIME_ROOT + value: /data + - name: RUNTIME_SUBDIRECTORY + value: ratelimit + - name: RUNTIME_WATCH_ROOT + value: "false" + - name: RUNTIME_IGNOREDOTFILES + value: "true" + {{- if .Values.rateLimiting.rls.env }} + {{- range $key, $val := .Values.rateLimiting.rls.env }} + - name: {{ $key }} + value: "{{ $val }}" + {{- end }} + {{- end }} + ports: + - containerPort: 8080 + - containerPort: 8081 + - containerPort: 6070 + volumeMounts: + - name: config-volume + mountPath: /data/ratelimit/config + volumes: + - name: config-volume + configMap: + name: rls-{{ .Values.revision | default "default" }} + items: + - key: config.yaml + path: config.yaml + dnsPolicy: ClusterFirst + restartPolicy: Always + securityContext: {} + terminationGracePeriodSeconds: 30 diff --git a/resources/helm/v2.5/rls/templates/service.yaml b/resources/helm/v2.5/rls/templates/service.yaml new file mode 100644 index 0000000000..a005c9e307 --- /dev/null +++ b/resources/helm/v2.5/rls/templates/service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: rls-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + ports: + - port: 8080 + targetPort: 8080 + name: http-port + protocol: TCP + - port: 8081 + targetPort: 8081 + name: grpc-port + protocol: TCP + selector: + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} diff --git a/resources/helm/v2.5/rls/templates/serviceaccount.yaml b/resources/helm/v2.5/rls/templates/serviceaccount.yaml new file mode 100644 index 0000000000..1a6ff88852 --- /dev/null +++ b/resources/helm/v2.5/rls/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: rls-{{ .Values.revision | default "default" }} + namespace: {{ .Release.Namespace }} + labels: + maistra-version: "2.5.0" + app: rls + istio.io/rev: {{ .Values.revision | default "default" }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.global.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} diff --git a/resources/helm/v2.5/rls/values.yaml b/resources/helm/v2.5/rls/values.yaml new file mode 100644 index 0000000000..4a8599ab0f --- /dev/null +++ b/resources/helm/v2.5/rls/values.yaml @@ -0,0 +1,21 @@ +global: + imagePullSecrets: [] + +rateLimiting: + rls: + enabled: true + autoscaleEnabled: false + autoscaleMin: 1 + autoscaleMax: 5 + replicaCount: 1 + rollingMaxSurge: 100% + rollingMaxUnavailable: 25% + + image: rls + + env: {} + + cpu: + targetAverageUtilization: 80 + + rawRules: {} diff --git a/resources/smcp-templates/v2.5/base b/resources/smcp-templates/v2.5/base new file mode 100644 index 0000000000..4dc3461245 --- /dev/null +++ b/resources/smcp-templates/v2.5/base @@ -0,0 +1,88 @@ +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +metadata: + name: base +spec: + version: v2.5 + gateways: + enabled: true + ingress: + enabled: true + ingress: false + service: + type: ClusterIP + egress: + enabled: true + openshiftRoute: + enabled: true + + general: + logging: + componentLevels: + default: warn + + proxy: + injection: + autoInject: false + networking: + protocol: + autoDetect: + inbound: false + outbound: false + dns: + refreshRate: 300s + + security: + identity: + type: Kubernetes + + telemetry: + type: Istiod + + policy: + type: None + + tracing: + type: Jaeger + + addons: + prometheus: + enabled: true + install: + service: + metadata: + annotations: + service.alpha.openshift.io/serving-cert-secret-name: prometheus-tls + ingress: + enabled: true + + jaeger: + name: jaeger + install: + storage: + type: Memory + ingress: + enabled: true + + grafana: + enabled: true + install: + service: + metadata: + annotations: + service.alpha.openshift.io/serving-cert-secret-name: grafana-tls + ingress: + enabled: true + kiali: + enabled: true + name: kiali + install: + dashboard: + viewOnly: false + service: + ingress: + enabled: true + techPreview: + sidecarInjectorWebhook: + objectSelector: + enabled: false diff --git a/resources/smcp-templates/v2.5/gateway-controller b/resources/smcp-templates/v2.5/gateway-controller new file mode 100644 index 0000000000..03836446bb --- /dev/null +++ b/resources/smcp-templates/v2.5/gateway-controller @@ -0,0 +1,21 @@ +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +spec: + mode: ClusterWide + addons: + grafana: + enabled: false + kiali: + enabled: false + prometheus: + enabled: false + gateways: + enabled: false + tracing: + type: None + techPreview: + global: + caCertConfigMapName: ossm-ca-root-cert + gatewayAPI: + enabled: true + controllerMode: true diff --git a/resources/smcp-templates/v2.5/maistra b/resources/smcp-templates/v2.5/maistra new file mode 100644 index 0000000000..2c692a4ec3 --- /dev/null +++ b/resources/smcp-templates/v2.5/maistra @@ -0,0 +1,46 @@ +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +spec: + profiles: + - base + - small + + runtime: + defaults: + container: + imageRegistry: docker.io/maistra + imageTag: 2.5.0 + components: + grafana: + container: + imageName: grafana-ubi8 + pilot: + container: + imageName: pilot-ubi8 + prometheus: + container: + imageName: prometheus-ubi8 + 3scale: + container: + imageRegistry: quay.io/3scale + imageName: 3scale-istio-adapter + imageTag: v2.0.0 + global.oauthproxy: + container: + imageRegistry: quay.io/openshift + imageName: origin-oauth-proxy + imageTag: "4.9" + imagePullPolicy: IfNotPresent + rateLimiting.rls: + container: + imageName: ratelimit-ubi8 + + proxy: + runtime: + container: + imageName: proxyv2-ubi8 + networking: + initialization: + initContainer: + runtime: + imageName: proxy-init-centos7 diff --git a/resources/smcp-templates/v2.5/servicemesh b/resources/smcp-templates/v2.5/servicemesh new file mode 100644 index 0000000000..9d2c9c2a01 --- /dev/null +++ b/resources/smcp-templates/v2.5/servicemesh @@ -0,0 +1,46 @@ +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +spec: + profiles: + - base + - small + + runtime: + defaults: + container: + imageRegistry: registry.redhat.io/openshift-service-mesh + imageTag: 2.5.0 + components: + grafana: + container: + imageName: grafana-rhel8 + pilot: + container: + imageName: pilot-rhel8 + prometheus: + container: + imageName: prometheus-rhel8 + 3scale: + container: + imageRegistry: registry.redhat.io/openshift-service-mesh + imageName: 3scale-istio-adapter-rhel8 + imageTag: 2.0.0 + global.oauthproxy: + container: + imageRegistry: registry.redhat.io/openshift4 + imageName: ose-oauth-proxy + imageTag: v4.9 + imagePullPolicy: IfNotPresent + rateLimiting.rls: + container: + imageName: ratelimit-rhel8 + + proxy: + runtime: + container: + imageName: proxyv2-rhel8 + networking: + initialization: + initContainer: + runtime: + imageName: proxy-init-rhel7 diff --git a/resources/smcp-templates/v2.5/small b/resources/smcp-templates/v2.5/small new file mode 100644 index 0000000000..1479666555 --- /dev/null +++ b/resources/smcp-templates/v2.5/small @@ -0,0 +1,73 @@ +apiVersion: maistra.io/v2 +kind: ServiceMeshControlPlane +metadata: + name: small +spec: + runtime: + defaults: + deployment: + podDisruption: + enabled: false + container: + # constrain resources for use in smaller environments + resources: + requests: + cpu: 10m + memory: 128Mi + limits: {} + components: + pilot: + deployment: + autoScaling: + enabled: false + container: + # constrain resources for use in smaller environments + resources: + requests: + cpu: 10m + memory: 128Mi + limits: {} + prometheus: + container: + # constrain resources for use in smaller environments + resources: + requests: + cpu: 10m + memory: 128Mi + limits: {} + + gateways: + ingress: + runtime: + deployment: + autoScaling: + enabled: false + container: + # constrain resources for use in smaller environments + resources: + requests: + cpu: 10m + memory: 128Mi + limits: {} + egress: + runtime: + deployment: + autoScaling: + enabled: false + container: + # constrain resources for use in smaller environments + resources: + requests: + cpu: 10m + memory: 128Mi + limits: {} + + proxy: + runtime: + container: + # constrain resources for use in smaller environments + resources: + requests: + cpu: 10m + memory: 128Mi + limits: {}