├── .gitignore ├── logo.png ├── .helmignore ├── templates ├── podDisruption.yaml ├── serviceAccount.yaml ├── configmap.yaml ├── rbac-cluster.yaml ├── bzm-gateway.yaml ├── _helpers.tpl ├── rbac-ns.yaml ├── tests │ ├── testrbac.yaml │ └── testhook.yaml ├── secretStore.yaml └── crane.yaml ├── Chart.yaml ├── LICENSE ├── values.yaml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS* 2 | *.key 3 | *.pem -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Blazemeter/helm-crane/main/logo.png -------------------------------------------------------------------------------- /.helmignore: -------------------------------------------------------------------------------- 1 | *.png 2 | .git 3 | *.md 4 | .gitignore 5 | *.key 6 | *.crt 7 | *.pem -------------------------------------------------------------------------------- /templates/podDisruption.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.podDisruptionBudget.enable | default false }} 2 | apiVersion: policy/v1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | name: {{ .Release.Name }}-pdb 6 | namespace: {{ .Release.Namespace }} 7 | spec: 8 | {{ if and (.Values.podDisruptionBudget.maxUnavailable) ( empty .Values.podDisruptionBudget.minAvailable) }} 9 | maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} 10 | {{ else }} 11 | minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} 12 | {{ end }} 13 | selector: 14 | matchLabels: 15 | {{ .Values.podDisruptionBudget.matchLabels | toYaml | nindent 8 }} 16 | {{ end }} -------------------------------------------------------------------------------- /templates/serviceAccount.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.deployment.serviceAccount.create | default false}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "blazemeter-crane.serviceAccountName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | {{ if .Values.deployment.serviceAccount.annotations | default false}} 8 | annotations: 9 | {{- with .Values.deployment.serviceAccount.annotations }} 10 | {{ toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{ end }} 13 | labels: 14 | role: {{ include "crane.roleName" . }} 15 | clusterrole: {{ include "crane.clusterroleName" . }} 16 | {{ if .Values.labelsCrane.enable | default false -}} 17 | {{ .Values.labelsCrane.syntax | toYaml | nindent 4 -}} 18 | {{ end -}} 19 | {{ end }} 20 | -------------------------------------------------------------------------------- /templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | {{ if or ( .Values.ca_bundle.enable | default false ) ( .Values.gridProxy.enable | default false ) }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ .Release.Name }}-configmap 6 | namespace: {{ .Release.Namespace }} 7 | data: 8 | {{ if .Values.ca_bundle.enable }} 9 | {{ .Values.ca_bundle.request_ca_bundle }}: |- 10 | {{ .Files.Get .Values.ca_bundle.request_ca_bundle | indent 4 }} 11 | {{ .Values.ca_bundle.aws_ca_bundle }}: |- 12 | {{ .Files.Get .Values.ca_bundle.aws_ca_bundle | indent 4 }} 13 | {{ end -}} 14 | {{ if .Values.gridProxy.enable }} 15 | {{ .Values.gridProxy.tlsKeyGrid }}: |- 16 | {{ .Files.Get .Values.gridProxy.tlsKeyGrid | indent 4 }} 17 | {{ .Values.gridProxy.tlsCertGrid }}: |- 18 | {{ .Files.Get .Values.gridProxy.tlsCertGrid | indent 4 }} 19 | {{ end -}} 20 | {{ end -}} -------------------------------------------------------------------------------- /templates/rbac-cluster.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.deployment.clusterrole }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: {{ include "crane.clusterroleName" . }} 6 | rules: 7 | - apiGroups: [""] 8 | resources: ["nodes"] 9 | verbs: ["get", "list", "update", "watch", "patch" ] 10 | --- 11 | {{ end }} 12 | apiVersion: rbac.authorization.k8s.io/v1 13 | kind: ClusterRoleBinding 14 | metadata: 15 | name: {{ include "crane.clusterroleName" . }}binding-{{ template "blazemeter-crane.serviceAccountName" . }}-{{ .Release.Name }} 16 | roleRef: 17 | apiGroup: rbac.authorization.k8s.io 18 | kind: ClusterRole 19 | name: {{ include "crane.clusterroleName" . }} 20 | subjects: 21 | - kind: ServiceAccount 22 | name: {{ template "blazemeter-crane.serviceAccountName" . }} 23 | namespace: {{ .Release.Namespace }} -------------------------------------------------------------------------------- /templates/bzm-gateway.yaml: -------------------------------------------------------------------------------- 1 | {{ if eq .Values.service_virtualization.ingressType "istio" | default "" }} 2 | apiVersion: networking.istio.io/v1alpha3 3 | kind: Gateway 4 | metadata: 5 | name: {{ .Release.Name }}-gateway 6 | namespace : {{ .Release.Namespace }} 7 | spec: 8 | selector: 9 | istio: ingressgateway 10 | servers: 11 | - port: 12 | number: 80 13 | name: http-80 14 | protocol: HTTP 15 | hosts: 16 | - "*" 17 | - port: 18 | number: 443 19 | name: https-443 20 | protocol: HTTPS 21 | hosts: 22 | - "*" 23 | tls: 24 | mode: SIMPLE 25 | # This must be located in the "istio-system" namespace 26 | credentialName: {{ .Values.service_virtualization.credentialName }} 27 | - port: 28 | number: 15443 29 | name: https-15443 30 | protocol: HTTPS 31 | hosts: 32 | - "*" 33 | tls: 34 | mode: PASSTHROUGH 35 | {{ end }} 36 | -------------------------------------------------------------------------------- /Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: helm-crane 3 | description: A Helm chart for Blazemeter crane private location engine deployment. 4 | keywords: 5 | - crane 6 | - Blazemeter 7 | - Kubernetes 8 | - Private location 9 | - OPL 10 | - Automation Testing 11 | - Load Generator 12 | - Auto scalling 13 | - CA_Bundle 14 | - Proxy-configurations 15 | - Istio 16 | - Ingress 17 | - Labels 18 | - ResourceLimit 19 | - Nginx Ingress 20 | - NodeSelector 21 | - Tolerations 22 | - TLS Grid 23 | - Grid Proxy 24 | - Ephemeral Storage 25 | - ImageOverride 26 | - Private repository 27 | - ReadinessProbe 28 | - LivenessProbe 29 | - Secret Store CSI 30 | - Pod Disruption Budget 31 | - External Secret Operator 32 | - Test Hook 33 | - Custom Annotations 34 | 35 | type: application 36 | icon: https://github.com/Blazemeter/helm-crane/raw/main/logo.png 37 | #dependencies: 38 | # - name: nginx 39 | # condition: .Values.installed 40 | 41 | version: 1.4.4 42 | 43 | maintainers: 44 | - name: Manan Patel 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | 2 | {{- define "blazemeter-crane.fullname" -}} 3 | {{- default .Chart.Name .Release.Name | trunc 63 | trimSuffix "-" }} 4 | {{- end }} 5 | 6 | {{- define "blazemeter-crane.serviceAccountName" -}} 7 | {{- if .Values.deployment.serviceAccount.create }} 8 | {{- default (include "blazemeter-crane.fullname" .) .Values.deployment.serviceAccount.name -}} 9 | {{- else }} 10 | {{- default "default" .Values.deployment.serviceAccount.name -}} 11 | {{- end }} 12 | {{- end }} 13 | 14 | # Return the role name: use .Values.deployment.role if set, else use the default {{ .Release.Name }}-role. 15 | {{- define "crane.roleName" }} 16 | {{- if .Values.deployment.role }} 17 | {{- .Values.deployment.role }} 18 | {{- else }} 19 | {{- printf "%s-role" .Release.Name }} 20 | {{- end }} 21 | {{- end }} 22 | 23 | {{- define "crane.clusterroleName" }} 24 | {{- if .Values.deployment.clusterrole }} 25 | {{- .Values.deployment.clusterrole }} 26 | {{- else }} 27 | {{- printf "%s-clusterrole" .Release.Name }} 28 | {{- end }} 29 | {{- end }} 30 | 31 | # This helper function returns the imageOverrides as a JSON object if set. 32 | {{- define "helm-crane.imageOverridesJson" -}} 33 | {{- $overrides := .Values.imageOverride.executorImages | default dict -}} 34 | {{- $nonEmpty := dict -}} 35 | {{- range $k, $v := $overrides -}} 36 | {{- if $v -}} 37 | {{- $_ := set $nonEmpty $k $v -}} 38 | {{- end -}} 39 | {{- end -}} 40 | {{- if eq (len $nonEmpty) 0 -}} 41 | {} 42 | {{- else -}} 43 | {{- $first := true -}} 44 | {{- print "{" -}} 45 | {{- range $k, $v := $nonEmpty -}} 46 | {{- if not $first -}}{{- print "," -}}{{- end -}} 47 | {{- printf "\"%s\":\"%s\"" $k $v -}} 48 | {{- $first = false -}} 49 | {{- end -}} 50 | {{- print "}" -}} 51 | {{- end -}} 52 | {{- end -}} -------------------------------------------------------------------------------- /templates/rbac-ns.yaml: -------------------------------------------------------------------------------- 1 | {{ if not .Values.deployment.role }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: {{ include "crane.roleName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | rules: 8 | - apiGroups: [""] 9 | resources: ["pods/exec"] 10 | verbs: ["create"] 11 | - apiGroups: [""] 12 | resources: ["pods", "pods/log"] 13 | verbs: ["get", "list"] 14 | - apiGroups: ["extensions", "apps", "batch", ""] # leave empty string for core 15 | resources: ["pods", "services", "endpoints", "daemonsets", "pods/*", "pods/exec", "deployments", "replicasets", "ingresses", "deployments/scale", "jobs"] 16 | verbs: ["get", "list", "watch", "create", "update", "patch", "delete", "deletecollection", "createcollection"] 17 | {{ if eq .Values.service_virtualization.ingressType "istio" }} 18 | # this is for istio ingress mock services deployment 19 | - apiGroups: ["networking.istio.io"] 20 | resources: ["destinationrules", "virtualservices", "gateways"] 21 | verbs: ["get", "list", "create", "delete", "patch", "update"] 22 | {{ else if eq .Values.service_virtualization.ingressType "nginx" }} 23 | # this is for nginx ingress mock services deployment 24 | - apiGroups: ["networking.k8s.io"] 25 | resources: ["virtualservices", "gateways", "ingresses"] 26 | verbs: ["get", "list", "create", "delete", "patch", "update"] 27 | {{ end }} 28 | --- 29 | {{ end }} 30 | apiVersion: rbac.authorization.k8s.io/v1 31 | kind: RoleBinding 32 | metadata: 33 | name: {{ include "crane.roleName" . }}binding-{{ template "blazemeter-crane.serviceAccountName" . }}-{{ .Release.Name }} 34 | namespace: {{ .Release.Namespace }} 35 | subjects: 36 | - kind: ServiceAccount 37 | name: {{ template "blazemeter-crane.serviceAccountName" . }} 38 | namespace: {{ .Release.Namespace }} 39 | roleRef: 40 | kind: Role 41 | name: {{ include "crane.roleName" . }} 42 | apiGroup: rbac.authorization.k8s.io -------------------------------------------------------------------------------- /templates/tests/testrbac.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: test-hookrole 5 | namespace: {{ .Release.Namespace }} 6 | annotations: 7 | "helm.sh/hook": pre-install 8 | "helm.sh/hook-delete-policy": before-hook-creation 9 | rules: 10 | - apiGroups: ["rbac.authorization.k8s.io"] 11 | resources: ["rolebindings", "roles"] 12 | verbs: ["get", "list"] 13 | - apiGroups: [""] 14 | resources: ["secrets", "namespaces", "pods", "nodes", "services", "endpoints", "configmaps"] 15 | verbs: ["get", "list"] 16 | - apiGroups: ["networking.k8s.io"] 17 | resources: ["ingresses"] 18 | verbs: ["get", "list"] 19 | 20 | --- 21 | apiVersion: rbac.authorization.k8s.io/v1 22 | kind: RoleBinding 23 | metadata: 24 | name: test-hookrole-binding-{{ template "blazemeter-crane.serviceAccountName" . }} 25 | namespace: {{ .Release.Namespace }} 26 | annotations: 27 | "helm.sh/hook": pre-install 28 | "helm.sh/hook-delete-policy": before-hook-creation 29 | subjects: 30 | - kind: ServiceAccount 31 | name: {{ template "blazemeter-crane.serviceAccountName" . }} 32 | namespace: {{ .Release.Namespace }} 33 | roleRef: 34 | kind: Role 35 | name: test-hookrole 36 | apiGroup: rbac.authorization.k8s.io 37 | 38 | {{- if eq ((.Values.service_virtualization | default dict).ingressType | default "") "istio" }} 39 | --- 40 | apiVersion: rbac.authorization.k8s.io/v1 41 | kind: Role 42 | metadata: 43 | name: test-hookrole-istio 44 | namespace: istio-system 45 | annotations: 46 | "helm.sh/hook": pre-install 47 | "helm.sh/hook-delete-policy": before-hook-creation 48 | rules: 49 | - apiGroups: [""] 50 | resources: ["secrets"] 51 | verbs: ["get", "list"] 52 | - apiGroups: ["networking.istio.io"] 53 | resources: ["virtualservices", "destinationrules", "gateways", "serviceentries"] 54 | verbs: ["get", "list"] 55 | --- 56 | apiVersion: rbac.authorization.k8s.io/v1 57 | kind: RoleBinding 58 | metadata: 59 | name: test-hookrole-istio-binding-{{ template "blazemeter-crane.serviceAccountName" . }} 60 | namespace: istio-system 61 | annotations: 62 | "helm.sh/hook": pre-install 63 | "helm.sh/hook-delete-policy": before-hook-creation 64 | subjects: 65 | - kind: ServiceAccount 66 | name: {{ template "blazemeter-crane.serviceAccountName" . }} # or your custom SA name 67 | namespace: {{ .Release.Namespace }} # your pod's namespace 68 | roleRef: 69 | kind: Role 70 | name: test-hookrole-istio 71 | apiGroup: rbac.authorization.k8s.io 72 | {{ end }} -------------------------------------------------------------------------------- /templates/tests/testhook.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: cranehook 5 | namespace: {{ .Release.Namespace }} 6 | {{ if .Values.labelsCrane.enable | default false -}} 7 | labels: 8 | {{ .Values.labelsCrane.syntax | toYaml | nindent 4 }} 9 | {{ end }} 10 | annotations: 11 | "helm.sh/hook": test 12 | "helm.sh/hook-delete-policy": before-hook-creation 13 | "helm.sh/hook-container-name": cranetest-ctr 14 | "sidecar.istio.io/inject": "false" 15 | {{ if .Values.annotationsCrane.enable | default false -}} 16 | {{ .Values.annotationsCrane.syntax | toYaml | nindent 4 }} 17 | {{ end }} 18 | spec: 19 | serviceAccountName: {{ template "blazemeter-crane.serviceAccountName" . }} 20 | automountServiceAccountToken: true 21 | #ttlSecondsAfterFinished: 90 22 | {{ if .Values.nodeSelectorCrane.enable | default false }} 23 | nodeSelector: 24 | {{ .Values.nodeSelectorCrane.syntax | toYaml | nindent 4 }} 25 | {{ end -}} 26 | {{ if .Values.tolerationCrane.enable }} 27 | tolerations: 28 | {{ .Values.tolerationCrane.syntax | toYaml | nindent 4 }} 29 | {{ end }} 30 | containers: 31 | - name: cranehook-ctr 32 | securityContext: 33 | runAsUser: 1337 34 | runAsGroup: 1337 35 | allowPrivilegeEscalation: false 36 | runAsNonRoot: true 37 | env: 38 | - name: WORKING_NAMESPACE 39 | value: {{ .Release.Namespace | quote }} 40 | - name: ROLE_NAME 41 | value: {{ include "crane.roleName" . }} 42 | - name: ROLE_BINDING_NAME 43 | value: {{ include "crane.roleName" . }}binding-{{ template "blazemeter-crane.serviceAccountName" . }}-{{ .Release.Name }} 44 | - name: SERVICE_ACCOUNT_NAME 45 | value: {{ template "blazemeter-crane.serviceAccountName" . }} 46 | {{ if .Values.service_virtualization.enable | default false -}} 47 | {{ if eq .Values.service_virtualization.ingressType "istio" }} 48 | - name: KUBERNETES_WEB_EXPOSE_TYPE 49 | value: "ISTIO" 50 | - name: KUBERNETES_ISTIO_GATEWAY_NAME 51 | value: {{ .Release.Name }}-gateway 52 | {{ else if eq .Values.service_virtualization.ingressType "nginx" }} 53 | - name: KUBERNETES_WEB_EXPOSE_TYPE 54 | value: "INGRESS" 55 | {{ end }} 56 | - name: KUBERNETES_WEB_EXPOSE_TLS_SECRET_NAME 57 | value: {{ .Values.service_virtualization.credentialName | default "wildcard-credential" | quote }} 58 | {{ end }} 59 | - name: DOCKER_REGISTRY 60 | value: {{ .Values.imageOverride.docker_registry | default "gcr.io/verdant-bulwark-278" | quote }} 61 | {{ if .Values.proxy.enable | default false -}} 62 | {{ if ne .Values.proxy.http_path "" }} 63 | - name: HTTP_PROXY 64 | value: {{ .Values.proxy.http_path }} 65 | {{ end -}} 66 | {{ if ne .Values.proxy.https_path "" }} 67 | - name: HTTPS_PROXY 68 | value: {{ .Values.proxy.https_path }} 69 | {{ end }} 70 | - name: NO_PROXY 71 | value: {{ .Values.proxy.no_proxy | default "kubernetes.default,127.0.0.1,localhost"}} 72 | {{ end -}} 73 | image: {{ .Values.imageOverride.testImage | default "gcr.io/verdant-bulwark-278/cranehook"}}:{{ .Values.imageOverride.testTag | default "latest" }} 74 | imagePullPolicy: "Always" 75 | resources: 76 | requests: 77 | cpu: 100m 78 | memory: 256Mi 79 | limits: 80 | cpu: 200m 81 | memory: 512Mi 82 | volumeMounts: 83 | - name: testhook-tmp 84 | mountPath: /tmp/testhook 85 | volumes: 86 | - name: testhook-tmp 87 | emptyDir: {} 88 | restartPolicy: "Never" 89 | -------------------------------------------------------------------------------- /templates/secretStore.yaml: -------------------------------------------------------------------------------- 1 | {{ if and (.Values.secretProviderClass.enable | default false ) (not .Values.externalSecretsOperator.enable | default false ) }} 2 | apiVersion: secrets-store.csi.x-k8s.io/v1 3 | kind: SecretProviderClass 4 | metadata: 5 | name: {{ .Release.Name }}-secrets-store 6 | namespace: {{ .Release.Namespace }} 7 | spec: 8 | parameters: 9 | objects: | 10 | {{ .Values.secretProviderClass.objects | toYaml | nindent 6 }} 11 | provider: {{ .Values.secretProviderClass.provider }} 12 | {{ if .Values.secretProviderClass.secretObjects }} 13 | secretObjects: 14 | {{- range .Values.secretProviderClass.secretObjects }} 15 | - secretName: {{ .secretName }} 16 | type: {{ .type }} 17 | data: 18 | {{- range .data }} 19 | - key: {{ .key }} 20 | objectName: {{ .objectName }} 21 | {{- end }} 22 | {{- end }} 23 | {{ end }} 24 | {{ end }} 25 | {{ if and (.Values.externalSecretsOperator.enable) (not .Values.secretProviderClass.enable) }} 26 | apiVersion: external-secrets.io/v1 27 | kind: SecretStore 28 | {{ with .Values.externalSecretsOperator.secretStore }} 29 | metadata: 30 | name: {{ .name }} 31 | namespace: {{ $.Release.Namespace }} 32 | spec: 33 | {{ with .provider }} 34 | provider: 35 | {{ if and ( .aws.enable ) (not .gcpsm.enable ) }} 36 | aws: 37 | service: {{ .aws.service }} 38 | region: {{ .aws.region }} 39 | auth: 40 | {{ if not .aws.authSecretRef.enable }} 41 | jwt: 42 | serviceAccountRef: 43 | name: {{ template "blazemeter-crane.serviceAccountName" $ }} 44 | namespace: {{ $.Release.Namespace }} 45 | {{ else }} 46 | secretRef: 47 | accessKeyID: 48 | name: {{ .aws.authSecretRef.accessKeyID.name }} 49 | key: {{ .aws.authSecretRef.accessKeyID.key }} 50 | secretAccessKey: 51 | name: {{ .aws.authSecretRef.secretAccessKey.name }} 52 | key: {{ .aws.authSecretRef.secretAccessKey.key }} 53 | {{ end }} 54 | {{ else if and (.gcpsm.enable) (not .aws.enable) }} 55 | gcpsm: 56 | projectID: {{ .gcpsm.projectID }} 57 | auth: 58 | {{ if not .gcpsm.secretRef.enable }} 59 | workloadIdentity: 60 | serviceAccountRef: 61 | name: {{ template "blazemeter-crane.serviceAccountName" $ }} 62 | namespace: {{ $.Release.Namespace }} 63 | {{ else }} 64 | secretRef: 65 | secretKeyRef: 66 | name: {{ .gcpsm.secretRef.secretAccessKeySecretRef.name }} 67 | key: {{ .gcpsm.secretRef.secretAccessKeySecretRef.key }} 68 | {{ end }} 69 | {{ else }} 70 | {{ fail "Either AWS or gcpsm provider must be enabled or disabled, not both." }} 71 | {{ end }} 72 | {{ end }} 73 | {{ end }} 74 | --- 75 | apiVersion: external-secrets.io/v1 76 | kind: ExternalSecret 77 | metadata: 78 | {{ with .Values.externalSecretsOperator }} 79 | name: {{ .externalSecret.name }} 80 | namespace: {{ $.Release.Namespace }} 81 | spec: 82 | refreshInterval: {{ .externalSecret.refreshInterval }} 83 | secretStoreRef: 84 | name: {{ .secretStore.name }} # Reference the SecretStore 85 | kind: SecretStore 86 | target: 87 | name: {{ .externalSecret.target.name }} # Name of Kubernetes Secret to make 88 | data: 89 | {{ range .externalSecret.data }} 90 | - secretKey: {{ .secretKey }} # New key to make 91 | remoteRef: 92 | key: {{ .remoteRef.key }} # Name of the Secret in Secrets Manager 93 | {{- if .remoteRef.property }} 94 | property: {{ .remoteRef.property }} # JSON property to extract 95 | {{ end }} 96 | {{- end }} 97 | {{- end }} 98 | {{ end }} 99 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [2024-25] [Manan Patel] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /values.yaml: -------------------------------------------------------------------------------- 1 | 2 | deployment: 3 | # This is the name of existing roles and clusterroles to use, defaults to releaseName-role and releaseName-clusterrole 4 | role: # Mention if you wish to use the existing role in the namespace 5 | clusterrole: # Mention if you wish to use the existing clusterrole 6 | serviceAccount: 7 | # Specifies whether a ServiceAccount should be created, if already exists, the value should be false. 8 | create: false 9 | # The name of the ServiceAccount to use, keep empty to use default ServiceAccount. 10 | name: # sample-serviceAccount-name 11 | annotations: 12 | # This is a sample annotation. You can add any annotations here. Comment out if not needed. 13 | eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/example-role 14 | custom.annotation/key: custom-value 15 | restartPolicy: # Defaults to Always as recommended 16 | 17 | env: 18 | # if you plan to pass the AUTH_TOKEN through secret store, use secret store CSI driver or External Secrets Operator, the below will be ignored. 19 | authtoken: 20 | harbour_id: 21 | ship_id: 22 | 23 | # Allows the override of the default image received from BZA for the container to run. Set the key to the original value (Example: apm-image:latest). Set the value to the new repository name with a tag. Extract the appropriate version number from 'admin/ship-stats'. 24 | imageOverride: 25 | # Add the details below to override the default image used by Crane and default configuration. 26 | docker_registry: # Example: "gcr.io/" 27 | craneImage: # Example: "gcr.io//blazemeter/crane" 28 | tag: # Default: "latest-master" 29 | auto_update: # Default: true 30 | auto_update_running_containers: # Controls auto update of components, default false. Also, either AUTO_UPDATE or AUTO_KUBERNETES_UPDATE must be true for this option to work, depending on the platform Crane is running on. 31 | # Example: {"blazemeter/crane:latest":"gcr.io/verdant-bulwark-278/blazemeter/crane:3.6.47"} 32 | pullPolicy: # Default: "Always" 33 | #executorImages: # {"taurus-cloud:latest": "pathToYourRepo/", "torero:latest": "pathToYourRepo/", "blazemeter/service-mock:latest": "pathToYourRepo/", "blazemeter/mock-pc-service:latest": "pathToYourRepo/", "blazemeter/sv-bridge:latest": "pathToYourRepo/", "blazemeter/doduo:latest": "pathToYourRepo/"} 34 | executorImages: 35 | crane:latest: # "pathToYourRepo/crane:version" 36 | taurus-cloud:latest: #"pathToYourRepo/taurus-cloud:version" 37 | torero:latest: #"pathToYourRepo/torero:version" 38 | service-mock:latest: # "pathToYourRepo/service-mock:version" 39 | sv-bridge:latest: # "pathToYourRepo/sv-bridge:version" 40 | doduo:latest: # "pathToYourRepo/doduo:version" 41 | proxy-recorder:latest: # "pathToYourRepo/proxy-recorder:version" 42 | apm-image:latest: # "pathToYourRepo/apm-image:version" 43 | # CHECK VERSION IN THE RSS FEED 44 | # blazemeter/charmander/microsoftedge_128.0.2739.81:latest: # "pathToYourRepo/charmander/microsoftedge_128.0.2739.81:version" 45 | # blazemeter/charmander/safari_15.0:latest: # "pathToYourRepo/charmander/safari_15.0:version" 46 | # blazemeter/charmander/firefox_128.0:latest: # "pathToYourRepo/charmander/firefox_128.0:version" 47 | # blazemeter/charmander/chrome_128.0.6613.137:latest: # "pathToYourRepo/charmander/chrome_128.0.6613.137:version" 48 | 49 | testImage: # Default: "gcr.io/verdant-bulwark-278/cranehook", used for test-hook 50 | testTag: # Default: "latest" 51 | 52 | # Proxy configurations here, change enable to yes, followed by http/https configuration 53 | proxy: 54 | enable: no 55 | # If you have authentication required for your proxy, then you will need to add username:password@server:port 56 | http_path: # "http://server:port" 57 | https_path: # "https://server:port" 58 | # The NO_PROXY settings for 127.0.0.1 and localhost (provided below) are required for the Service Virtualization integration and transaction-based Mock Services to work. If you do not enable any HTTP_PROXY or HTTPS_PROXY settings, you can skip the NO_PROXY setting. 59 | no_proxy: # "kubernetes.default,127.0.0.1,localhost,myHostname.com" 60 | 61 | # Configure CA Bundle here - Change enable: yes 62 | # Add these certifates to the chart main directory, for example: we have placed certificate.crt in the chart main directory. 63 | ca_bundle: 64 | enable: no 65 | request_ca_bundle: "certificate.crt" 66 | aws_ca_bundle: "certificate2.crt" 67 | volume: 68 | volume_name: "volume-cm" 69 | mount_path: "/var/cm" 70 | readOnly: true 71 | 72 | #For functional test only. This uses the same environment. Place the certificate in chart main directory. 73 | gridProxy: 74 | enable: no 75 | a_environment: 'https://your.environment.net' 76 | tlsKeyGrid: "certificate.key" # The private key for the domain used to run the BlazeMeter Grid proxy over HTTPS. Value in string format. 77 | tlsCertGrid: "certificate.crt" # The public certificate for the domain used to run the BlazeMeter Grid proxy over HTTPS. Value in string format. 78 | mount_path: "/etc/ssl/certs/doduo" 79 | doduoPort: 9070 # The user-defined port where to run Doduo (BlazeMeter Grid Proxy). By default, Doduo listens on port 8000. 80 | volume: 81 | volume_name: "tls-files" 82 | mount_path: "/etc/ssl/certs/doduo" 83 | readOnly: true 84 | 85 | 86 | # If you plan to enable non-privileged containers, please enable the below configuration, change enable:yes 87 | # This will run all pods/containers (related to private location installation)as well as crane within the cluster as non_root. 88 | # Non-root deployment requires qualifying plan and an additional feature to be enabled, please contact support for enabling this feature if your account has a qualifying plan. 89 | non_privilege_container: 90 | enable: no 91 | runAsGroup: 1337 92 | runAsUser: 1337 93 | 94 | 95 | # Enable the service_virtualization if this Private location is going to run service-virtualisation or formerly called: mock-services 96 | # Select the ingressType as nginx or istio, depending on your cluster ingress setup. 97 | # Follow Blazemeter guide for more information: https://help.blazemeter.com/docs/guide/private-locations-install-blazemeter-agent-for-kubernetes-for-mock-services.html 98 | 99 | service_virtualization: 100 | enable: no 101 | ingressType: # nginx or istio 102 | credentialName: # "wildcard-credential" 103 | web_expose_subdomain: # "mydomain.local" 104 | 105 | 106 | # Labels to add to crane and child resources created by Crane, must be in JSON format. 107 | labelsCrane: 108 | enable: no 109 | syntax: {"label_1": "label_1_value", "label_2": "label_2_value"} 110 | labelsExecutors: 111 | enable: no 112 | syntax: {"label_1": "label_1_value", "label_2": "label_2_value"} 113 | 114 | #Set to specify the tolerations for the crane and child resources. Must be in JSON format. 115 | tolerationCrane: 116 | enable: no 117 | syntax: [{ "effect": "NoSchedule", "key": "lifecycle", "operator": "Equal", "value": "spot" }] 118 | tolerationExecutors: 119 | enable: no 120 | syntax: [{ "effect": "NoSchedule", "key": "lifecycle", "operator": "Equal", "value": "spot" }] 121 | 122 | #Used to configure the k8s nodeSelector field to match specific node labels for the Crane as well as child resources. Must be in JSON format. 123 | nodeSelectorCrane: 124 | enable: no 125 | syntax: {"label_1": "label_1_value", "label_2": "label_2_value"} 126 | nodeSelectorExecutor: 127 | enable: no 128 | syntax: {"label_1": "label_1_value", "label_2": "label_2_value"} 129 | 130 | 131 | # Used to add annotations to the Crane and it's child resources. Must be in JSON format. 132 | # "cluster-autoscaler.kubernetes.io/safe-to-evict" is set to 'false' by default for child resources. 133 | 134 | annotationsCrane: 135 | enable: no 136 | syntax: {"custom_annotation1": "value1", "custom_annotation2": "value2"} 137 | annotationsExecutor: 138 | enable: no 139 | syntax: {"custom_annotation1": "value1", "custom_annotation2": "value2"} 140 | 141 | 142 | # CPU & Memory limits & requests for resources for crane deployment. You can also specify ephemeral storage limits for the crane. 143 | resourcesCrane: 144 | requests: 145 | CPU: 250m 146 | MEM: 512Mi 147 | storage: #100 148 | limits: 149 | CPU: #1 150 | MEM: #2Gi 151 | storage: #1024 152 | 153 | # CPU & Memory limits & requests for resources for child resources. You can also specify ephemeral storage limits for the child resources. 154 | resourcesExecutors: 155 | requests: 156 | CPU: 1000m 157 | MEM: 4096 # This value should be an integer unlike other values that supports k8s standard for declaring resource limits/requests. 158 | storage: #100 159 | limits: 160 | CPU: #2 161 | MEM: #8Gi 162 | storage: #1024 163 | 164 | 165 | #Configure Liveness & Readiness Probes, defaults are used, if not specified. See commented values below. 166 | probes: 167 | enable: yes 168 | livenessProbe: 169 | httpGet: 170 | path: /healtz 171 | port: # 5000 172 | scheme: HTTP 173 | failureThreshold: # 5 174 | initialDelaySeconds: # 5 175 | periodSeconds: # 15 176 | successThreshold: # 1 177 | timeoutSeconds: # 10 178 | 179 | readinessProbe: 180 | httpGet: 181 | path: /healtz 182 | port: # 5000 183 | scheme: HTTP 184 | failureThreshold: # 3 185 | initialDelaySeconds: # 5 186 | periodSeconds: # 15 187 | successThreshold: # 1 188 | timeoutSeconds: # 10 189 | 190 | 191 | podDisruptionBudget: 192 | enable: no 193 | # min or max, disruptions can only support one. - https://kubernetes.io/docs/tasks/run-application/configure-pdb/ 194 | # If both are specified, minAvailable is used. 195 | minAvailable: 1 196 | maxUnavailable: #5 197 | matchLabels: {"label_1": "label_1_value", "label_2": "label_2_value"} 198 | 199 | 200 | secretProviderClass: 201 | enable: no 202 | provider: aws 203 | # This is in JSON, to allow users configure different spec, like: secretPath, secretKey, objectAlias, etc. 204 | objects: [{ "objectName": "arn:aws:secretsmanager:ap-southeast-2:{{AWS ACCOUNT}}:secret:harbour-id-{{dummy}}","objectType": "secretsmanager","objectAlias": "harbour-id-opl"},{"objectName": "arn:aws:secretsmanager:ap-southeast-2:{{AWS ACCOUNT}}:secret:ship-id-{{dummy}}","objectType": "secretsmanager","objectAlias": "ship-id-opl"}] 205 | secretObjects: 206 | # Comment out the below section if you do not plan to create secrets in the namespace. 207 | - secretName: auth-token 208 | type: Opaque 209 | data: 210 | - key: auth-token-key 211 | objectName: auth-token-opl 212 | envName: AUTH_TOKEN 213 | - secretName: harbour-id 214 | type: Opaque 215 | data: 216 | - key: harbour-id-key 217 | objectName: harbour-id-opl 218 | envName: HARBOR_ID 219 | - secretName: ship-id 220 | type: Opaque 221 | data: 222 | - key: ship-id-key 223 | objectName: ship-id-opl 224 | envName: SHIP_ID 225 | volume: 226 | name: # (Optional) If not provided, will be linked with release name - see helm template 227 | readOnly: # (Default: true) 228 | path: /mnt/secrets 229 | 230 | 231 | externalSecretsOperator: 232 | enable: no 233 | volume: 234 | name: # (Optional) If not provided, will be linked with release name - see helm template 235 | readOnly: # Default: true 236 | path: # Default: /mnt/secrets 237 | 238 | externalSecret: 239 | name: blaze-external-secret 240 | refreshInterval: "15s" 241 | target: 242 | name: blazemeter-secrets-store # Name of Kubernetes Secret to make 243 | data: 244 | - secretKey: ship-id # New key to make 245 | remoteRef: 246 | key: ship-id # Name of the Secret in Secrets Manager 247 | property: ship-id # The JSON key within the secret 248 | envName: SHIP_ID 249 | - secretKey: harbour-id # New key to make 250 | remoteRef: 251 | key: harbour-id # Name of the Secret in Secrets Manager 252 | property: harbour-id # The JSON key within the secret 253 | envName: HARBOR_ID 254 | - secretKey: auth-token # New key to make 255 | remoteRef: 256 | key: auth-token # Name of the Secret in Secrets Manager 257 | property: authtoken # The JSON key within the secret 258 | envName: AUTH_TOKEN 259 | 260 | secretStore: 261 | name: blaze-secret-store 262 | provider: 263 | # The provider can be aws, gcpsm, switch the enable flag to true for the provider you want to use. 264 | aws: 265 | enable: true 266 | #role: iam-role #USE IF REQUIRED. 267 | service: SecretsManager 268 | region: ap-southeast-2 269 | # Chart wiill use JWT authentication to access the AWS Secrets Manager. 270 | # The JWT will use the serviceAccount used in this chart 271 | # Unless the below authSecretRef is enabled 272 | authSecretRef: 273 | enable: false 274 | accessKeyID: 275 | name: #awssm-secret 276 | key: #access-key 277 | secretAccessKey: 278 | name: #awssm-secret 279 | key: #secret-access-key 280 | 281 | gcpsm: 282 | enable: false 283 | projectID: your-gcp-project-id 284 | # Chart will use the Workload Identity to access the GCP Secret Manager. 285 | # The Workload Identity will use the serviceAccount used in this chart 286 | # Unless the below secretRef is enabled 287 | secretRef: 288 | enable: false 289 | secretAccessKeySecretRef: 290 | name: gcpsm-secret 291 | key: secret-access-credentials 292 | -------------------------------------------------------------------------------- /templates/crane.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | role: {{ include "crane.roleName" . }} 6 | {{ if .Values.labelsCrane.enable | default false -}} 7 | {{ .Values.labelsCrane.syntax | toYaml | nindent 4 }} 8 | {{ end }} 9 | name: {{ .Release.Name }} 10 | namespace: {{ .Release.Namespace }} 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | role: {{ include "crane.roleName" . }} 16 | crane: ready 17 | strategy: 18 | type: Recreate 19 | template: 20 | metadata: 21 | labels: 22 | {{ if .Values.labelsCrane.enable | default false -}} 23 | {{ .Values.labelsCrane.syntax | toYaml | nindent 8 -}} 24 | {{ end }} 25 | role: {{ include "crane.roleName" . }} 26 | crane: ready 27 | {{ if .Values.annotationsCrane.enable | default false -}} 28 | annotations: 29 | {{ .Values.annotationsCrane.syntax | toYaml | nindent 8 -}} 30 | {{ end }} 31 | spec: 32 | serviceAccountName: {{ template "blazemeter-crane.serviceAccountName" . }} 33 | automountServiceAccountToken: true 34 | {{ if .Values.nodeSelectorCrane.enable | default false }} 35 | nodeSelector: 36 | {{ .Values.nodeSelectorCrane.syntax | toYaml | nindent 8 }} 37 | {{ end -}} 38 | {{ if .Values.tolerationCrane.enable | default false }} 39 | tolerations: 40 | {{ .Values.tolerationCrane.syntax | toYaml | nindent 8 }} 41 | {{ end }} 42 | containers: 43 | - env: 44 | {{- if and ( .Values.secretProviderClass.enable | default false ) ( not .Values.externalSecretsOperator.enable | default false) }} 45 | {{- range .Values.secretProviderClass.secretObjects }} 46 | - name: {{ .envName }} 47 | valueFrom: 48 | secretKeyRef: 49 | name: {{ .secretName }} 50 | key: {{ (index .data 0).key }} 51 | {{ end -}} 52 | {{ else if and (.Values.externalSecretsOperator.enable | default false) ( not .Values.secretProviderClass.enable | default false) }} 53 | {{- $root := . }} 54 | {{ range .Values.externalSecretsOperator.externalSecret.data }} 55 | - name: {{ .envName }} 56 | valueFrom: 57 | secretKeyRef: 58 | name: {{ $root.Values.externalSecretsOperator.externalSecret.target.name }} 59 | key: {{ .secretKey }} 60 | {{ end -}} 61 | {{ else }} 62 | - name: AUTH_TOKEN 63 | value: {{ .Values.env.authtoken }} 64 | - name: HARBOR_ID 65 | value: {{ .Values.env.harbour_id }} 66 | - name: SHIP_ID 67 | value: {{ .Values.env.ship_id }} 68 | {{ end }} 69 | - name: CONTAINER_MANAGER_TYPE 70 | value: KUBERNETES 71 | - name: IMAGE_OVERRIDES 72 | value: {{ include "helm-crane.imageOverridesJson" . | quote }} 73 | - name: DOCKER_REGISTRY 74 | value: {{ .Values.imageOverride.docker_registry | default "gcr.io/verdant-bulwark-278" | quote }} 75 | - name: AUTO_KUBERNETES_UPDATE 76 | value: {{ .Values.imageOverride.auto_update | default "true" | quote }} 77 | - name: AUTO_UPDATE_CONTAINERS_WHILE_RUNNING 78 | value: {{ .Values.imageOverride.auto_update_running_containers | default "false" | quote }} 79 | {{ if .Values.proxy.enable | default false -}} 80 | {{ if ne .Values.proxy.http_path "" }} 81 | - name: HTTP_PROXY 82 | value: {{ .Values.proxy.http_path }} 83 | {{ end -}} 84 | {{ if ne .Values.proxy.https_path "" }} 85 | - name: HTTPS_PROXY 86 | value: {{ .Values.proxy.https_path }} 87 | {{ end }} 88 | - name: NO_PROXY 89 | value: {{ .Values.proxy.no_proxy | default "kubernetes.default,127.0.0.1,localhost"}} 90 | {{ end -}} 91 | {{ if .Values.ca_bundle.enable | default false }} 92 | - name: REQUESTS_CA_BUNDLE 93 | value: {{ .Values.ca_bundle.volume.mount_path }}/{{ .Values.ca_bundle.request_ca_bundle }} 94 | - name: AWS_CA_BUNDLE 95 | value: {{ .Values.ca_bundle.volume.mount_path }}/{{ .Values.ca_bundle.aws_ca_bundle }} 96 | {{ if not .Values.gridProxy.enable }} 97 | - name: KUBERNETES_CA_BUNDLE_MOUNT 98 | value: REQUESTS_CA_BUNDLE={{ .Release.Name }}-configmap={{ .Values.ca_bundle.request_ca_bundle }}:AWS_CA_BUNDLE={{ .Release.Name }}-configmap={{ .Values.ca_bundle.aws_ca_bundle }} 99 | {{ end -}} 100 | {{ end -}} 101 | {{ if .Values.gridProxy.enable }} 102 | - name: A_ENVIRONMENT 103 | value: {{ .Values.gridProxy.a_environment }} 104 | - name: TLS_KEY_GRID 105 | value: {{ .Values.gridProxy.volume.mount_path }}/{{ .Values.gridProxy.tlsKeyGrid }} 106 | - name: TLS_CERT_GRID 107 | value: {{ .Values.gridProxy.volume.mount_path }}/{{ .Values.gridProxy.tlsCertGrid }} 108 | {{ if not .Values.ca_bundle.enable }} 109 | - name: KUBERNETES_CA_BUNDLE_MOUNT 110 | value: TLS_KEY_GRID={{ .Release.Name }}-configmap={{ .Values.gridProxy.tlsKeyGrid }}:TLS_CERT_GRID={{ .Release.Name }}-configmap={{ .Values.gridProxy.tlsCertGrid }} 111 | {{ end -}} 112 | {{ end -}} 113 | {{ if and .Values.ca_bundle.enable .Values.gridProxy.enable }} 114 | - name: KUBERNETES_CA_BUNDLE_MOUNT 115 | value: REQUESTS_CA_BUNDLE={{ .Release.Name }}-configmap={{ .Values.ca_bundle.request_ca_bundle }}:AWS_CA_BUNDLE={{ .Release.Name }}-configmap={{ .Values.ca_bundle.aws_ca_bundle }}:TLS_KEY_GRID={{ .Release.Name }}-configmap={{ .Values.gridProxy.tlsKeyGrid }}:TLS_CERT_GRID={{ .Release.Name }}-configmap={{ .Values.gridProxy.tlsCertGrid }} 116 | {{ end -}} 117 | {{ if .Values.service_virtualization.enable | default false -}} 118 | {{ if eq .Values.service_virtualization.ingressType "istio" }} 119 | - name: KUBERNETES_WEB_EXPOSE_TYPE 120 | value: ISTIO 121 | - name: KUBERNETES_SERVICES_BLOCKING_GET 122 | value: "true" 123 | - name: KUBERNETES_ISTIO_GATEWAY_NAME 124 | value: {{ .Release.Name }}-gateway 125 | {{ else if eq .Values.service_virtualization.ingressType "nginx" }} 126 | - name: KUBERNETES_WEB_EXPOSE_TYPE 127 | value: INGRESS 128 | - name: KUBERNETES_INGRESS_CLASS 129 | value: "nginx" 130 | - name: PARALLEL_HANDLERS_COUNT 131 | value: '50' 132 | - name: USE_PARALLEL_HANDLER 133 | value: 'true' 134 | - name: RUN_HEALTH_WEB_SERVICE 135 | value: 'true' 136 | {{ end }} 137 | - name: KUBERNETES_WEB_EXPOSE_SUB_DOMAIN 138 | value: {{ .Values.service_virtualization.web_expose_subdomain | default "mydomain.local" | quote }} 139 | - name: KUBERNETES_WEB_EXPOSE_TLS_SECRET_NAME 140 | value: {{ .Values.service_virtualization.credentialName | default "wildcard-credential" | quote }} 141 | - name: KUBERNETES_SERVICE_USE_TYPE 142 | value: CLUSTERIP 143 | {{ end -}} 144 | {{ if .Values.non_privilege_container.enable | default false }} 145 | - name: INHERIT_RUNNING_USER_AND_GROUP 146 | value: 'true' 147 | - name: KUBERNETES_SECURITY_CONTEXT_CAP_JSON 148 | value: '{"drop": ["ALL"]}' 149 | {{ end -}} 150 | {{ if .Values.labelsExecutors.enable | default false }} 151 | - name: KUBERNETES_LABELS 152 | value: {{ .Values.labelsExecutors.syntax | toJson | quote }} 153 | {{ end -}} 154 | {{ if .Values.tolerationExecutors.enable | default false }} 155 | - name: KUBERNETES_TOLERATIONS_JSON 156 | value: {{ .Values.tolerationExecutors.syntax | toJson | quote }} 157 | {{ end -}} 158 | {{ if .Values.nodeSelectorExecutor.enable | default false }} 159 | - name: KUBERNETES_NODE_SELECTOR_JSON 160 | value: {{ .Values.nodeSelectorExecutor.syntax | toJson | quote }} 161 | {{ end -}} 162 | {{ if .Values.resourcesExecutors.requests.CPU }} 163 | - name: KUBERNETES_RESOURCES_DEFAULT_CPU 164 | value: {{ .Values.resourcesExecutors.requests.CPU | quote }} 165 | {{ end -}} 166 | {{ if .Values.resourcesExecutors.requests.MEM }} 167 | - name: KUBERNETES_RESOURCES_DEFAULT_MEM 168 | value: {{ .Values.resourcesExecutors.requests.MEM | quote }} 169 | {{ end -}} 170 | {{ if .Values.resourcesExecutors.limits.CPU }} 171 | - name: KUBERNETES_RESOURCES_LIMITS_CPU 172 | value: {{ .Values.resourcesExecutors.limits.CPU | quote }} 173 | {{ end -}} 174 | {{ if .Values.resourcesExecutors.limits.MEM }} 175 | - name: KUBERNETES_RESOURCES_LIMITS_MEMORY 176 | value: {{ .Values.resourcesExecutors.limits.MEM | quote }} 177 | {{ end -}} 178 | {{ if .Values.resourcesExecutors.limits.storage }} 179 | - name: KUBERNETES_LIMITS_EPHEMERAL_STORAGE 180 | value: {{ .Values.resourcesExecutors.limits.storage | quote }} 181 | {{ end -}} 182 | {{ if .Values.resourcesExecutors.requests.storage }} 183 | - name: KUBERNETES_REQUESTS_EPHEMERAL_STORAGE 184 | value: {{ .Values.resourcesExecutors.requests.storage| quote }} 185 | {{ end -}} 186 | {{ if .Values.gridProxy.enable | default false}} 187 | - name: DODUO_PORT 188 | value: {{ .Values.gridProxy.doduoPort | quote }} 189 | - name: TLS_CERT_GRID 190 | value: {{ .Values.gridProxy.tlsCertGrid | quote }} 191 | - name: TLS_KEY_GRID 192 | value: {{ .Values.gridProxy.tlsKeyGrid | quote }} 193 | {{ end -}} 194 | {{ if .Values.annotationsExecutor.enable | default false }} 195 | - name: KUBERNETES_CUSTOM_ANNOTATIONS_JSON 196 | value: {{ .Values.annotationsExecutor.syntax | toJson | quote }} 197 | {{ end }} 198 | image: {{ .Values.imageOverride.craneImage | default (printf "gcr.io/verdant-bulwark-278/blazemeter/crane") }}:{{ .Values.imageOverride.tag | default "latest-master"}} 199 | imagePullPolicy: {{ .Values.imageOverride.pullPolicy | default "Always" }} 200 | name: crane-container 201 | {{ with .Values.resourcesCrane -}} 202 | {{ if or (.requests.CPU) (.limits.CPU) (.limits.MEM) (.requests.MEM) (.requests.storage) (.limits.storage) }} 203 | resources: 204 | {{ if or (.requests.MEM) (.requests.CPU) (.requests.storage) }} 205 | requests: 206 | cpu: {{ .requests.CPU | default "250m" }} 207 | memory: {{ .requests.MEM | default "512Mi" }} 208 | {{ if .requests.storage }} 209 | storage: {{ .requests.storage }} 210 | {{ end -}} 211 | {{ end -}} 212 | {{ if or (.limits.MEM) (.limits.CPU) (.limits.storage) }} 213 | limits: 214 | cpu: {{ .limits.CPU | default "1" }} 215 | memory: {{ .limits.MEM | default "2Gi" }} 216 | {{ if .limits.storage }} 217 | storage: {{ .limits.storage }} 218 | {{ end -}} 219 | {{ end -}} 220 | {{ end -}} 221 | {{ end -}} 222 | {{ if .Values.non_privilege_container.enable | default false}} 223 | securityContext: 224 | allowPrivilegeEscalation: false 225 | capabilities: 226 | drop: 227 | - ALL 228 | runAsGroup: {{ .Values.non_privilege_container.runAsGroup }} 229 | runAsUser: {{ .Values.non_privilege_container.runAsUser }} 230 | {{ end -}} 231 | {{ with .Values.probes -}} 232 | {{ if .enable | default true }} 233 | livenessProbe: 234 | httpGet: 235 | path: /healtz 236 | port: {{ .livenessProbe.port | default 5000 }} 237 | scheme: HTTP 238 | failureThreshold: {{ .livenessProbe.failureThreshold | default 5 }} 239 | initialDelaySeconds: {{ .livenessProbe.initialDelaySeconds | default 5 }} 240 | periodSeconds: {{ .livenessProbe.periodSeconds | default 15 }} 241 | successThreshold: {{ .livenessProbe.successThreshold | default 1 }} 242 | timeoutSeconds: {{ .livenessProbe.timeoutSeconds | default 10 }} 243 | 244 | readinessProbe: 245 | httpGet: 246 | path: /healtz 247 | port: {{ .readinessProbe.port | default 5000 }} 248 | scheme: HTTP 249 | failureThreshold: {{ .readinessProbe.failureThreshold | default 3 }} 250 | initialDelaySeconds: {{ .readinessProbe.initialDelaySeconds | default 5 }} 251 | periodSeconds: {{ .readinessProbe.periodSeconds | default 15 }} 252 | successThreshold: {{ .readinessProbe.successThreshold | default 1 }} 253 | timeoutSeconds: {{ .readinessProbe.timeoutSeconds | default 10 }} 254 | {{ end -}} 255 | {{ end -}} 256 | {{ if or ( .Values.ca_bundle.enable ) ( .Values.gridProxy.enable ) (.Values.secretProviderClass.enable) (.Values.externalSecretsOperator.enable) | default false }} 257 | volumeMounts: 258 | {{ if .Values.ca_bundle.enable }} 259 | - name: {{ .Values.ca_bundle.volume.volume_name }} 260 | mountPath: {{ .Values.ca_bundle.volume.mount_path }} 261 | readOnly: {{ .Values.ca_bundle.volume.readOnly }} 262 | {{ end -}} 263 | {{ if .Values.gridProxy.enable }} 264 | - name: {{ .Values.gridProxy.volume.volume_name }} 265 | mountPath: {{ .Values.gridProxy.volume.mount_path }} 266 | readOnly: {{ .Values.gridProxy.volume.readOnly }} 267 | {{ end -}} 268 | {{ if .Values.secretProviderClass.enable }} 269 | - name: {{ .Values.secretProviderClass.volume.name | default (printf "%s-secrets-store-volume" .Release.Name) }} #npd-blaze-secret-store 270 | mountPath: {{ .Values.secretProviderClass.volume.path | default "/mnt/secrets" }} 271 | readOnly: {{ .Values.secretProviderClass.volume.readOnly | default true }} 272 | {{ end -}} 273 | {{ if .Values.externalSecretsOperator.enable }} 274 | - name: {{ .Values.externalSecretsOperator.volume.name | default (printf "%s-externalsecrets-volume" .Release.Name) }} 275 | mountPath: {{ .Values.externalSecretsOperator.volume.path | default "/mnt/secrets" }} 276 | readOnly: {{ .Values.externalSecretsOperator.volume.readOnly | default true }} 277 | {{ end }} 278 | volumes: 279 | {{ if .Values.ca_bundle.enable }} 280 | - name: {{ .Values.ca_bundle.volume.volume_name }} 281 | configMap: 282 | name: {{ .Release.Name }}-configmap 283 | {{ end -}} 284 | {{ if .Values.gridProxy.enable }} 285 | - name: {{ .Values.gridProxy.volume.volume_name }} 286 | configMap: 287 | name: {{ .Release.Name }}-configmap 288 | {{ end -}} 289 | {{ if .Values.secretProviderClass.enable }} 290 | - name: {{ .Values.secretProviderClass.volume.name | default (printf "%s-secrets-store-volume" .Release.Name) }} 291 | csi: 292 | driver: secrets-store.csi.k8s.io 293 | readOnly: {{ .Values.secretProviderClass.volume.readOnly | default true }} 294 | volumeAttributes: 295 | secretProviderClass: {{ .Release.Name }}-secrets-store #non-prod-blaze-deployment-aws-secrets 296 | {{ end -}} 297 | {{ if .Values.externalSecretsOperator.enable }} 298 | - name: {{ .Values.externalSecretsOperator.volume.name | default (printf "%s-externalsecrets-volume" .Release.Name) }} 299 | secret: 300 | secretName: {{ .Values.externalSecretsOperator.externalSecret.target.name }} 301 | {{ end -}} 302 | {{ end }} 303 | restartPolicy: {{ .Values.deployment.restartPolicy | default "Always" }} 304 | terminationGracePeriodSeconds: 30 305 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Helm for Blazemeter Private Location 2 | 3 | [Download the latest Chart](https://github.com/Blazemeter/helm-crane/releases) 4 | 5 | Deploy Blazemeter private location to your Kubernetes cluster using HELM chart. The chart allows to make advanced/custom configurations to your Blazemeter private location deployment. 6 | 7 | ![Helm-crane](/logo.png) 8 | 9 | ## [1.0] Requirements 10 | 1. A [BlazeMeter account](https://a.blazemeter.com/) 11 | 2. A Kubernetes cluster 12 | 3. Latest [Helm installed](https://helm.sh/docs/helm/helm_version/) 13 | 4. The kubernetes cluster needs to fulfill [Blazemeter Private location requirements](https://help.blazemeter.com/docs/guide/private-locations-system-requirements.html?tocpath=Private%20Locations%7CInstallation%20of%20Private%20Locations%7C_____1) 14 | --- 15 | 16 | 17 | ## [2.0] Generating Harbour_ID, Ship_ID and Auth_token in Blazemeter 18 | 19 | >To start with, you will need Harbour_ID, Ship_ID & Auth_token from Blazemeter. You can either generate these from Blazemeter GUI or through API as described below. 20 | 21 | 1. Get the Harbour_ID, Ship_ID and Auth_token through BlazeMeter GUI 22 | - Login to Blazemeter & create a [Private Location](https://help.blazemeter.com/docs/guide/private-locations-create.html?tocpath=Private%20Locations%7CInstallation%20of%20Private%20Locations%7C_____2) 23 | - Copy the [Harbour_ID](https://help.blazemeter.com/docs/guide/private-locations-where-to-find-harbor-id-and-ship-id.html?tocpath=Private%20Locations%7CPrivate%20Locations%20Knowledge%20Base%7C_____1) once the private location has been created in BlazeMeter. 24 | - Create an [Agent](https://help.blazemeter.com/docs/guide/private-locations-install-agent.html) 25 | - Copy the Ship_ID & Auth_token, you can copy Harbour_ID, when you click on the add agent button. 26 | 27 | 2. Get the Harbour_ID, Ship_ID and Auth_token through BlazeMeter API 28 | - You should have the Blazemeter API key and secret 29 | - Create a Private location [using API](https://help.blazemeter.com/apidocs/performance/private_locations_create_a_private_location.htm?tocpath=Performance%7CPrivate%20Locations%7C_____3) 30 | - Copy the Harbour ID 31 | - Create an Agent [using API](https://help.blazemeter.com/apidocs/performance/private_locations_create_an_agent.htm?tocpath=Performance%7CPrivate%20Locations%7C_____4) 32 | - Copy the Ship_ID 33 | - Generate the docker command [using API](https://help.blazemeter.com/apidocs/performance/private_locations_docker_command.htm?tocpath=Performance%7CPrivate%20Locations%7C_____5) 34 | - Copy Auth_token, harbour_id and ship_id from the docker command 35 | 36 | --- 37 | 38 | ## [3.0] Downloading the chart 39 | 40 | - Pull/Download the chart - tar file from the GitHub repository [Download the latest Chart](https://github.com/Blazemeter/helm-crane/releases) 41 | 42 | - Untar the chart 43 | ```bash 44 | tar -xvf helm-crane(version).tgz 45 | ``` 46 | 47 | 65 | 66 | --- 67 | ## [4.0] Configuring the Chart values before installing 68 | 69 | - Open the `values` file to apply configurations as per your deployment requirements. 70 | 71 | ### [4.1] Adding the basic/required configurations 72 | 73 | Before installing the chart, you must provide your BlazeMeter `harbour_id`, `ship_id`, and `authtoken` in the `values.yaml` file. These values are required for the Crane deployment to register and authenticate with BlazeMeter. 74 | Refer to [2.0](#20-generating-harbour_id-ship_id-and_auth_token-in-blazemeter) for instructions on how to obtain these values. 75 | 76 | **Example:** 77 | ```yaml 78 | env: 79 | authtoken: "YOUR_AUTH_TOKEN" 80 | harbour_id: "YOUR_HARBOUR_ID" 81 | ship_id: "YOUR_SHIP_ID" 82 | ``` 83 | 84 | - Replace the example values above with your actual credentials. 85 | 86 | #### Using Kubernetes Secrets or External Secret Managers 87 | 88 | If you want to keep your credentials secure and **not** store them directly in `values.yaml`, you can use one of the following integrations: 89 | 90 | - **SecretProviderClass** (CSI Driver) 91 | - **ExternalSecrets Operator** 92 | 93 | When either of these integrations is enabled (`secretProviderClass.enable: yes` or `externalSecretsOperator.enable: yes`), the `env.authtoken`, `env.harbour_id`, and `env.ship_id` values in `values.yaml` will be ignored, and the credentials will be sourced from your external secret store. 94 | 95 | **Example:** 96 | ```yaml 97 | secretProviderClass: 98 | enable: yes 99 | provider: aws 100 | # ...other configuration... 101 | ``` 102 | or 103 | ```yaml 104 | externalSecretsOperator: 105 | enable: yes 106 | # ...other configuration... 107 | ``` 108 | 109 | **Notes:** 110 | >- If you use a secret manager, ensure your secret keys and environment variable mappings are correct in the relevant section. 111 | >- See [4.14](#414-configure-secretproviderclass) and [4.15](#415-configure-externalsecrets-operator) for detailed configuration examples. 112 | 113 | 114 | **Important:** 115 | - Only set credentials in one place. If both `env` and a secret integration are set, the secret integration takes precedence. 116 | - Do **not** commit sensitive values to version control. 117 | 118 | --- 119 | 120 | ### [4.2] Configuring Deployment Options 121 | 122 | The `.Values.deployment` section in `values.yaml` controls how the main Crane deployment is created, including service account, RBAC roles, and restart policy of the deployment (should it fails). 123 | 124 | **Example:** 125 | ```yaml 126 | deployment: 127 | role: # (Optional) Name of an existing Role to use in the namespace. If not set, defaults to -role. 128 | clusterrole: # (Optional) Name of an existing ClusterRole to use. If not set, defaults to -clusterrole. 129 | serviceAccount: 130 | create: false # Set to true to create a new ServiceAccount, or false to use an existing one. 131 | name: # (Optional) Name of the ServiceAccount to use. Leave empty to use the default. 132 | annotations: # (Optional) Annotations to add to the ServiceAccount. 133 | eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/example-role 134 | custom.annotation/key: custom-value 135 | restartPolicy: # (Optional) Pod restart policy. Defaults to "Always". 136 | ``` 137 | 138 | - `role`: Use an existing Kubernetes Role for RBAC. Leave empty to let the chart create one. 139 | - `clusterrole`: Use an existing ClusterRole for cluster-wide permissions. Leave empty to let the chart create one. 140 | - `serviceAccount.create`: If `true`, the chart creates a new ServiceAccount. If `false`, you must specify an existing ServiceAccount in `serviceAccount.name`. 141 | - `serviceAccount.name`: Name of the ServiceAccount to use. If empty, the default ServiceAccount is used. 142 | - `serviceAccount.annotations`: Add custom annotations (e.g., for IAM roles or workload identity). 143 | - `restartPolicy`: Pod restart policy (`Always`, `OnFailure`, or `Never`). Defaults to `Always`. 144 | 145 | **Notes:** 146 | - If your cluster uses IAM roles for service accounts (IRSA) or workload identity, add the required annotations under `serviceAccount.annotations`. 147 | - If `create: false`, the chart will not create or modify the existing ServiceAccount, and the annotations in values.yaml will be ignored. 148 | - If you want to use pre-existing RBAC roles, specify their names in `role` and `clusterrole`. 149 | - For most installations, you can leave these fields at their defaults unless you have specific security or compliance requirements. 150 | 151 | **Example for creating a new ServiceAccount with a custom IAM role:** 152 | ```yaml 153 | deployment: 154 | serviceAccount: 155 | create: true 156 | name: my-existing-sa 157 | annotations: 158 | eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/my-crane-role 159 | ``` 160 | 161 | 162 | ### [4.3] Configuring Image Overrides 163 | 164 | The chart supports overriding the default images used for Crane and its components through the `imageOverride` section in your `values.yaml` file. This allows you to specify custom registries, images, tags, and pull policies for all relevant containers. 165 | 166 | Example configuration: 167 | ```yaml 168 | imageOverride: 169 | docker_registry: "gcr.io/" 170 | craneImage: "gcr.io//blazemeter/crane" 171 | tag: "latest-master" 172 | auto_update: true 173 | auto_update_running_containers: false 174 | executorImages: 175 | taurus-cloud:latest: "pathToYourRepo/taurus-cloud:version" 176 | torero:latest: "pathToYourRepo/torero:version" 177 | service-mock:latest: "pathToYourRepo/service-mock:version" 178 | mock-pc-service:latest: "pathToYourRepo/mock-pc-service:version" 179 | sv-bridge:latest: "pathToYourRepo/sv-bridge:version" 180 | doduo:latest: "pathToYourRepo/doduo:version" 181 | pullPolicy: "Always" 182 | testImage: "gcr.io/verdant-bulwark-278/cranehook" 183 | testTag: "latest" 184 | ``` 185 | 186 | - **docker_registry**: Custom Docker registry for all images. 187 | - **craneImage**: Path to the Crane image. 188 | - **tag**: Image tag to use. 189 | - **auto_update**: Enable or disable automatic updates. 190 | - **auto_update_running_containers**: Control auto-update for running containers. 191 | - **executorImages**: Map of executor/component images to override. 192 | - **pullPolicy**: Image pull policy (`Always`, `IfNotPresent`, etc.). 193 | - **testImage** and **testTag**: Image and tag for the test hook. 194 | 195 | **Note:** 196 | >- If you do not need to override images, you can leave this section commented or empty, and the chart will use the default images provided by BlazeMeter. 197 | 198 | 199 | ### [4.4] Configure Proxy Settings 200 | 201 | If your environment requires the use of a proxy, you can enable and configure proxy settings for the Crane deployment. Set `enable` to `yes` and provide the relevant proxy URLs in your `values.yaml` file. 202 | 203 | Example configuration: 204 | ```yaml 205 | proxy: 206 | enable: yes 207 | http_path: "http://your-http-proxy:port" 208 | https_path: "https://your-https-proxy:port" 209 | no_proxy: "kubernetes.default,127.0.0.1,localhost,myHostname.com" 210 | ``` 211 | 212 | - **enable**: Set to `yes` to activate proxy configuration. 213 | - **http_path**: (Optional) HTTP proxy URL. 214 | - **https_path**: (Optional) HTTPS proxy URL. 215 | - **no_proxy**: (Optional) Comma-separated list of hosts or domains that should bypass the proxy. 216 | 217 | **Note:** 218 | >- Only set the proxy values if your cluster requires outbound traffic to go through a proxy. The `no_proxy` field helps exclude internal or local addresses (defaults to "kubernetes.default,127.0.0.1,localhost") 219 | 220 | 221 | ### [4.5] Adding CA certificates (only configure if required, & for service virtualisation only) 222 | 223 | - If you plan to configure the Kubernetes installation to use [CA certificates](https://help.blazemeter.com/docs/guide/private-locations-optional-installation-step-configure-kubernetes-agent-to-use-ca-bundle.html?tocpath=Private%20Locations%7CInstallation%20of%20Private%20Locations%7C_____12), make changes to the following section of the values.yaml file: 224 | - Change the `enable` to `yes` 225 | - Provide the path to the certificate file respectively for both (ca_subpath & aws_subpath). You will need to copy/move these cert files in the same directory as this chart and just provide the name of the certs instead of the complete path. ' 226 | 227 | ```yaml 228 | ca_bundle: 229 | enable: no 230 | request_ca_bundle: "certificate.crt" 231 | aws_ca_bundle: "certificate2.crt" 232 | volume: 233 | volume_name: "volume-cm" 234 | mount_path: "/var/cm" 235 | readOnly: true 236 | ``` 237 | 238 | 239 | ### [4.6] Adding gridProxy configuration (only configure if required, & for GUI functional testing only) 240 | 241 | - If you plan to configure your crane installation to use [gridProxy](https://help.blazemeter.com/docs/guide/functional-run-gridproxy-over-https.htm?Highlight=grid%20proxy), make changes to the following section of the `values.yaml` file. Grid Proxy enables you to run Selenium functional tests in BlazeMeter without using a local server. You can run Grid Proxy over the HTTPS protocol using the following methods: 242 | 243 | ```yaml 244 | gridProxy: 245 | enable: yes 246 | a_environment: 'https://your.environment.net' 247 | tlsKeyGrid: "certificate.key" # The private key for the domain used to run the BlazeMeter Grid proxy over HTTPS. Value in string format. 248 | tlsCertGrid: "certificate.crt" # The public certificate for the domain used to run the BlazeMeter Grid proxy over HTTPS. Value in string format. 249 | mount_path: "/etc/ssl/certs/doduo" 250 | doduoPort: 9070 # The user-defined port where to run Doduo (BlazeMeter Grid Proxy). By default, Doduo listens on port 8000. 251 | volume: 252 | volume_name: "tls-files" 253 | mount_path: "/etc/ssl/certs/doduo" 254 | readOnly: true 255 | ``` 256 | 257 | 258 | ### [4.7] Deploying Non_privilege container - NON_ROOT deployment. 259 | - If you plan to deploy the Blazemeter crane as a non_privileged installation, make changes to the following part of the `values` file. Change the `enable` to `yes` and this will automatically run the deployment and consecutive pods as Non_root/Non_privilege. You can amend the runAsGroup and runAsUser to any value of your choice. We can only have same user/groupId for both crane and child resources. 260 | 261 | ```yaml 262 | non_privilege_container: 263 | enable: no 264 | runAsGroup: 1337 265 | runAsUser: 1337 266 | ``` 267 | **Note:** 268 | >- Non-root deployment requires an additional feature to be enabled at account level, please contact support for enabling this feature.* 269 | >- This will automatically configure the `securityContext.Capabilities` to `drop all` for crane and child resources.* 270 | 271 | 272 | ### [4.8] Configure deployment to support Service Virtualisation (Mock Services) 273 | 274 | If your Private Location will run service-virtualisation (mock services), enable the `service_virtualization` section in your `values.yaml` file. This allows you to expose mock services using either Istio or NGINX ingress controllers. 275 | 276 | ```yaml 277 | service_virtualization: 278 | enable: yes 279 | ingressType: nginx # or istio, depending on your cluster setup 280 | credentialName: "wildcard-credential" 281 | web_expose_subdomain: "mydomain.local" 282 | ``` 283 | 284 | - **enable**: Set to `yes` to activate service virtualisation. 285 | - **ingressType**: Choose `nginx` or `istio` based on your ingress controller. 286 | - **credentialName**: Name of the credential (e.g., wildcard certificate) to use. 287 | - **web_expose_subdomain**: Subdomain to expose mock services. 288 | 289 | **Note:** 290 | >- Only one ingress type can be enabled at a time. Ensure the corresponding ingress controller (NGINX or Istio) is installed and configured in your cluster. 291 | >- For more details, see the [Blazemeter guide](https://help.blazemeter.com/docs/guide/private-locations-install-blazemeter-agent-for-kubernetes-for-mock-services.html). 292 | 293 | 294 | 295 | ### [4.9] Configuring Labels for Crane and Child Resources 296 | 297 | You can add custom labels to the main Crane deployment, crane pod and its child resources (such as executor pods) using the following sections in your `values.yaml` file. This is useful for organizing, tracking, or applying policies to your resources. 298 | 299 | There are three label sections: 300 | - `labelsCrane`: Labels for the Crane Pod & deployment. 301 | - `labelsExecutors`: Labels for child resources (executors/agents). 302 | 303 | Each section has: 304 | - `enable`: Set to `yes` to apply the labels. 305 | - `syntax`: Provide your labels in JSON format. 306 | 307 | **Example configuration:** 308 | ```yaml 309 | labelsCrane: 310 | enable: yes 311 | syntax: {"purpose": "loadtest", "owner": "devops"} 312 | 313 | labelsExecutors: 314 | enable: yes 315 | syntax: {"type": "executor", "region": "us-east-1"} 316 | ``` 317 | 318 | **Notes:** 319 | >- Use these sections to ensure your Crane deployment and all related resources are labeled according to your organization’s standards 320 | >- These labels are added in addition to any default labels set by the helm chart and Blazemeter. 321 | >- If `enable` is set to `no`, labels will not be applied for that resource type. 322 | 323 | 324 | 325 | ### [4.10] Configure deployment to support for tolerations 326 | 327 | - The configuration is used to specify the tolerations for crane and child resources. Switch the `enable` to `yes` and add tolerations for crane and & child resources. Add tolerations in a Json format as per the example: 328 | ```yaml 329 | tolerationCrane: 330 | enable: no 331 | syntax: [{ "effect": "NoSchedule", "key": "lifecycle", "operator": "Equal", "value": "spot" }] 332 | tolerationExecutors: 333 | enable: no 334 | syntax: [{ "effect": "NoSchedule", "key": "lifecycle", "operator": "Equal", "value": "spot" }] 335 | ``` 336 | 337 | **Note:** 338 | >- `tolerationCrane` is for tolerations declared for crane and `tolerationExecutors` is for tolerations declared for child resources.* 339 | 340 | 341 | 342 | ### [4.11] Configure deployment to support node selector for crane & child resources 343 | - The configuration is used to specify the node selector for crane and child resources. Switch the `enable` to `yes` and add node selectors for crane and child resources. Add node selectors in a Json format as per the example: 344 | ```yaml 345 | nodeSelectorCrane: 346 | enable: no 347 | syntax: {"label_1": "label_1_value", "label_2": "label_2_value"} 348 | nodeSelectorExecutor: 349 | enable: no 350 | syntax: {"label_1": "label_1_value", "label_2": "label_2_value"} 351 | ``` 352 | 353 | **Note:** 354 | >- `nodeSelectorCrane` is for node selectors declared for crane and `nodeSelectorExecutor` is for node selectors declared for child resources.* 355 | 356 | 357 | 358 | ### [4.12] Configure resource limits and requests for Crane & child resources 359 | 360 | You can specify CPU, memory, and ephemeral storage resource requests and limits for both the Crane deployment and its child resources. Use the `resourcesCrane` section for the main Crane deployment, and `resourcesExecutors` for child resources (executors/agents). 361 | 362 | Add or update the following in your `values.yaml` file: 363 | 364 | ```yaml 365 | # Resource requests and limits for the Crane deployment. 366 | resourcesCrane: 367 | requests: 368 | CPU: 250m 369 | MEM: 512Mi 370 | storage: 100 # Ephemeral storage in MB (optional) 371 | limits: 372 | CPU: 1 # Example: 1 core 373 | MEM: 2Gi 374 | storage: 1024 # Ephemeral storage in MB (optional) 375 | 376 | # Resource requests and limits for child resources (executors/agents). 377 | resourcesExecutors: 378 | requests: 379 | CPU: 1000m 380 | MEM: 4096 # This value should be an integer (Mi), unlike other values that support k8s standard notation. 381 | storage: 100 # Ephemeral storage in MB (optional) 382 | limits: 383 | CPU: 2 384 | MEM: 8Gi 385 | storage: 1024 386 | ``` 387 | 388 | **Notes:** 389 | >- `resourcesCrane` applies to the main Crane deployment. 390 | >- `resourcesExecutors` applies to child resources created by the agent. 391 | >- For `resourcesExecutors`, the `MEM` value should be an integer (in Mi), not a string (e.g., `4096` not `4096Mi`). 392 | >- The `storage` field is optional and represents ephemeral storage in MB. 393 | >- If you do not need to set resource limits or requests, you can omit these sections or leave them 394 | 395 | 396 | ### [4.13] Configure the Pod Disruption Budget 397 | 398 | A [Pod Disruption Budget (PDB)](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) ensures that a minimum number of pods remain available during voluntary disruptions (such as node drains or cluster upgrades). You can configure a PDB for the Crane deployment by enabling the following settings in your `values.yaml` file. 399 | 400 | - **Enable PDB**: Set `enable` to `yes` to activate the PDB. 401 | - **minAvailable / maxUnavailable**: Specify either `minAvailable` (minimum pods that must be available) or `maxUnavailable` (maximum pods that can be unavailable). If both are set, `minAvailable` takes precedence. 402 | - **matchLabels**: You can then specify the labels to match pods for the PDB. 403 | 404 | Example configuration: 405 | ```yaml 406 | podDisruptionBudget: 407 | enable: yes 408 | # Only one of minAvailable or maxUnavailable should be set. 409 | minAvailable: 1 410 | # maxUnavailable: 1 411 | matchLabels: {"app": "crane"} 412 | ``` 413 | 414 | **Note:** 415 | >- If you do not require a PDB, leave `enable` as `no`. 416 | 417 | 418 | 419 | ### [4.14] Configure SecretProviderClass 420 | 421 | The [SecretProviderClass](https://secrets-store-csi-driver.sigs.k8s.io/topics/introduction.html) resource is used with the [Secrets Store CSI Driver](https://secrets-store-csi-driver.sigs.k8s.io/) to mount secrets, keys, or certificates from external secret management systems (such as Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault) into Kubernetes pods as files or Kubernetes secrets. 422 | 423 | You can enable and configure SecretProviderClass for the Crane deployment by updating the following section in your `values.yaml` file: 424 | 425 | - **Enable SecretProviderClass**: Set `enable` to `yes` to activate the integration. 426 | - **provider**: Specify the external secrets provider (e.g., `azure`, `aws`, `vault`). 427 | - **objects**: Add a list of provider-specific objects (such as secrets, alias or keys, etc.) 428 | - **secretObjects**: (Optional) Define Kubernetes secrets to be created from the mounted content. 429 | - **envName**: This is not a standard parameter in secretProviderClass, however, you are required to put in the env variable the specific secret is going to replace/populate. 430 | 431 | Example configuration: 432 | ```yaml 433 | secretProviderClass: 434 | enable: yes 435 | provider: aws 436 | # This is in JSON, to allow users configure different spec, like: secretPath, secretKey, objectAlias, etc. 437 | objects: [{ "objectName": "arn:aws:secretsmanager:ap-southeast-2:{{AWS ACCOUNT}}:secret:harbour-id-{{dummy}}","objectType": "secretsmanager","objectAlias": "harbour-id-opl"},{"objectName": "arn:aws:secretsmanager:ap-southeast-2:{{AWS ACCOUNT}}:secret:ship-id-{{dummy}}","objectType": "secretsmanager","objectAlias": "ship-id-opl"}] 438 | secretObjects: 439 | # Comment out the below section if you do not plan to create secrets in the namespace. 440 | - secretName: auth-token 441 | type: Opaque 442 | data: 443 | - key: auth-token-key 444 | objectName: auth-token-opl 445 | envName: AUTH_TOKEN 446 | - secretName: harbour-id 447 | type: Opaque 448 | data: 449 | - key: harbour-id-key 450 | objectName: harbour-id-opl 451 | envName: HARBOR_ID 452 | - secretName: ship-id 453 | type: Opaque 454 | data: 455 | - key: ship-id-key 456 | objectName: ship-id-opl 457 | envName: SHIP_ID 458 | ``` 459 | 460 | **Notes:** 461 | >- You can specify as many as you need in the same map/slice fashion. The chart is designed to loop over these items. 462 | >- The `parameters` and `secretObjects` fields should be customized based on your secrets provider and use case. 463 | >- If you do not require SecretProviderClass integration, leave `enable` as `no`. 464 | 465 | 466 | 467 | ### [4.15] Configure ExternalSecrets Operator 468 | 469 | The [ExternalSecrets Operator](https://external-secrets.io/) allows you to synchronize secrets from external secret management systems (such as AWS Secrets Manager or Google Cloud Secret Manager) into Kubernetes secrets. This integration is useful if you want your Crane deployment to automatically fetch and manage secrets from your external provider. 470 | 471 | You can enable and configure the ExternalSecrets Operator for the Crane deployment by updating the following section in your `values.yaml` file: 472 | 473 | - **Enable ExternalSecrets Operator**: Set `enable` to `yes` to activate the integration. 474 | - **volume**: (Optional) Configure the volume name, mount path, and readOnly flag for mounting secrets. 475 | - **externalSecret**: Configure the ExternalSecret resource: 476 | - `name`: Name of the ExternalSecret resource. 477 | - `refreshInterval`: How often the operator should refresh the secret. 478 | - `target.name`: Name of the Kubernetes Secret to create. 479 | - `data`: List of secrets to fetch, mapping `secretKey` (Kubernetes key) to `remoteRef.key` (external secret name) and `envName` (environment variable to populate). 480 | - **secretStore**: Configure the SecretStore resource: 481 | - `name`: Name of the SecretStore. 482 | - `provider`: Configure your secrets provider (e.g., AWS or GCP). 483 | - **AWS**: Set `enable` for `aws` to `true`, specify `service` and `region`. 484 | - **authSecretRef**: (Optional) Use this if you want to authenticate to AWS using static credentials (not recommended for production). 485 | - `accessKeyID`: Reference to a Kubernetes Secret containing your AWS access key ID. 486 | - `secretAccessKey`: Reference to a Kubernetes Secret containing your AWS secret access key. 487 | - If `authSecretRef.enable` is `false`, the chart will use the service account associated with the deployment (recommended). 488 | - **GCP**: Set `enable` for `gcpsm` to `true`, specify `projectID`. 489 | - **secretRef**: (Optional) Use this if you want to authenticate to GCP using a static service account key. 490 | - `secretAccessKeySecretRef`: Reference to a Kubernetes Secret containing your GCP credentials. 491 | - If `secretRef.enable` is `false`, the chart will use Workload Identity with the service account (recommended). 492 | 493 | **Example configuration:** 494 | ```yaml 495 | externalSecretsOperator: 496 | enable: yes 497 | volume: 498 | name: 499 | readOnly: 500 | path: 501 | 502 | externalSecret: 503 | name: blaze-external-secret 504 | refreshInterval: "15s" 505 | target: 506 | name: blazemeter-secrets-store 507 | data: 508 | - secretKey: ship-id 509 | remoteRef: 510 | key: ship-id 511 | envName: SHIP_ID 512 | - secretKey: harbour-id 513 | remoteRef: 514 | key: harbour-id 515 | envName: HARBOR_ID 516 | - secretKey: auth-token 517 | remoteRef: 518 | key: auth-token 519 | envName: AUTH_TOKEN 520 | 521 | secretStore: 522 | name: blaze-secret-store 523 | provider: 524 | aws: 525 | enable: true 526 | service: SecretsManager 527 | region: ap-southeast-2 528 | # Optionally configure authentication using static credentials: 529 | authSecretRef: 530 | enable: false 531 | # ---- ---- 532 | ``` 533 | 534 | **Notes:** 535 | - Only enable the provider you intend to use (`aws` or `gcpsm`). For other providers (such as Azure), please contact support. 536 | - The chart will use the service account associated with the deployment for authentication unless `authSecretRef` (AWS) or `secretRef` (GCP) is enabled. 537 | - `authSecretRef` and `secretRef` allow you to reference Kubernetes secrets for static credentials, but using IAM roles (AWS) or Workload Identity (GCP) is recommended for production. 538 | - The `data` section allows you to map external secrets to Kubernetes secrets and environment variables. 539 | - If you do not require ExternalSecrets Operator integration, leave `enable` as `no`. 540 | - For more details, see the [ExternalSecrets Operator documentation](https://external-secrets.io/). 541 | 542 | 543 | ### [4.16] Configure Custom Annotations 544 | 545 | You can add custom annotations to the main Crane deployment and its child resources (such as executor pods) using the annotations sections in your `values.yaml` file. This is useful for integrating with cluster autoscaler, admission controllers, monitoring systems, service meshes like Istio, or other Kubernetes tools that rely on pod annotations. 546 | 547 | There are two annotation sections: 548 | - `annotationsCrane`: Annotations for the Crane Pod. 549 | - `annotationsExecutor`: Annotations for child resources (executors/agents). 550 | 551 | Each section has: 552 | - `enable`: Set to `yes` to apply the annotations. 553 | - `syntax`: Provide your annotations in JSON format. 554 | 555 | **Common use cases examples:** 556 | 557 | 1. Istio Service Mesh Integration: 558 | ```yaml 559 | annotationsCrane: 560 | enable: yes 561 | syntax: {"sidecar.istio.io/inject": "true", "sidecar.istio.io/proxyCPU": "100m", "sidecar.istio.io/proxyMemory": "128Mi"} 562 | 563 | annotationsExecutor: 564 | enable: yes 565 | syntax: {"sidecar.istio.io/inject": "true", "traffic.sidecar.istio.io/excludeOutboundPorts": "443,8080"} 566 | ``` 567 | 568 | 2. Custom Resource Management or Prometheus: 569 | ```yaml 570 | annotationsCrane: 571 | enable: yes 572 | syntax: {"prometheus.io/scrape": "true", "prometheus.io/port": "5000"} 573 | 574 | annotationsExecutor: 575 | enable: yes 576 | syntax: {"custom.company.com/workload-type": "load-testing", "custom.company.com/billing-code": "project-alpha"} 577 | ``` 578 | 579 | **Notes:** 580 | - `annotationsCrane` applies annotations only to the Crane pod. 581 | - `annotationsExecutor` applies annotations to all child resources (executor/agent pods) created by Crane. 582 | - The `syntax` field must be valid JSON format. 583 | - Child resources automatically get `"cluster-autoscaler.kubernetes.io/safe-to-evict": "false"` by default to prevent premature eviction during tests. 584 | - These annotations are added in addition to any default annotations set by the chart. 585 | - If `enable` is set to `no`, custom annotations will not be applied for that resource type. 586 | 587 | *Use these sections to ensure your Crane deployment and related resources work seamlessly with your cluster's automation, monitoring, service mesh, and management tools.* 588 | 589 | --- 590 | 591 | ## [5.0] Verify if everything is setup correctly 592 | 593 | - Once the values are updated, please verify if the values are correctly used in the helm chart: 594 | 595 | ```sh 596 | helm lint 597 | helm template 598 | ``` 599 | 600 | This will print the template Helm will use to install this chart. Check the values and if something is missing, please make amends. 601 | 602 | --- 603 | 604 | 605 | ## [6.0] Installing the chart 606 | 607 | - Install the helm chart 608 | ```sh 609 | helm install crane /path/to/chart --namespace 610 | ``` 611 | **Here, crane is the name we are setting for the chart release** 612 | 613 | --- 614 | 615 | 616 | 617 | ## [7.0] Testing the chart & k8s infrastructure 618 | 619 | After installing the chart, you can verify both the deployment and the underlying Kubernetes infrastructure using Helm’s built-in test hooks. This chart includes a test pod that checks for essential connectivity and configuration, ensuring your environment is ready for BlazeMeter workloads. 620 | 621 | ### [7.1] Run the Helm test 622 | 623 | To execute the test: 624 | 625 | ```sh 626 | helm test -n 627 | ``` 628 | 629 | - Replace `` with the name you used for your Helm release (e.g., `crane`). 630 | - Replace `` with the namespace where you installed the chart. 631 | 632 | ### [7.2] What does the test do? 633 | 634 | The test pod will: 635 | - Validate that the Cluster resources are suitable to run Crane & child deployment 636 | - Check for required roles and mappings. 637 | - Verify network connectivity and DNS resolution from within the cluster. 638 | - Validate if the required k8s resources are deployed to support crane and its functionalities 639 | 640 | 641 | ### [7.3] Interpreting results 642 | 643 | - **Success:** 644 | If the test passes, you’ll see output similar to: 645 | ```sh 646 | NAME: crane 647 | LAST DEPLOYED: Tue Jun 3 20:24:12 2025 648 | NAMESPACE: default 649 | STATUS: deployed 650 | REVISION: 5 651 | TEST SUITE: cranetesthook 652 | Last Started: Tue Jun 3 20:24:24 2025 653 | Last Completed: Tue Jun 3 20:24:30 2025 654 | Phase: Succeeded 655 | ``` 656 | This means your chart and infrastructure are ready. 657 | 658 | - **Failure:** 659 | If the test fails, review the logs for details. The `--logs` flag would point to the issue that is causing the failure. 660 | Common issues include missing secrets, network restrictions, or misconfigured values/specs. Address any reported issues and re-run the test. 661 | 662 | ### [7.4] Additional tips 663 | 664 | - You can add the `--logs` flag to `helm test` to automatically print the test pod logs: 665 | ```sh 666 | helm test --logs 667 | ``` 668 | - If the test pod is stuck or fails to start, check for k8s scheduler error (possible with third-party admission controllers), image pull errors, or missing configuration. 669 | 670 | If you continue to encounter issues, please contact your cloud or DevOps team for assistance. 671 | 672 | --- 673 | 674 | 675 | ## [8.0] Upgrading the existing chart 676 | 677 | To upgrade your existing Helm release to a new version of the chart, use the `helm upgrade` command. This allows you to apply new chart versions or updated configuration values without uninstalling and reinstalling. 678 | 679 | ### [8.1] Basic upgrade command 680 | 681 | ```sh 682 | helm upgrade /path/to/newchart -n 683 | ``` 684 | - Replace `` with the name of your Helm release (e.g., `crane`). 685 | - Replace `/path/to/newchart` with the path to the new or updated chart directory or `.tgz` file. 686 | - Replace `` with the namespace where your release is installed. 687 | 688 | ### [8.2] Upgrading with custom values 689 | 690 | If you have a custom `values.yaml` file, specify it with the `-f` flag: 691 | 692 | ```sh 693 | helm upgrade /path/to/newchart -n -f /path/to/values.yaml 694 | ``` 695 | 696 | You can specify multiple `-f` flags to merge several values files. 697 | 698 | ### [8.3] Additional tips 699 | 700 | - Before upgrading, you can preview the changes with: 701 | ```sh 702 | helm diff upgrade /path/to/newchart -n -f /path/to/values.yaml 703 | ``` 704 | (Requires the [helm-diff plugin](https://github.com/databus23/helm-diff).) 705 | - If you want to force resource updates (for example, if only config or secrets changed), add `--force`: 706 | ```sh 707 | helm upgrade /path/to/newchart -n --force 708 | ``` 709 | - After upgrading, verify the deployment and run the Helm test as described in the previous section. 710 | 711 | If you encounter issues during upgrade, review the output for errors and consult the [Helm upgrade documentation](https://helm.sh/docs/helm/helm_upgrade/). 712 | 713 | --- 714 | 715 | 716 | ## [9.0] Uninstalling the chart 717 | 718 | - To uninstall the Helm chart run: 719 | ```sh 720 | helm uninstall -n 721 | ``` 722 | --- 723 | 724 | 725 | 726 | ## [10.0] Changelog: 727 | 728 | - 1.4.3: Inclusion of `securityContext.Capabilities` which would default to `drop: ["ALL"]` in our chart for child resources/executors. (No change to the values YAML file) 729 | - 1.4.2: Support for custom annotations with Crane and child resources. 730 | - 1.4.1: Added default values for secret wildcard credential for test-hook. Fixed minor condition handling for istio-based test-hook role configuration. No changes to main chart functionality. 731 | - 1.4.0: Added support for Pod Disruption Budgets (PDB) and SecretProviderClass integration. Introduced ExternalSecrets Operator support. Addition of testHook for faster/accurate validation of installation. Simplified the image override usage. Incorporation of ingress setup & usage in one single config. Other minor bug fixes and template enhancements. Extended documentations on chart usage. 732 | - 1.3.1: Readiness and Liveness probes are now added. 733 | - 1.3.0: Chart can support image-override configuration. gridProxy is in working configuration. Resource (CPU & MEM) limit/requests are now configurable for crane and child resources and also for ephemeral storage. Simplified nesting and values configuration. The chart can now work with non-default serviceAccount. Tolerations, nodeSelector and labels can be declared for Crane and child resources separately, with Major fixes & calibrations. 734 | - **Anything below 1.3.0 - UNSUPPORTED** 735 | --------------------------------------------------------------------------------