Start migrating to Kubernetes in earnest

This commit is contained in:
Radon Rosborough 2022-12-19 15:14:23 -07:00
parent 31b0185505
commit 59a92b2ca4
19 changed files with 4758 additions and 2 deletions

5
.gitignore vendored
View File

@ -1,12 +1,13 @@
*.log
*.out
*.out.*
*.pem
.env
.lsp-repl-history
.terraform
bin
build
env.yaml
node_modules
out
sentinel.h
financials/????-??/*
!financials/????-??/breakdown.txt

20
env.yaml.bash Executable file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
registry_password="$(pwgen -s 20 1)"
cat <<EOF
networking:
domain: riju.example.com # FIXME
ip: x.y.z.w # FIXME
metallb:
secretkey: "$(pwgen -s 256 1)"
registry:
password: "${registry_password}"
htpasswd: "$(htpasswd -nbB admin "${registry_password}")"
EOF

105
k8s/cluster.yaml Normal file
View File

@ -0,0 +1,105 @@
apiVersion: k0s.k0sproject.io/v1beta1
kind: ClusterConfig
metadata:
creationTimestamp: null
name: k0s
spec:
api:
address: 192.168.0.216
k0sApiPort: 9443
port: 6443
sans:
- 192.168.0.216
- 192.168.122.1
- 172.21.0.1
- 172.17.0.1
- 172.23.0.1
- 10.88.0.1
- 10.244.0.1
- 2601:646:4000:3060::be49
- 2601:646:4000:3060:8b13:5b76:2703:28f
- 2601:646:4000:3060:683c:7a51:eee8:2eb
- fe80::1fbd:2949:a12e:cedf
- fe80::42:d5ff:fe58:a84f
- fe80::844c:59ff:fe46:20dc
- fe80::20e5:9dff:fe7a:4698
- fe80::f86c:22ff:feb0:59ac
- fe80::b0d0:51ff:fe45:ce31
- fe80::3cd5:9eff:fed1:5f72
tunneledNetworkingMode: false
controllerManager: {}
extensions:
helm:
charts: null
repositories: null
storage:
type: openebs_local_storage
images:
calico:
cni:
image: docker.io/calico/cni
version: v3.24.5
kubecontrollers:
image: docker.io/calico/kube-controllers
version: v3.24.5
node:
image: docker.io/calico/node
version: v3.24.5
coredns:
image: docker.io/coredns/coredns
version: 1.9.4
default_pull_policy: IfNotPresent
konnectivity:
image: quay.io/k0sproject/apiserver-network-proxy-agent
version: 0.0.32-k0s1
kubeproxy:
image: registry.k8s.io/kube-proxy
version: v1.25.4
kuberouter:
cni:
image: docker.io/cloudnativelabs/kube-router
version: v1.5.1
cniInstaller:
image: quay.io/k0sproject/cni-node
version: 1.1.1-k0s.0
metricsserver:
image: registry.k8s.io/metrics-server/metrics-server
version: v0.6.1
pushgateway:
image: quay.io/k0sproject/pushgateway-ttl
version: edge@sha256:7031f6bf6c957e2fdb496161fe3bea0a5bde3de800deeba7b2155187196ecbd9
installConfig:
users:
etcdUser: etcd
kineUser: kube-apiserver
konnectivityUser: konnectivity-server
kubeAPIserverUser: kube-apiserver
kubeSchedulerUser: kube-scheduler
konnectivity:
adminPort: 8133
agentPort: 8132
network:
calico: null
clusterDomain: cluster.local
dualStack: {}
kubeProxy:
mode: iptables
kuberouter:
autoMTU: true
hairpinMode: false
metricsPort: 8080
mtu: 0
peerRouterASNs: ""
peerRouterIPs: ""
podCIDR: 10.244.0.0/16
provider: kuberouter
serviceCIDR: 10.96.0.0/12
scheduler: {}
storage:
etcd:
externalCluster: null
peerAddress: 192.168.0.216
type: etcd
telemetry:
enabled: true
status: {}

View File

@ -0,0 +1,9 @@
---
kind: IPAddressPool
apiVersion: metallb.io/v1beta1
metadata:
namespace: metallb
name: self
spec:
addresses:
- "{{ .networking.ip }}/32"

1108
k8s/metallb-crds.yaml Normal file

File diff suppressed because it is too large Load Diff

352
k8s/metallb-rbac.yaml Normal file
View File

@ -0,0 +1,352 @@
# Based on bitnami/metallb helm chart 4.1.12 for metallb 0.13.7
---
kind: ServiceAccount
apiVersion: v1
metadata:
namespace: metallb
name: metallb-controller
automountServiceAccountToken: true
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: metallb-controller
rules:
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- update
- apiGroups:
- ""
resources:
- services/status
verbs:
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resourceNames:
- metallb-controller
resources:
- podsecuritypolicies
verbs:
- use
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
- mutatingwebhookconfigurations
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metallb-controller
subjects:
- kind: ServiceAccount
namespace: metallb
name: metallb-controller
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: metallb-controller
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-controller
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
resourceNames:
- metallb-memberlist
verbs:
- list
- apiGroups:
- apps
resources:
- deployments
resourceNames:
- metallb-controller
verbs:
- get
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- metallb.io
resources:
- addresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- ipaddresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bgppeers
verbs:
- get
- list
- apiGroups:
- metallb.io
resources:
- bgpadvertisements
verbs:
- get
- list
- apiGroups:
- metallb.io
resources:
- l2advertisements
verbs:
- get
- list
- apiGroups:
- metallb.io
resources:
- communities
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bfdprofiles
verbs:
- get
- list
- watch
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-controller
subjects:
- kind: ServiceAccount
namespace: metallb
name: metallb-controller
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: metallb-controller
---
kind: ServiceAccount
apiVersion: v1
metadata:
namespace: metallb
name: metallb-speaker
automountServiceAccountToken: true
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: metallb-speaker
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- policy
resourceNames:
- metallb-speaker
resources:
- podsecuritypolicies
verbs:
- use
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: metallb-speaker
subjects:
- kind: ServiceAccount
namespace: metallb
name: metallb-speaker
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: metallb-speaker
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-pod-lister
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- addresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bfdprofiles
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bgppeers
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- l2advertisements
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- bgpadvertisements
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- ipaddresspools
verbs:
- get
- list
- watch
- apiGroups:
- metallb.io
resources:
- communities
verbs:
- get
- list
- watch
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: metallb
name: metallb-pod-lister
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: metallb-pod-lister
subjects:
- kind: ServiceAccount
name: metallb-speaker

326
k8s/metallb.yaml Normal file
View File

@ -0,0 +1,326 @@
# Based on bitnami/metallb helm chart 4.1.12 for metallb 0.13.7
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
namespace: metallb
name: metallb-speaker
spec:
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: metallb-speaker
template:
metadata:
labels:
app: metallb-speaker
spec:
serviceAccountName: metallb-speaker
hostNetwork: true
securityContext:
fsGroup: 0
terminationGracePeriodSeconds: 2
containers:
- name: metallb-speaker
image: "docker.io/bitnami/metallb-speaker:0.13.7-debian-11-r8"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
add:
- NET_ADMIN
- NET_RAW
- SYS_ADMIN
drop:
- ALL
readOnlyRootFilesystem: true
runAsUser: 0
args:
- "--port=7472"
env:
- name: METALLB_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: METALLB_HOST
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: METALLB_ML_BIND_ADDR
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: METALLB_ML_LABELS
value: app=metallb-speaker
- name: METALLB_ML_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: METALLB_ML_SECRET_KEY
valueFrom:
secretKeyRef:
name: metallb-memberlist
key: secretkey
ports:
- name: metrics
containerPort: 7472
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
resources: {}
---
kind: Secret
apiVersion: v1
metadata:
namespace: metallb
name: webhook-server-cert
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: metallb
name: metallb-controller
labels:
app.kubernetes.io/name: metallb
spec:
replicas: 1
strategy:
type: RollingUpdate
revisionHistoryLimit: 3
selector:
matchLabels:
app: metallb-controller
template:
metadata:
labels:
app: metallb-controller
spec:
serviceAccountName: metallb-controller
securityContext:
fsGroup: 1001
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
containers:
- name: metallb-controller
image: "docker.io/bitnami/metallb-controller:0.13.7-debian-11-r9"
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
args:
- --port=7472
- --cert-service-name=metallb-webhook-service
ports:
- name: webhook-server
containerPort: 9443
- name: metrics
containerPort: 7472
volumeMounts:
- name: cert
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
httpGet:
path: /metrics
port: metrics
resources: {}
---
kind: Service
apiVersion: v1
metadata:
namespace: metallb
name: metallb-webhook-service
spec:
ports:
- port: 443
targetPort: 9443
selector:
app: metallb-controller
---
kind: ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
metadata:
name: metallb-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-addresspool
failurePolicy: Fail
name: addresspoolvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- addresspools
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta2-bgppeer
failurePolicy: Fail
name: bgppeervalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta2
operations:
- CREATE
- UPDATE
resources:
- bgppeers
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-ipaddresspool
failurePolicy: Fail
name: ipaddresspoolvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- ipaddresspools
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-bgpadvertisement
failurePolicy: Fail
name: bgpadvertisementvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- bgpadvertisements
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-community
failurePolicy: Fail
name: communityvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- communities
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-bfdprofile
failurePolicy: Fail
name: bfdprofileyvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- DELETE
resources:
- bfdprofiles
sideEffects: None
- admissionReviewVersions:
- v1
clientConfig:
service:
namespace: metallb
name: metallb-webhook-service
path: /validate-metallb-io-v1beta1-l2advertisement
failurePolicy: Fail
name: l2advertisementvalidationwebhook.metallb.io
rules:
- apiGroups:
- metallb.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- l2advertisements
sideEffects: None

17
k8s/namespaces.yaml Normal file
View File

@ -0,0 +1,17 @@
---
kind: Namespace
apiVersion: v1
metadata:
name: traefik
---
kind: Namespace
apiVersion: v1
metadata:
name: metallb
---
kind: Namespace
apiVersion: v1
metadata:
name: riju

25
k8s/provisioning.md Normal file
View File

@ -0,0 +1,25 @@
```bash
curl -sSLf https://get.k0s.sh | sudo sh
sudo mkdir /etc/k0s
k0s config create > /etc/k0s/k0s.yaml
```
Edit to have this config:
```yaml
spec:
extensions:
storage:
type: openebs_local_storage
```
```bash
sudo k0s install controller --single
sudo k0s start
```
Go to client machine:
```bash
ssh riju-k8s sudo -S k0s kubeconfig admin > ~/.kube/config
```

124
k8s/riju.yaml Normal file
View File

@ -0,0 +1,124 @@
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
namespace: riju
name: docker-registry
spec:
replicas: 1
serviceName: docker-registry
selector:
matchLabels:
app: docker-registry
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 128Gi
storageClassName: openebs-hostpath
template:
metadata:
labels:
app: docker-registry
spec:
volumes:
- name: auth
secret:
secretName: registry-auth
containers:
- name: registry
image: "registry:2"
env:
- name: REGISTRY_AUTH
value: htpasswd
- name: REGISTRY_AUTH_HTPASSWD_REALM
value: "Registry Realm"
- name: REGISTRY_AUTH_HTPASSWD_PATH
value: /var/run/registry/auth/htpasswd
ports:
- name: api
containerPort: 5000
volumeMounts:
- name: auth
mountPath: /var/run/registry/auth
- name: data
mountPath: /var/lib/registry
---
kind: Service
apiVersion: v1
metadata:
namespace: riju
name: docker-registry
spec:
type: NodePort
selector:
app: docker-registry
ports:
- name: api
port: 80
nodePort: 30999
targetPort: 5000
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: riju
name: riju-server
spec:
replicas: 1
selector:
matchLabels:
app: riju-server
template:
metadata:
labels:
app: riju-server
spec:
volumes:
- name: cache
hostPath:
path: /var/cache/riju
- name: docker
hostPath:
path: /var/run/docker.sock
containers:
- name: server
image: "localhost:30999/riju:app"
resources:
requests:
cpu: "1000m"
memory: "6Gi"
limits:
cpu: "1000m"
memory: "6Gi"
ports:
- name: http
containerPort: 6119
volumeMounts:
- name: cache
mountPath: /var/cache/riju
- name: docker
mountPath: /var/run/docker.sock
readOnly: true
---
kind: Service
apiVersion: v1
metadata:
namespace: riju
name: riju-server
spec:
selector:
app: riju-server
ports:
- name: http
port: 80
targetPort: 6119
---
kind: Ingress

17
k8s/secrets.in.yaml Normal file
View File

@ -0,0 +1,17 @@
---
kind: Secret
apiVersion: v1
metadata:
namespace: metallb
name: metallb-memberlist
data:
secretkey: "{{ .metallb.secretkey | b64enc }}"
---
kind: Secret
apiVersion: v1
metadata:
namespace: riju
name: registry-auth
data:
htpasswd: "{{ .registry.htpasswd | println | b64enc }}"

2288
k8s/traefik-crds.yaml Normal file

File diff suppressed because it is too large Load Diff

72
k8s/traefik-rbac.yaml Normal file
View File

@ -0,0 +1,72 @@
# Based on traefik/traefik helm chart 20.8.0 for traefik v2.9.6
---
kind: ServiceAccount
apiVersion: v1
metadata:
namespace: traefik
name: traefik
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik
rules:
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingressclasses
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- ingressroutes
- ingressroutetcps
- ingressrouteudps
- middlewares
- middlewaretcps
- tlsoptions
- tlsstores
- traefikservices
- serverstransports
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: traefik
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: traefik
subjects:
- namespace: traefik
kind: ServiceAccount
name: traefik

145
k8s/traefik.yaml Normal file
View File

@ -0,0 +1,145 @@
# Based on traefik/traefik helm chart 20.8.0 for traefik v2.9.6
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: traefik
name: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
minReadySeconds: 0
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "9100"
labels:
app: traefik
spec:
serviceAccountName: traefik
terminationGracePeriodSeconds: 60
hostNetwork: false
containers:
- image: traefik:v2.9.6
imagePullPolicy: IfNotPresent
name: traefik
resources: {}
readinessProbe:
httpGet:
path: /ping
port: 9000
scheme: HTTP
failureThreshold: 1
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
livenessProbe:
httpGet:
path: /ping
port: 9000
scheme: HTTP
failureThreshold: 3
initialDelaySeconds: 2
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 2
ports:
- name: traefik
containerPort: 9000
- name: web
containerPort: 8000
- name: websecure
containerPort: 8443
- name: metrics
containerPort: 9100
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsGroup: 65532
runAsNonRoot: true
runAsUser: 65532
volumeMounts:
- name: data
mountPath: /data
- name: tmp
mountPath: /tmp
args:
- "--global.checknewversion"
- "--global.sendanonymoususage"
- "--entrypoints.metrics.address=:9100/tcp"
- "--entrypoints.traefik.address=:9000/tcp"
- "--entrypoints.web.address=:8000/tcp"
- "--entrypoints.websecure.address=:8443/tcp"
- "--api.dashboard=true"
- "--ping=true"
- "--metrics.prometheus=true"
- "--metrics.prometheus.entrypoint=metrics"
- "--providers.kubernetescrd"
- "--providers.kubernetesingress"
- "--entrypoints.websecure.http.tls=true"
volumes:
- name: data
emptyDir: {}
- name: tmp
emptyDir: {}
securityContext:
fsGroup: 65532
---
kind: Service
apiVersion: v1
metadata:
namespace: traefik
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- port: 80
name: "web"
targetPort: web
protocol: TCP
- port: 443
name: "websecure"
targetPort: websecure
protocol: TCP
---
kind: IngressClass
apiVersion: networking.k8s.io/v1
metadata:
name: traefik
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: traefik.io/ingress-controller
---
kind: IngressRoute
apiVersion: traefik.containo.us/v1alpha1
metadata:
namespace: traefik
name: traefik-dashboard
spec:
entryPoints:
- traefik
routes:
- match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
kind: Rule
services:
- name: api@internal
kind: TraefikService

5
tools/template/Makefile Normal file
View File

@ -0,0 +1,5 @@
bin:
mkdir bin
bin/template: bin go.mod go.sum template.go
go build -o bin/template template.go

8
tools/template/go.mod Normal file
View File

@ -0,0 +1,8 @@
module github.com/raxod502/riju/tools/go
go 1.16
require (
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
gopkg.in/yaml.v2 v2.4.0
)

39
tools/template/go.sum Normal file
View File

@ -0,0 +1,39 @@
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904 h1:bXoxMPcSLOq08zI3/c5dEBT6lE4eh+jOh886GHrn6V8=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

7
tools/template/template Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
make -s bin/template
exec bin/template

View File

@ -0,0 +1,88 @@
package main
import (
"bytes"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/Masterminds/sprig/v3"
"gopkg.in/yaml.v2"
)
func findProjectRoot() (string, error) {
curDir, err := os.Getwd()
if err != nil {
return "", err
}
prevDir := ""
for curDir != prevDir {
if _, err := os.Stat(filepath.Join(curDir, ".git")); err == nil {
return curDir, nil
} else if !os.IsNotExist(err) {
return "", err
}
prevDir = curDir
curDir = filepath.Dir(curDir)
}
return "", fmt.Errorf("not a git repository (or any of the parent directories): .git")
}
func mainInternal() error {
projectRoot, err := findProjectRoot()
if err != nil {
return err
}
envText, err := os.ReadFile(filepath.Join(projectRoot, "env.yaml"))
if err != nil {
return err
}
var env interface{}
if err := yaml.Unmarshal(envText, &env); err != nil {
return err
}
if err := filepath.WalkDir(projectRoot, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.Name() == ".git" {
return fs.SkipDir
}
dir := filepath.Dir(path)
if strings.Contains(d.Name(), ".in.") {
fmt.Fprintf(os.Stderr, "template_secrets.go: processing %s\n", path)
input, err := os.ReadFile(path)
if err != nil {
return err
}
tmpl, err := template.New("").Funcs(sprig.TxtFuncMap()).Option("missingkey=error").Parse(string(input))
if err != nil {
return err
}
var output bytes.Buffer
if err := tmpl.Execute(&output, env); err != nil {
return err
}
if err := os.WriteFile(
filepath.Join(dir, strings.ReplaceAll(d.Name(), ".in.", ".out.")),
output.Bytes(), 0644,
); err != nil {
return err
}
}
return nil
}); err != nil {
return err
}
return nil
}
func main() {
if err := mainInternal(); err != nil {
fmt.Fprintf(os.Stderr, "template.go: %s\n", err.Error())
os.Exit(1)
}
}