feat(snips): initial setup
All checks were successful
Renovate / renovate (push) Successful in 31s

This commit is contained in:
Peter 2024-03-06 22:11:07 +01:00
parent 166b2973cc
commit 3fdbfe8d7e
Signed by: prskr
GPG key ID: F56BED6903BC5E37
11 changed files with 335 additions and 0 deletions

View file

@ -17,6 +17,14 @@ spec:
- kind: TCPRoute
namespaces:
from: All
- name: snips-ssh
protocol: TCP
port: 2222
allowedRoutes:
kinds:
- kind: TCPRoute
namespaces:
from: All
- name: http
protocol: HTTP
port: 80

View file

@ -16,6 +16,7 @@ spec:
containers:
- name: fider
image: docker.io/getfider/fider:stable
imagePullPolicy: Always
ports:
- containerPort: 3000
protocol: TCP

6
snips/config/.env Normal file
View file

@ -0,0 +1,6 @@
SNIPS_DB_FILEPATH=/data/snips.db
SNIPS_SSH_HOSTKEYPATH=/etc/snips/snips
SNIPS_SSH_AUTHORIZEDKEYSPATH=/etc/snips/authorized_keys
SNIPS_HTTP_EXTERNAL=https://snips.icb4dc0.de
SNIPS_SSH_EXTERNAL=ssh://snips.icb4dc0.de:2222
SNIPS_ENABLEGUESSER=true

View file

@ -0,0 +1,12 @@
addr: ":9090"
dbs:
- path: /data/snips.db
replicas:
- type: s3
endpoint: https://2df513adaee2eeae12106af900bed297.r2.cloudflarestorage.com
bucket: backup
path: snips
region: us-east-1
retention: 72h
snapshot-interval: 1h

View file

@ -0,0 +1,40 @@
apiVersion: v1
kind: Secret
metadata:
name: snips-secrets
stringData:
hmackey: ENC[AES256_GCM,data:Srvw37mEYlKUGZ0ep+CBXQQ0xubkcg8ab6jJ1VK2oUC2nFDnC6oExJuoZRUlwCFfahdfju6iB8JyD9dWmWV+Hx1Kq/TlyPQREYol8XIJdqkwv7xe5CO825cU5Zirx/7650WiZpwz9kz7LG6U5HPcvlEv/AZT/wJZMGGOqdogy5E=,iv:P3OEEuuLaBLCq2Rstvhj9xThUYiOr6AUKV2b0EiPiKg=,tag:QFUgQKEsOcbEfATKeYIv1A==,type:str]
authorized_keys: ENC[AES256_GCM,data:vWIUncU3s1XUz+opHZNuNviwecQMTFP2QNIY29LnSZgrGkLb/ws/D8DrNixCgEiqMlU0V7ut58rdIaklNfQ0zc8N95DeIqdbnZora0gQ+xfrmDNMVXfgMdDzEEhKQto1yFqj75MjEsfC9riZxKoGP5tx3qjkXPqfH4tNvx+3Cwtb8m8GQukR5fq9D2K43Qb12yk0rDrEnZ3S0okBbPgmrkfCqKTv+8HrvEiuqvPIRun5Nu5lLHJKtNmfNbmfzzv8eyGJUW9CFM+2qmIIscpGeh3Est1MIk/ubSO7c2iEPMxNcmil7ZmDVJ5dU/9QTgr4M27crS8agWQ8953WJ7pNnbDHFWpTfWsnEhiK4tp4gR3EeQiFHOvdaxa32uDWi1rSBRWQzt7lK6U7fIZ4Gagi0eieogbt++HWuM3zXT+QmLwyRfA3sy4UazUazkyr+WH6ea6F3awaRQEe2og29Ghaepc21cniarZDYZcaAMMKLRqmVFL+WY3+M9YwyTeUZGvyyXHI4DB9UM//Ik1/UxK27d+tHnLpYjOsKbTmxTovi897BFUKOOajYy4YCkK/qLPSEgzm1CVReh7VhX7url/lRSx6/5421zvlx+yKmRIVcD0Hbp2xRkIso8iMRhC6tPDr2uhapyeidcv7GKOLnuSHoqEcse4HqLbnVMSGfbVBUdf9vGfOE8KEjx2bPnZPECUjPlwXgRoJ3lRfpKSJl1V3fJj3/cjwh1fUdnQa+g2D+B6MkR9lOha3pD9Aufv5iTAiNbBEgKBN8+UVZjU5chy2plkRDm3dfrccVAtfwmH3YItkDLSfKFDMRyBB6WZpwo7N9viBqQHy75bq2TJEWY7wou5+tkx9NZOQ1KTELpiedhUwK8RNU+KiIBF2/CikSeJ+5/syoo8zqyOzQ01lRPWywo/3TcUlh6JVRx6xintAkfjqRJ8/huKu8UsAZ0Jh5HXrQacpB+wWGdo52hae5DadMmf6trXxZA==,iv:FTydQ7piJuTYkhgzEImD3RWF6AwWUBkXcEFisykNlSM=,tag:FSu7srqamA4F6dtwLysRgQ==,type:str]
snips: ENC[AES256_GCM,data:qM3fmKclXaf2ebI2vz6qTFNuk2HzOO5rYHqU0M7ugffI/damdMpAbTrOe3sa8+A11RMcKWYBEABOjfGesH8f7HJj4kO6cTJ3dSQwA2c7A2NiSLLEhjARBTx7rW57eNGp2nmUCwk2LFZWSTaRyaYhZtWtj6+7Zlt/2Se/zZSuguBNZqc1erOkkErMfRGjUggMu0FhQHiwIt7isofBbBO460sx6EiDsZFGYqJLSptKfQr5FusBBRHNj2vgtki7qLowr5saS3rf+0zGT5OV0CFWMKunX2dAwoquwNWaYdLGH1Yc1E25ofoivBA0i9JLpfdwvsku3WwNxioBeIolW0YqaaDg6XFqWIXW7UAzN2bdTVHq1ln0SFpvXt4ihkYciFlLg5FAO1lAhz/rRA5XBRCDPYU44oo6KsDjnBIOsXSTkqS02cSIiKVgbMqzUChqR2mQD6pfNvpbOZ7IHiPrT4O0oD8W5S12oJnofViZj+4/B/cbf0ZsvVTGo3dmBp0moChv7Sli,iv:cHUL5DJGs8F/cQS1lTFYZUS23TP272XJ0uc8gjRDJSs=,tag:vYy8VUb9rjne2fQVs0TjWQ==,type:str]
snips.pub: ENC[AES256_GCM,data:09R5K9p5QmsBPAdM2/rDZpUja4+t2yaeqYPLQI0JkErRlF/nvdv1GbFqoOmeDL3VYejiguAevAfV+vbOgub95JF6lAH6XQSNCPVCaA+W5b588RyDZ/HAxmb/Lxwxmxb8A1L3,iv:Qa9eYBoGAGjYfwcgClGolhijnWFV/ekRr7OvLyPZFGU=,tag:GWsA3mk1pU2fKLZfattvnw==,type:str]
r2-access-key: ENC[AES256_GCM,data:eJK3BRpEdJDfShlNeUV2BAL6FDs082SsueO6gnQ+Uyk=,iv:bGPbyngp4yCxudHbRUToR8FoFWGYBKpMfg9imbcTxO8=,tag:BUEoS0o4QqCWz8AxSM7x6Q==,type:str]
r2-secret-key: ENC[AES256_GCM,data:aFRc3BO1ue4tITSDmce2Pndzqx/1fD0RnL4u+KPt52VkjtQ65WfI9LOoC4bw9OtIjNBP6iyK0SpdqMmBFEtWVg==,iv:/IEaWqgQ/eNFfxA5If5D92hDaek3DHHdVHTnsyrEfYc=,tag:HPWWp8d3TOH6US0ITIFcRg==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age18e0w4jn03n66qwg8h3rjstz7g5zx2vhvz28aterkfkfetrxtpuysftp6we
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6ZjM1Y0M1TnBlNHd2eFda
cDlqVmt5bCt2WmJ4TXhyR2J2eEFYRGVQR21zCmMvQWpsMWJIVW9IL2xZUWF1MnJn
djRnMmRFMnNEOHI5ZUMwYWtJL3Y0ZWcKLS0tIHlCRFhtV0xkTVI5SUZaT1ZoMnhu
cGVNNVpQU2JRVFVjUjRlamtteXhpd2MK7T3aBSFPit5ulg3FU49vXfvO4q2S2VQl
nb0f+QW8nyKcl1PSsquUM3G7PAg9lLxWlDnwXRxsaZQ0WUuTF0NBwQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age1yssdnqk90tn6zzggmwt70krndw04yfk9hwzdac3wsgfxmttngd7q89qzjr
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpNGFERlp1a0ZIMXVjVEFN
ems2VnV2TlZhRlBJcnMrWlhLRDV4cTVqNUhVCkREMm5BRVVrK1NJeWRpWlJCNmJl
UXh6OVhVdXNnTm5lTnlsWnVkbnpQY2cKLS0tIFlQY0VuSklLOU1aN2R4eHNEZ25J
TElVdVRyM05nRjJYMWFCL29YZyt4TjgK56s837z/U6dswH2ZSQH3PA3aJ7blAa0F
sX8koiFtwkVcnrHvdPvKqitKLot7C3fu9BRZkFfcdi4tYh1vAeKS9w==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-03-06T19:44:14Z"
mac: ENC[AES256_GCM,data:BwnqY1C0PCNPOoUidMvOsyjAiTnCiqktfrgPnbwsdKlFZUElccbCn9pF+e03lAjUU6f9vZ7TaEi9pcgLZ6dMIG7/FQN95XLeEyBfzbYqO0bkAdFxlZmQLX4zzrKkb8wC4kFwRz2m0HSd3+CT7W3SPdqNWGNrnsFKKip4F61Akgw=,iv:dCI+9pObu3EvtJFj/zGWYmGPqjprbZEEmMB4pJCVfk0=,tag:9TvUtXve7qfJ6u8lIluyIg==,type:str]
pgp: []
unencrypted_regex: ^(apiVersion|metadata|kind|type)$
version: 3.8.1

35
snips/kustomization.yaml Normal file
View file

@ -0,0 +1,35 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: snips
images:
- name: snips
newName: ghcr.io/robherley/snips.sh
newTag: v0.3.2
- name: litestream
newName: litestream/litestream
newTag: "0.3"
labels:
- includeSelectors: true
pairs:
app.kubernetes.io/instance: icb4dc0de
app.kubernetes.io/managed-by: kustomize
resources:
- resources/namespace.yaml
- resources/statefulset.yaml
- resources/service.yaml
- resources/routes.yaml
configMapGenerator:
- name: snips-config
envs:
- config/.env
- name: litestream-config
files:
- config/litestream.yml
generators:
- ./secret-generator.yaml

View file

@ -0,0 +1,7 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: snips
labels:
prometheus: default

View file

@ -0,0 +1,48 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: snips-http
spec:
parentRefs:
- name: contour
sectionName: http
namespace: projectcontour
hostnames:
- snips.icb4dc0.de
rules:
- filters:
- type: RequestRedirect
requestRedirect:
scheme: https
statusCode: 301
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: snips-https
spec:
parentRefs:
- name: contour
sectionName: https
namespace: projectcontour
hostnames:
- snips.icb4dc0.de
rules:
- backendRefs:
- name: snips
port: 8080
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: snips-ssh
spec:
parentRefs:
- name: contour
sectionName: snips-ssh
namespace: projectcontour
rules:
- backendRefs:
- name: snips
port: 2222

View file

@ -0,0 +1,17 @@
---
apiVersion: v1
kind: Service
metadata:
name: snips
spec:
selector:
app.kubernetes.io/name: snips
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
- name: ssh
protocol: TCP
port: 2222
targetPort: 2222

View file

@ -0,0 +1,150 @@
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: snips
spec:
replicas: 1
serviceName: snips
selector:
matchLabels:
app.kubernetes.io/name: snips
template:
metadata:
labels:
app.kubernetes.io/name: snips
spec:
initContainers:
- name: init-litestream
image: litestream
args: ['restore', '-if-db-not-exists', '-if-replica-exists', '/data/snips.db']
volumeMounts:
- name: data
mountPath: /data
- name: litestream-config
mountPath: /etc/litestream.yml
subPath: litestream.yml
env:
- name: LITESTREAM_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: snips-secrets
key: r2-access-key
- name: LITESTREAM_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: snips-secrets
key: r2-secret-key
containers:
- name: snips
image: snips
envFrom:
- configMapRef:
name: snips-config
env:
- name: SNIPS_HMACKEY
valueFrom:
secretKeyRef:
name: snips-secrets
key: hmackey
ports:
- containerPort: 8080
protocol: TCP
name: http
- containerPort: 2222
protocol: TCP
name: ssh
livenessProbe:
tcpSocket:
port: 2222
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
tcpSocket:
port: 2222
initialDelaySeconds: 5
periodSeconds: 5
resources:
limits:
cpu: 100m
memory: 200Mi
requests:
cpu: 50m
memory: 50Mi
volumeMounts:
- name: snips-secrets
readOnly: true
mountPath: /etc/snips
- name: data
mountPath: /data
- name: litestream
image: litestream
args: ['replicate']
volumeMounts:
- name: data
mountPath: /data
- name: litestream-config
mountPath: /etc/litestream.yml
subPath: litestream.yml
env:
- name: LITESTREAM_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: snips-secrets
key: r2-access-key
- name: LITESTREAM_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: snips-secrets
key: r2-secret-key
readinessProbe:
httpGet:
path: /metrics
port: 9090
initialDelaySeconds: 5
periodSeconds: 5
livenessProbe:
httpGet:
path: /metrics
port: 9090
initialDelaySeconds: 5
periodSeconds: 5
ports:
- name: metrics
containerPort: 9090
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- snips
topologyKey: topology.kubernetes.io/zone
volumes:
- name: snips-secrets
secret:
secretName: snips-secrets
items:
- key: authorized_keys
path: authorized_keys
- key: snips
path: snips
- key: snips.pub
path: snips.pub
- name: litestream-config
configMap:
name: litestream-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: r2

View file

@ -0,0 +1,11 @@
apiVersion: viaduct.ai/v1
kind: ksops
metadata:
# Specify a name
name: snips-secret-generator
annotations:
config.kubernetes.io/function: |
exec:
path: ksops
files:
- config/secrets.enc.yml