mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-08-23 12:24:57 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
116f763bd8 |
14 changed files with 507 additions and 2 deletions
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
|
|
@ -46,3 +46,31 @@ jobs:
|
|||
|
||||
- name: golangci-lint
|
||||
run: go tool golangci-lint run ./...
|
||||
|
||||
helm:
|
||||
name: Helm chart
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||
with:
|
||||
version: v3.18.6
|
||||
|
||||
- name: Lint chart
|
||||
run: helm lint deploy/charts/proxy
|
||||
|
||||
- name: Render chart variants
|
||||
run: |
|
||||
set -euo pipefail
|
||||
helm template proxy deploy/charts/proxy >/dev/null
|
||||
helm template proxy deploy/charts/proxy \
|
||||
--set persistence.enabled=false \
|
||||
--set config.existingConfigMap=proxy-config \
|
||||
--set ingress.enabled=true \
|
||||
--set 'ingress.hosts[0].host=proxy.example.com' \
|
||||
--set 'ingress.hosts[0].paths[0].path=/' \
|
||||
--set 'ingress.hosts[0].paths[0].pathType=Prefix' \
|
||||
>/dev/null
|
||||
|
|
|
|||
63
.github/workflows/publish.yml
vendored
63
.github/workflows/publish.yml
vendored
|
|
@ -96,3 +96,66 @@ jobs:
|
|||
for predicate in sbom-linux-amd64.spdx.json sbom-linux-arm64.spdx.json; do
|
||||
cosign attest --yes --type spdxjson --predicate "$predicate" "$reference"
|
||||
done
|
||||
|
||||
publish_chart:
|
||||
name: Push Helm chart to GHCR
|
||||
if: github.ref_type == 'tag'
|
||||
needs: push_to_registry
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
||||
with:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.sha }}
|
||||
|
||||
- uses: azure/setup-helm@1a275c3b69536ee54be43f2070a358922e12c8d4 # v4.3.1
|
||||
with:
|
||||
version: v3.18.6
|
||||
|
||||
- name: Validate and normalize release version
|
||||
id: version
|
||||
env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
semver='^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(-((0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*)(\.(0|[1-9][0-9]*|[0-9]*[A-Za-z-][0-9A-Za-z-]*))*))?$'
|
||||
[[ "$TAG" =~ $semver ]] || {
|
||||
echo "Tag must be strict SemVer of the form vMAJOR.MINOR.PATCH[-PRERELEASE]: $TAG" >&2
|
||||
exit 1
|
||||
}
|
||||
version="${TAG#v}"
|
||||
[[ "$version" != "0.0.0" ]] || {
|
||||
echo "0.0.0 is a development placeholder and must not be published" >&2
|
||||
exit 1
|
||||
}
|
||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Log in to GHCR
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: printf '%s' "$GH_TOKEN" | helm registry login ghcr.io --username "$GITHUB_ACTOR" --password-stdin
|
||||
|
||||
- name: Lint and package chart
|
||||
env:
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
helm lint deploy/charts/proxy
|
||||
mkdir -p build
|
||||
helm package \
|
||||
--destination build \
|
||||
--version "$VERSION" \
|
||||
--app-version "$VERSION" \
|
||||
deploy/charts/proxy
|
||||
metadata="$(helm show chart "build/proxy-${VERSION}.tgz")"
|
||||
[[ "$(awk '$1 == "version:" {print $2}' <<<"$metadata")" == "$VERSION" ]]
|
||||
[[ "$(awk '$1 == "appVersion:" {gsub(/\"/, "", $2); print $2}' <<<"$metadata")" == "$VERSION" ]]
|
||||
|
||||
- name: Push chart
|
||||
env:
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: helm push "build/proxy-${VERSION}.tgz" oci://ghcr.io/git-pkgs/charts
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -4,7 +4,7 @@
|
|||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
proxy
|
||||
/proxy
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
|
|
|||
15
README.md
15
README.md
|
|
@ -62,6 +62,21 @@ brew install git-pkgs/git-pkgs/proxy
|
|||
|
||||
Or download a binary from the [releases page](https://github.com/git-pkgs/proxy/releases).
|
||||
|
||||
### Helm
|
||||
|
||||
Install the chart from GHCR, setting the public URL that package-manager clients
|
||||
will use to reach the proxy:
|
||||
|
||||
```bash
|
||||
helm install proxy oci://ghcr.io/git-pkgs/charts/proxy \
|
||||
--set config.data.base_url=https://proxy.example.com
|
||||
```
|
||||
|
||||
The default chart deploys one replica backed by a 10 GiB persistent volume,
|
||||
using SQLite and filesystem artifact storage under `/data`. See
|
||||
[`deploy/charts/proxy/values.yaml`](deploy/charts/proxy/values.yaml) for ingress,
|
||||
external database and object-storage configuration options.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
|
|
|
|||
6
deploy/charts/proxy/.helmignore
Normal file
6
deploy/charts/proxy/.helmignore
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.DS_Store
|
||||
.git/
|
||||
.github/
|
||||
*.swp
|
||||
*.tmp
|
||||
*.tgz
|
||||
11
deploy/charts/proxy/Chart.yaml
Normal file
11
deploy/charts/proxy/Chart.yaml
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: v2
|
||||
name: proxy
|
||||
description: A caching proxy for package registries
|
||||
type: application
|
||||
version: 0.0.0
|
||||
appVersion: "0.0.0"
|
||||
home: https://github.com/git-pkgs/proxy
|
||||
sources:
|
||||
- https://github.com/git-pkgs/proxy
|
||||
annotations:
|
||||
artifacthub.io/license: MIT
|
||||
15
deploy/charts/proxy/templates/NOTES.txt
Normal file
15
deploy/charts/proxy/templates/NOTES.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
git-pkgs proxy has been installed.
|
||||
|
||||
The default base URL is intended for local port forwarding. Before exposing the
|
||||
proxy, set config.data.base_url to the URL used by package-manager clients.
|
||||
|
||||
To access the proxy locally:
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} port-forward service/{{ include "proxy.fullname" . }} {{ .Values.service.port }}:{{ .Values.service.port }}
|
||||
|
||||
Then visit http://localhost:{{ .Values.service.port }}/.
|
||||
|
||||
{{- if not .Values.persistence.enabled }}
|
||||
WARNING: persistence is disabled. Cached artifacts and the default SQLite
|
||||
database will be lost when the pod is replaced.
|
||||
{{- end }}
|
||||
46
deploy/charts/proxy/templates/_helpers.tpl
Normal file
46
deploy/charts/proxy/templates/_helpers.tpl
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
{{/* Expand the chart name. */}}
|
||||
{{- define "proxy.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/* Create a release-specific, DNS-safe resource name. */}}
|
||||
{{- define "proxy.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := include "proxy.name" . }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "proxy.labels" -}}
|
||||
helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{ include "proxy.selectorLabels" . }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "proxy.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "proxy.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "proxy.configMapName" -}}
|
||||
{{- default (include "proxy.fullname" .) .Values.config.existingConfigMap }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "proxy.claimName" -}}
|
||||
{{- default (include "proxy.fullname" .) .Values.persistence.existingClaim }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "proxy.image" -}}
|
||||
{{- if .Values.image.digest -}}
|
||||
{{- printf "%s@%s" .Values.image.repository .Values.image.digest -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" .Values.image.repository (default .Chart.AppVersion .Values.image.tag) -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
12
deploy/charts/proxy/templates/configmap.yaml
Normal file
12
deploy/charts/proxy/templates/configmap.yaml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{{- if not .Values.config.existingConfigMap }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "proxy.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "proxy.labels" . | nindent 4 }}
|
||||
data:
|
||||
{{ required "config.existingConfigMapKey is required" .Values.config.existingConfigMapKey }}: |
|
||||
{{- toYaml .Values.config.data | nindent 4 }}
|
||||
{{- end }}
|
||||
102
deploy/charts/proxy/templates/deployment.yaml
Normal file
102
deploy/charts/proxy/templates/deployment.yaml
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "proxy.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "proxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
strategy:
|
||||
{{- toYaml .Values.deploymentStrategy | nindent 4 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "proxy.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "proxy.selectorLabels" . | nindent 8 }}
|
||||
{{- with .Values.podLabels }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
annotations:
|
||||
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||
{{- with .Values.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
image: {{ include "proxy.image" . | quote }}
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
|
||||
args:
|
||||
- serve
|
||||
- -config
|
||||
- /etc/proxy/{{ .Values.config.existingConfigMapKey }}
|
||||
{{- with .Values.extraEnv }}
|
||||
env:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with .Values.extraEnvFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.containerPort }}
|
||||
protocol: TCP
|
||||
startupProbe:
|
||||
{{- toYaml .Values.startupProbe | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml .Values.readinessProbe | nindent 12 }}
|
||||
livenessProbe:
|
||||
{{- toYaml .Values.livenessProbe | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/proxy/{{ .Values.config.existingConfigMapKey }}
|
||||
subPath: {{ .Values.config.existingConfigMapKey }}
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: {{ .Values.persistence.mountPath }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: {{ include "proxy.configMapName" . }}
|
||||
items:
|
||||
- key: {{ required "config.existingConfigMapKey is required" .Values.config.existingConfigMapKey }}
|
||||
path: {{ .Values.config.existingConfigMapKey }}
|
||||
- name: data
|
||||
{{- if .Values.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "proxy.claimName" . }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
36
deploy/charts/proxy/templates/ingress.yaml
Normal file
36
deploy/charts/proxy/templates/ingress.yaml
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{{- if .Values.ingress.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ include "proxy.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "proxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with .Values.ingress.className }}
|
||||
ingressClassName: {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- with .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path | quote }}
|
||||
pathType: {{ .pathType }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ include "proxy.fullname" $ }}
|
||||
port:
|
||||
number: {{ $.Values.service.port }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
22
deploy/charts/proxy/templates/pvc.yaml
Normal file
22
deploy/charts/proxy/templates/pvc.yaml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: {{ include "proxy.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "proxy.labels" . | nindent 4 }}
|
||||
{{- with .Values.persistence.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- toYaml .Values.persistence.accessModes | nindent 4 }}
|
||||
{{- with .Values.persistence.storageClass }}
|
||||
storageClassName: {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.persistence.size }}
|
||||
{{- end }}
|
||||
16
deploy/charts/proxy/templates/service.yaml
Normal file
16
deploy/charts/proxy/templates/service.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "proxy.fullname" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "proxy.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
selector:
|
||||
{{- include "proxy.selectorLabels" . | nindent 4 }}
|
||||
133
deploy/charts/proxy/values.yaml
Normal file
133
deploy/charts/proxy/values.yaml
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
replicaCount: 1
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
image:
|
||||
repository: ghcr.io/git-pkgs/proxy
|
||||
# An empty tag uses the chart appVersion.
|
||||
tag: ""
|
||||
# When set, digest takes precedence over tag.
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
# Keep this aligned with config.data.listen (or the listen address in an
|
||||
# existing ConfigMap).
|
||||
containerPort: 8080
|
||||
|
||||
# The generated configuration is ignored when existingConfigMap is set.
|
||||
config:
|
||||
existingConfigMap: ""
|
||||
existingConfigMapKey: config.yaml
|
||||
data:
|
||||
listen: ":8080"
|
||||
# Set this to the URL package-manager clients use to reach the proxy.
|
||||
base_url: "http://localhost:8080"
|
||||
storage:
|
||||
url: "file:///data/artifacts"
|
||||
database:
|
||||
driver: sqlite
|
||||
path: "/data/proxy.db"
|
||||
log:
|
||||
level: info
|
||||
format: json
|
||||
|
||||
# Environment variables override values from the configuration file. This is
|
||||
# also the recommended way to supply secret values such as database passwords
|
||||
# and object-storage credentials.
|
||||
extraEnv: []
|
||||
# - name: PROXY_DATABASE_URL
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: proxy-database
|
||||
# key: url
|
||||
|
||||
extraEnvFrom: []
|
||||
# - secretRef:
|
||||
# name: proxy-object-storage
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
mountPath: /data
|
||||
existingClaim: ""
|
||||
annotations: {}
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
size: 10Gi
|
||||
storageClass: ""
|
||||
|
||||
deploymentStrategy:
|
||||
type: Recreate
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
hosts: []
|
||||
# - host: proxy.example.com
|
||||
# paths:
|
||||
# - path: /
|
||||
# pathType: Prefix
|
||||
tls: []
|
||||
# - secretName: proxy-tls
|
||||
# hosts:
|
||||
# - proxy.example.com
|
||||
|
||||
podAnnotations: {}
|
||||
podLabels: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
runAsGroup: 1000
|
||||
fsGroup: 1000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
containerSecurityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
|
||||
resources: {}
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# limits:
|
||||
# memory: 512Mi
|
||||
|
||||
startupProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 2
|
||||
|
||||
# /health checks both the database and storage backends and can take up to ten
|
||||
# seconds. It is intentionally a readiness check rather than a liveness check.
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: http
|
||||
timeoutSeconds: 11
|
||||
periodSeconds: 15
|
||||
failureThreshold: 2
|
||||
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
periodSeconds: 20
|
||||
failureThreshold: 3
|
||||
|
||||
terminationGracePeriodSeconds: 30
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
Loading…
Reference in a new issue