Add reuse service landing page
This commit is contained in:
@@ -17,9 +17,30 @@ app.kubernetes.io/name: {{ include "reuse.fullname" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "reuse.landingFullname" -}}
|
||||
{{- printf "%s-landing" (include "reuse.fullname" .) | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "reuse.redirectMiddlewareName" -}}
|
||||
{{- printf "%s-redirect-https" (include "reuse.fullname" .) | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "reuse.landingSelectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "reuse.fullname" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: landing
|
||||
{{- end -}}
|
||||
|
||||
{{- define "reuse.image" -}}
|
||||
{{- if not .Values.image.tag -}}
|
||||
{{- fail "image.tag is required - pin it in helm/reuse-surface-values.yaml" -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s:%s" .Values.image.repository .Values.image.tag -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "reuse.landingImage" -}}
|
||||
{{- if not .Values.landing.image.tag -}}
|
||||
{{- fail "landing.image.tag is required when landing.enabled=true" -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s:%s" .Values.landing.image.repository .Values.landing.image.tag -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -2,7 +2,9 @@ apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "reuse.fullname" . }}
|
||||
labels: {{- include "reuse.labels" . | nindent 4 }}
|
||||
labels:
|
||||
{{- include "reuse.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
@@ -14,7 +16,9 @@ spec:
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels: {{- include "reuse.selectorLabels" . | nindent 8 }}
|
||||
labels:
|
||||
{{- include "reuse.selectorLabels" . | nindent 8 }}
|
||||
app.kubernetes.io/component: api
|
||||
spec:
|
||||
enableServiceLinks: false
|
||||
securityContext: {{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
@@ -78,4 +82,4 @@ spec:
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations: {{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -18,6 +18,24 @@ spec:
|
||||
- host: {{ .Values.ingress.host }}
|
||||
http:
|
||||
paths:
|
||||
{{- if .Values.landing.enabled }}
|
||||
{{- range .Values.ingress.apiPaths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "reuse.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "reuse.landingFullname" . }}
|
||||
port:
|
||||
number: {{ .Values.landing.service.port }}
|
||||
{{- else }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
@@ -25,4 +43,5 @@ spec:
|
||||
name: {{ include "reuse.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
135
charts/reuse-surface/templates/landing-configmap.yaml
Normal file
135
charts/reuse-surface/templates/landing-configmap.yaml
Normal file
@@ -0,0 +1,135 @@
|
||||
{{- if .Values.landing.enabled }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "reuse.landingFullname" . }}
|
||||
labels:
|
||||
{{- include "reuse.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: landing
|
||||
data:
|
||||
index.html: |
|
||||
{{ if .Values.landing.html }}
|
||||
{{ tpl .Values.landing.html . | nindent 4 }}
|
||||
{{ else }}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{{- if .Values.landing.noindex }}
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
{{- end }}
|
||||
{{- if and .Values.landing.redirect.enabled .Values.landing.redirect.target }}
|
||||
<meta http-equiv="refresh" content="{{ .Values.landing.redirect.delaySeconds }}; url={{ .Values.landing.redirect.target }}">
|
||||
{{- end }}
|
||||
<title>{{ .Values.landing.title }}</title>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: light;
|
||||
--ink: #1d2733;
|
||||
--muted: #536271;
|
||||
--line: #d9e0e7;
|
||||
--paper: #f8fafc;
|
||||
--accent: #2066a8;
|
||||
--accent-dark: #164b7e;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
min-height: 100vh;
|
||||
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
color: var(--ink);
|
||||
background: var(--paper);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 32px 18px;
|
||||
}
|
||||
main {
|
||||
width: min(100%, 720px);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
background: #ffffff;
|
||||
padding: clamp(28px, 5vw, 48px);
|
||||
box-shadow: 0 18px 48px rgba(29, 39, 51, 0.08);
|
||||
}
|
||||
.eyebrow {
|
||||
margin: 0 0 12px;
|
||||
color: var(--accent-dark);
|
||||
font-size: 0.86rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: clamp(2rem, 7vw, 3rem);
|
||||
line-height: 1.05;
|
||||
}
|
||||
p {
|
||||
max-width: 62ch;
|
||||
margin: 18px 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 1rem;
|
||||
line-height: 1.65;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
margin-top: 28px;
|
||||
}
|
||||
a {
|
||||
color: var(--accent);
|
||||
}
|
||||
.button {
|
||||
display: inline-flex;
|
||||
min-height: 44px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
background: var(--accent);
|
||||
color: #ffffff;
|
||||
padding: 0 18px;
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
}
|
||||
.button:focus,
|
||||
.button:hover {
|
||||
background: var(--accent-dark);
|
||||
}
|
||||
.links {
|
||||
margin-top: 26px;
|
||||
padding-top: 22px;
|
||||
border-top: 1px solid var(--line);
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<p class="eyebrow">{{ .Values.landing.eyebrow }}</p>
|
||||
<h1>{{ .Values.landing.title }}</h1>
|
||||
<p>{{ .Values.landing.body }}</p>
|
||||
{{- $target := .Values.landing.primaryUrl }}
|
||||
{{- if and .Values.landing.redirect.enabled .Values.landing.redirect.target }}
|
||||
{{- $target = .Values.landing.redirect.target }}
|
||||
{{- end }}
|
||||
{{- if $target }}
|
||||
<div class="actions">
|
||||
<a class="button" href="{{ $target }}">{{ .Values.landing.buttonLabel }}</a>
|
||||
</div>
|
||||
{{- end }}
|
||||
{{- if .Values.landing.links }}
|
||||
<nav class="links" aria-label="Service links">
|
||||
{{- range .Values.landing.links }}
|
||||
<a href="{{ .url }}">{{ .label }}</a>
|
||||
{{- end }}
|
||||
</nav>
|
||||
{{- end }}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
59
charts/reuse-surface/templates/landing-deployment.yaml
Normal file
59
charts/reuse-surface/templates/landing-deployment.yaml
Normal file
@@ -0,0 +1,59 @@
|
||||
{{- if .Values.landing.enabled }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "reuse.landingFullname" . }}
|
||||
labels:
|
||||
{{- include "reuse.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: landing
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "reuse.landingSelectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 1
|
||||
maxUnavailable: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "reuse.landingSelectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
enableServiceLinks: false
|
||||
containers:
|
||||
- name: landing
|
||||
image: {{ include "reuse.landingImage" . | quote }}
|
||||
imagePullPolicy: {{ .Values.landing.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.landing.service.targetPort }}
|
||||
protocol: TCP
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
resources: {{- toYaml .Values.landing.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: landing-page
|
||||
mountPath: /usr/share/nginx/html/index.html
|
||||
subPath: index.html
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: landing-page
|
||||
configMap:
|
||||
name: {{ include "reuse.landingFullname" . }}
|
||||
{{- end }}
|
||||
18
charts/reuse-surface/templates/landing-service.yaml
Normal file
18
charts/reuse-surface/templates/landing-service.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
{{- if .Values.landing.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "reuse.landingFullname" . }}
|
||||
labels:
|
||||
{{- include "reuse.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: landing
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "reuse.landingSelectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.landing.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
23
charts/reuse-surface/templates/redirect-ingress.yaml
Normal file
23
charts/reuse-surface/templates/redirect-ingress.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
{{- if and .Values.ingress.enabled .Values.ingress.redirectHttp.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "reuse.fullname" . }}-http-redirect
|
||||
labels: {{- include "reuse.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: web
|
||||
traefik.ingress.kubernetes.io/router.middlewares: {{ printf "%s-%s@kubernetescrd" .Release.Namespace (include "reuse.redirectMiddlewareName" .) | quote }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
rules:
|
||||
- host: {{ .Values.ingress.host }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "reuse.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- end }}
|
||||
11
charts/reuse-surface/templates/redirect-middleware.yaml
Normal file
11
charts/reuse-surface/templates/redirect-middleware.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
{{- if and .Values.ingress.enabled .Values.ingress.redirectHttp.enabled }}
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: {{ include "reuse.redirectMiddlewareName" . }}
|
||||
labels: {{- include "reuse.labels" . | nindent 4 }}
|
||||
spec:
|
||||
redirectScheme:
|
||||
scheme: https
|
||||
permanent: {{ .Values.ingress.redirectHttp.permanent }}
|
||||
{{- end }}
|
||||
@@ -5,9 +5,11 @@ metadata:
|
||||
labels: {{- include "reuse.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
selector: {{- include "reuse.selectorLabels" . | nindent 4 }}
|
||||
selector:
|
||||
{{- include "reuse.selectorLabels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: api
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
protocol: TCP
|
||||
|
||||
@@ -26,11 +26,48 @@ resources:
|
||||
|
||||
envSecretName: reuse-surface-env
|
||||
|
||||
landing:
|
||||
enabled: false
|
||||
image:
|
||||
repository: nginxinc/nginx-unprivileged
|
||||
tag: "1.27-alpine"
|
||||
pullPolicy: IfNotPresent
|
||||
service:
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
noindex: true
|
||||
title: "Railiance service endpoint"
|
||||
eyebrow: "Railiance S5"
|
||||
body: "This endpoint is available for automated clients and operators."
|
||||
buttonLabel: "Continue"
|
||||
primaryUrl: ""
|
||||
redirect:
|
||||
enabled: false
|
||||
target: ""
|
||||
delaySeconds: 5
|
||||
links: []
|
||||
html: ""
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: traefik
|
||||
host: reuse.coulomb.social
|
||||
tls: true
|
||||
redirectHttp:
|
||||
enabled: false
|
||||
permanent: true
|
||||
apiPaths:
|
||||
- path: /health
|
||||
pathType: Exact
|
||||
- path: /v1
|
||||
pathType: Prefix
|
||||
annotations:
|
||||
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||
traefik.ingress.kubernetes.io/router.tls: "true"
|
||||
@@ -56,4 +93,4 @@ securityContext: {}
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
affinity: {}
|
||||
|
||||
Reference in New Issue
Block a user