mirror of
https://github.com/labring/sealos.git
synced 2026-09-21 13:51:32 +08:00
feat(providers): migrate app deploys to helm charts (#6954)
* feat(providers): migrate app deploys to helm charts * fix(aiproxy): use sealos-compatible entrypoint command * fix(providers): use sealos-compatible kubefile commands
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
FROM scratch
|
||||
COPY . .
|
||||
CMD ["bash install.sh"]
|
||||
|
||||
USER 65532:65532
|
||||
|
||||
COPY charts charts
|
||||
COPY aiproxy-web-entrypoint.sh aiproxy-web-entrypoint.sh
|
||||
|
||||
CMD ["bash aiproxy-web-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"aiproxy-web"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"aiproxy-system"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/aiproxy"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
get_deploy_env() {
|
||||
local namespace="$1"
|
||||
local deployment="$2"
|
||||
local key="$3"
|
||||
kubectl get deployment -n "${namespace}" "${deployment}" -o "jsonpath={.spec.template.spec.containers[0].env[?(@.name==\"${key}\")].value}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
NODE_COUNT=$(kubectl get nodes --no-headers 2>/dev/null | wc -l | tr -d " ")
|
||||
if [ "${NODE_COUNT}" = "1" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set replicas=1"
|
||||
fi
|
||||
|
||||
JWT_INTERNAL=${JWT_INTERNAL:-"${jwtInternal:-$(get_cm_value sealos-system sealos-config jwtInternal)}"}
|
||||
ADMIN_KEY=${ADMIN_KEY:-"${adminKey:-$(get_cm_value aiproxy-system aiproxy-env ADMIN_KEY)}"}
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
CURRENCY_SYMBOL=${CURRENCY_SYMBOL:-"${currencySymbol:-$(get_deploy_env dbprovider-frontend dbprovider-frontend CURRENCY_SYMBOL)}"}
|
||||
SUFFIX=${SUFFIX:-"${suffix:-}"}
|
||||
|
||||
if [ "${CURRENCY_SYMBOL}" = "usd" ] && [ -z "${SUFFIX}" ]; then
|
||||
SUFFIX="/en/home"
|
||||
fi
|
||||
|
||||
add_set_string aiproxy.APP_TOKEN_JWT_KEY "${JWT_INTERNAL}"
|
||||
add_set_string aiproxy.AI_PROXY_BACKEND_KEY "${ADMIN_KEY}"
|
||||
add_set_string cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
add_set_string cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
add_set_string aiproxy.CURRENCY_SYMBOL "${CURRENCY_SYMBOL}"
|
||||
add_set_string suffix "${SUFFIX}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap aiproxy-web
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service aiproxy-web
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment aiproxy-web
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress aiproxy-web
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io aiproxy
|
||||
|
||||
SERVICE_NAME="aiproxy-web"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/aiproxy/${SERVICE_NAME}-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/aiproxy/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -0,0 +1,17 @@
|
||||
# Custom values for aiproxy web helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicas: 2
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 50Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
|
||||
aiproxy:
|
||||
CURRENCY_SYMBOL: ""
|
||||
IS_INVITATION_ACTIVE: "false"
|
||||
DOC_URL: "https://sealos.run/docs/guides/ai-proxy"
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
timestamp() {
|
||||
date +"%Y-%m-%d %T"
|
||||
}
|
||||
print() {
|
||||
flag=$(timestamp)
|
||||
echo -e "\033[1;32m\033[1m INFO [$flag] >> $* \033[0m"
|
||||
}
|
||||
warn() {
|
||||
flag=$(timestamp)
|
||||
echo -e "\033[33m WARN [$flag] >> $* \033[0m"
|
||||
}
|
||||
info() {
|
||||
flag=$(timestamp)
|
||||
echo -e "\033[36m INFO [$flag] >> $* \033[0m"
|
||||
}
|
||||
#===========================================================================
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
|
||||
NODE_COUNT=$(kubectl get nodes --no-headers | wc -l)
|
||||
REPLICA_OPTIONS=""
|
||||
if [ "$NODE_COUNT" -eq 1 ]; then
|
||||
REPLICA_OPTIONS="--set replicas=1 "
|
||||
HELM_OPTS="${HELM_OPTS} ${REPLICA_OPTIONS}"
|
||||
fi
|
||||
|
||||
|
||||
varJwtInternal=$(kubectl get configmap sealos-config -n sealos-system -o jsonpath='{.data.jwtInternal}')
|
||||
adminKey=$(kubectl get configmap aiproxy-env -n aiproxy-system -o jsonpath='{.data.ADMIN_KEY}' )
|
||||
SEALOS_CLOUD_DOMAIN=$(kubectl get configmap sealos-config -n sealos-system -o jsonpath='{.data.cloudDomain}')
|
||||
SEALOS_CLOUD_PORT=$(kubectl get configmap sealos-config -n sealos-system -o jsonpath='{.data.cloudPort}')
|
||||
CURRENCY_SYMBOL=$(kubectl get deployment -n dbprovider-frontend dbprovider-frontend -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="CURRENCY_SYMBOL")].value}')
|
||||
if [[ "${CURRENCY_SYMBOL}" == "usd" ]]; then
|
||||
SUFFIX="/en/home"
|
||||
fi
|
||||
|
||||
helm upgrade -i aiproxy-web -n aiproxy-system charts/aiproxy ${HELM_OPTS} \
|
||||
--set aiproxy.APP_TOKEN_JWT_KEY=${varJwtInternal} --set aiproxy.AI_PROXY_BACKEND_KEY=${adminKey} \
|
||||
--set suffix=${SUFFIX} \
|
||||
--set cloudDomain=${SEALOS_CLOUD_DOMAIN} --set cloudPort=${SEALOS_CLOUD_PORT} --set aiproxy.CURRENCY_SYMBOL=${CURRENCY_SYMBOL} --create-namespace
|
||||
@@ -3,11 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY cloudserver-frontend-entrypoint.sh cloudserver-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
ENV lafBaseUrl=""
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash cloudserver-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: cloudserver-frontend
|
||||
description: Sealos cloudserver Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
# Custom values for cloudserver-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
cloudserverConfig:
|
||||
lafBaseUrl: ""
|
||||
jwtSecretApp: ""
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "cloudserver-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "cloudserver-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "cloudserver-frontend.chart" . }}
|
||||
{{ include "cloudserver-frontend.selectorLabels" . }}
|
||||
{{ include "cloudserver-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.selectorLabels" -}}
|
||||
app: {{ include "cloudserver-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "cloudserver-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.cloudserverConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.port" -}}
|
||||
{{- $scheme := include "cloudserver-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.cloudserverConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.cloudserverConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.portSuffix" -}}
|
||||
{{- $port := include "cloudserver-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.portEnv" -}}
|
||||
{{- $port := include "cloudserver-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.cloudOrigin" -}}
|
||||
{{- include "cloudserver-frontend.scheme" . -}}://{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "cloudserver-frontend.scheme" . -}}://*.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.host" -}}
|
||||
{{- default (printf "cloudserver.%s" .Values.cloudserverConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cloudserver-frontend.appUrl" -}}
|
||||
{{- include "cloudserver-frontend.scheme" . -}}://{{ include "cloudserver-frontend.host" . }}{{ include "cloudserver-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+7
-5
@@ -6,12 +6,14 @@ metadata:
|
||||
spec:
|
||||
data:
|
||||
desc: cloudserver
|
||||
url: "https://cloudserver.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
icon: "https://cloudserver.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}/logo.svg"
|
||||
url: {{ include "cloudserver-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "cloudserver-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: 云主机
|
||||
zh-Hans:
|
||||
name: 云主机
|
||||
menuData:
|
||||
name: cloudserver
|
||||
type: iframe
|
||||
displayType: normal
|
||||
i18n:
|
||||
zh:
|
||||
name: 云主机
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "cloudserver-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "cloudserver-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "cloudserver-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "cloudserver-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "cloudserver-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "cloudserver-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: LAF_BASE_URL
|
||||
value: {{ .Values.cloudserverConfig.lafBaseUrl | quote }}
|
||||
- name: JWT_SECRET_APP
|
||||
value: {{ .Values.cloudserverConfig.jwtSecretApp | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: cloudserver-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: cloudserver-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "cloudserver-frontend.fullname" . }}-config
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "cloudserver-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ include "cloudserver-frontend.cloudOrigin" . }}, {{ include "cloudserver-frontend.wildcardCloudOrigin" . }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "cloudserver-frontend.cloudOrigin" . }} {{ include "cloudserver-frontend.wildcardCloudOrigin" . }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} {{ .Values.cloudserverConfig.cloudDomain }}{{ include "cloudserver-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "cloudserver-frontend.cloudOrigin" . }} {{ include "cloudserver-frontend.wildcardCloudOrigin" . }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "cloudserver-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "cloudserver-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.cloudserverConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "cloudserver-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.cloudserverConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "cloudserver-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "cloudserver-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "cloudserver-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,52 @@
|
||||
# Default values for cloudserver-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-cloudserver-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "cloudserver-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
cloudserverConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
lafBaseUrl: ""
|
||||
jwtSecretApp: ""
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
affinity: {}
|
||||
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"cloudserver-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"cloudserver-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/cloudserver-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string cloudserverConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string cloudserverConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string cloudserverConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string cloudserverConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string cloudserverConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
SEALOS_JWT_INTERNAL=${SEALOS_JWT_INTERNAL:-"${jwtInternal:-$(get_cm_value sealos-system sealos-config jwtInternal)}"}
|
||||
add_set_string cloudserverConfig.jwtSecretApp "${SEALOS_JWT_INTERNAL}"
|
||||
add_set_string cloudserverConfig.lafBaseUrl "${lafBaseUrl:-}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap cloudserver-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service cloudserver-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment cloudserver-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress cloudserver-frontend
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io cloudserver
|
||||
|
||||
|
||||
SERVICE_NAME="cloudserver-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/cloudserver-frontend/cloudserver-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/cloudserver-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -1,83 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app: cloudserver-frontend
|
||||
name: cloudserver-frontend
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cloudserver-frontend-config
|
||||
namespace: cloudserver-frontend
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cloudserver-frontend
|
||||
namespace: cloudserver-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cloudserver-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cloudserver-frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: cloudserver-frontend
|
||||
env:
|
||||
- name: LAF_BASE_URL
|
||||
value: {{ .lafBaseUrl }}
|
||||
- name: JWT_SECRET_APP
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- 'ALL'
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
# do not modify this image, it is used for CI/CD
|
||||
image: ghcr.io/labring/sealos-cloudserver-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: cloudserver-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
volumes:
|
||||
- name: cloudserver-frontend-volume
|
||||
configMap:
|
||||
name: cloudserver-frontend-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: cloudserver-frontend
|
||||
name: cloudserver-frontend
|
||||
namespace: cloudserver-frontend
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: cloudserver-frontend
|
||||
@@ -1,51 +0,0 @@
|
||||
# Copyright © 2023 sealos.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}, https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
name: cloudserver-frontend
|
||||
namespace: cloudserver-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: cloudserver.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: cloudserver-frontend
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- cloudserver.{{ .cloudDomain }}
|
||||
secretName: {{ .certSecretName }}
|
||||
@@ -4,5 +4,6 @@ USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY charts charts
|
||||
COPY costcenter-frontend-entrypoint.sh costcenter-frontend-entrypoint.sh
|
||||
|
||||
CMD ["./costcenter-frontend-entrypoint.sh"]
|
||||
CMD ["bash costcenter-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -9,6 +9,8 @@ fullnameOverride: "costcenter-frontend"
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
@@ -23,11 +25,46 @@ service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
# Costcenter frontend configuration
|
||||
# Note: jwtInternal is auto-configured by entrypoint.sh from sealos-config ConfigMap
|
||||
# For business configurations (transfer, invoice, recharge, etc.), see costcenter-frontend-values.yaml
|
||||
costcenterConfig:
|
||||
jwtInternal: "" # Auto-injected by entrypoint script
|
||||
transferEnabled: true
|
||||
currencyType: "shellCoin"
|
||||
invoice:
|
||||
enabled: false
|
||||
feiShuBotURL: ""
|
||||
aliSms:
|
||||
endpoint: ""
|
||||
accessKeyID: ""
|
||||
accessKeySecret: ""
|
||||
templateCode: ""
|
||||
signName: ""
|
||||
invoiceCompletedTemplateCode: ""
|
||||
mongo:
|
||||
uri: ""
|
||||
recharge:
|
||||
enabled: false
|
||||
payMethods:
|
||||
wechat:
|
||||
enabled: false
|
||||
alipay:
|
||||
enabled: false
|
||||
stripe:
|
||||
enabled: false
|
||||
publicKey: ""
|
||||
components:
|
||||
accountService:
|
||||
url: "http://account-service.account-system.svc:2333"
|
||||
|
||||
# Affinity for pod anti-affinity
|
||||
affinity:
|
||||
|
||||
@@ -3,13 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY cronjob-frontend-entrypoint.sh cronjob-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
|
||||
ENV SUCCESSFUL_JOBS_HISTORY_LIMIT="3"
|
||||
ENV FAILED_JOBS_HISTORY_LIMIT="3"
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash cronjob-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: cronjob-frontend
|
||||
description: Sealos CronJob Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Custom values for cronjob-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
cronjobConfig:
|
||||
successfulJobsHistoryLimit: 3
|
||||
failedJobsHistoryLimit: 3
|
||||
podCpuMilliCores: 50
|
||||
podMemoryMiB: 64
|
||||
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "cronjob-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "cronjob-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "cronjob-frontend.chart" . }}
|
||||
{{ include "cronjob-frontend.selectorLabels" . }}
|
||||
{{ include "cronjob-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.selectorLabels" -}}
|
||||
app: {{ include "cronjob-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "cronjob-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.cronjobConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.port" -}}
|
||||
{{- $scheme := include "cronjob-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.cronjobConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.cronjobConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.portSuffix" -}}
|
||||
{{- $port := include "cronjob-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.portEnv" -}}
|
||||
{{- $port := include "cronjob-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.cloudOrigin" -}}
|
||||
{{- include "cronjob-frontend.scheme" . -}}://{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "cronjob-frontend.scheme" . -}}://*.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.host" -}}
|
||||
{{- default (printf "cronjob.%s" .Values.cronjobConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "cronjob-frontend.appUrl" -}}
|
||||
{{- include "cronjob-frontend.scheme" . -}}://{{ include "cronjob-frontend.host" . }}{{ include "cronjob-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+6
-6
@@ -6,14 +6,14 @@ metadata:
|
||||
spec:
|
||||
data:
|
||||
desc: CronJob
|
||||
url: "https://cronjob.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
icon: "https://cronjob.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}/logo.svg"
|
||||
menuData:
|
||||
name: CronJob
|
||||
type: iframe
|
||||
displayType: normal
|
||||
url: {{ include "cronjob-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "cronjob-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: 定时任务
|
||||
zh-Hans:
|
||||
name: 定时任务
|
||||
menuData:
|
||||
name: CronJob
|
||||
type: iframe
|
||||
displayType: normal
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "cronjob-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "cronjob-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
cloud:
|
||||
domain: {{ .Values.cronjobConfig.cloudDomain | quote }}
|
||||
desktopDomain: {{ .Values.cronjobConfig.cloudDomain | quote }}
|
||||
cronjob:
|
||||
components:
|
||||
applaunchpad:
|
||||
url: {{ printf "https://applaunchpad.%s%s" .Values.cronjobConfig.cloudDomain (include "cronjob-frontend.portSuffix" .) | quote }}
|
||||
podResources:
|
||||
cpuMilliCores: {{ .Values.cronjobConfig.podCpuMilliCores }}
|
||||
memoryMiB: {{ .Values.cronjobConfig.podMemoryMiB }}
|
||||
jobHistory:
|
||||
successfulLimit: {{ .Values.cronjobConfig.successfulJobsHistoryLimit }}
|
||||
failedLimit: {{ .Values.cronjobConfig.failedJobsHistoryLimit }}
|
||||
@@ -0,0 +1,67 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "cronjob-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "cronjob-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "cronjob-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "cronjob-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .Values.cronjobConfig.cloudDomain | quote }}
|
||||
- name: APPLAUNCHPAD_URL
|
||||
value: {{ printf "applaunchpad.%s" .Values.cronjobConfig.cloudDomain | quote }}
|
||||
- name: SUCCESSFUL_JOBS_HISTORY_LIMIT
|
||||
value: {{ .Values.cronjobConfig.successfulJobsHistoryLimit | quote }}
|
||||
- name: FAILED_JOBS_HISTORY_LIMIT
|
||||
value: {{ .Values.cronjobConfig.failedJobsHistoryLimit | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: cronjob-frontend-volume
|
||||
mountPath: /app/data/config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: cronjob-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "cronjob-frontend.fullname" . }}-config
|
||||
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "cronjob-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ include "cronjob-frontend.cloudOrigin" . }}, {{ include "cronjob-frontend.wildcardCloudOrigin" . }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "cronjob-frontend.cloudOrigin" . }} {{ include "cronjob-frontend.wildcardCloudOrigin" . }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} {{ .Values.cronjobConfig.cloudDomain }}{{ include "cronjob-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "cronjob-frontend.cloudOrigin" . }} {{ include "cronjob-frontend.wildcardCloudOrigin" . }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "cronjob-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "cronjob-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.cronjobConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "cronjob-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.cronjobConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "cronjob-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "cronjob-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "cronjob-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,65 @@
|
||||
# Default values for cronjob-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-cronjob-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "cronjob-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
cronjobConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
successfulJobsHistoryLimit: 3
|
||||
failedJobsHistoryLimit: 3
|
||||
podCpuMilliCores: 50
|
||||
podMemoryMiB: 64
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- cronjob-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"cronjob-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"cronjob-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/cronjob-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string cronjobConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string cronjobConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string cronjobConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string cronjobConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string cronjobConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
add_set_string cronjobConfig.successfulJobsHistoryLimit "${successfulJobsHistoryLimit:-}"
|
||||
add_set_string cronjobConfig.failedJobsHistoryLimit "${failedJobsHistoryLimit:-}"
|
||||
add_set_string cronjobConfig.podCpuMilliCores "${podCpuMilliCores:-}"
|
||||
add_set_string cronjobConfig.podMemoryMiB "${podMemoryMiB:-}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap cronjob-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service cronjob-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment cronjob-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress cronjob-frontend
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io cronjob
|
||||
|
||||
|
||||
SERVICE_NAME="cronjob-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/cronjob-frontend/cronjob-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/cronjob-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -1,100 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app: cronjob-frontend
|
||||
name: cronjob-frontend
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: cronjob-frontend-config
|
||||
namespace: cronjob-frontend
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cronjob-frontend
|
||||
namespace: cronjob-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cronjob-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cronjob-frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: cronjob-frontend
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: APPLAUNCHPAD_URL
|
||||
value: applaunchpad.{{ .cloudDomain }}
|
||||
- name: SUCCESSFUL_JOBS_HISTORY_LIMIT
|
||||
value: "{{ .SUCCESSFUL_JOBS_HISTORY_LIMIT }}"
|
||||
- name: FAILED_JOBS_HISTORY_LIMIT
|
||||
value: "{{ .FAILED_JOBS_HISTORY_LIMIT }}"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- 'ALL'
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
# do not modify this image, it is used for CI/CD
|
||||
image: ghcr.io/labring/sealos-cronjob-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: cronjob-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- cronjob-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
volumes:
|
||||
- name: cronjob-frontend-volume
|
||||
configMap:
|
||||
name: cronjob-frontend-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: cronjob-frontend
|
||||
name: cronjob-frontend
|
||||
namespace: cronjob-frontend
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: cronjob-frontend
|
||||
@@ -1,51 +0,0 @@
|
||||
# Copyright © 2023 sealos.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}, https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
name: cronjob-frontend
|
||||
namespace: cronjob-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: cronjob.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: cronjob-frontend
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- cronjob.{{ .cloudDomain }}
|
||||
secretName: {{ .certSecretName }}
|
||||
@@ -3,20 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY dbprovider-frontend-entrypoint.sh dbprovider-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
ENV monitorUrl="http://database-monitor.sealos.svc.cluster.local:9090"
|
||||
ENV minioUrl=""
|
||||
ENV minioAccessKey=""
|
||||
ENV minioSecretKey=""
|
||||
ENV minioPort=""
|
||||
ENV migrateFileImage=""
|
||||
ENV minioBucketName=""
|
||||
ENV guideEnabled="true"
|
||||
ENV billingUrl="http://account-service.account-system.svc:2333"
|
||||
ENV vlogsBaseUrl="http://service-vlogs.sealos.svc.cluster.local:8428"
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash dbprovider-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: dbprovider-frontend
|
||||
description: Sealos Database Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
# Custom values for dbprovider-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
dbproviderConfig:
|
||||
monitorUrl: "http://database-monitor.sealos.svc.cluster.local:9090"
|
||||
minioUrl: ""
|
||||
minioAccessKey: ""
|
||||
minioSecretKey: ""
|
||||
minioPort: 9000
|
||||
minioUseSSL: false
|
||||
minioBucketName: "file-migration"
|
||||
migrateFileFetchFileImage: "quay.io/minio/mc:latest"
|
||||
migrateFileImportDataImage: "sealos.hub:5000/db-import-client:latest"
|
||||
guideEnabled: true
|
||||
billingUrl: "http://account-service.account-system.svc:2333"
|
||||
billingSecret: ""
|
||||
alertingUrl: "http://database-alert-service.sealos.svc.cluster.local:8000"
|
||||
alertingSecret: ""
|
||||
vlogsBaseUrl: "http://service-vlogs.sealos.svc.cluster.local:8428"
|
||||
migrationJobCPURequirement: 2000
|
||||
migrationJobMemoryRequirement: 4096
|
||||
dumpImportJobCPURequirement: 2000
|
||||
dumpImportJobMemoryRequirement: 4096
|
||||
backupJobCPURequirement: 300
|
||||
backupJobMemoryRequirement: 256
|
||||
backupEnabled: false
|
||||
showDocument: true
|
||||
managedDbEnabled: false
|
||||
fileImportEnabled: false
|
||||
currencySymbol: "shellCoin"
|
||||
forcedStorageClassName: ""
|
||||
storageMaxSize: 300
|
||||
customScripts: []
|
||||
eventAnalysisEnabled: false
|
||||
eventAnalysisUrl: "https://fastgpt.run/api/openapi"
|
||||
eventAnalysisModelId: "6455c433f437e55c638e630c"
|
||||
eventAnalysisFastGPTKey: ""
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "dbprovider-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "dbprovider-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "dbprovider-frontend.chart" . }}
|
||||
{{ include "dbprovider-frontend.selectorLabels" . }}
|
||||
{{ include "dbprovider-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.selectorLabels" -}}
|
||||
app: {{ include "dbprovider-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "dbprovider-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.dbproviderConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.port" -}}
|
||||
{{- $scheme := include "dbprovider-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.dbproviderConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.dbproviderConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.portSuffix" -}}
|
||||
{{- $port := include "dbprovider-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.portEnv" -}}
|
||||
{{- $port := include "dbprovider-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.cloudOrigin" -}}
|
||||
{{- include "dbprovider-frontend.scheme" . -}}://{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "dbprovider-frontend.scheme" . -}}://*.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.host" -}}
|
||||
{{- default (printf "dbprovider.%s" .Values.dbproviderConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "dbprovider-frontend.appUrl" -}}
|
||||
{{- include "dbprovider-frontend.scheme" . -}}://{{ include "dbprovider-frontend.host" . }}{{ include "dbprovider-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+2
-2
@@ -6,8 +6,8 @@ metadata:
|
||||
spec:
|
||||
data:
|
||||
desc: Database
|
||||
url: "https://dbprovider.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
icon: "https://dbprovider.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}/logo.svg"
|
||||
url: {{ include "dbprovider-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "dbprovider-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: 数据库
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "dbprovider-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dbprovider-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
cloud:
|
||||
domain: {{ .Values.dbproviderConfig.cloudDomain | quote }}
|
||||
desktopDomain: {{ .Values.dbproviderConfig.cloudDomain | quote }}
|
||||
dbprovider:
|
||||
features:
|
||||
guide: {{ .Values.dbproviderConfig.guideEnabled }}
|
||||
showDocument: {{ .Values.dbproviderConfig.showDocument }}
|
||||
fileImport: {{ .Values.dbproviderConfig.fileImportEnabled }}
|
||||
ui:
|
||||
currencySymbol: {{ .Values.dbproviderConfig.currencySymbol | quote }}
|
||||
customScripts:
|
||||
{{- toYaml .Values.dbproviderConfig.customScripts | nindent 10 }}
|
||||
storage:
|
||||
forcedClassName: {{ if .Values.dbproviderConfig.forcedStorageClassName }}{{ .Values.dbproviderConfig.forcedStorageClassName | quote }}{{ else }}null{{ end }}
|
||||
maxSize: {{ .Values.dbproviderConfig.storageMaxSize }}
|
||||
components:
|
||||
monitoring:
|
||||
url: {{ .Values.dbproviderConfig.monitorUrl | quote }}
|
||||
alerting:
|
||||
url: {{ .Values.dbproviderConfig.alertingUrl | quote }}
|
||||
secret: {{ .Values.dbproviderConfig.alertingSecret | quote }}
|
||||
billing:
|
||||
url: {{ .Values.dbproviderConfig.billingUrl | quote }}
|
||||
secret: {{ .Values.dbproviderConfig.billingSecret | quote }}
|
||||
logging:
|
||||
url: {{ .Values.dbproviderConfig.vlogsBaseUrl | quote }}
|
||||
storage:
|
||||
url: {{ .Values.dbproviderConfig.minioUrl | quote }}
|
||||
port: {{ .Values.dbproviderConfig.minioPort }}
|
||||
useSSL: {{ .Values.dbproviderConfig.minioUseSSL }}
|
||||
bucketName: {{ .Values.dbproviderConfig.minioBucketName | quote }}
|
||||
accessKey: {{ .Values.dbproviderConfig.minioAccessKey | quote }}
|
||||
secretKey: {{ .Values.dbproviderConfig.minioSecretKey | quote }}
|
||||
eventAnalysis:
|
||||
enabled: {{ .Values.dbproviderConfig.eventAnalysisEnabled }}
|
||||
url: {{ .Values.dbproviderConfig.eventAnalysisUrl | quote }}
|
||||
modelId: {{ .Values.dbproviderConfig.eventAnalysisModelId | quote }}
|
||||
fastGPTKey: {{ .Values.dbproviderConfig.eventAnalysisFastGPTKey | quote }}
|
||||
migration:
|
||||
fetchFileImage: {{ .Values.dbproviderConfig.migrateFileFetchFileImage | quote }}
|
||||
importDataImage: {{ .Values.dbproviderConfig.migrateFileImportDataImage | quote }}
|
||||
jobCpuMillicores: {{ .Values.dbproviderConfig.migrationJobCPURequirement }}
|
||||
jobMemoryMiB: {{ .Values.dbproviderConfig.migrationJobMemoryRequirement }}
|
||||
dumpImportCpuMillicores: {{ .Values.dbproviderConfig.dumpImportJobCPURequirement }}
|
||||
dumpImportMemoryMiB: {{ .Values.dbproviderConfig.dumpImportJobMemoryRequirement }}
|
||||
backup:
|
||||
enabled: {{ .Values.dbproviderConfig.backupEnabled }}
|
||||
jobCpuMillicores: {{ .Values.dbproviderConfig.backupJobCPURequirement }}
|
||||
jobMemoryMiB: {{ .Values.dbproviderConfig.backupJobMemoryRequirement }}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "dbprovider-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dbprovider-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "dbprovider-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "dbprovider-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
serviceAccountName: cluster-version-reader
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .Values.dbproviderConfig.cloudDomain | quote }}
|
||||
- name: DESKTOP_DOMAIN
|
||||
value: {{ .Values.dbproviderConfig.cloudDomain | quote }}
|
||||
- name: SEALOS_PORT
|
||||
value: {{ include "dbprovider-frontend.portEnv" . | quote }}
|
||||
- name: MONITOR_URL
|
||||
value: {{ .Values.dbproviderConfig.monitorUrl | quote }}
|
||||
- name: MINIO_URL
|
||||
value: {{ .Values.dbproviderConfig.minioUrl | quote }}
|
||||
- name: MINIO_ACCESS_KEY
|
||||
value: {{ .Values.dbproviderConfig.minioAccessKey | quote }}
|
||||
- name: MINIO_SECRET_KEY
|
||||
value: {{ .Values.dbproviderConfig.minioSecretKey | quote }}
|
||||
- name: MIGRATE_FILE_FETCH_FILE_IMAGE
|
||||
value: {{ .Values.dbproviderConfig.migrateFileFetchFileImage | quote }}
|
||||
- name: MIGRATE_FILE_IMPORT_DATA_IMAGE
|
||||
value: {{ .Values.dbproviderConfig.migrateFileImportDataImage | quote }}
|
||||
- name: MINIO_PORT
|
||||
value: {{ .Values.dbproviderConfig.minioPort | quote }}
|
||||
- name: MINIO_BUCKET_NAME
|
||||
value: {{ .Values.dbproviderConfig.minioBucketName | quote }}
|
||||
- name: BACKUP_ENABLED
|
||||
value: {{ .Values.dbproviderConfig.backupEnabled | quote }}
|
||||
- name: SHOW_DOCUMENT
|
||||
value: {{ .Values.dbproviderConfig.showDocument | quote }}
|
||||
- name: GUIDE_ENABLED
|
||||
value: {{ .Values.dbproviderConfig.guideEnabled | quote }}
|
||||
- name: BILLING_URL
|
||||
value: {{ .Values.dbproviderConfig.billingUrl | quote }}
|
||||
- name: MANAGED_DB_ENABLED
|
||||
value: {{ .Values.dbproviderConfig.managedDbEnabled | quote }}
|
||||
- name: VLOGS_BASE_URL
|
||||
value: {{ .Values.dbproviderConfig.vlogsBaseUrl | quote }}
|
||||
- name: MIGRATION_JOB_CPU_REQUIREMENT
|
||||
value: {{ .Values.dbproviderConfig.migrationJobCPURequirement | quote }}
|
||||
- name: MIGRATION_JOB_MEMORY_REQUIREMENT
|
||||
value: {{ .Values.dbproviderConfig.migrationJobMemoryRequirement | quote }}
|
||||
- name: DUMPIMPORT_JOB_CPU_REQUIREMENT
|
||||
value: {{ .Values.dbproviderConfig.dumpImportJobCPURequirement | quote }}
|
||||
- name: DUMPIMPORT_JOB_MEMORY_REQUIREMENT
|
||||
value: {{ .Values.dbproviderConfig.dumpImportJobMemoryRequirement | quote }}
|
||||
- name: BACKUP_JOB_CPU_REQUIREMENT
|
||||
value: {{ .Values.dbproviderConfig.backupJobCPURequirement | quote }}
|
||||
- name: BACKUP_JOB_MEMORY_REQUIREMENT
|
||||
value: {{ .Values.dbproviderConfig.backupJobMemoryRequirement | quote }}
|
||||
- name: CURRENCY_SYMBOL
|
||||
value: {{ .Values.dbproviderConfig.currencySymbol | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: dbprovider-frontend-volume
|
||||
mountPath: /app/data/config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: dbprovider-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "dbprovider-frontend.fullname" . }}-config
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "dbprovider-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ include "dbprovider-frontend.cloudOrigin" . }}, {{ include "dbprovider-frontend.wildcardCloudOrigin" . }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "dbprovider-frontend.cloudOrigin" . }} {{ include "dbprovider-frontend.wildcardCloudOrigin" . }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} {{ .Values.dbproviderConfig.cloudDomain }}{{ include "dbprovider-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "dbprovider-frontend.cloudOrigin" . }} {{ include "dbprovider-frontend.wildcardCloudOrigin" . }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "dbprovider-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "dbprovider-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.dbproviderConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "dbprovider-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.dbproviderConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,42 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: cluster-version-reader
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "dbprovider-frontend.labels" . | nindent 4 }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cluster-version-reader
|
||||
rules:
|
||||
- apiGroups: ["extensions.kubeblocks.io"]
|
||||
resources: ["addons"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: ["apps.kubeblocks.io"]
|
||||
resources: ["clusterversions"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: ["dataprotection.kubeblocks.io"]
|
||||
resources: ["backuprepos"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: ["apps.kubeblocks.io"]
|
||||
resources: ["componentversions"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: ["app.sealos.io"]
|
||||
resources: ["apps"]
|
||||
resourceNames: ["dataflow"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cluster-version-reader-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-version-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cluster-version-reader
|
||||
namespace: {{ .Release.Namespace }}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "dbprovider-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "dbprovider-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "dbprovider-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,94 @@
|
||||
# Default values for dbprovider-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-dbprovider-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "dbprovider-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
dbproviderConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
monitorUrl: "http://database-monitor.sealos.svc.cluster.local:9090"
|
||||
minioUrl: ""
|
||||
minioAccessKey: ""
|
||||
minioSecretKey: ""
|
||||
minioPort: 9000
|
||||
minioUseSSL: false
|
||||
minioBucketName: "file-migration"
|
||||
migrateFileFetchFileImage: "quay.io/minio/mc:latest"
|
||||
migrateFileImportDataImage: "sealos.hub:5000/db-import-client:latest"
|
||||
guideEnabled: true
|
||||
billingUrl: "http://account-service.account-system.svc:2333"
|
||||
billingSecret: ""
|
||||
alertingUrl: "http://database-alert-service.sealos.svc.cluster.local:8000"
|
||||
alertingSecret: ""
|
||||
vlogsBaseUrl: "http://service-vlogs.sealos.svc.cluster.local:8428"
|
||||
migrationJobCPURequirement: 2000
|
||||
migrationJobMemoryRequirement: 4096
|
||||
dumpImportJobCPURequirement: 2000
|
||||
dumpImportJobMemoryRequirement: 4096
|
||||
backupJobCPURequirement: 300
|
||||
backupJobMemoryRequirement: 256
|
||||
backupEnabled: false
|
||||
showDocument: true
|
||||
managedDbEnabled: false
|
||||
fileImportEnabled: false
|
||||
currencySymbol: "shellCoin"
|
||||
forcedStorageClassName: ""
|
||||
storageMaxSize: 300
|
||||
customScripts: []
|
||||
eventAnalysisEnabled: false
|
||||
eventAnalysisUrl: "https://fastgpt.run/api/openapi"
|
||||
eventAnalysisModelId: "6455c433f437e55c638e630c"
|
||||
eventAnalysisFastGPTKey: ""
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- dbprovider-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"dbprovider-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"dbprovider-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/dbprovider-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string dbproviderConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string dbproviderConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string dbproviderConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string dbproviderConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string dbproviderConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
add_set_string dbproviderConfig.monitorUrl "${monitorUrl:-}"
|
||||
add_set_string dbproviderConfig.minioUrl "${minioUrl:-}"
|
||||
add_set_string dbproviderConfig.minioAccessKey "${minioAccessKey:-}"
|
||||
add_set_string dbproviderConfig.minioSecretKey "${minioSecretKey:-}"
|
||||
add_set_string dbproviderConfig.minioPort "${minioPort:-}"
|
||||
add_set_string dbproviderConfig.minioUseSSL "${minioUseSSL:-}"
|
||||
add_set_string dbproviderConfig.minioBucketName "${minioBucketName:-}"
|
||||
add_set_string dbproviderConfig.migrateFileFetchFileImage "${migrateFileFetchFileImage:-}"
|
||||
add_set_string dbproviderConfig.migrateFileImportDataImage "${migrateFileImportDataImage:-}"
|
||||
add_set_string dbproviderConfig.guideEnabled "${guideEnabled:-}"
|
||||
add_set_string dbproviderConfig.billingUrl "${billingUrl:-}"
|
||||
add_set_string dbproviderConfig.billingSecret "${billingSecret:-}"
|
||||
add_set_string dbproviderConfig.alertingUrl "${alertingUrl:-}"
|
||||
add_set_string dbproviderConfig.alertingSecret "${alertingSecret:-}"
|
||||
add_set_string dbproviderConfig.vlogsBaseUrl "${vlogsBaseUrl:-}"
|
||||
add_set_string dbproviderConfig.migrationJobCPURequirement "${migrationJobCPURequirement:-}"
|
||||
add_set_string dbproviderConfig.migrationJobMemoryRequirement "${migrationJobMemoryRequirement:-}"
|
||||
add_set_string dbproviderConfig.dumpImportJobCPURequirement "${dumpImportJobCPURequirement:-}"
|
||||
add_set_string dbproviderConfig.dumpImportJobMemoryRequirement "${dumpImportJobMemoryRequirement:-}"
|
||||
add_set_string dbproviderConfig.backupJobCPURequirement "${backupJobCPURequirement:-}"
|
||||
add_set_string dbproviderConfig.backupJobMemoryRequirement "${backupJobMemoryRequirement:-}"
|
||||
add_set_string dbproviderConfig.backupEnabled "${backupEnabled:-}"
|
||||
add_set_string dbproviderConfig.showDocument "${showDocument:-}"
|
||||
add_set_string dbproviderConfig.managedDbEnabled "${managedDbEnabled:-}"
|
||||
add_set_string dbproviderConfig.fileImportEnabled "${fileImportEnabled:-}"
|
||||
add_set_string dbproviderConfig.currencySymbol "${currencySymbol:-}"
|
||||
add_set_string dbproviderConfig.forcedStorageClassName "${forcedStorageClassName:-}"
|
||||
add_set_string dbproviderConfig.storageMaxSize "${storageMaxSize:-}"
|
||||
add_set_string dbproviderConfig.customScripts "${customScripts:-}"
|
||||
add_set_string dbproviderConfig.eventAnalysisEnabled "${eventAnalysisEnabled:-}"
|
||||
add_set_string dbproviderConfig.eventAnalysisUrl "${eventAnalysisUrl:-}"
|
||||
add_set_string dbproviderConfig.eventAnalysisModelId "${eventAnalysisModelId:-}"
|
||||
add_set_string dbproviderConfig.eventAnalysisFastGPTKey "${eventAnalysisFastGPTKey:-}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" serviceaccount cluster-version-reader
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap dbprovider-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service dbprovider-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment dbprovider-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress dbprovider-frontend
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io dbprovider
|
||||
adopt_cluster_resource clusterrole cluster-version-reader
|
||||
adopt_cluster_resource clusterrolebinding cluster-version-reader-rolebinding
|
||||
|
||||
SERVICE_NAME="dbprovider-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/dbprovider-frontend/dbprovider-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/dbprovider-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -1,139 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app: dbprovider-frontend
|
||||
name: dbprovider-frontend
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: dbprovider-frontend-config
|
||||
namespace: dbprovider-frontend
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: dbprovider-frontend
|
||||
namespace: dbprovider-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: dbprovider-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: dbprovider-frontend
|
||||
spec:
|
||||
serviceAccountName: cluster-version-reader
|
||||
containers:
|
||||
- name: dbprovider-frontend
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: DESKTOP_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: SEALOS_PORT
|
||||
value: "{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
- name: MONITOR_URL
|
||||
value: {{ .monitorUrl }}
|
||||
- name: MINIO_URL
|
||||
value: {{ .minioUrl }}
|
||||
- name: MINIO_ACCESS_KEY
|
||||
value: {{ .minioAccessKey }}
|
||||
- name: MINIO_SECRET_KEY
|
||||
value: {{ .minioSecretKey }}
|
||||
- name: MIGRATE_FILE_FETCH_FILE_IMAGE
|
||||
value: {{ .migrateFileFetchFileImage }}
|
||||
- name: MIGRATE_FILE_IMPORT_DATA_IMAGE
|
||||
value: {{ .migrateFileImportDataImage }}
|
||||
- name: MINIO_PORT
|
||||
value: '{{ .minioPort }}'
|
||||
- name: MINIO_BUCKET_NAME
|
||||
value: {{ .minioBucketName }}
|
||||
- name: BACKUP_ENABLED
|
||||
value: "false"
|
||||
- name: SHOW_DOCUMENT
|
||||
value: "true"
|
||||
- name: GUIDE_ENABLED
|
||||
value: "{{ .guideEnabled }}"
|
||||
- name: BILLING_URL
|
||||
value: {{ .billingUrl }}
|
||||
- name: MANAGED_DB_ENABLED
|
||||
value: "false"
|
||||
- name: VLOGS_BASE_URL
|
||||
value: {{ .vlogsBaseUrl }}
|
||||
- name: MIGRATION_JOB_CPU_REQUIREMENT
|
||||
value: {{ .migrationJobCPURequirement }}
|
||||
- name: MIGRATION_JOB_MEMORY_REQUIREMENT
|
||||
value: {{ .migrationJobMemoryRequirement }}
|
||||
- name: DUMPIMPORT_JOB_CPU_REQUIREMENT
|
||||
value: {{ .dumpImportJobCPURequirement }}
|
||||
- name: DUMPIMPORT_JOB_MEMORY_REQUIREMENT
|
||||
value: {{ .dumpImportJobMemoryRequirement }}
|
||||
- name: BACKUP_JOB_CPU_REQUIREMENT
|
||||
value: {{ .backupJobCPURequirement }}
|
||||
- name: BACKUP_JOB_MEMORY_REQUIREMENT
|
||||
value: {{ .backupJobMemoryRequirement }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- 'ALL'
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
# do not modify this image, it is used for CI/CD
|
||||
image: ghcr.io/labring/sealos-dbprovider-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: dbprovider-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- dbprovider-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
volumes:
|
||||
- name: dbprovider-frontend-volume
|
||||
configMap:
|
||||
name: dbprovider-frontend-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: dbprovider-frontend
|
||||
name: dbprovider-frontend
|
||||
namespace: dbprovider-frontend
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: dbprovider-frontend
|
||||
@@ -1,31 +0,0 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com; frame-src 'self' {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com; frame-src 'self' {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
name: dbprovider-frontend
|
||||
namespace: dbprovider-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: dbprovider.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: dbprovider-frontend
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- dbprovider.{{ .cloudDomain }}
|
||||
secretName: {{ .certSecretName }}
|
||||
@@ -1,40 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: cluster-version-reader
|
||||
namespace: dbprovider-frontend
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cluster-version-reader
|
||||
rules:
|
||||
- apiGroups: [ 'extensions.kubeblocks.io' ]
|
||||
resources: [ 'addons' ]
|
||||
verbs: [ 'get', 'watch', 'list' ]
|
||||
- apiGroups: ['apps.kubeblocks.io']
|
||||
resources: ['clusterversions']
|
||||
verbs: ['get', 'watch', 'list']
|
||||
- apiGroups: ['dataprotection.kubeblocks.io']
|
||||
resources: ['backuprepos']
|
||||
verbs: ['get', 'watch', 'list']
|
||||
- apiGroups: ['apps.kubeblocks.io']
|
||||
resources: ['componentversions']
|
||||
verbs: ['get', 'watch', 'list']
|
||||
- apiGroups: ['app.sealos.io']
|
||||
resources: ['apps']
|
||||
resourceNames: ['dataflow']
|
||||
verbs: ['get']
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cluster-version-reader-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-version-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cluster-version-reader
|
||||
namespace: dbprovider-frontend
|
||||
@@ -3,11 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY devbox-frontend-entrypoint.sh devbox-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
ENV registryAddr="sealos.hub:5000"
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash devbox-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: devbox-frontend
|
||||
description: Sealos DevBox Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
@@ -0,0 +1,41 @@
|
||||
# Custom values for devbox-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
devboxConfig:
|
||||
databaseUrl: ""
|
||||
databaseProvider: "cockroachdb"
|
||||
tlsRejectUnauthorized: "1"
|
||||
sshDomain: ""
|
||||
registryAddr: "sealos.hub:5000"
|
||||
monitorUrl: "http://launchpad-monitor.sealos.svc.cluster.local:8428"
|
||||
accountUrl: "http://account-service.account-system.svc.cluster.local:2333"
|
||||
rootRuntimeNamespace: "devbox-system"
|
||||
currencySymbol: "usd"
|
||||
gpuEnable: false
|
||||
storageLimit: "10Gi"
|
||||
runtimeClassName: "devbox-runtime"
|
||||
retagSvcUrl: "http://devbox-service.devbox-system.svc.cluster.local:8092"
|
||||
jwtSecret: ""
|
||||
regionUid: ""
|
||||
enableImportFeature: false
|
||||
enableWebideFeature: false
|
||||
enableAdvancedConfig: false
|
||||
cpuSlideMarkList: "1,2,4,8,16"
|
||||
memorySlideMarkList: "2,4,8,16,32"
|
||||
devboxDomainChallengeSecret: "default-dev-secret-change-in-production"
|
||||
nfsStorageClassName: "nfs-csi"
|
||||
customScripts: "[]"
|
||||
documentUrlZh: "https://sealos.run/docs/overview/intro"
|
||||
documentUrlEn: "https://sealos.io/docs/overview/intro"
|
||||
privacyUrlZh: "https://sealos.run/docs/msa/privacy-policy"
|
||||
privacyUrlEn: "https://sealos.io/docs/msa/privacy-policy"
|
||||
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "devbox-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "devbox-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "devbox-frontend.chart" . }}
|
||||
{{ include "devbox-frontend.selectorLabels" . }}
|
||||
{{ include "devbox-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.selectorLabels" -}}
|
||||
app: {{ include "devbox-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "devbox-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.devboxConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.port" -}}
|
||||
{{- $scheme := include "devbox-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.devboxConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.devboxConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.portSuffix" -}}
|
||||
{{- $port := include "devbox-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.portEnv" -}}
|
||||
{{- $port := include "devbox-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.cloudOrigin" -}}
|
||||
{{- include "devbox-frontend.scheme" . -}}://{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "devbox-frontend.scheme" . -}}://*.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.host" -}}
|
||||
{{- default (printf "devbox.%s" .Values.devboxConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "devbox-frontend.appUrl" -}}
|
||||
{{- include "devbox-frontend.scheme" . -}}://{{ include "devbox-frontend.host" . }}{{ include "devbox-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+3
-2
@@ -6,13 +6,14 @@ metadata:
|
||||
spec:
|
||||
data:
|
||||
desc: DevBox
|
||||
url: 'https://devbox.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}'
|
||||
icon: 'https://devbox.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}/logo.svg'
|
||||
url: {{ include "devbox-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "devbox-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: DevBox
|
||||
zh-Hans:
|
||||
name: DevBox
|
||||
menuData:
|
||||
name: DevBox
|
||||
type: iframe
|
||||
displayType: normal
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
name: devbox-challenge
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
rules:
|
||||
- host: ""
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
service:
|
||||
name: {{ include "devbox-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
path: /api/.well-known/devbox-domain-challenge
|
||||
pathType: Prefix
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "devbox-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "devbox-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
@@ -0,0 +1,156 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "devbox-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "devbox-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "devbox-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "devbox-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
initContainers:
|
||||
- name: devbox-frontend-init
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
value: {{ .Values.devboxConfig.databaseUrl | quote }}
|
||||
- name: DATABASE_PROVIDER
|
||||
value: {{ .Values.devboxConfig.databaseProvider | quote }}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
args:
|
||||
- |-
|
||||
cd /app/providers/devbox
|
||||
DB_PROVIDER="${DATABASE_PROVIDER:-cockroachdb}"
|
||||
SCHEMA_PATH="./prisma/cockroach/schema.prisma"
|
||||
if [ "$DB_PROVIDER" = "postgresql" ] || [ "$DB_PROVIDER" = "postgres" ] || [ "$DB_PROVIDER" = "pg" ]; then
|
||||
SCHEMA_PATH="./prisma/postgresql/schema.prisma"
|
||||
HAS_UUID_FN=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_proc WHERE proname='gen_random_uuid' LIMIT 1;")
|
||||
if [ "$HAS_UUID_FN" != "1" ]; then
|
||||
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c 'CREATE OR REPLACE FUNCTION public.gen_random_uuid() RETURNS uuid LANGUAGE SQL VOLATILE AS $func$ SELECT md5(random()::text || clock_timestamp()::text || txid_current()::text)::uuid; $func$;'
|
||||
fi
|
||||
MIGRATION="20260125094114_add_template_repository_kind"
|
||||
HAS_MIGRATION=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM _prisma_migrations WHERE migration_name='${MIGRATION}' AND rolled_back_at IS NULL LIMIT 1;")
|
||||
if [ "$HAS_MIGRATION" = "1" ]; then
|
||||
prisma migrate deploy --schema "$SCHEMA_PATH"
|
||||
exit 0
|
||||
fi
|
||||
HAS_ENUM=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_enum e JOIN pg_type t ON t.oid = e.enumtypid WHERE t.typname IN ('TemplateRepositoryKind','template_repository_kind') AND e.enumlabel = 'SERVICE' LIMIT 1;")
|
||||
if [ "$HAS_ENUM" = "1" ]; then
|
||||
prisma migrate resolve --schema "$SCHEMA_PATH" --applied "$MIGRATION"
|
||||
fi
|
||||
fi
|
||||
prisma migrate deploy --schema "$SCHEMA_PATH"
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: NODE_TLS_REJECT_UNAUTHORIZED
|
||||
value: {{ .Values.devboxConfig.tlsRejectUnauthorized | quote }}
|
||||
- name: DOCUMENT_URL_ZH
|
||||
value: {{ .Values.devboxConfig.documentUrlZh | quote }}
|
||||
- name: DOCUMENT_URL_EN
|
||||
value: {{ .Values.devboxConfig.documentUrlEn | quote }}
|
||||
- name: PRIVACY_URL_ZH
|
||||
value: {{ .Values.devboxConfig.privacyUrlZh | quote }}
|
||||
- name: PRIVACY_URL_EN
|
||||
value: {{ .Values.devboxConfig.privacyUrlEn | quote }}
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .Values.devboxConfig.cloudDomain | quote }}
|
||||
- name: SSH_DOMAIN
|
||||
value: {{ .Values.devboxConfig.sshDomain | quote }}
|
||||
- name: INGRESS_SECRET
|
||||
value: {{ .Values.devboxConfig.certSecretName | quote }}
|
||||
- name: REGISTRY_ADDR
|
||||
value: {{ .Values.devboxConfig.registryAddr | quote }}
|
||||
- name: DEVBOX_AFFINITY_ENABLE
|
||||
value: {{ "true" | quote }}
|
||||
- name: MONITOR_URL
|
||||
value: {{ .Values.devboxConfig.monitorUrl | quote }}
|
||||
- name: ACCOUNT_URL
|
||||
value: {{ .Values.devboxConfig.accountUrl | quote }}
|
||||
- name: ROOT_RUNTIME_NAMESPACE
|
||||
value: {{ .Values.devboxConfig.rootRuntimeNamespace | quote }}
|
||||
- name: INGRESS_DOMAIN
|
||||
value: {{ .Values.devboxConfig.cloudDomain | quote }}
|
||||
- name: CURRENCY_SYMBOL
|
||||
value: {{ .Values.devboxConfig.currencySymbol | quote }}
|
||||
- name: GPU_ENABLE
|
||||
value: {{ .Values.devboxConfig.gpuEnable | quote }}
|
||||
- name: STORAGE_LIMIT
|
||||
value: {{ .Values.devboxConfig.storageLimit | quote }}
|
||||
- name: DEVBOX_RUNTIME_CLASS_NAME
|
||||
value: {{ .Values.devboxConfig.runtimeClassName | quote }}
|
||||
- name: RETAG_SVC_URL
|
||||
value: {{ .Values.devboxConfig.retagSvcUrl | quote }}
|
||||
- name: JWT_SECRET
|
||||
value: {{ .Values.devboxConfig.jwtSecret | quote }}
|
||||
- name: REGION_UID
|
||||
value: {{ .Values.devboxConfig.regionUid | quote }}
|
||||
- name: DATABASE_URL
|
||||
value: {{ .Values.devboxConfig.databaseUrl | quote }}
|
||||
- name: DATABASE_PROVIDER
|
||||
value: {{ .Values.devboxConfig.databaseProvider | quote }}
|
||||
- name: ENABLE_IMPORT_FEATURE
|
||||
value: {{ .Values.devboxConfig.enableImportFeature | quote }}
|
||||
- name: ENABLE_WEBIDE_FEATURE
|
||||
value: {{ .Values.devboxConfig.enableWebideFeature | quote }}
|
||||
- name: ENABLE_ADVANCED_CONFIG
|
||||
value: {{ .Values.devboxConfig.enableAdvancedConfig | quote }}
|
||||
- name: CPU_SLIDE_MARK_LIST
|
||||
value: {{ .Values.devboxConfig.cpuSlideMarkList | quote }}
|
||||
- name: MEMORY_SLIDE_MARK_LIST
|
||||
value: {{ .Values.devboxConfig.memorySlideMarkList | quote }}
|
||||
- name: DEVBOX_DOMAIN_CHALLENGE_SECRET
|
||||
value: {{ .Values.devboxConfig.devboxDomainChallengeSecret | quote }}
|
||||
- name: NFS_STORAGE_CLASS_NAME
|
||||
value: {{ .Values.devboxConfig.nfsStorageClassName | quote }}
|
||||
- name: CUSTOM_SCRIPTS
|
||||
value: {{ .Values.devboxConfig.customScripts | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: devbox-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: devbox-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "devbox-frontend.fullname" . }}-config
|
||||
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "devbox-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ include "devbox-frontend.cloudOrigin" . }}, {{ include "devbox-frontend.wildcardCloudOrigin" . }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "devbox-frontend.cloudOrigin" . }} {{ include "devbox-frontend.wildcardCloudOrigin" . }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} {{ .Values.devboxConfig.cloudDomain }}{{ include "devbox-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "devbox-frontend.cloudOrigin" . }} {{ include "devbox-frontend.wildcardCloudOrigin" . }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "devbox-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "devbox-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.devboxConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "devbox-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.devboxConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "devbox-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "devbox-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "devbox-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,88 @@
|
||||
# Default values for devbox-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-devbox-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "devbox-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
devboxConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
databaseUrl: ""
|
||||
databaseProvider: "cockroachdb"
|
||||
tlsRejectUnauthorized: "1"
|
||||
sshDomain: ""
|
||||
registryAddr: "sealos.hub:5000"
|
||||
monitorUrl: "http://launchpad-monitor.sealos.svc.cluster.local:8428"
|
||||
accountUrl: "http://account-service.account-system.svc.cluster.local:2333"
|
||||
rootRuntimeNamespace: "devbox-system"
|
||||
currencySymbol: "usd"
|
||||
gpuEnable: false
|
||||
storageLimit: "10Gi"
|
||||
runtimeClassName: "devbox-runtime"
|
||||
retagSvcUrl: "http://devbox-service.devbox-system.svc.cluster.local:8092"
|
||||
jwtSecret: ""
|
||||
regionUid: ""
|
||||
enableImportFeature: false
|
||||
enableWebideFeature: false
|
||||
enableAdvancedConfig: false
|
||||
cpuSlideMarkList: "1,2,4,8,16"
|
||||
memorySlideMarkList: "2,4,8,16,32"
|
||||
devboxDomainChallengeSecret: "default-dev-secret-change-in-production"
|
||||
nfsStorageClassName: "nfs-csi"
|
||||
customScripts: "[]"
|
||||
documentUrlZh: "https://sealos.run/docs/overview/intro"
|
||||
documentUrlEn: "https://sealos.io/docs/overview/intro"
|
||||
privacyUrlZh: "https://sealos.run/docs/msa/privacy-policy"
|
||||
privacyUrlEn: "https://sealos.io/docs/msa/privacy-policy"
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- devbox-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
@@ -0,0 +1,117 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"devbox-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"devbox-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/devbox-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string devboxConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string devboxConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string devboxConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string devboxConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string devboxConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
SEALOS_DATABASE_GLOBAL_COCKROACHDB_URI=${SEALOS_DATABASE_GLOBAL_COCKROACHDB_URI:-"${databaseGlobalCockroachdbURI:-$(get_cm_value sealos-system sealos-config databaseGlobalCockroachdbURI)}"}
|
||||
add_set_string devboxConfig.databaseUrl "${SEALOS_DATABASE_GLOBAL_COCKROACHDB_URI}"
|
||||
SEALOS_JWT_INTERNAL=${SEALOS_JWT_INTERNAL:-"${jwtInternal:-$(get_cm_value sealos-system sealos-config jwtInternal)}"}
|
||||
add_set_string devboxConfig.jwtSecret "${SEALOS_JWT_INTERNAL}"
|
||||
SEALOS_REGION_UID=${SEALOS_REGION_UID:-"${regionUid:-${regionUID:-$(get_cm_value sealos-system sealos-config regionUID)}}"}
|
||||
add_set_string devboxConfig.regionUid "${SEALOS_REGION_UID}"
|
||||
add_set_string devboxConfig.databaseProvider "${databaseProvider:-}"
|
||||
add_set_string devboxConfig.tlsRejectUnauthorized "${tlsRejectUnauthorized:-}"
|
||||
add_set_string devboxConfig.sshDomain "${sshDomain:-}"
|
||||
add_set_string devboxConfig.registryAddr "${registryAddr:-}"
|
||||
add_set_string devboxConfig.monitorUrl "${monitorUrl:-}"
|
||||
add_set_string devboxConfig.accountUrl "${accountUrl:-}"
|
||||
add_set_string devboxConfig.rootRuntimeNamespace "${rootRuntimeNamespace:-}"
|
||||
add_set_string devboxConfig.currencySymbol "${currencySymbol:-}"
|
||||
add_set_string devboxConfig.gpuEnable "${gpuEnable:-}"
|
||||
add_set_string devboxConfig.storageLimit "${storageLimit:-}"
|
||||
add_set_string devboxConfig.runtimeClassName "${runtimeClassName:-}"
|
||||
add_set_string devboxConfig.retagSvcUrl "${retagSvcUrl:-}"
|
||||
add_set_string devboxConfig.enableImportFeature "${enableImportFeature:-}"
|
||||
add_set_string devboxConfig.enableWebideFeature "${enableWebideFeature:-}"
|
||||
add_set_string devboxConfig.enableAdvancedConfig "${enableAdvancedConfig:-}"
|
||||
add_set_string devboxConfig.cpuSlideMarkList "${cpuSlideMarkList:-}"
|
||||
add_set_string devboxConfig.memorySlideMarkList "${memorySlideMarkList:-}"
|
||||
add_set_string devboxConfig.devboxDomainChallengeSecret "${devboxDomainChallengeSecret:-}"
|
||||
add_set_string devboxConfig.nfsStorageClassName "${nfsStorageClassName:-}"
|
||||
add_set_string devboxConfig.customScripts "${customScripts:-}"
|
||||
add_set_string devboxConfig.documentUrlZh "${documentUrlZh:-}"
|
||||
add_set_string devboxConfig.documentUrlEn "${documentUrlEn:-}"
|
||||
add_set_string devboxConfig.privacyUrlZh "${privacyUrlZh:-}"
|
||||
add_set_string devboxConfig.privacyUrlEn "${privacyUrlEn:-}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap devbox-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service devbox-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment devbox-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress devbox-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress devbox-challenge
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io devbox
|
||||
|
||||
|
||||
SERVICE_NAME="devbox-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/devbox-frontend/devbox-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/devbox-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -1,189 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app: devbox-frontend
|
||||
name: devbox-frontend
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: devbox-frontend-config
|
||||
namespace: devbox-frontend
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: devbox-frontend
|
||||
namespace: devbox-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: devbox-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: devbox-frontend
|
||||
spec:
|
||||
initContainers:
|
||||
- name: devbox-frontend-init
|
||||
image: ghcr.io/labring/sealos-devbox-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: DATABASE_URL
|
||||
value: {{ .databaseUrl }} # -nsealos cm desktop-frontend-config ->database->global + devbox
|
||||
- name: DATABASE_PROVIDER
|
||||
value: "{{ default "cockroachdb" .databaseProvider }}"
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
args:
|
||||
- |-
|
||||
cd /app/providers/devbox
|
||||
DB_PROVIDER="${DATABASE_PROVIDER:-cockroachdb}"
|
||||
SCHEMA_PATH="./prisma/cockroach/schema.prisma"
|
||||
if [ "$DB_PROVIDER" = "postgresql" ] || [ "$DB_PROVIDER" = "postgres" ] || [ "$DB_PROVIDER" = "pg" ]; then
|
||||
SCHEMA_PATH="./prisma/postgresql/schema.prisma"
|
||||
HAS_UUID_FN=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_proc WHERE proname='gen_random_uuid' LIMIT 1;")
|
||||
if [ "$HAS_UUID_FN" != "1" ]; then
|
||||
psql "$DATABASE_URL" -v ON_ERROR_STOP=1 -c 'CREATE OR REPLACE FUNCTION public.gen_random_uuid() RETURNS uuid LANGUAGE SQL VOLATILE AS $func$ SELECT md5(random()::text || clock_timestamp()::text || txid_current()::text)::uuid; $func$;'
|
||||
fi
|
||||
MIGRATION="20260125094114_add_template_repository_kind"
|
||||
HAS_MIGRATION=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM _prisma_migrations WHERE migration_name='${MIGRATION}' AND rolled_back_at IS NULL LIMIT 1;")
|
||||
if [ "$HAS_MIGRATION" = "1" ]; then
|
||||
prisma migrate deploy --schema "$SCHEMA_PATH"
|
||||
exit 0
|
||||
fi
|
||||
HAS_ENUM=$(psql "$DATABASE_URL" -tAc "SELECT 1 FROM pg_enum e JOIN pg_type t ON t.oid = e.enumtypid WHERE t.typname IN ('TemplateRepositoryKind','template_repository_kind') AND e.enumlabel = 'SERVICE' LIMIT 1;")
|
||||
if [ "$HAS_ENUM" = "1" ]; then
|
||||
prisma migrate resolve --schema "$SCHEMA_PATH" --applied "$MIGRATION"
|
||||
fi
|
||||
fi
|
||||
prisma migrate deploy --schema "$SCHEMA_PATH"
|
||||
containers:
|
||||
- name: devbox-frontend
|
||||
env:
|
||||
- name: NODE_TLS_REJECT_UNAUTHORIZED
|
||||
value: "{{ default "1" .tlsRejectUnauthorized }}"
|
||||
- name: DOCUMENT_URL_ZH
|
||||
value: https://sealos.run/docs/overview/intro
|
||||
- name: DOCUMENT_URL_EN
|
||||
value: https://sealos.io/docs/overview/intro
|
||||
- name: PRIVACY_URL_ZH
|
||||
value: https://sealos.run/docs/msa/privacy-policy
|
||||
- name: PRIVACY_URL_EN
|
||||
value: https://sealos.io/docs/msa/privacy-policy
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: SSH_DOMAIN
|
||||
value: {{ default "" .sshDomain }}
|
||||
- name: INGRESS_SECRET
|
||||
value: wildcard-cert
|
||||
- name: REGISTRY_ADDR
|
||||
value: {{ .registryAddr }}
|
||||
- name: DEVBOX_AFFINITY_ENABLE
|
||||
value: 'true'
|
||||
- name: MONITOR_URL
|
||||
value: http://launchpad-monitor.sealos.svc.cluster.local:8428
|
||||
- name: ACCOUNT_URL
|
||||
value: http://account-service.account-system.svc.cluster.local:2333
|
||||
- name: ROOT_RUNTIME_NAMESPACE
|
||||
value: devbox-system
|
||||
- name: INGRESS_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: CURRENCY_SYMBOL
|
||||
value: usd # 'shellCoin' | 'cny' | 'usd'
|
||||
- name: GPU_ENABLE
|
||||
value: 'false'
|
||||
- name: STORAGE_LIMIT
|
||||
value: 10Gi # default is 10Gi
|
||||
- name: DEVBOX_RUNTIME_CLASS_NAME
|
||||
value: devbox-runtime
|
||||
- name: RETAG_SVC_URL
|
||||
value: http://devbox-service.devbox-system.svc.cluster.local:8092
|
||||
- name: JWT_SECRET
|
||||
value: {{ .jwtSecret }} # -nsealos cm desktop-frontend-config ->jwt->Internal
|
||||
- name: REGION_UID
|
||||
value: {{ .regionUid }} # -nsealos cm desktop-frontend-config ->regionUid
|
||||
- name: DATABASE_URL
|
||||
value: {{ .databaseUrl }} # -nsealos cm desktop-frontend-config ->database->global + devbox
|
||||
- name: DATABASE_PROVIDER
|
||||
value: "{{ default "cockroachdb" .databaseProvider }}"
|
||||
- name: ENABLE_IMPORT_FEATURE
|
||||
value: 'false'
|
||||
- name: ENABLE_WEBIDE_FEATURE
|
||||
value: 'false'
|
||||
- name: ENABLE_ADVANCED_CONFIG
|
||||
value: 'false'
|
||||
- name: CPU_SLIDE_MARK_LIST
|
||||
value: '1,2,4,8,16'
|
||||
- name: MEMORY_SLIDE_MARK_LIST
|
||||
value: '2,4,8,16,32'
|
||||
- name: DEVBOX_DOMAIN_CHALLENGE_SECRET
|
||||
value: {{ .devboxDomainChallengeSecret }}
|
||||
- name: NFS_STORAGE_CLASS_NAME
|
||||
value: {{ default "nfs-csi" .nfsStorageClassName }}
|
||||
- name: CUSTOM_SCRIPTS
|
||||
value: '{{ default "[]" .customScripts }}'
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- 'ALL'
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
# do not modify this image, it is used for CI/CD
|
||||
image: ghcr.io/labring/sealos-devbox-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: devbox-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: 'app'
|
||||
operator: In
|
||||
values:
|
||||
- devbox-frontend
|
||||
topologyKey: 'kubernetes.io/hostname'
|
||||
volumes:
|
||||
- name: devbox-frontend-volume
|
||||
configMap:
|
||||
name: devbox-frontend-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: devbox-frontend
|
||||
name: devbox-frontend
|
||||
namespace: devbox-frontend
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: devbox-frontend
|
||||
@@ -1,51 +0,0 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com; frame-src 'self' {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com; frame-src 'self' {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
name: devbox-frontend
|
||||
namespace: devbox-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: devbox.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: devbox-frontend
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- devbox.{{ .cloudDomain }}
|
||||
secretName: {{ .certSecretName }} # wildcard-cert
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
name: devbox-challenge
|
||||
namespace: devbox-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: ""
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
service:
|
||||
name: devbox-frontend
|
||||
port:
|
||||
number: 3000
|
||||
path: /api/.well-known/devbox-domain-challenge
|
||||
pathType: Prefix
|
||||
@@ -3,11 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY invite-frontend-entrypoint.sh invite-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
ENV lafBaseUrl=""
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash invite-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: invite-frontend
|
||||
description: Sealos invite Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
@@ -0,0 +1,16 @@
|
||||
# Custom values for invite-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
inviteConfig:
|
||||
lafBaseUrl: ""
|
||||
giftRatio: "0.1"
|
||||
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "invite-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "invite-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "invite-frontend.chart" . }}
|
||||
{{ include "invite-frontend.selectorLabels" . }}
|
||||
{{ include "invite-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.selectorLabels" -}}
|
||||
app: {{ include "invite-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "invite-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.inviteConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.port" -}}
|
||||
{{- $scheme := include "invite-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.inviteConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.inviteConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.portSuffix" -}}
|
||||
{{- $port := include "invite-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.portEnv" -}}
|
||||
{{- $port := include "invite-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.cloudOrigin" -}}
|
||||
{{- include "invite-frontend.scheme" . -}}://{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "invite-frontend.scheme" . -}}://*.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.host" -}}
|
||||
{{- default (printf "invite.%s" .Values.inviteConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "invite-frontend.appUrl" -}}
|
||||
{{- include "invite-frontend.scheme" . -}}://{{ include "invite-frontend.host" . }}{{ include "invite-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+7
-5
@@ -6,12 +6,14 @@ metadata:
|
||||
spec:
|
||||
data:
|
||||
desc: invite
|
||||
url: "https://invite.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
icon: "https://invite.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}/logo.svg"
|
||||
url: {{ include "invite-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "invite-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: 邀请注册
|
||||
zh-Hans:
|
||||
name: 邀请注册
|
||||
menuData:
|
||||
name: invite
|
||||
type: iframe
|
||||
displayType: normal
|
||||
i18n:
|
||||
zh:
|
||||
name: 邀请注册
|
||||
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "invite-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "invite-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
@@ -0,0 +1,65 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "invite-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "invite-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "invite-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "invite-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .Values.inviteConfig.cloudDomain | quote }}
|
||||
- name: LAF_BASE_URL
|
||||
value: {{ .Values.inviteConfig.lafBaseUrl | quote }}
|
||||
- name: GIFT_RATIO
|
||||
value: {{ .Values.inviteConfig.giftRatio | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: invite-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: invite-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "invite-frontend.fullname" . }}-config
|
||||
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "invite-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ include "invite-frontend.cloudOrigin" . }}, {{ include "invite-frontend.wildcardCloudOrigin" . }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "invite-frontend.cloudOrigin" . }} {{ include "invite-frontend.wildcardCloudOrigin" . }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} {{ .Values.inviteConfig.cloudDomain }}{{ include "invite-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "invite-frontend.cloudOrigin" . }} {{ include "invite-frontend.wildcardCloudOrigin" . }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "invite-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "invite-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.inviteConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "invite-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.inviteConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "invite-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "invite-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "invite-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,52 @@
|
||||
# Default values for invite-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-invite-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "invite-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
inviteConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
lafBaseUrl: ""
|
||||
giftRatio: "0.1"
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
affinity: {}
|
||||
@@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"invite-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"invite-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/invite-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string inviteConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string inviteConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string inviteConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string inviteConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string inviteConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
add_set_string inviteConfig.lafBaseUrl "${lafBaseUrl:-}"
|
||||
add_set_string inviteConfig.giftRatio "${giftRatio:-}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap invite-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service invite-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment invite-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress invite-frontend
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io invite
|
||||
|
||||
|
||||
SERVICE_NAME="invite-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/invite-frontend/invite-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/invite-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -1,86 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app: invite-frontend
|
||||
name: invite-frontend
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: invite-frontend-config
|
||||
namespace: invite-frontend
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: invite-frontend
|
||||
namespace: invite-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: invite-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: invite-frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: invite-frontend
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: LAF_BASE_URL
|
||||
value: {{ .lafBaseUrl }}
|
||||
- name: GIFT_RATIO
|
||||
value: "0.1"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- 'ALL'
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
# do not modify this image, it is used for CI/CD
|
||||
image: ghcr.io/labring/sealos-invite-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: invite-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
volumes:
|
||||
- name: invite-frontend-volume
|
||||
configMap:
|
||||
name: invite-frontend-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: invite-frontend
|
||||
name: invite-frontend
|
||||
namespace: invite-frontend
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: invite-frontend
|
||||
@@ -1,51 +0,0 @@
|
||||
# Copyright © 2023 sealos.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}, https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
name: invite-frontend
|
||||
namespace: invite-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: invite.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: invite-frontend
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- invite.{{ .cloudDomain }}
|
||||
secretName: {{ .certSecretName }}
|
||||
@@ -2,11 +2,8 @@ FROM scratch
|
||||
|
||||
USER 65532:65532
|
||||
|
||||
COPY manifests manifests
|
||||
COPY registry registry
|
||||
COPY charts charts
|
||||
COPY kubepanel-frontend-entrypoint.sh kubepanel-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash kubepanel-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: kubepanel-frontend
|
||||
description: Sealos Kube Panel Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
# Custom values for kubepanel-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
kubepanelConfig:
|
||||
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "kubepanel-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "kubepanel-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "kubepanel-frontend.chart" . }}
|
||||
{{ include "kubepanel-frontend.selectorLabels" . }}
|
||||
{{ include "kubepanel-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.selectorLabels" -}}
|
||||
app: {{ include "kubepanel-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "kubepanel-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.kubepanelConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.port" -}}
|
||||
{{- $scheme := include "kubepanel-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.kubepanelConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.kubepanelConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.portSuffix" -}}
|
||||
{{- $port := include "kubepanel-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.portEnv" -}}
|
||||
{{- $port := include "kubepanel-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.cloudOrigin" -}}
|
||||
{{- include "kubepanel-frontend.scheme" . -}}://{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "kubepanel-frontend.scheme" . -}}://*.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.host" -}}
|
||||
{{- default (printf "kubepanel.%s" .Values.kubepanelConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "kubepanel-frontend.appUrl" -}}
|
||||
{{- include "kubepanel-frontend.scheme" . -}}://{{ include "kubepanel-frontend.host" . }}{{ include "kubepanel-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+2
-2
@@ -6,8 +6,8 @@ metadata:
|
||||
spec:
|
||||
data:
|
||||
desc: Kube Panel
|
||||
url: "https://kubepanel.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
icon: "https://kubepanel.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}/logo.svg"
|
||||
url: {{ include "kubepanel-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "kubepanel-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: 资源监控
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "kubepanel-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "kubepanel-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "kubepanel-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "kubepanel-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "kubepanel-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "kubepanel-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .Values.kubepanelConfig.cloudDomain | quote }}
|
||||
- name: SEALOS_PORT
|
||||
value: {{ include "kubepanel-frontend.portEnv" . | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: kubepanel-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: kubepanel-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "kubepanel-frontend.fullname" . }}-config
|
||||
@@ -0,0 +1,43 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "kubepanel-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/enable-cors: "true"
|
||||
nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, DELETE, PATCH, OPTIONS"
|
||||
nginx.ingress.kubernetes.io/cors-allow-origin: "{{ include "kubepanel-frontend.cloudOrigin" . }}, {{ include "kubepanel-frontend.wildcardCloudOrigin" . }}"
|
||||
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
|
||||
nginx.ingress.kubernetes.io/cors-max-age: "600"
|
||||
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "kubepanel-frontend.cloudOrigin" . }} {{ include "kubepanel-frontend.wildcardCloudOrigin" . }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }}; img-src * data: blob: resource: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} resource: *.baidu.com *.bdstatic.com https://js.stripe.com; frame-src 'self' *.{{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} {{ .Values.kubepanelConfig.cloudDomain }}{{ include "kubepanel-frontend.portSuffix" . }} mailto: tel: weixin: mtt: *.baidu.com https://js.stripe.com; frame-ancestors 'self' {{ include "kubepanel-frontend.cloudOrigin" . }} {{ include "kubepanel-frontend.wildcardCloudOrigin" . }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "kubepanel-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "kubepanel-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.kubepanelConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "kubepanel-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.kubepanelConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "kubepanel-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "kubepanel-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "kubepanel-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,61 @@
|
||||
# Default values for kubepanel-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-kubepanel-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "kubepanel-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
kubepanelConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- kubepanel-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"kubepanel-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"kubepanel-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/kubepanel-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string kubepanelConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string kubepanelConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string kubepanelConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string kubepanelConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string kubepanelConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap kubepanel-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service kubepanel-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment kubepanel-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress kubepanel-frontend
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io kubepanel
|
||||
|
||||
|
||||
SERVICE_NAME="kubepanel-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/kubepanel-frontend/kubepanel-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/kubepanel-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -1,96 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app: kubepanel-frontend
|
||||
name: kubepanel-frontend
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: kubepanel-frontend-config
|
||||
namespace: kubepanel-frontend
|
||||
data:
|
||||
config.yaml: |-
|
||||
addr: :3000
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: kubepanel-frontend
|
||||
namespace: kubepanel-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: kubepanel-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 25%
|
||||
maxSurge: 25%
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: kubepanel-frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: kubepanel-frontend
|
||||
env:
|
||||
- name: SEALOS_DOMAIN
|
||||
value: {{ .cloudDomain }}
|
||||
- name: SEALOS_PORT
|
||||
value: "{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- 'ALL'
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1024Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
# do not modify this image, it is used for CI/CD
|
||||
image: ghcr.io/labring/sealos-kubepanel-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: kubepanel-frontend-volume
|
||||
mountPath: /config.yaml
|
||||
subPath: config.yaml
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- kubepanel-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
volumes:
|
||||
- name: kubepanel-frontend-volume
|
||||
configMap:
|
||||
name: kubepanel-frontend-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: kubepanel-frontend
|
||||
name: kubepanel-frontend
|
||||
namespace: kubepanel-frontend
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 3000
|
||||
protocol: TCP
|
||||
targetPort: 3000
|
||||
selector:
|
||||
app: kubepanel-frontend
|
||||
@@ -1,45 +0,0 @@
|
||||
# Copyright © 2022 sealos.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
more_clear_headers "X-Frame-Options:";
|
||||
more_set_headers "Content-Security-Policy: default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}";
|
||||
more_set_headers "X-Xss-Protection: 1; mode=block";
|
||||
higress.io/response-header-control-remove: X-Frame-Options
|
||||
higress.io/response-header-control-update: |
|
||||
Content-Security-Policy "default-src * blob: data: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; img-src * data: blob: resource: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}; connect-src * wss: blob: resource:; style-src 'self' 'unsafe-inline' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource:; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} resource: *.baidu.com *.bdstatic.com; frame-src 'self' *.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} {{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} mailto: tel: weixin: mtt: *.baidu.com; frame-ancestors 'self' https://{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }} https://*.{{ .cloudDomain }}{{ if .cloudPort }}:{{ .cloudPort }}{{ end }}"
|
||||
X-Xss-Protection "1; mode=block"
|
||||
name: kubepanel-frontend
|
||||
namespace: kubepanel-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: kubepanel.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: kubepanel-frontend
|
||||
port:
|
||||
number: 3000
|
||||
tls:
|
||||
- hosts:
|
||||
- kubepanel.{{ .cloudDomain }}
|
||||
secretName: {{ .certSecretName }}
|
||||
@@ -3,9 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY object-storage-frontend-entrypoint.sh object-storage-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain=${cloudDomain:-"127.0.0.1.nip.io"}
|
||||
ENV cloudPort=${cloudPort:-"443"}
|
||||
|
||||
CMD ["kubectl apply -f manifests/deploy.yaml"]
|
||||
CMD ["bash object-storage-frontend-entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: v2
|
||||
name: objectstorage-frontend
|
||||
description: Sealos Object Storage Frontend Helm Chart
|
||||
type: application
|
||||
version: 1.0.0
|
||||
appVersion: "latest"
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
# Custom values for objectstorage-frontend helm chart.
|
||||
# This file contains user-customizable configurations.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
objectstorageConfig:
|
||||
monitorUrl: "http://object-storage-monitor.objectstorage-system.svc.cluster.local:9090/q"
|
||||
billingUrl: ""
|
||||
billingSecret: ""
|
||||
appLaunchpadUrl: "http://applaunchpad-frontend.applaunchpad-frontend.svc.cluster.local:3000/api/v1alpha"
|
||||
appTokenJwtKey: ""
|
||||
hostingPodCpuMilliCores: 200
|
||||
hostingPodMemoryMiB: 128
|
||||
hostingAppNamePrefix: "static-host"
|
||||
hostingNetworkProtocol: "HTTP"
|
||||
hostingNetworkPort: 80
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
{{/* Expand the name of the chart. */}}
|
||||
{{- define "objectstorage-frontend.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a default fully qualified app name. */}}
|
||||
{{- define "objectstorage-frontend.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.labels" -}}
|
||||
helm.sh/chart: {{ include "objectstorage-frontend.chart" . }}
|
||||
{{ include "objectstorage-frontend.selectorLabels" . }}
|
||||
{{ include "objectstorage-frontend.recommendedLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.selectorLabels" -}}
|
||||
app: {{ include "objectstorage-frontend.fullname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.recommendedLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "objectstorage-frontend.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.scheme" -}}
|
||||
{{- if eq (toString .Values.objectstorageConfig.disableHttps) "true" -}}http{{- else -}}https{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.port" -}}
|
||||
{{- $scheme := include "objectstorage-frontend.scheme" . -}}
|
||||
{{- $port := toString .Values.objectstorageConfig.cloudPort -}}
|
||||
{{- if eq $scheme "http" -}}
|
||||
{{- $port = toString .Values.objectstorageConfig.httpPort -}}
|
||||
{{- end -}}
|
||||
{{- if or (and (eq $scheme "https") (or (eq $port "") (eq $port "443"))) (and (eq $scheme "http") (or (eq $port "") (eq $port "80"))) -}}
|
||||
{{- "" -}}
|
||||
{{- else -}}
|
||||
{{- $port -}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.portSuffix" -}}
|
||||
{{- $port := include "objectstorage-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.portEnv" -}}
|
||||
{{- $port := include "objectstorage-frontend.port" . -}}
|
||||
{{- if $port -}}:{{ $port }}{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.cloudOrigin" -}}
|
||||
{{- include "objectstorage-frontend.scheme" . -}}://{{ .Values.objectstorageConfig.cloudDomain }}{{ include "objectstorage-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.wildcardCloudOrigin" -}}
|
||||
{{- include "objectstorage-frontend.scheme" . -}}://*.{{ .Values.objectstorageConfig.cloudDomain }}{{ include "objectstorage-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.host" -}}
|
||||
{{- default (printf "objectstorage.%s" .Values.objectstorageConfig.cloudDomain) .Values.ingress.host -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "objectstorage-frontend.appUrl" -}}
|
||||
{{- include "objectstorage-frontend.scheme" . -}}://{{ include "objectstorage-frontend.host" . }}{{ include "objectstorage-frontend.portSuffix" . }}
|
||||
{{- end }}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
apiVersion: app.sealos.io/v1
|
||||
kind: App
|
||||
metadata:
|
||||
name: objectstorage
|
||||
namespace: app-system
|
||||
spec:
|
||||
data:
|
||||
desc: object storage
|
||||
url: {{ include "objectstorage-frontend.appUrl" . | quote }}
|
||||
icon: {{ printf "%s/logo.svg" (include "objectstorage-frontend.appUrl" .) | quote }}
|
||||
i18n:
|
||||
zh:
|
||||
name: 对象存储
|
||||
zh-Hans:
|
||||
name: 对象存储
|
||||
menuData:
|
||||
name: Object Storage
|
||||
type: iframe
|
||||
displayType: normal
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "objectstorage-frontend.fullname" . }}-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "objectstorage-frontend.labels" . | nindent 4 }}
|
||||
data:
|
||||
config.yaml: |-
|
||||
cloud:
|
||||
domain: {{ .Values.objectstorageConfig.cloudDomain | quote }}
|
||||
port: {{ default 443 .Values.objectstorageConfig.cloudPort }}
|
||||
objectStorage:
|
||||
resources:
|
||||
hostingPodCpuMilliCores: {{ .Values.objectstorageConfig.hostingPodCpuMilliCores }}
|
||||
hostingPodMemoryMiB: {{ .Values.objectstorageConfig.hostingPodMemoryMiB }}
|
||||
components:
|
||||
monitoring:
|
||||
url: {{ .Values.objectstorageConfig.monitorUrl | quote }}
|
||||
billing:
|
||||
url: {{ .Values.objectstorageConfig.billingUrl | quote }}
|
||||
secret: {{ .Values.objectstorageConfig.billingSecret | quote }}
|
||||
appLaunchpad:
|
||||
url: {{ .Values.objectstorageConfig.appLaunchpadUrl | quote }}
|
||||
realName:
|
||||
appTokenJwtKey: {{ .Values.objectstorageConfig.appTokenJwtKey | quote }}
|
||||
hosting:
|
||||
appNamePrefix: {{ .Values.objectstorageConfig.hostingAppNamePrefix | quote }}
|
||||
networkProtocol: {{ .Values.objectstorageConfig.hostingNetworkProtocol | quote }}
|
||||
networkPort: {{ .Values.objectstorageConfig.hostingNetworkPort }}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "objectstorage-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "objectstorage-frontend.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
revisionHistoryLimit: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "objectstorage-frontend.selectorLabels" . | nindent 6 }}
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
maxSurge: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "objectstorage-frontend.labels" . | nindent 8 }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ .Values.image | quote }}
|
||||
imagePullPolicy: {{ .Values.imagePullPolicy }}
|
||||
{{- if .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: MONITOR_URL
|
||||
value: {{ .Values.objectstorageConfig.monitorUrl | quote }}
|
||||
- name: APP_LAUNCHPAD_URL
|
||||
value: {{ .Values.objectstorageConfig.appLaunchpadUrl | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: object-storage-frontend-volume
|
||||
mountPath: /app/data/config.yaml
|
||||
subPath: config.yaml
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: object-storage-frontend-volume
|
||||
configMap:
|
||||
name: {{ include "objectstorage-frontend.fullname" . }}-config
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "objectstorage-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: {{ .Values.ingress.className | quote }}
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
if ($request_uri ~* \.(js|css|gif|jpe?g|png)) {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 3g
|
||||
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "180"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "180"
|
||||
{{- with .Values.ingress.annotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
ingressClassName: {{ .Values.ingress.className | quote }}
|
||||
rules:
|
||||
- host: {{ include "objectstorage-frontend.host" . | quote }}
|
||||
http:
|
||||
paths:
|
||||
- pathType: Prefix
|
||||
path: /
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "objectstorage-frontend.fullname" . }}
|
||||
port:
|
||||
number: {{ .Values.service.port }}
|
||||
{{- if not (eq (toString .Values.objectstorageConfig.disableHttps) "true") }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ include "objectstorage-frontend.host" . | quote }}
|
||||
secretName: {{ .Values.objectstorageConfig.certSecretName | quote }}
|
||||
{{- end }}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "objectstorage-frontend.labels" . | nindent 4 }}
|
||||
name: {{ include "objectstorage-frontend.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
targetPort: {{ .Values.service.port }}
|
||||
selector:
|
||||
{{- include "objectstorage-frontend.selectorLabels" . | nindent 4 }}
|
||||
@@ -0,0 +1,71 @@
|
||||
# Default values for objectstorage-frontend helm chart.
|
||||
|
||||
image: ghcr.io/labring/sealos-objectstorage-frontend:latest
|
||||
imagePullPolicy: Always
|
||||
|
||||
imagePullSecrets: []
|
||||
fullnameOverride: "object-storage-frontend"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1001
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- "ALL"
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
|
||||
ingress:
|
||||
className: nginx
|
||||
host: ""
|
||||
annotations: {}
|
||||
|
||||
objectstorageConfig:
|
||||
cloudDomain: "127.0.0.1.nip.io"
|
||||
cloudPort: ""
|
||||
httpPort: ""
|
||||
disableHttps: false
|
||||
certSecretName: "wildcard-cert"
|
||||
monitorUrl: "http://object-storage-monitor.objectstorage-system.svc.cluster.local:9090/q"
|
||||
billingUrl: ""
|
||||
billingSecret: ""
|
||||
appLaunchpadUrl: "http://applaunchpad-frontend.applaunchpad-frontend.svc.cluster.local:3000/api/v1alpha"
|
||||
appTokenJwtKey: ""
|
||||
hostingPodCpuMilliCores: 200
|
||||
hostingPodMemoryMiB: 128
|
||||
hostingAppNamePrefix: "static-host"
|
||||
hostingNetworkProtocol: "HTTP"
|
||||
hostingNetworkPort: 80
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- object-storage-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
@@ -1,128 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: objectstorage-frontend
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: object-storage-frontend
|
||||
namespace: objectstorage-frontend
|
||||
labels:
|
||||
app: object-storage-frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: object-storage-frontend
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
maxSurge: 0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: object-storage-frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: object-storage-frontend
|
||||
image: ghcr.io/labring/sealos-objectstorage-frontend:latest
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
protocol: TCP
|
||||
env:
|
||||
- name: MONITOR_URL
|
||||
value: http://object-storage-monitor.objectstorage-system.svc.cluster.local:9090/q
|
||||
- name: APP_LAUNCHPAD_URL
|
||||
value: http://applaunchpad-frontend.applaunchpad-frontend.svc.cluster.local:3000/api/v1alpha
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2048Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 128Mi
|
||||
imagePullPolicy: Always
|
||||
volumeMounts: []
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- weight: 100
|
||||
podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: "app"
|
||||
operator: In
|
||||
values:
|
||||
- object-storage-frontend
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
volumes: []
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: object-storage-frontend
|
||||
namespace: objectstorage-frontend
|
||||
labels:
|
||||
app: object-storage-frontend
|
||||
spec:
|
||||
ports:
|
||||
- port: 3000
|
||||
targetPort: 3000
|
||||
protocol: TCP
|
||||
selector:
|
||||
app: object-storage-frontend
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: nginx
|
||||
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||||
if ($request_uri ~* \.(js|css|gif|jpe?g|png)) {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: 3g
|
||||
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: '180'
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: '180'
|
||||
name: object-storage-frontend
|
||||
namespace: objectstorage-frontend
|
||||
spec:
|
||||
rules:
|
||||
- host: objectstorage.{{ .cloudDomain }}
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
service:
|
||||
name: object-storage-frontend
|
||||
port:
|
||||
number: 3000
|
||||
path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- hosts:
|
||||
- objectstorage.{{ .cloudDomain }}
|
||||
secretName: wildcard-cert
|
||||
---
|
||||
apiVersion: app.sealos.io/v1
|
||||
kind: App
|
||||
metadata:
|
||||
name: objectstorage
|
||||
namespace: app-system
|
||||
spec:
|
||||
data:
|
||||
desc: object storage
|
||||
url: https://objectstorage.{{ .cloudDomain }}:{{ .cloudPort }}
|
||||
displayType: normal
|
||||
i18n:
|
||||
zh:
|
||||
name: 对象存储
|
||||
zh-Hans:
|
||||
name: 对象存储
|
||||
icon: https://objectstorage.{{ .cloudDomain }}:{{ .cloudPort }}/logo.svg
|
||||
menuData:
|
||||
name: Object Storage
|
||||
type: iframe
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
RELEASE_NAME=${RELEASE_NAME:-"object-storage-frontend"}
|
||||
RELEASE_NAMESPACE=${RELEASE_NAMESPACE:-"objectstorage-frontend"}
|
||||
CHART_PATH=${CHART_PATH:-"./charts/objectstorage-frontend"}
|
||||
HELM_OPTS=${HELM_OPTS:-""}
|
||||
HELM_OPTIONS=${HELM_OPTIONS:-""}
|
||||
AUTO_CONFIG_HELM_OPTS=""
|
||||
|
||||
get_cm_value() {
|
||||
local namespace="$1"
|
||||
local name="$2"
|
||||
local key="$3"
|
||||
kubectl get configmap "${name}" -n "${namespace}" -o "jsonpath={.data.${key}}" 2>/dev/null || true
|
||||
}
|
||||
|
||||
add_set_string() {
|
||||
local key="$1"
|
||||
local value="$2"
|
||||
if [ -n "${value}" ]; then
|
||||
AUTO_CONFIG_HELM_OPTS="${AUTO_CONFIG_HELM_OPTS} --set-string ${key}=${value}"
|
||||
fi
|
||||
}
|
||||
|
||||
SEALOS_CLOUD_DOMAIN=${SEALOS_CLOUD_DOMAIN:-"${cloudDomain:-$(get_cm_value sealos-system sealos-config cloudDomain)}"}
|
||||
add_set_string objectstorageConfig.cloudDomain "${SEALOS_CLOUD_DOMAIN}"
|
||||
SEALOS_CLOUD_PORT=${SEALOS_CLOUD_PORT:-"${cloudPort:-$(get_cm_value sealos-system sealos-config cloudPort)}"}
|
||||
add_set_string objectstorageConfig.cloudPort "${SEALOS_CLOUD_PORT}"
|
||||
SEALOS_HTTP_PORT=${SEALOS_HTTP_PORT:-"${httpPort:-$(get_cm_value sealos-system sealos-config httpPort)}"}
|
||||
add_set_string objectstorageConfig.httpPort "${SEALOS_HTTP_PORT}"
|
||||
SEALOS_DISABLE_HTTPS=${SEALOS_DISABLE_HTTPS:-"${disableHttps:-$(get_cm_value sealos-system sealos-config disableHttps)}"}
|
||||
add_set_string objectstorageConfig.disableHttps "${SEALOS_DISABLE_HTTPS}"
|
||||
SEALOS_CERT_SECRET_NAME=${SEALOS_CERT_SECRET_NAME:-"${certSecretName:-$(get_cm_value sealos-system sealos-config certSecretName)}"}
|
||||
add_set_string objectstorageConfig.certSecretName "${SEALOS_CERT_SECRET_NAME}"
|
||||
SEALOS_JWT_INTERNAL=${SEALOS_JWT_INTERNAL:-"${jwtInternal:-$(get_cm_value sealos-system sealos-config jwtInternal)}"}
|
||||
add_set_string objectstorageConfig.appTokenJwtKey "${SEALOS_JWT_INTERNAL}"
|
||||
add_set_string objectstorageConfig.monitorUrl "${monitorUrl:-}"
|
||||
add_set_string objectstorageConfig.billingUrl "${billingUrl:-}"
|
||||
add_set_string objectstorageConfig.billingSecret "${billingSecret:-}"
|
||||
add_set_string objectstorageConfig.appLaunchpadUrl "${appLaunchpadUrl:-}"
|
||||
add_set_string objectstorageConfig.hostingPodCpuMilliCores "${hostingPodCpuMilliCores:-}"
|
||||
add_set_string objectstorageConfig.hostingPodMemoryMiB "${hostingPodMemoryMiB:-}"
|
||||
add_set_string objectstorageConfig.hostingAppNamePrefix "${hostingAppNamePrefix:-}"
|
||||
add_set_string objectstorageConfig.hostingNetworkProtocol "${hostingNetworkProtocol:-}"
|
||||
add_set_string objectstorageConfig.hostingNetworkPort "${hostingNetworkPort:-}"
|
||||
|
||||
adopt_namespaced_resource() {
|
||||
local namespace="$1"
|
||||
local kind="$2"
|
||||
local name="$3"
|
||||
if kubectl -n "${namespace}" get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${namespace}/${name}..."
|
||||
kubectl -n "${namespace}" label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl -n "${namespace}" annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
adopt_cluster_resource() {
|
||||
local kind="$1"
|
||||
local name="$2"
|
||||
if kubectl get "${kind}" "${name}" >/dev/null 2>&1; then
|
||||
echo "Adopting ${kind} ${name}..."
|
||||
kubectl label "${kind}" "${name}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate "${kind}" "${name}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking and adopting existing resources..."
|
||||
if kubectl get namespace "${RELEASE_NAMESPACE}" >/dev/null 2>&1; then
|
||||
kubectl label namespace "${RELEASE_NAMESPACE}" app.kubernetes.io/managed-by=Helm --overwrite >/dev/null 2>&1 || true
|
||||
kubectl annotate namespace "${RELEASE_NAMESPACE}" meta.helm.sh/release-name="${RELEASE_NAME}" meta.helm.sh/release-namespace="${RELEASE_NAMESPACE}" --overwrite >/dev/null 2>&1 || true
|
||||
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" configmap object-storage-frontend-config
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" service object-storage-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" deployment object-storage-frontend
|
||||
adopt_namespaced_resource "${RELEASE_NAMESPACE}" ingress object-storage-frontend
|
||||
fi
|
||||
|
||||
adopt_namespaced_resource app-system apps.app.sealos.io objectstorage
|
||||
|
||||
|
||||
SERVICE_NAME="object-storage-frontend"
|
||||
USER_VALUES_PATH="/root/.sealos/cloud/values/core/${SERVICE_NAME}-values.yaml"
|
||||
|
||||
if [ ! -f "${USER_VALUES_PATH}" ]; then
|
||||
mkdir -p "$(dirname "${USER_VALUES_PATH}")"
|
||||
cp "./charts/objectstorage-frontend/object-storage-frontend-values.yaml" "${USER_VALUES_PATH}"
|
||||
fi
|
||||
|
||||
HELM_ARGS="${AUTO_CONFIG_HELM_OPTS} ${HELM_OPTIONS} ${HELM_OPTS}"
|
||||
|
||||
echo "Deploying Helm chart..."
|
||||
helm upgrade -i "${RELEASE_NAME}" -n "${RELEASE_NAMESPACE}" --create-namespace "${CHART_PATH}" \
|
||||
-f "./charts/objectstorage-frontend/values.yaml" \
|
||||
-f "${USER_VALUES_PATH}" \
|
||||
${HELM_ARGS}
|
||||
@@ -3,17 +3,7 @@ FROM scratch
|
||||
USER 65532:65532
|
||||
|
||||
COPY registry registry
|
||||
COPY manifests manifests
|
||||
COPY charts charts
|
||||
COPY template-frontend-entrypoint.sh template-frontend-entrypoint.sh
|
||||
|
||||
ENV cloudDomain="127.0.0.1.nip.io"
|
||||
ENV cloudPort=""
|
||||
ENV userDomain=""
|
||||
ENV certSecretName="wildcard-cert"
|
||||
ENV templateRepoUrl="https://github.com/labring-actions/templates"
|
||||
ENV templateRepoBranch="main"
|
||||
ENV templateRepoPath="templates"
|
||||
ENV guideEnabled="true"
|
||||
ENV billingUrl="http://account-service.account-system.svc:2333"
|
||||
ENV enableReadmeFetch="true"
|
||||
|
||||
CMD ["kubectl apply -f manifests"]
|
||||
CMD ["bash template-frontend-entrypoint.sh"]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user