ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c
17 changed files with 145336 additions and 0 deletions

View file

@ -0,0 +1,271 @@
static_resources:
listeners:
- name: forge-code
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: forge_code
normalize_path: true
merge_slashes: true
path_with_escaped_slashes_action: REJECT_REQUEST
use_remote_address: true
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
log_format:
text_format_source:
inline_string: "%START_TIME% %REQ(:METHOD)% %RESPONSE_CODE% %RESPONSE_CODE_DETAILS%\n"
route_config:
name: forge-code
request_headers_to_remove:
- authorization
- cookie
- proxy-authorization
- signature
- x-ssh-certificate
- x-webauth-email
- x-webauth-fullname
- x-webauth-user
response_headers_to_remove:
- set-cookie
- www-authenticate
- proxy-authenticate
virtual_hosts:
- name: forge-code
domains:
- "*"
routes:
- match:
path: /user/login
headers:
- name: :method
string_match:
safe_regex:
regex: "GET|HEAD"
direct_response:
status: 303
response_headers_to_add:
- header:
key: location
value: /login-disabled
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: cache-control
value: no-store
append_action: OVERWRITE_IF_EXISTS_OR_ADD
typed_per_filter_config:
envoy.filters.http.rbac:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
- match:
path: /login-disabled
headers:
- name: :method
string_match:
safe_regex:
regex: "GET|HEAD"
direct_response:
status: 200
body:
filename: /etc/envoy/login-disabled.html
response_headers_to_add:
- header:
key: content-type
value: text/html; charset=utf-8
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: cache-control
value: no-store
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: referrer-policy
value: no-referrer
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: x-content-type-options
value: nosniff
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: content-security-policy
value: "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'self'; frame-ancestors 'none'"
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- match:
path: /robots.txt
headers:
- name: :method
string_match:
safe_regex:
regex: "GET|HEAD"
direct_response:
status: 200
body:
filename: /etc/envoy/robots.txt
response_headers_to_add:
- header:
key: content-type
value: text/plain; charset=utf-8
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: cache-control
value: public, max-age=3600
append_action: OVERWRITE_IF_EXISTS_OR_ADD
- header:
key: x-content-type-options
value: nosniff
append_action: OVERWRITE_IF_EXISTS_OR_ADD
typed_per_filter_config:
envoy.filters.http.rbac:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
- match:
prefix: /assets/
route:
cluster: forge-code
timeout: 0s
- match:
prefix: /
route:
cluster: forge-code
timeout: 0s
response_headers_to_add:
- header:
key: vary
value: Accept, Accept-Language
append_action: APPEND_IF_EXISTS_OR_ADD
http_filters:
- name: envoy.filters.http.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: DENY
policies:
authentication-paths:
permissions:
- header:
name: :path
string_match:
safe_regex:
regex: '^/(user|login/oauth|admin|notifications)([/?].*)?$'
principals:
- any: true
authenticated-global-pages:
permissions:
- header:
name: :path
string_match:
safe_regex:
regex: '^/(repo|issues|pulls|milestones|report_abuse)([/?].*)?$'
principals:
- any: true
authenticated-organization-pages:
permissions:
- or_rules:
rules:
- header:
name: :path
string_match:
safe_regex:
regex: '^/org/(create|invite)([/?].*)?$'
- header:
name: :path
string_match:
safe_regex:
regex: '^/org/[^/?]+/(dashboard|issues|pulls|milestones|teams|settings)([/?].*)?$'
principals:
- any: true
authenticated-repository-pages:
permissions:
- or_rules:
rules:
- header:
name: :path
string_match:
safe_regex:
regex: '^/[^/?]+/[^/?]+/(settings|action|fork)([/?].*)?$'
- header:
name: :path
string_match:
safe_regex:
regex: '^/[^/?]+/[^/?]+/(_edit|_new|_delete|_upload|_diffpatch|_cherrypick)([/?].*)?$'
- header:
name: :path
string_match:
safe_regex:
regex: '^/[^/?]+/[^/?]+/releases/(new|edit)([/?].*)?$'
principals:
- any: true
receive-pack:
permissions:
- header:
name: :path
string_match:
safe_regex:
regex: ".*(git-receive-pack|service=git-receive-pack).*"
principals:
- any: true
query-credentials:
permissions:
- header:
name: :path
string_match:
safe_regex:
regex: ".*[?&](token|access_token)=[^&]*.*"
principals:
- any: true
authenticated-methods:
permissions:
- header:
name: :method
string_match:
safe_regex:
regex: "PUT|PATCH|DELETE"
principals:
- any: true
authenticated-posts:
permissions:
- and_rules:
rules:
- header:
name: :method
string_match:
exact: POST
- not_rule:
header:
name: :path
string_match:
safe_regex:
regex: '^/[^/?]+/[^/?]+/(git-upload-pack|lastcommit/.*|archive/.*)([?].*)?$'
principals:
- any: true
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: forge-code
type: STRICT_DNS
load_assignment:
cluster_name: forge-code
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: forge-code-http.forgejo-public.svc.cluster.local.
port_value: 3000
overload_manager:
refresh_interval: 0.25s
resource_monitors:
- name: envoy.resource_monitors.global_downstream_max_connections
typed_config:
"@type": type.googleapis.com/envoy.extensions.resource_monitors.downstream_connections.v3.DownstreamConnectionsConfig
max_active_downstream_connections: 1024
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9901

View file

@ -0,0 +1,93 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="refresh" content="5;url=/explore">
<title>Sign in is disabled</title>
<style>
:root {
color-scheme: light dark;
--body: #fff;
--panel: #fafafa;
--border: #e4e4e7;
--text: #18181b;
--muted: #3f3f46;
--button: #e4e4e7;
--button-hover: #d4d4d8;
--button-text: #18181b;
--focus: #fdba74;
}
@media (prefers-color-scheme: dark) {
:root {
--body: #171e26;
--panel: #1d262f;
--border: #242d38;
--text: #d2e0f0;
--muted: #c0cfe0;
--button: #242d38;
--button-hover: #2b3642;
--button-text: #d2e0f0;
--focus: #fed7aa;
}
}
* { box-sizing: border-box; }
body {
min-height: 100vh;
min-height: 100svh;
margin: 0;
display: grid;
place-items: center;
padding: 1rem;
color: var(--text);
background: var(--body);
font: 14px/1.45 "Liberation Sans", Arial, sans-serif;
}
main {
width: min(28rem, 100%);
padding: 2rem;
text-align: center;
background: var(--panel);
border: 1px solid var(--border);
border-radius: .4rem;
box-shadow: 0 .25rem .75rem rgb(0 0 0 / 8%);
}
svg { width: 3rem; height: 3rem; margin-bottom: .75rem; }
h1 { margin: 0 0 .75rem; font-size: 1.5rem; line-height: 1.25; }
p { margin: .4rem 0; color: var(--muted); }
form { margin-top: 1.5rem; }
button {
width: 100%;
padding: .7rem 1rem;
color: var(--button-text);
background: var(--button);
border: 1px solid transparent;
border-radius: .28571429rem;
font: inherit;
font-weight: 600;
cursor: pointer;
}
button:hover { background: var(--button-hover); }
button:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
</style>
</head>
<body>
<main>
<svg viewBox="0 0 212 212" role="img" aria-label="Forgejo">
<g transform="translate(6 6)" fill="none">
<path d="M58 168V70a50 50 0 0 1 50-50h20" stroke="#f60" stroke-width="25"/>
<path d="M58 168v-30a50 50 0 0 1 50-50h20" stroke="#d40000" stroke-width="25"/>
<circle cx="142" cy="20" r="18" stroke="#f60" stroke-width="15"/>
<circle cx="142" cy="88" r="18" stroke="#d40000" stroke-width="15"/>
<circle cx="58" cy="180" r="18" stroke="#d40000" stroke-width="15"/>
</g>
</svg>
<h1>Sign in is disabled</h1>
<p>This public view does not accept sign-ins.</p>
<p>Returning to Explore in five seconds.</p>
<form action="/explore" method="get">
<button type="submit">Go back now</button>
</form>
</main>
</body>
</html>

View file

@ -0,0 +1,66 @@
# code.quorate.dev anonymous root.
# Source, blame, commits, raw files, and public API reads stay crawlable.
# Archives, attachments, and query variants stay disallowed.
# Upstream default: https://forgejo.org/docs/latest/admin/search-engines-indexation/
User-agent: *
Disallow: /avatars/
Disallow: /user/
Disallow: /login-disabled
Disallow: /swagger.*.json
Disallow: /explore/*?*
Disallow: /repo/create
Disallow: /repo/migrate
Disallow: /org/create
Disallow: /*/*/fork
Disallow: /*/*/watchers
Disallow: /*/*/stargazers
Disallow: /*/*/forks
Disallow: /*/*/tags
Disallow: /*/*/graph
Disallow: /*/*/branches
Disallow: /*/*/compare
Disallow: /*/*/lastcommit/
Disallow: /*/*/rss/branch/
Disallow: /*/*/atom/branch/
Disallow: /*/*/activity
Disallow: /*/*/activity_author_data
Disallow: /*/*/actions
Disallow: /*/*/projects
Disallow: /*/*/labels
Disallow: /*/*/milestones
Disallow: /*/*/find/
Disallow: /*/*/tree-list/
Disallow: /*/*/search/
Disallow: /*/-/code
Disallow: /*/*/issues/new
Disallow: /*/*/pulls/*/files
Disallow: /*/*/pulls/*/commits
Disallow: /attachments/
Disallow: /*/*/attachments/
Disallow: /*/*/issues/*/attachments/
Disallow: /*/*/pulls/*/attachments/
Disallow: /*/*/releases/attachments
Disallow: /*/*/releases/download
Disallow: /*/*/archive/
Disallow: /*.bundle$
Disallow: /*.patch$
Disallow: /*.diff$
Disallow: /*.atom$
Disallow: /*.rss$
Disallow: /*lang=*
Disallow: /*redirect_to=*
Disallow: /*tab=*
Disallow: /*q=*
Disallow: /*sort=*
Disallow: /*repo-search-archived=*

View file

@ -0,0 +1,140 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: forge-code-facade
namespace: forgejo-public
automountServiceAccountToken: false
---
apiVersion: v1
kind: Service
metadata:
name: forge-code-facade
namespace: forgejo-public
labels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
app.kubernetes.io/component: forge-code
spec:
selector:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
ports:
- name: http
port: 8080
targetPort: http
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: forge-code-facade
namespace: forgejo-public
labels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
app.kubernetes.io/component: forge-code
spec:
replicas: 2
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
selector:
matchLabels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
template:
metadata:
labels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
app.kubernetes.io/component: forge-code
spec:
runtimeClassName: gvisor
serviceAccountName: forge-code-facade
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
seccompProfile:
type: RuntimeDefault
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
containers:
- name: envoy
image: envoyproxy/envoy:v1.40.2@sha256:8de97e654644827d62afdbf7e1d3dc9fee01a8690d410dd1c63a30dc6b6cecbb
imagePullPolicy: IfNotPresent
args:
- -c
- /etc/envoy/envoy.yaml
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: admin
containerPort: 9901
protocol: TCP
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
startupProbe:
httpGet:
path: /ready
port: admin
failureThreshold: 30
periodSeconds: 2
readinessProbe:
httpGet:
path: /ready
port: admin
periodSeconds: 5
livenessProbe:
httpGet:
path: /ready
port: admin
failureThreshold: 3
periodSeconds: 10
volumeMounts:
- name: config
mountPath: /etc/envoy
readOnly: true
- name: tmp
mountPath: /tmp
volumes:
- name: config
configMap:
name: forge-code-facade-config
- name: tmp
emptyDir: {}
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: forge-code-facade
namespace: forgejo-public
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade

View file

@ -0,0 +1,331 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: forgejo-public-common-values
namespace: forgejo-public
data:
values.yaml: |
replicaCount: 2
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
image:
registry: code.forgejo.org
repository: forgejo/forgejo
tag: 17.0.1
digest: sha256:5ef02fbcf22beef56b8c844952ffad58cfe177b6f98e46e6abb5df90b88dc8d3
pullPolicy: IfNotPresent
rootless: true
initPreScript: |
mkdir -p /data/gitea/log
chmod ug+rwx /data/gitea/log
serviceAccount:
create: false
name: forgejo-public
automountServiceAccountToken: false
podSecurityContext:
fsGroup: 1000
containerSecurityContext:
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
capabilities:
drop:
- ALL
add:
- SYS_CHROOT
deployment:
env:
- name: SSL_CERT_DIR
value: /usr/local/share/ca-certificates
extraVolumes:
- name: internal-ca
secret:
secretName: forgejo-public-internal-ca
- name: private-config
emptyDir: {}
extraContainerVolumeMounts:
- name: internal-ca
mountPath: /usr/local/share/ca-certificates
readOnly: true
- name: private-config
mountPath: /data/gitea/conf
extraInitVolumeMounts:
- name: private-config
mountPath: /data/gitea/conf
service:
http:
type: ClusterIP
port: 3000
ssh:
type: ClusterIP
port: 22
persistence:
enabled: true
create: false
claimName: forgejo-public-shared-storage-rwx
size: 20Gi
accessModes:
- ReadWriteMany
storageClass: longhorn-rwx
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
memory: 2Gi
gitea:
admin:
existingSecret: ""
username: ""
additionalConfigSources:
- secret:
secretName: forgejo-public-secrets
additionalConfigFromEnvs:
- name: FORGEJO__DATABASE__PASSWD
valueFrom:
secretKeyRef:
name: forgejo-public-db
key: password
config:
APP_NAME: "Quorate Git"
log:
LEVEL: info
LOGGER_ROUTER_MODE: console
ROOT_PATH: /data/gitea/log
server:
PROTOCOL: http
HTTP_PORT: 3000
LANDING_PAGE: explore
OFFLINE_MODE: true
DISABLE_SSH: true
START_SSH_SERVER: false
SSH_EXPOSE_ANONYMOUS: false
LFS_START_SERVER: false
database:
DB_TYPE: postgres
HOST: main-rw.postgres.svc.cluster.local:5432
NAME: forgejo_public
USER: forgejo_public
SSL_MODE: require
security:
INSTALL_LOCK: true
DISABLE_QUERY_AUTH_TOKEN: true
DISABLE_GIT_HOOKS: true
DISABLE_WEBHOOKS: true
REVERSE_PROXY_LIMIT: 0
service:
DISABLE_REGISTRATION: false
ALLOW_ONLY_EXTERNAL_REGISTRATION: true
SHOW_REGISTRATION_BUTTON: false
REQUIRE_SIGNIN_VIEW: false
ENABLE_INTERNAL_SIGNIN: false
ENABLE_BASIC_AUTHENTICATION: false
ENABLE_REVERSE_PROXY_AUTHENTICATION: false
ENABLE_REVERSE_PROXY_AUTHENTICATION_API: false
DEFAULT_KEEP_EMAIL_PRIVATE: true
DEFAULT_ALLOW_CREATE_ORGANIZATION: false
DEFAULT_USER_IS_RESTRICTED: true
ENABLE_USER_HEATMAP: false
AUTO_WATCH_NEW_REPOS: false
service.explore:
REQUIRE_SIGNIN_VIEW: false
DISABLE_USERS_PAGE: true
DISABLE_ORGANIZATIONS_PAGE: false
DISABLE_CODE_PAGE: true
admin:
DEFAULT_EMAIL_NOTIFICATIONS: disabled
DISABLE_REGULAR_ORG_CREATION: true
EXTERNAL_USER_DISABLE_FEATURES: deletion,manage_ssh_keys,manage_password
repository:
ROOT: /data/git/repositories
DEFAULT_PRIVATE: public
DEFAULT_PUSH_CREATE_PRIVATE: false
MAX_CREATION_LIMIT: 0
DISABLE_HTTP_GIT: false
ENABLE_PUSH_CREATE_USER: false
ENABLE_PUSH_CREATE_ORG: false
DISABLED_REPO_UNITS: repo.issues,repo.pulls,repo.wiki,repo.projects,repo.packages,repo.actions,repo.ext_issues,repo.ext_wiki
DEFAULT_REPO_UNITS: repo.code,repo.releases
DISABLE_MIGRATIONS: true
DISABLE_STARS: true
DISABLE_FORKS: true
DISABLE_DOWNLOAD_SOURCE_ARCHIVES: false
DEFAULT_BRANCH: main
repository.upload:
ENABLED: false
indexer:
ISSUE_INDEXER_TYPE: db
REPO_INDEXER_ENABLED: false
git.timeout:
GREP: 2
openid:
ENABLE_OPENID_SIGNIN: false
ENABLE_OPENID_SIGNUP: false
api:
ENABLE_SWAGGER: false
MAX_RESPONSE_ITEMS: 50
DEFAULT_PAGING_NUM: 30
DEFAULT_MAX_BLOB_SIZE: 10485760
packages:
ENABLED: false
federation:
ENABLED: false
camo:
ENABLED: false
mirror:
ENABLED: false
actions:
ENABLED: false
cron:
ENABLED: false
mailer:
ENABLED: false
email.incoming:
ENABLED: false
metrics:
ENABLED: false
other:
SHOW_FOOTER_VERSION: false
SHOW_FOOTER_TEMPLATE_LOAD_TIME: false
ENABLE_SITEMAP: true
ENABLE_FEED: true
test:
enabled: false
---
apiVersion: v1
kind: ConfigMap
metadata:
name: forge-code-values
namespace: forgejo-public
data:
values.yaml: |
fullnameOverride: forge-code
extraVolumes:
- name: internal-ca
secret:
secretName: forgejo-public-internal-ca
- name: private-config
emptyDir: {}
- name: theme
configMap:
name: forge-code-theme
extraContainerVolumeMounts:
- name: internal-ca
mountPath: /usr/local/share/ca-certificates
readOnly: true
- name: private-config
mountPath: /data/gitea/conf
- name: theme
mountPath: /data/gitea/public/assets/css
readOnly: true
service:
http:
labels:
health.quorate.dev/name: Code
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-code
gitea:
additionalConfigSources:
- secret:
secretName: forgejo-public-secrets
- secret:
secretName: forge-code-session
config:
ui:
DEFAULT_THEME: quorate
THEMES: quorate,forgejo-auto
oauth2:
ENABLED: false
server:
DOMAIN: code.quorate.dev
ROOT_URL: https://code.quorate.dev/
session:
COOKIE_SECURE: true
COOKIE_NAME: forge_code_session
DOMAIN: ""
SAME_SITE: lax
---
apiVersion: v1
kind: ConfigMap
metadata:
name: forge-git-values
namespace: forgejo-public
data:
values.yaml: |
fullnameOverride: forge-git
service:
http:
labels:
health.quorate.dev/name: Git
ssh:
type: LoadBalancer
port: 22
externalTrafficPolicy: Local
annotations:
lbipam.cilium.io/ips: "10.47.201.154"
labels:
io.cilium/bgp-announce: "true"
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-git
gitea:
oauth:
- name: Zitadel
provider: openidConnect
existingSecret: forge-git-oidc-zitadel
autoDiscoverUrl: https://auth.quorate.dev/.well-known/openid-configuration
scopes: "openid profile email groups"
requiredClaimName: "groups"
requiredClaimValue: "forgejo_login"
groupClaimName: "groups"
adminGroup: "forgejo_admin"
restrictedGroup: "forgejo_restricted"
additionalConfigSources:
- secret:
secretName: forgejo-public-secrets
- secret:
secretName: forge-git-session
config:
server:
DOMAIN: git.quorate.dev
ROOT_URL: https://git.quorate.dev/
DISABLE_SSH: false
START_SSH_SERVER: true
SSH_DOMAIN: git-ssh.quorate.internal
SSH_PORT: 22
SSH_LISTEN_PORT: 2222
admin:
EXTERNAL_USER_DISABLE_FEATURES: deletion,manage_password
oauth2_client:
OPENID_CONNECT_SCOPES: "openid profile email groups"
ENABLE_AUTO_REGISTRATION: true
USERNAME: nickname
ACCOUNT_LINKING: disabled
UPDATE_AVATAR: false
GROUP_CLAIM_NAME: groups
ADMIN_GROUP: forgejo_admin
ENABLE_OIDC_GROUP_CLAIM: true
RE_MANAGE_GROUPS_ON_SIGNIN: true
FETCH_USER_INFO_FROM_USERINFO_ENDPOINT: true
session:
COOKIE_SECURE: true
COOKIE_NAME: forge_git_session
DOMAIN: ""
SAME_SITE: lax

View file

@ -0,0 +1,27 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- pvc-rwx.yaml
- vso.yaml
- helm-values.yaml
- releases/code
- releases/git
- poddisruptionbudget.yaml
- facade-code.yaml
- network-policies.yaml
- route-git.yaml
configMapGenerator:
- name: forge-code-theme
namespace: forgejo-public
files:
- theme-quorate.css
options:
disableNameSuffixHash: true
- name: forge-code-facade-config
namespace: forgejo-public
files:
- envoy.yaml=facade-code-config.yaml
- login-disabled.html=facade-code-login-disabled.html
- robots.txt=facade-code-robots.txt

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: Namespace
metadata:
name: forgejo-public
labels:
gateway.quorate.internal/allow-public: "true"
security.quorate.internal/public-runtime: gvisor
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: forgejo-public
namespace: forgejo-public

View file

@ -0,0 +1,313 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: forge-code
namespace: forgejo-public
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-code
ingress:
- fromEntities:
- host
toPorts:
- ports:
- port: "3000"
protocol: TCP
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: forgejo-public
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
toPorts:
- ports:
- port: "3000"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: forge-git
namespace: forgejo-public
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-git
ingress:
- fromEntities:
- host
- ingress
toPorts:
- ports:
- port: "3000"
protocol: TCP
- port: "2222"
protocol: TCP
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
gateway.networking.k8s.io/gateway-name: gateway-relay
toPorts:
- ports:
- port: "3000"
protocol: TCP
- fromCIDR:
- 10.115.187.218/24
- 10.63.81.107/24
- 10.162.8.60/24
toPorts:
- ports:
- port: "2222"
protocol: TCP
egress:
- toEntities:
- world
toPorts:
- serverNames:
- auth.quorate.dev
ports:
- port: "443"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: forgejo-public-shared-egress
namespace: forgejo-public
spec:
endpointSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- forgejo
- key: app.kubernetes.io/instance
operator: In
values:
- forge-code
- forge-git
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: postgres
cnpg.io/cluster: main
toPorts:
- ports:
- port: "5432"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: dragonfly
app.kubernetes.io/name: dragonfly
app: forgejo-public
toPorts:
- ports:
- port: "6379"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: versitygw
app.kubernetes.io/name: versitygw
app.kubernetes.io/instance: versitygw
toPorts:
- ports:
- port: "7070"
protocol: TCP
- toCIDR:
- 10.66.127.81/32
toPorts:
- ports:
- port: "443"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: forge-code-facade
namespace: forgejo-public
spec:
endpointSelector:
matchLabels:
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
ingress:
- fromEntities:
- host
toPorts:
- ports:
- port: "8080"
protocol: TCP
- port: "9901"
protocol: TCP
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: cloudflare-tunnel
app.kubernetes.io/name: cloudflared
app.kubernetes.io/instance: cloudflare-tunnel
toPorts:
- ports:
- port: "8080"
protocol: TCP
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: forgejo-public
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-code
toPorts:
- ports:
- port: "3000"
protocol: TCP
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: kube-system
k8s-app: kube-dns
toPorts:
- ports:
- port: "53"
protocol: UDP
- port: "53"
protocol: TCP
rules:
dns:
- matchName: forge-code-http.forgejo-public.svc.cluster.local
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: gateway-relay-egress-forge-git
spec:
endpointSelector:
matchLabels:
"reserved:ingress": ""
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: forgejo-public
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-git
toPorts:
- ports:
- port: "3000"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-egress-forgejo-public
spec:
nodeSelector: {}
egress:
- toEndpoints:
- matchExpressions:
- key: k8s:io.kubernetes.pod.namespace
operator: In
values:
- forgejo-public
- key: app.kubernetes.io/name
operator: In
values:
- forgejo
- key: app.kubernetes.io/instance
operator: In
values:
- forge-code
- forge-git
toPorts:
- ports:
- port: "3000"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-egress-forge-code-facade
spec:
nodeSelector: {}
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: forgejo-public
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
toPorts:
- ports:
- port: "8080"
protocol: TCP
- port: "9901"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-egress-forge-git-ssh
spec:
nodeSelector: {}
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: forgejo-public
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-git
toPorts:
- ports:
- port: "2222"
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-ingress-forgejo-public-replies
spec:
nodeSelector: {}
ingress:
- fromEndpoints:
- matchExpressions:
- key: k8s:io.kubernetes.pod.namespace
operator: In
values:
- forgejo-public
- key: app.kubernetes.io/name
operator: In
values:
- forgejo
- key: app.kubernetes.io/instance
operator: In
values:
- forge-code
- forge-git
toPorts:
- ports:
- port: "32768"
endPort: 60999
protocol: TCP
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
name: host-ingress-forge-code-facade-replies
spec:
nodeSelector: {}
ingress:
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: forgejo-public
app.kubernetes.io/name: envoy
app.kubernetes.io/instance: forge-code-facade
toPorts:
- ports:
- port: "32768"
endPort: 60999
protocol: TCP

View file

@ -0,0 +1,23 @@
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: forge-code
namespace: forgejo-public
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-code
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: forge-git
namespace: forgejo-public
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: forgejo
app.kubernetes.io/instance: forge-git

View file

@ -0,0 +1,13 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: forgejo-public-shared-storage-rwx
namespace: forgejo-public
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn-rwx
volumeMode: Filesystem
resources:
requests:
storage: 20Gi

View file

@ -0,0 +1,39 @@
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: forge
namespace: forgejo-public
spec:
interval: 15m
releaseName: forge
targetNamespace: forgejo-public
chart:
spec:
chart: forgejo
version: 17.3.2
sourceRef:
kind: HelmRepository
name: forgejo
namespace: flux-system
install:
remediation:
retries: 3
upgrade:
remediation:
retries: 3
postRenderers:
- kustomize:
patches:
- target:
kind: Deployment
patch: |-
- op: add
path: /spec/template/spec/runtimeClassName
value: gvisor
- op: add
path: /spec/minReadySeconds
value: 5
valuesFrom:
- kind: ConfigMap
name: forgejo-public-common-values
valuesKey: values.yaml

View file

@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- helm-release.yaml

View file

@ -0,0 +1,18 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
nameSuffix: -code
patches:
- target:
kind: HelmRelease
patch: |-
- op: replace
path: /spec/releaseName
value: forge-code
- op: add
path: /spec/valuesFrom/-
value:
kind: ConfigMap
name: forge-code-values
valuesKey: values.yaml

View file

@ -0,0 +1,33 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../base
nameSuffix: -git
patches:
- target:
kind: HelmRelease
patch: |-
- op: replace
path: /spec/releaseName
value: forge-git
- op: add
path: /spec/postRenderers/-
value:
kustomize:
patches:
- target:
kind: Deployment
name: forge-git
patch: |-
- op: add
path: /spec/template/metadata/labels/gateway.quorate.internal~1allow-gateway-client
value: "true"
- op: add
path: /spec/template/metadata/labels/quorate.dev~1zitadel-relay
value: "true"
- op: add
path: /spec/valuesFrom/-
value:
kind: ConfigMap
name: forge-git-values
valuesKey: values.yaml

View file

@ -0,0 +1,40 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: forge-git
namespace: forgejo-public
spec:
parentRefs:
- name: gateway-relay
namespace: kube-system
sectionName: https
hostnames:
- git.quorate.dev
rules:
- matches:
- path:
type: Exact
value: /robots.txt
filters:
- type: RequestRedirect
requestRedirect:
hostname: quorate.dev
port: 443
statusCode: 301
path:
type: ReplaceFullPath
replaceFullPath: /robots-deny.txt
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: X-Robots-Tag
value: noindex
- filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
set:
- name: X-Robots-Tag
value: noindex
backendRefs:
- name: forge-git-http
port: 3000

View file

@ -0,0 +1,251 @@
@import url("./theme-forgejo-auto.css");
@font-face {
font-family: "Comic Neue";
src: url("https://quorate.dev/fonts/neue.ttf") format("truetype");
font-weight: 400;
font-display: swap;
}
@font-face {
font-family: "Comic Neue";
src: url("https://quorate.dev/fonts/neue-bold.ttf") format("truetype");
font-weight: 700;
font-display: swap;
}
@font-face {
font-family: "Comic Mono";
src: url("https://quorate.dev/fonts/comic.ttf") format("truetype");
font-display: swap;
}
:root {
--paper: #eeeeee;
--surface: #f4f4f4;
--ink: #292828;
--muted: #57514a;
--rule: #8d8d8d;
--band: #e2e2e2;
--hover: #d6d6d6;
--link: #7b392c;
--good: #3f672c;
--mixed: #7a521c;
--down: #a8352b;
--fonts-proportional: "Comic Neue", sans-serif;
--fonts-monospace: "Comic Mono", monospace;
--border-radius: 0;
--border-radius-medium: 0;
--border-radius-circle: 0;
}
@media (prefers-color-scheme: dark) {
:root {
--paper: #181818;
--surface: #1a1a1a;
--ink: #f3eee5;
--muted: #c0b9b0;
--rule: #626262;
--band: #202020;
--hover: #282828;
--link: #efb99b;
--good: #afd49a;
--mixed: #e5c080;
--down: #f2ab99;
}
}
:root {
--color-primary: var(--link);
--color-primary-contrast: var(--paper);
--color-primary-dark-1: var(--link);
--color-primary-dark-2: var(--ink);
--color-primary-dark-3: var(--ink);
--color-primary-dark-4: var(--ink);
--color-primary-dark-5: var(--ink);
--color-primary-dark-6: var(--ink);
--color-primary-dark-7: var(--ink);
--color-primary-light-1: var(--link);
--color-primary-light-2: var(--link);
--color-primary-light-3: var(--muted);
--color-primary-light-4: var(--muted);
--color-primary-light-5: var(--band);
--color-primary-light-6: var(--band);
--color-primary-light-7: var(--paper);
--color-primary-hover: var(--ink);
--color-primary-active: var(--ink);
--color-primary-alpha-20: color-mix(in srgb, var(--rule) 20%, transparent);
--color-primary-alpha-40: color-mix(in srgb, var(--rule) 40%, transparent);
--color-primary-alpha-50: color-mix(in srgb, var(--rule) 50%, transparent);
--color-secondary: var(--band);
--color-secondary-hover: var(--band);
--color-secondary-active: var(--band);
--color-secondary-alpha-30: color-mix(in srgb, var(--rule) 30%, transparent);
--color-body: var(--paper);
--color-box-header: var(--band);
--color-box-body: var(--surface);
--color-box-body-highlight: var(--band);
--color-highlight-bg: var(--band);
--color-text-dark: var(--ink);
--color-text: var(--ink);
--color-text-light: var(--muted);
--color-text-light-1: var(--muted);
--color-text-light-2: var(--muted);
--color-text-light-3: var(--muted);
--color-footer: var(--paper);
--color-timeline: var(--rule);
--color-input-text: var(--ink);
--color-input-background: var(--surface);
--color-input-toggle-background: var(--surface);
--color-input-border: var(--rule);
--color-input-border-hover: var(--muted);
--color-header-wrapper: var(--paper);
--color-hover: var(--hover);
--color-active: var(--hover);
--color-menu: var(--surface);
--color-card: var(--surface);
--fancy-card-bg: var(--surface);
--fancy-card-border: var(--rule);
--color-markup-code-block: var(--surface);
--color-markup-code-inline: var(--band);
--color-button: var(--paper);
--color-label-text: var(--ink);
--color-label-bg: var(--band);
--color-label-hover-bg: var(--hover);
--color-label-active-bg: var(--hover);
--color-label-bg-alt: var(--band);
--color-light-border: var(--rule);
--color-code-bg: var(--paper);
--color-shadow: transparent;
--color-secondary-bg: var(--band);
--color-expand-button: var(--band);
--color-placeholder-text: var(--muted);
--color-editor-line-highlight: var(--band);
--color-nav-bg: var(--paper);
--color-nav-hover-bg: var(--hover);
--color-secondary-nav-bg: var(--paper);
--color-accent: var(--link);
--color-small-accent: var(--band);
}
.diff-detail-stats {
--color-green: var(--good);
--color-yellow: var(--mixed);
--color-red: var(--down);
}
.ui.disabled.labeled.button {
opacity: 1 !important;
}
@media (prefers-color-scheme: light) {
.chroma :is(.k, .kc, .kd, .kn, .kp, .kr, .na, .o, .ow) {
color: #9d2638;
}
}
@media (prefers-color-scheme: dark) {
.chroma :is(.s, .s1, .s2, .sb, .sd, .sh, .sx) {
color: #e4d58a;
}
}
body {
font-size: 16px;
line-height: 1.5;
}
a {
text-underline-offset: 0.15em;
}
.ui.button,
.ui.input > input,
.ui.form input:not([type]),
.ui.form input[type="text"],
.ui.form input[type="search"],
.ui.dropdown,
.ui.menu,
.ui.segment,
.ui.segments,
.ui.table,
.ui.label,
.ui.message,
.ui.attached.header,
.ui.tabular.menu .item,
.ui.secondary.menu .item,
.ui.secondary.vertical.menu,
.ui.selection.dropdown,
.ui.dropdown .menu,
.markup code,
.markup pre {
border-radius: 0 !important;
box-shadow: none;
}
.ui.menu,
.ui.segment,
.ui.segments,
.ui.table,
.ui.attached.header {
border-color: var(--rule);
}
.ui.primary.button {
background: var(--ink);
color: var(--paper);
}
.ui.primary.button:hover,
.ui.primary.button:focus {
background: var(--link);
color: var(--paper);
}
.ui.secondary.pointing.menu .active.item {
border-color: var(--ink);
}
#navbar {
border-bottom: 1px solid var(--rule);
box-shadow: none;
}
#navbar .brand {
color: var(--ink);
}
footer {
border-top: 1px solid var(--rule);
}
.markup {
font-family: var(--fonts-proportional);
line-height: 1.65;
}
.markup a:not(.anchor) {
text-decoration: underline;
}
.markup h1,
.markup h2,
.markup h3 {
color: var(--ink);
border-color: var(--rule);
}
.markup blockquote {
color: var(--muted);
border-left: 2px solid var(--rule);
}
.markup table tr,
.markup table tr:nth-child(2n) {
background: var(--paper);
}
:focus-visible {
outline: 2px solid var(--ink);
outline-offset: 3px;
}

210
vendor/workloads/forgejo-public/vso.yaml vendored Normal file
View file

@ -0,0 +1,210 @@
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: default
namespace: forgejo-public
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: forgejo-public
serviceAccount: forgejo-public
vaultConnectionRef: vault/vault
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: forge-git-oidc-zitadel
namespace: forgejo-public
spec:
type: kv-v2
mount: secret
path: forgejo-public/oidc/zitadel
destination:
name: forge-git-oidc-zitadel
create: true
rolloutRestartTargets:
- kind: Deployment
name: forge-git
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultDynamicSecret
metadata:
name: forgejo-public-db
namespace: forgejo-public
spec:
mount: database
path: static-creds/forgejo-public
destination:
name: forgejo-public-db
create: true
rolloutRestartTargets:
- kind: Deployment
name: forge-code
- kind: Deployment
name: forge-git
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: forgejo-public-secrets
namespace: forgejo-public
spec:
type: kv-v2
mount: secret
path: forgejo-public/secrets
destination:
name: forgejo-public-secrets
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
cache:
text: |
ADAPTER=redis
HOST=redis://default:{{ get .Secrets "redis_password" }}@forgejo-public.dragonfly.svc.cluster.local:6379/0?pool_size=100&idle_timeout=180s
queue:
text: |
TYPE=redis
CONN_STR=redis://default:{{ get .Secrets "redis_password" }}@forgejo-public.dragonfly.svc.cluster.local:6379/2?pool_size=100&idle_timeout=180s
attachment:
text: |
STORAGE_TYPE=minio
MINIO_ENDPOINT=s3.quorate.internal
MINIO_ACCESS_KEY_ID=forgejo-public
MINIO_SECRET_ACCESS_KEY={{ get .Secrets "s3_secret_key" }}
MINIO_BUCKET=forgejo-public
MINIO_BUCKET_LOOKUP=path
MINIO_LOCATION=us-east-1
MINIO_USE_SSL=true
MINIO_INSECURE_SKIP_VERIFY=false
MINIO_BASE_PATH=attachments/
avatar:
text: |
STORAGE_TYPE=minio
MINIO_ENDPOINT=s3.quorate.internal
MINIO_ACCESS_KEY_ID=forgejo-public
MINIO_SECRET_ACCESS_KEY={{ get .Secrets "s3_secret_key" }}
MINIO_BUCKET=forgejo-public
MINIO_BUCKET_LOOKUP=path
MINIO_LOCATION=us-east-1
MINIO_USE_SSL=true
MINIO_INSECURE_SKIP_VERIFY=false
MINIO_BASE_PATH=avatars/
repo-avatar:
text: |
STORAGE_TYPE=minio
MINIO_ENDPOINT=s3.quorate.internal
MINIO_ACCESS_KEY_ID=forgejo-public
MINIO_SECRET_ACCESS_KEY={{ get .Secrets "s3_secret_key" }}
MINIO_BUCKET=forgejo-public
MINIO_BUCKET_LOOKUP=path
MINIO_LOCATION=us-east-1
MINIO_USE_SSL=true
MINIO_INSECURE_SKIP_VERIFY=false
MINIO_BASE_PATH=repo-avatars/
repo-archive:
text: |
STORAGE_TYPE=minio
MINIO_ENDPOINT=s3.quorate.internal
MINIO_ACCESS_KEY_ID=forgejo-public
MINIO_SECRET_ACCESS_KEY={{ get .Secrets "s3_secret_key" }}
MINIO_BUCKET=forgejo-public
MINIO_BUCKET_LOOKUP=path
MINIO_LOCATION=us-east-1
MINIO_USE_SSL=true
MINIO_INSECURE_SKIP_VERIFY=false
MINIO_BASE_PATH=repo-archives/
rolloutRestartTargets:
- kind: Deployment
name: forge-code
- kind: Deployment
name: forge-git
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: forge-code-session
namespace: forgejo-public
spec:
type: kv-v2
mount: secret
path: forgejo-public/secrets
destination:
name: forge-code-session
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
session:
text: |
PROVIDER=redis
PROVIDER_CONFIG=redis://default:{{ get .Secrets "redis_password" }}@forgejo-public.dragonfly.svc.cluster.local:6379/1?pool_size=100&idle_timeout=180s&prefix=forge-code:
rolloutRestartTargets:
- kind: Deployment
name: forge-code
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: forge-git-session
namespace: forgejo-public
spec:
type: kv-v2
mount: secret
path: forgejo-public/secrets
destination:
name: forge-git-session
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
session:
text: |
PROVIDER=redis
PROVIDER_CONFIG=redis://default:{{ get .Secrets "redis_password" }}@forgejo-public.dragonfly.svc.cluster.local:6379/1?pool_size=100&idle_timeout=180s&prefix=forge-git:
rolloutRestartTargets:
- kind: Deployment
name: forge-git
vaultAuthRef: default
---
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: forgejo-public-internal-ca
namespace: forgejo-public
spec:
type: kv-v2
mount: secret
path: forgejo-public/secrets
destination:
name: forgejo-public-internal-ca
create: true
overwrite: true
transformation:
excludeRaw: true
excludes:
- .*
templates:
internal-ca.crt:
text: |
{{ get .Secrets "internal_ca_cert" }}
rolloutRestartTargets:
- kind: Deployment
name: forge-code
- kind: Deployment
name: forge-git
vaultAuthRef: default