Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion applications/samples/deploy/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ harness:
service:
port: 8080
auto: true
route_pattern: '/(?!\/metrics\/?$)\/.*'
use_services:
- name: common
deployment:
Expand Down Expand Up @@ -96,4 +97,4 @@ harness:

dockerfile:
buildArgs:
TEST_ARGUMENT: example value
TEST_ARGUMENT: example value
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ spec:
solvers:
- http01:
ingress:
class: nginx
class: {{ .Values.ingress.ingressClass }}
{{ end }}
19 changes: 14 additions & 5 deletions deployment-configuration/helm/templates/ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
{{- end }}
{{- end }}
{{- end }}
- path: /(.*)
- path: {{ default .root.Values.ingress.route_pattern $app.harness.route_pattern }}
pathType: ImplementationSpecific
backend:
service:
Expand All @@ -52,7 +52,8 @@
{{ $domain := .root.Values.domain }}
{{ $secured_gatekeepers := and .root.Values.secured_gatekeepers }}
{{ $app := get .root.Values.apps .service_name}}
- path: /proxy/{{ $app.harness.service.name }}/(.*)
{{ $routePattern := default .root.Values.ingress.route_pattern $app.harness.route_pattern }}
- path: /proxy/{{ $app.harness.service.name }}{{ $routePattern }}
pathType: ImplementationSpecific
backend:
service:
Expand All @@ -69,11 +70,12 @@ kind: Ingress
metadata:
name: {{ .Values.ingress.name | quote }}
annotations:
kubernetes.io/ingress.class: nginx # Deprecated by Kubernetes, however still required for GKE
kubernetes.io/ingress.class: {{ .Values.ingress.ingressClass }} # Deprecated by Kubernetes, however still required for GKE
{{- if and (not .Values.local) $tls }}
kubernetes.io/tls-acme: 'true'
cert-manager.io/issuer: {{ printf "%s-%s" "letsencrypt" .Values.namespace }}
{{- end }}
{{- if eq .Values.ingress.ingressClass "nginx" }}
nginx.ingress.kubernetes.io/ssl-redirect: {{ (and $tls .Values.ingress.ssl_redirect) | quote }}
nginx.ingress.kubernetes.io/proxy-body-size: '{{ .Values.proxy.payload.max }}m'
nginx.ingress.kubernetes.io/proxy-buffer-size: '128k'
Expand All @@ -86,8 +88,15 @@ metadata:
nginx.ingress.kubernetes.io/proxy-read-timeout: {{ .Values.proxy.timeout.read | quote }}
nginx.ingress.kubernetes.io/proxy-send-timeout: {{ .Values.proxy.timeout.send | quote }}
nginx.ingress.kubernetes.io/use-forwarded-headers: {{ .Values.proxy.forwardedHeaders | quote }}
{{- else if eq .Values.ingress.ingressClass "traefik" }}
traefik.ingress.kubernetes.io/router.pathmatcher: "PathRegexp"
traefik.ingress.kubernetes.io/router.middlewares: {{ printf "%s-ch-rewrite-target@kubernetescrd,%s-ch-body-size@kubernetescrd" .Values.namespace .Values.namespace }}{{ if and $tls .Values.ingress.ssl_redirect }},{{ printf "%s-ch-ssl-redirect@kubernetescrd" .Values.namespace }}{{ end }}
{{- end }}
{{- with .Values.ingress.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: nginx
ingressClassName: {{ .Values.ingress.ingressClass }}
rules:
{{- range $app := .Values.apps }}
{{- if (and $mainapp (and $app.harness.name (eq $app.harness.name $mainapp))) }}
Expand Down Expand Up @@ -147,4 +156,4 @@ spec:
{{- end }}
secretName: tls-secret
{{- end }}
{{- end }}
{{- end }}
35 changes: 35 additions & 0 deletions deployment-configuration/helm/templates/traefik-middlewares.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{{- if and .Values.ingress.enabled (eq .Values.ingress.ingressClass "traefik") }}
{{ $tls := not (not .Values.tls) }}
# Rewrite target: equivalent of nginx.ingress.kubernetes.io/rewrite-target: /$1
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ch-rewrite-target
spec:
replacePathRegex:
regex: "^/[^/]+(.*)"
replacement: "/$1"
---
# Body size / buffering: equivalent of nginx proxy-body-size, proxy-buffer-size
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ch-body-size
spec:
buffering:
maxRequestBodyBytes: {{ mul .Values.proxy.payload.max 1048576 }}
memRequestBodyBytes: 131072
memResponseBodyBytes: 131072
{{- if and $tls .Values.ingress.ssl_redirect }}
---
# SSL redirect: equivalent of nginx.ingress.kubernetes.io/ssl-redirect
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ch-ssl-redirect
spec:
redirectScheme:
scheme: https
permanent: true
{{- end }}
{{- end }}
8 changes: 7 additions & 1 deletion deployment-configuration/helm/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@ ingress:
enabled: true
# -- K8s Name of ingress.
name: cloudharness-ingress
# -- The ingress class to use (e.g. "nginx", "traefik").
ingressClass: nginx
# -- Additional custom annotations to add to the Ingress resource.
annotations: {}
# -- Enables/disables SSL redirect.
ssl_redirect: true
letsencrypt:
# -- Email for letsencrypt.
email: cloudharness@metacell.us
# -- Default regex segment for routes (used in paths like '/(pattern)').
route_pattern: "/(.*)"
backup:
# -- Flag to enable/disable backups.
active: false
Expand Down Expand Up @@ -89,4 +95,4 @@ proxy:
requests:
memory: "32Mi"
limits:
memory: "64Mi"
memory: "64Mi"
36 changes: 35 additions & 1 deletion docs/ingress-domains-proxies.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,38 @@ proxy:

Note that in the case that gatekeepers are enabled, the same configurations are applied
to the gatekeepers, unless the application override them on `harness.proxy.*`.
See also the [gatekeepers documentation](./accounts.md#secure-and-enpoint-with-the-gatekeeper).
See also the [gatekeepers documentation](./accounts.md#secure-and-enpoint-with-the-gatekeeper).

## Route pattern configuration

Cloud Harness allows customizing which request paths are routed to an application
via a glob-style regular expression. There are two levels where this can be set:

- **Global**: `ingress.route_pattern` in `deployment-configuration/helm/values.yaml` (applies to all apps by default).
- **Application**: `harness.route_pattern` in an application's `values.yaml` (overrides the global value for that app).

The Helm ingress template uses the application-level `harness.route_pattern` when present,
falling back to the global `ingress.route_pattern` otherwise.

Example (global default in `deployment-configuration/helm/values.yaml`):

```yaml
ingress:
# Default regex segment for routes (used in paths like '/(pattern)')
route_pattern: "/(.*)"
```

Example (application override in `applications/<app>/deploy/values.yaml`):

```yaml
harness:
# route_pattern is used to build the Ingress path for the app
route_pattern: '/((?!(?:metrics)(?:/)?$).*)' # exclude only '/metrics' and '/metrics/'
```

Notes:
- The pattern is inserted into the generated Ingress `path` field. Make sure the regex
is valid for your ingress controller and matches the expected path syntax.
- If you only need to exclude a single exact path (for example `/metrics`), use a
negative lookahead like the example above. If you prefer a simpler global default,
leave `ingress.route_pattern` as `"/(.*)"` and override per-app when needed.
2 changes: 1 addition & 1 deletion tools/deployment-cli-tools/tests/test_codefresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,7 @@ def test_steps_ordered_by_stage_in_generated_config():
assert step_stage_indices == sorted(step_stage_indices), \
"Steps are not ordered by stage. Got stages: " + str(
[step.get('stage') for step in steps.values() if step and isinstance(step, dict)]
)
)
finally:
import shutil
shutil.rmtree(BUILD_MERGE_DIR, ignore_errors=True)
Expand Down
Loading