diff --git a/charts/selenium/Chart.yaml b/charts/selenium/Chart.yaml new file mode 100644 index 0000000..d2fc826 --- /dev/null +++ b/charts/selenium/Chart.yaml @@ -0,0 +1,13 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +apiVersion: v2 +name: selenium-grid +description: A Helm chart for deploying a Selenium Grid with Firefox or Chrome Node(s) +type: application +home: "galasa.dev" +version: "0.1.0" +appVersion: "4.21.0" diff --git a/charts/selenium/templates/node-deployment.yaml b/charts/selenium/templates/node-deployment.yaml new file mode 100644 index 0000000..29a6ec8 --- /dev/null +++ b/charts/selenium/templates/node-deployment.yaml @@ -0,0 +1,74 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-{{ .Values.node.type }}-node + labels: + app: {{ .Release.Name }}-{{ .Values.node.type }}-node +spec: + replicas: {{ .Values.node.replicaCount | default 1 }} + selector: + matchLabels: + app: {{ .Release.Name }}-{{ .Values.node.type }}-node + template: + metadata: + labels: + app: {{ .Release.Name }}-{{ .Values.node.type }}-node + spec: + serviceAccountName: {{ .Values.serviceAccountName | default "default" }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Values.node.type }} + image: "{{ .Values.node.image.repository }}:{{ .Values.node.image.tag }}" + imagePullPolicy: "{{ .Values.node.image.pullPolicy }}" + ports: + - containerPort: 4444 + name: webdriver + protocol: TCP + - containerPort: 5900 + name: vnc + protocol: TCP + - containerPort: 7900 + name: novnc + protocol: TCP + env: + - name: SE_EVENT_BUS_HOST + value: "{{ .Release.Name }}-hub" + - name: SE_EVENT_BUS_PUBLISH_PORT + value: "4442" + - name: SE_EVENT_BUS_SUBSCRIBE_PORT + value: "4443" + - name: SE_NODE_PORT + value: "4444" + - name: SE_NODE_MAX_SESSION + value: "{{ .Values.node.maxSession | default "1" }}" + - name: SE_NODE_SESSION_TIMEOUT + value: "{{ .Values.node.sessionTimeout | default "60" }}" + - name: SE_VNC_NO_PASSWORD + value: "true" + livenessProbe: + httpGet: + path: /status + port: 4444 + initialDelaySeconds: 10 + periodSeconds: 20 + failureThreshold: 3 + readinessProbe: + httpGet: + path: /status + port: 4444 + initialDelaySeconds: 5 + periodSeconds: 10 + failureThreshold: 3 + {{- with .Values.node.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} \ No newline at end of file diff --git a/charts/selenium/templates/node-service.yaml b/charts/selenium/templates/node-service.yaml new file mode 100644 index 0000000..99802ad --- /dev/null +++ b/charts/selenium/templates/node-service.yaml @@ -0,0 +1,31 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-{{ .Values.node.type }}-node + labels: + app: {{ .Release.Name }}-{{ .Values.node.type }}-node + annotations: + description: "Exposes the {{ .Values.node.type | title }} node's WebDriver (4444), VNC (5900), and noVNC (7900) ports for live view access if headless mode is not turned on" +spec: + type: {{ .Values.node.service.type }} + ports: + - name: webdriver + port: 4444 + targetPort: 4444 + protocol: TCP + - name: vnc + port: 5900 + targetPort: 5900 + protocol: TCP + - name: novnc + port: 7900 + targetPort: 7900 + protocol: TCP + selector: + app: {{ .Release.Name }}-{{ .Values.node.type }}-node diff --git a/charts/selenium/templates/selenium-grid-hub.yaml b/charts/selenium/templates/selenium-grid-hub.yaml new file mode 100644 index 0000000..27e3c9a --- /dev/null +++ b/charts/selenium/templates/selenium-grid-hub.yaml @@ -0,0 +1,66 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-hub + labels: + app: {{ .Release.Name }}-hub +spec: + replicas: {{ .Values.hub.replicaCount }} + selector: + matchLabels: + app: {{ .Release.Name }}-hub + template: + metadata: + labels: + app: {{ .Release.Name }}-hub + spec: + serviceAccountName: {{ .Values.serviceAccountName | default "default" }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: hub + image: "{{ .Values.hub.image.repository }}:{{ .Values.hub.image.tag }}" + imagePullPolicy: {{ .Values.hub.image.pullPolicy }} + ports: + - name: web + containerPort: 4444 + protocol: TCP + - name: event-pub + containerPort: 4442 + protocol: TCP + - name: event-sub + containerPort: 4443 + protocol: TCP + env: + - name: GRID_BROWSER_TIMEOUT + value: "{{ .Values.hub.browserTimeout }}" + - name: GRID_TIMEOUT + value: "{{ .Values.hub.timeout }}" + - name: SE_EVENT_BUS_PUBLISH_PORT + value: "4442" + - name: SE_EVENT_BUS_SUBSCRIBE_PORT + value: "4443" + {{- with .Values.hub.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: /status + port: 4444 + initialDelaySeconds: 10 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /status + port: 4444 + initialDelaySeconds: 5 + periodSeconds: 5 diff --git a/charts/selenium/templates/selenium-grid-ingress.yaml b/charts/selenium/templates/selenium-grid-ingress.yaml new file mode 100644 index 0000000..3d1ed27 --- /dev/null +++ b/charts/selenium/templates/selenium-grid-ingress.yaml @@ -0,0 +1,35 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Release.Name }}-hub + labels: + app: {{ .Release.Name }}-hub + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end }} + {{- with .Values.ingress.tls }} + tls: + {{- toYaml . | nindent 4 }} + {{- end }} + rules: + - host: {{ .Values.ingress.externalHostname }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Release.Name }}-hub + port: + number: {{ .Values.hub.service.port | default 4444 }} diff --git a/charts/selenium/templates/selenium-grid-service.yaml b/charts/selenium/templates/selenium-grid-service.yaml new file mode 100644 index 0000000..b134078 --- /dev/null +++ b/charts/selenium/templates/selenium-grid-service.yaml @@ -0,0 +1,29 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-hub + labels: + app: {{ .Release.Name }}-hub +spec: + type: {{ .Values.hub.service.type }} + ports: + - name: web + port: 4444 + targetPort: 4444 + protocol: TCP + - name: event-pub + port: 4442 + targetPort: 4442 + protocol: TCP + - name: event-sub + port: 4443 + targetPort: 4443 + protocol: TCP + selector: + app: {{ .Release.Name }}-hub diff --git a/charts/selenium/values.yaml b/charts/selenium/values.yaml new file mode 100644 index 0000000..faaf7fc --- /dev/null +++ b/charts/selenium/values.yaml @@ -0,0 +1,74 @@ +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# + +hub: + replicaCount: 1 # Number of Selenium Hub replicas to run + + image: + repository: selenium/hub # Docker image repository for Selenium Hub + tag: 4.8.3-20230328 # Specific image tag/version to use + pullPolicy: IfNotPresent # Image pull policy (IfNotPresent to avoid pulling if image exists) + + browserTimeout: "60" # Timeout (in seconds) for browser requests to the hub + timeout: "60" # General timeout (in seconds) for hub operations + + resources: # Kubernetes resource requests and limits for the hub pods + limits: + cpu: "500m" # Max CPU allowed + memory: "512Mi" # Max memory allowed + requests: + cpu: "250m" # Minimum CPU requested + memory: "256Mi" # Minimum memory requested + + service: + type: ClusterIP # Kubernetes Service type (ClusterIP, NodePort, or LoadBalancer) + port: 4444 # Port exposed by the Selenium Hub service + +serviceAccountName: "" # Name of Kubernetes ServiceAccount to use + +nodeSelector: + kubernetes.io/arch: amd64 # Node architecture selector; schedules pods to amd64 nodes + +ingress: + enabled: true # Enable or disable Ingress for the Selenium Hub + ingressClassName: nginx # Ingress controller class name (e.g., nginx) + externalHostname: "justin-test-selenium-ingress.cicsk8s.hursley.ibm.com" + # External hostname for accessing the hub via ingress + + annotations: # Annotations for the Ingress resource + nginx.ingress.kubernetes.io/ssl-redirect: "false" + # Disable automatic SSL redirect + nginx.ingress.kubernetes.io/rewrite-target: / + # Rewrite target path for incoming requests + + # tls: # TLS configuration (optional) for HTTPS ingress + # - hosts: + # - seleniumhub.example.com + # secretName: seleniumhub-tls-secret + +node: + type: chrome # Browser type for nodes; options: "firefox" or "chrome" + replicaCount: 3 # Number of browser nodes to deploy + + service: + type: ClusterIP # Service type for browser nodes (ClusterIP, NodePort, LoadBalancer) + + image: + repository: selenium/node-chrome # Docker image repo for browser node + # Change to "selenium/node-firefox" for Firefox nodes + tag: 4.8.3-20230328 # Image tag/version + pullPolicy: IfNotPresent # Image pull policy + + maxSession: 1 # Maximum concurrent sessions per browser node + sessionTimeout: 300 # Timeout in seconds for each session on the node + + resources: # Kubernetes resource requests and limits for browser nodes + limits: + cpu: "500m" # Max CPU allowed per node pod + memory: "512Mi" # Max memory allowed per node pod + requests: + cpu: "250m" # Minimum CPU requested per node pod + memory: "256Mi" # Minimum memory requested per node pod