feat: implement secret management with SOPS
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
tmp/
|
||||
pkg/secrets/
|
||||
5
.sops.yaml
Normal file
5
.sops.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
creation_rules:
|
||||
- path_regex: \.yaml$
|
||||
encrypted_regex: ^(data|stringData)$
|
||||
age: >-
|
||||
age1pq1sv3sp559cz4uvdynlfp3j9kr4kur56q655385d86aqrqraz8hejmrfqfwf6qrduzua3t7gap67rk0tenyj3nqu33fqana0zeugvr8y2xrgr33th48pja57wzvk9hscyg5jg9rxwk3y7dpkqmtvfkuhg6gz7xepkegu5wuxdegv2gxvk9027skh7wrjpawfdr59d6azmcwpa8ez46zv0ynkfu6xdxceqrwkxphw3wc2m6e22vxzyzzmxkqmj8qa49q5pfyveezf33varg2uvmchujrff5twfrrn4mmhwpry44p2hf5akwvuwvwdqczcd6hlghqm9fh9rlv9v27gz9u07qvvpmwyyt8z643z9zflat6lwjvpl6zmcrw4776hpqkvsyd09gwh530gvtg7qmnfky8ef8xtxpjdqskw95tydqv9n86gunwt8zf3km9g4lpjgynpgxu79nzkds39axygs982q7xeft7u5rw9vyr2hk0y3c589s9r9qtr3usy3uw4sygs56dgllwufnhmqe7zlqvf5wk73z3fl59xrw3pgys50eectrjqvzkukmtrzkjt4mdv6y35s0xefmjvsdlumg85rxyt283g4gf96yn2d6p92ue329xt6x3xxfs2p4xqw33w90qqdt9enjdxcd2tppcr9c8hxf3s2p6m4sdr5rc0r4c384ysm5f4exa63f3vpnzwy6qk2v7ymmfv3yyfwg9fgc28h2yym3xsp8y6a457zer8tk2ndmz4pu3g2wrcggg9zze4xs2vyhsf5umqykzfeptquqp3nqgplejsuemnxpuc7qvuk8t5fdn9c5rgrkuqtmxq4cv4y88lgz4tnmqdda6azsa2krupkgrksqpg0uk6lscezk86cka5hecrg9v7742uarqevlqytxv37jgf2ueyaxcccqzfzvxt3jet6kergarq2mvvdgt8x8m8n5n9qye5e2d2jw2z3n96a8d6sh0gfxzf8mk4gm7d60pa7r7tmk59ggch55s8w5p9lwpunvspdg73theqrsd9cykzkf93f95l9yw5g8ex595cxe6xy9tw67msej2vmntsad0v8tsc642kthwft6v0thelt8vktzc4e3azqjrkzkyhyyn9q2yuetx34yr65u27xvdpdrhl352rluaj2g32yxkum30sj845wx2vwqez4ztveva7g5j884d6l0rylkwz4f8jdexnnmehdxn2t759utazhnsx48984cxmncnd6cr8fpjvv4ugzefs44x0w6kyy7nzml7w2jsdgjs43k5mlent5sqqckmnpvr4y9s828t7d55jcjxfydgj2exqert9r4m7myqwehgdxgzsgmceu7uat4rpjfrag0x0gyewk7xgdyvvqp3cj44v0u24e73q47gqrma0c6n7djsrmyctv9vfr579s594ss5heg87aq08j8u6g5cs3xthtz7ckhkw0pz3h5vv06r9psrp63ggdrdq9jzrtp6vfl34dgw33nt4efyh7rrpl9psfwp6yn8rcv7acew0cecjqr6gd0s2wtt6996aapj82epyzvksenc9ew5j2xn9umh6y7jt0xsq9xz5e6v4r8xjmykapckgmq56awux29xzupu35gr9qv5crfkqzhe53dpczj930hwvrldqaq2z3g7e3tu92jqcl88ka43zxdkvwym4qacjsztl7gtv5v0juy9q0ctfd4l672wu2ps3vtypyzcpm2jyxvy093aqzpsfua2h6rycahupnxj8qstc3r0flhwx7l4vgw6vnzptvs98yp2spnqwr5y27xgu64nzdkj3pk5vdkrwuyyg78wthd3eh9qk7pzn6fl47ccrevundlq4lwlsjr7fm929cvxdp8dmyz8t45mapjvzk37yf2s7mddp0lpxzal739e5py082sq3c5wchkzc84cl4w
|
||||
18
README.md
18
README.md
@@ -17,7 +17,25 @@ The GitOps controller is running in a constant loop and always matches the Git s
|
||||
flux vs ArgoCD
|
||||
Flux is more CLI Driven ArgoCD has a richer GUI
|
||||
|
||||
## Dev dependencies
|
||||
- AGE
|
||||
- SOPS
|
||||
- Go Toolchain
|
||||
|
||||
## Secrets
|
||||
Some secrets are written a Go files, they must be decrypted first.
|
||||
Once decrypted they show up at `./pkg/secrets/..`. Note that they are referenced in `./cmd/secrets/main.go`.
|
||||
|
||||
## Flux
|
||||
Prerequisites:
|
||||
- Kubernetes Cluster
|
||||
-Github (giea, etc) personal access token
|
||||
|
||||
### Managing secrets with SOPS
|
||||
First step to manage secrets in Flux with SOPS, is to add the secret-key to Kubernetes and make it accessible to the flux system.
|
||||
|
||||
To decrypt secrets use:
|
||||
```sh
|
||||
sops --decrypt <file_path>
|
||||
```
|
||||
There must be an environment variable named `SOPS_AGE_KEY_FILE` that contains the path of the AGE key text file.
|
||||
|
||||
@@ -19,6 +19,16 @@ spec:
|
||||
- env:
|
||||
- name: LD_CSRF_TRUSTED_ORIGINS
|
||||
value: https://link.danicos.me
|
||||
- name: LD_SUPERUSER_NAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: supe_user_name
|
||||
name: linkding
|
||||
- name: LD_SUPERUSER_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
key: supe_user_password
|
||||
name: linkding
|
||||
image: sissbruecker/linkding:1.45.0
|
||||
name: linkding
|
||||
ports:
|
||||
|
||||
54
apps/hydra/secrets/linkding.yaml
Normal file
54
apps/hydra/secrets/linkding.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: linkding
|
||||
namespace: linkding
|
||||
stringData:
|
||||
supe_user_name: ENC[AES256_GCM,data:ksT268LhGr4oMajHODGVnEw=,iv:6MNfGQdAJysxySogJIAujqCBzA/UTBqy2tAmAz15FQY=,tag:fXiDattDh0ldXvdlwiGsSg==,type:str]
|
||||
supe_user_password: ENC[AES256_GCM,data:llPaiDegtQO0DzVyts854jA7a6lp7fkKluDCLN3AxTjca5YX/0jr9v+nbUM=,iv:H/vHd+aFnHXTK3idSBEeRdl/O1QAZH4ddzTfrZgYIgM=,tag:bg6p4xEtwhs7e3tB82x+jQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age1pq1sv3sp559cz4uvdynlfp3j9kr4kur56q655385d86aqrqraz8hejmrfqfwf6qrduzua3t7gap67rk0tenyj3nqu33fqana0zeugvr8y2xrgr33th48pja57wzvk9hscyg5jg9rxwk3y7dpkqmtvfkuhg6gz7xepkegu5wuxdegv2gxvk9027skh7wrjpawfdr59d6azmcwpa8ez46zv0ynkfu6xdxceqrwkxphw3wc2m6e22vxzyzzmxkqmj8qa49q5pfyveezf33varg2uvmchujrff5twfrrn4mmhwpry44p2hf5akwvuwvwdqczcd6hlghqm9fh9rlv9v27gz9u07qvvpmwyyt8z643z9zflat6lwjvpl6zmcrw4776hpqkvsyd09gwh530gvtg7qmnfky8ef8xtxpjdqskw95tydqv9n86gunwt8zf3km9g4lpjgynpgxu79nzkds39axygs982q7xeft7u5rw9vyr2hk0y3c589s9r9qtr3usy3uw4sygs56dgllwufnhmqe7zlqvf5wk73z3fl59xrw3pgys50eectrjqvzkukmtrzkjt4mdv6y35s0xefmjvsdlumg85rxyt283g4gf96yn2d6p92ue329xt6x3xxfs2p4xqw33w90qqdt9enjdxcd2tppcr9c8hxf3s2p6m4sdr5rc0r4c384ysm5f4exa63f3vpnzwy6qk2v7ymmfv3yyfwg9fgc28h2yym3xsp8y6a457zer8tk2ndmz4pu3g2wrcggg9zze4xs2vyhsf5umqykzfeptquqp3nqgplejsuemnxpuc7qvuk8t5fdn9c5rgrkuqtmxq4cv4y88lgz4tnmqdda6azsa2krupkgrksqpg0uk6lscezk86cka5hecrg9v7742uarqevlqytxv37jgf2ueyaxcccqzfzvxt3jet6kergarq2mvvdgt8x8m8n5n9qye5e2d2jw2z3n96a8d6sh0gfxzf8mk4gm7d60pa7r7tmk59ggch55s8w5p9lwpunvspdg73theqrsd9cykzkf93f95l9yw5g8ex595cxe6xy9tw67msej2vmntsad0v8tsc642kthwft6v0thelt8vktzc4e3azqjrkzkyhyyn9q2yuetx34yr65u27xvdpdrhl352rluaj2g32yxkum30sj845wx2vwqez4ztveva7g5j884d6l0rylkwz4f8jdexnnmehdxn2t759utazhnsx48984cxmncnd6cr8fpjvv4ugzefs44x0w6kyy7nzml7w2jsdgjs43k5mlent5sqqckmnpvr4y9s828t7d55jcjxfydgj2exqert9r4m7myqwehgdxgzsgmceu7uat4rpjfrag0x0gyewk7xgdyvvqp3cj44v0u24e73q47gqrma0c6n7djsrmyctv9vfr579s594ss5heg87aq08j8u6g5cs3xthtz7ckhkw0pz3h5vv06r9psrp63ggdrdq9jzrtp6vfl34dgw33nt4efyh7rrpl9psfwp6yn8rcv7acew0cecjqr6gd0s2wtt6996aapj82epyzvksenc9ew5j2xn9umh6y7jt0xsq9xz5e6v4r8xjmykapckgmq56awux29xzupu35gr9qv5crfkqzhe53dpczj930hwvrldqaq2z3g7e3tu92jqcl88ka43zxdkvwym4qacjsztl7gtv5v0juy9q0ctfd4l672wu2ps3vtypyzcpm2jyxvy093aqzpsfua2h6rycahupnxj8qstc3r0flhwx7l4vgw6vnzptvs98yp2spnqwr5y27xgu64nzdkj3pk5vdkrwuyyg78wthd3eh9qk7pzn6fl47ccrevundlq4lwlsjr7fm929cvxdp8dmyz8t45mapjvzk37yf2s7mddp0lpxzal739e5py082sq3c5wchkzc84cl4w
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IG1sa2VtNzY4eDI1NTE5IHZIVTI2OVlO
|
||||
d291TTlYN3JFbm9oY0ViVWNuOWpiNzh6UjVvVnFkQ1RLQmFmdlNJaDRBRGN6MWVL
|
||||
emllSVExelArWE4zNmtnS0RYQlU1UkZvUXRWVlgrdnhjNHBVV1dNY0lyMm1KRDBY
|
||||
cHlTVGtZbkJtUlhjQk1LMFh3UGtwRVlsK3dpM0JWOEQvWGlidmcrTUlleEZOTlhJ
|
||||
dFBYa2pLZVVpdDdjcDlRbjFZc1A4OTRvNHowcGR4NUIxNEVtREMyVEZiWGJXZXNy
|
||||
eHA0SHptbEFEUHBDcUxGbTZwTUZFMENpOW1HWnl1clYwNjlVRm9pMFM2bytFbEFP
|
||||
NFZmdTNOaVQxNlZVb1NwY2R6L2JKVVVyS3I3dVdNc3RJYWdJcklCcTFDRWZrWW4x
|
||||
dHJyczVGcTVKVUV2dHZzWnNObXNSTnBqbE1SdjdMZ1NhVDRmblFkanlZQVhvRjIr
|
||||
Y0VEZGxsSGVHWFhXUUQwNm5kQ1Buak8vYkYyMC95elB0Vm16M1d6U1V0NzRTOGlw
|
||||
OTd1MjBIVGo1TkljRUJDbVJDTzJ0dzNBeDBISnBydUQzNlpkdVl2dHJSYW1TanVj
|
||||
UFlnZis3MWtqNVhiY3FWTkVOc2dydm9BNXQwYXArMzBOcWcyTlZoRDRiR0J4Sk9w
|
||||
K2FZNklpUHh6RGpVaVIvVGlkeXkxV2tBeEtoN1FRV0Rpc21xS0c3Zy9zdWRvWDVj
|
||||
SVcwM2x5VnNYRGlFUk1zeGY0NEh4bG1MS2oyNTlIZG5UOE00NVBDWjlZa0pDaW1S
|
||||
QlBOejQxSW9HMFNid2FRdjdVRmluMWhGQUVoR2RjbUlEbFF5eXhmVFkvaUc0cTA4
|
||||
MDNlWFBLOFR3TUdsSGlVSXY3SnhhZk4xbUR5cEVpS0pOeERrRnVPeWZpSy9hNGtB
|
||||
bUhPTExxdmpKdFdkL3U0c0tCZXZhQzNrUWNlMitQb0N1ZXpZQ011SkNkTzZNUEta
|
||||
aDU4aFZKdmhHR2xLanBGRWk0M3dycGlrb1NZUUNkU25mTzFCTkdjaUlZb3U2MDdN
|
||||
NkFoZDVuOHBmWU42WTU1TTBMWktPRTBjajRWcmhMaUhnSWZvcTBiWStpY2RKVGpi
|
||||
L0NoZmZmOVVkOU53aTYrSGMwV0FKWlJTWkFQSHJCSW1qbi9xM0hLSFhpRWVQK0Rq
|
||||
bnVIbFY0NVJXK2ZRNWsxVnlSTzBpMmJhNUcwMlUyK0FKZkd2ZGZ0MHZQOWRTeHgv
|
||||
RnhrdUxhSXhCYmtMcGh2UmdFYXlFSllqZnF3YnZLS3V6WjVDeElYdUpKZTY5bmF5
|
||||
K3ZoTVpUUm5TQzhlbllBV0hiTE4zbWpjc2hEMWozNGp3Zi9MOWNPNXd2c0ZOUlVt
|
||||
T0pYKzRGeGJCb2N5S3kwRUNrdDNxREkrRDRFSWVMV1hYSFo2NzNLK2o2TVlNbGtI
|
||||
WjBYcFZBdVlEMEtpQW1DQnZBcCtrOGlDRC8yMlZSY2t3eGdxakYzQU96UFlVZkFM
|
||||
QmFmMzMwNWVkUDdRR0o0RkQzYnNmU2EvZG1iazQwbTArNDRBb3FIcGEwbVhjajZT
|
||||
eXo2MThqbEFPKzkrUHpSd2hpYUR3NjZzMkE3ZmozdHJycGoxL0FjbmtGQzNOeWFE
|
||||
UnZHR3F4SkV1V1htclFOZFVjZzh3VUJleWVUbDI3a1dYMld5cUttVTBoR3F1SFUv
|
||||
ZTN1dmgvVU5YWnFmbnM3djA3a0VEWVdlNWoyaDgwOVlsUXpWVStVUE5PVENDaUpD
|
||||
SE5wUno2dS8reFJ0ZXdLUTMySU9DV0o5RGNyanBzbFRWTUZPbU4wOVk0MGxHOHRr
|
||||
ek5sVHZjTXJkWVpoQVFxOXMyMUQ4a01TL0RoeHFYZ3VlQXdxNzZhaWNuTGk3ZmVH
|
||||
OFVUaXVmNUIvaXN2QUFUVktycGdGMjN0REMvL0h4d0RBMHVhL0lwUEV0Y0Z0Y2dy
|
||||
VjFkdVFXeTJ5WStzRm5OeFIyM1VsV2RqY0tMSzRuQ3ZTdFltdzFxcWNpeDVmdwpN
|
||||
aWFSUlYrUGhBZHc3QjRWdWlSY0xENWcrUHVzMlROWEFKQmRMU1dDcXZnCi0tLSBs
|
||||
SGU1WGU2Z0lXNXZtWUlyeS91TlNiVFJPbmw3YkF1V0xFZERqMWRiYzNvCoM/4Yxa
|
||||
2CVMQrIHVcDHgJS5zjtAGU1oJ+V6uagff94KmvhoxutLDZVzMOI4RXJLqX9dhbto
|
||||
y34d5A/e6B8EskY=
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-20T23:41:39Z"
|
||||
mac: ENC[AES256_GCM,data:p0Q4Jgx+qmk3ipmdO49zZJN9Te1lJ8g+WCtRcJmvG1jq0BUxmi4tLt4Ir1u+caK0U1wpLxd0mxkI/b41Wlke5vcd+462nR3GINhGFL0QGWyHv25PmWvWnHIMvxyRA9MmMPmIHQpG/JDUWShriNmKGQwUU2BqW4u53y6M2NguMag=,iv:8BQLnW2ZBzRXawyxcAE4SGpYFx+g+OBt5sxQbsx24AM=,tag:Gj5nIJqCHwfTSU5tvjBGIQ==,type:str]
|
||||
encrypted_regex: ^(data|stringData)$
|
||||
version: 3.12.2
|
||||
@@ -4,6 +4,10 @@ metadata:
|
||||
name: apps
|
||||
namespace: flux-system
|
||||
spec:
|
||||
decryption:
|
||||
provider: sops
|
||||
secretRef:
|
||||
name: sops-age
|
||||
interval: 10m0s
|
||||
path: ./apps/hydra
|
||||
prune: true
|
||||
|
||||
@@ -19,10 +19,10 @@ func main() {
|
||||
err := flux_stack.MarshalYamlFlat(root.FLUX_CLUSTER_HYDRA_PATH)
|
||||
assertNoErr(err)
|
||||
|
||||
hydraApps := map[string]stack.Stack{
|
||||
hydra_apps := map[string]stack.Stack{
|
||||
"linkding": linkding.Stack(),
|
||||
}
|
||||
for name, s := range hydraApps {
|
||||
for name, s := range hydra_apps {
|
||||
fmt.Printf("STACK: %s\n", name)
|
||||
err = s.MarshalYaml(root.FLUX_APPS_HYDRA_PATH)
|
||||
assertNoErr(err)
|
||||
22
cmd/secrets/main.go
Normal file
22
cmd/secrets/main.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"danicos.dev/daniel/homelab/pkg/root"
|
||||
"danicos.dev/daniel/homelab/pkg/secrets"
|
||||
)
|
||||
|
||||
func main() {
|
||||
secrets_stack := secrets.Stack()
|
||||
err := secrets_stack.MarshalYaml(root.TMP_FOLDER)
|
||||
assertNoErr(err)
|
||||
}
|
||||
|
||||
func assertNoErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -20,17 +20,27 @@ var Aliases = map[string]any{
|
||||
|
||||
func init() {
|
||||
Env := map[string]string{
|
||||
"LINUX_ADMIN": "arch",
|
||||
"CLUSTER_NAME": root.HYDRA_CLUSTER,
|
||||
"CLUSTER_HOST": root.HYDRA_HOSTNAME,
|
||||
"GITEA_HOST": root.GITEA_HOST,
|
||||
"LINUX_ADMIN": "arch",
|
||||
"CLUSTER_NAME": root.HYDRA_CLUSTER,
|
||||
"CLUSTER_HOST": root.HYDRA_HOSTNAME,
|
||||
"GITEA_HOST": root.GITEA_HOST,
|
||||
"GO_SECRETS": root.GO_SECRETS_FOLDER,
|
||||
"ENC_SECRETS_PATH": root.GO_ENC_SECRETS_FOLDER,
|
||||
"HYDRA_PATH": root.FLUX_APPS_HYDRA_PATH,
|
||||
"SECRETS_FOLDER": root.SECRETS_FOLDER,
|
||||
"HYDRA_SECRETS_PATH": root.FLUX_APPS_SECRETS_HYDRA_PATH,
|
||||
}
|
||||
r = target.NewRunner(Env, nil)
|
||||
}
|
||||
|
||||
func Build() error {
|
||||
t := target.NewA("go", "run", ".")
|
||||
return r.RunV("run", t)
|
||||
t := target.NewA("go", "run", "./cmd/apps/main.go")
|
||||
return r.RunV("Build apps", t)
|
||||
}
|
||||
|
||||
func Build_secrets() error {
|
||||
t := target.NewA("go", "run", "./cmd/secrets/main.go")
|
||||
return r.RunV("Build secrets", t)
|
||||
}
|
||||
|
||||
func InstallK3S() error {
|
||||
@@ -47,3 +57,15 @@ func InstallFlux() error {
|
||||
t := target.New("./scripts/install_flux.sh")
|
||||
return r.RunV("Install Flux", t)
|
||||
}
|
||||
|
||||
// Uploads AGE Key to flux as a Kubernetes secret
|
||||
func Enc_flux() error {
|
||||
t := target.New("./scripts/encrypt_flux.sh")
|
||||
return r.RunV("Upload key to flux", t)
|
||||
}
|
||||
|
||||
// Encrypt and decrypt Go files that contain secrets.
|
||||
func Enc_Dec(opt string) error {
|
||||
t := target.NewA("./scripts/enc_dec_go.sh", opt)
|
||||
return r.RunV("Enc or Dec Go secrets", t)
|
||||
}
|
||||
|
||||
BIN
pkg/enc/linkding.go.age
Normal file
BIN
pkg/enc/linkding.go.age
Normal file
Binary file not shown.
5
pkg/enc/secrets.go.age
Normal file
5
pkg/enc/secrets.go.age
Normal file
@@ -0,0 +1,5 @@
|
||||
age-encryption.org/v1
|
||||
-> mlkem768x25519 cYiJfHWipORzmkN1ltuNeQ+kEmMNZsQO8WGYRNgc5Gzd33AbnzswSzfDC16dfA5xLlu9397QgmSfgRxG6xD8e7N/MFLSUZRX16wVdV6Dl7GpOF/m/0fOwhSpdKKEJKW8NrwR/Ju6CSfzKtgPGL5qsRoWBSdgOLdkA+6W3DlUwfxHArVaJMNYvHP4E5XGnaVAzFUNYkTpGgJgTBATWP8C0M2kpEARMsTNjXgDPmgvjsvk/Xo5H81S6RiqmxdHIt9gN3y/rjNlOwRFAKk3uHxzzfbW5zGRZAisy4RPRdT9G121xWJmajnFGM9bEJcalbwI6N9w8A48oJfRgOGo0ecLCBEnkEq2OHamKzEZMj6CDgByvZL49BycJQpJ9ijNykZBnCgUPaM4SsqTj9affd2gxsLNHcvLNTmN/vUqkKQXD9bllnwyJ0Pz7t5Lg/tbfDfILCzgcgWGY8KtHDjHV1OTNdoROdrW+aEI95mpqtnkT1gzzcVTZ3ozD3Glkzm8sPBwGjhpARNRpI96eeBUnpgN8dYXpQlV3Gqxl5TEsdBkiVOtII0OaQeg/iW8eh2FTU8/Dg8xjWsyen2abhImROt4TnIvqGmhesLdKguyWa/miAh8flr4CazWpB5Pk2kD+DXUIWsEQCyaZMTZRhuGIBpbguyRbOyx2rCxWWTCevTwl99TQdI1nfu8dfR9jB+DhrTnak7rwLJej0D2jD0iQQ4J1KCNP4knQfR86ujVT4A5J6uU4giA7Hu9np/+JXmZjOl0rethtaq035a405a4uBbNAPn9lzefOC2yULMxM0P8GCWbezr3k9chFCNS9bsMZh/FdgtY7kJxqJOW75zlgm/6pos0Bj45/zFwOyM71y30dOgc7Ex51cKeHRBtYtgsItrNVwkM0DfCH9VU6GgRzMVCq4RrnUT0o3xARfIFaEL3zZD/KoarhMaINEva88tvbf+zm2lDZoW1EsrT2dGKEJzMqZdqC0NjJwOrGHJwh6wy1cRdtEZrGR8zzyAfYAW0XqgfHMljJ5QRgRbqBpqrGthP+3r5fdyWA+5z2Z4cWV2nBSpV0FlPVgxGRnxNMG1zgpeBt8JdAkftgat1AvCZzgSIw1jQJP+Win5DRewK+qzBBIdkPYYawwLPOO6aeG0ahwge0pMQY17F96Y3tw5mi5fHmh+/ms7yG6CJ/4WxdxgbvX2kUpUckT5ZLoAVLn9fAm5Jg4XVyj0z1anTKD8Gjyabaogfk8bHeNZByjo7qbEYHpf/apBFEbg0vgoC85JtmiqfpegTLhHuEaux/V0xCgIfNPHPiYOTQs3Ij//8ALWn3ZBbCg2pZ4I6y0wKtI46vcuVHThy8vWL992a7v601WyfPuB2ZAYpcAy0KU3cEJTQ1Jcc5nqTpT01nVJ3MZLQ5D1Zll+l8WtPYLgTlAEc+qulXReT/Z64clLAdJrdn4wwjBAs5S2RcWWF1CKDG9HJfKFiLA/qeTJDthUYbUQt/FBZew
|
||||
TIif8yenxheEYQcu8isoeyPZ4GUTSjgR/0UOALrhBo4
|
||||
--- ahXiHd/RR2JyVd0AB0/4LC5QBkPbfmuXj77awnvz/eQ
|
||||
g»NfL oÉ’:‡úç<C3BA>R²^àÌ9§ª^€Œ±º0ðSJ¥Ù&N„%…x ØÙ¥Š,¨Ô'ßë4!‡•íš\<Ó–¦I£=ýD·Ì´ÏR]rœ¨:Çédpµ¬çæÎð%›íÏ´»xh•ã¶w¬ªÌ-pGÖÖºžÒþ„h»á‹yšþû›©“TôÍLÙÐNI]ýÉj$ ætà1%¡GÃ8±ïÆŽ/_¹à¼U?¨‘i,ΑOhˆöÂüÙØnE‘¥ñS°r§>ðÙ¨dñ˜z¦½•øœ…ί_+¶à6u¾š:µ¸Å61gnçÄ€9•eý¡…ªOøðHª*–
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"danicos.dev/daniel/go-kube/pkg/stack"
|
||||
"danicos.dev/daniel/homelab/pkg/root"
|
||||
kz "github.com/fluxcd/kustomize-controller/api/v1"
|
||||
flux_meta "github.com/fluxcd/pkg/apis/meta"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@@ -28,6 +29,12 @@ func Apps() kz.Kustomization {
|
||||
retryInteval := durMin(1)
|
||||
timeout := durMin(5)
|
||||
spec := kz.KustomizationSpec{
|
||||
Decryption: &kz.Decryption{
|
||||
Provider: root.FLUX_DECRYPTION_PROVIDER,
|
||||
SecretRef: &flux_meta.LocalObjectReference{
|
||||
Name: "sops-age",
|
||||
},
|
||||
},
|
||||
Interval: durMin(10),
|
||||
RetryInterval: &retryInteval,
|
||||
Timeout: &timeout,
|
||||
|
||||
@@ -8,6 +8,16 @@ import (
|
||||
core "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
var Secret = struct {
|
||||
Name string
|
||||
SuperUserKey string
|
||||
SuperUserPasswordKey string
|
||||
}{
|
||||
Name: root.Linkding.Name,
|
||||
SuperUserKey: "supe_user_name",
|
||||
SuperUserPasswordKey: "supe_user_password",
|
||||
}
|
||||
|
||||
var meta kube.Metadata
|
||||
var Namespace = kube.Namespace("linkding")
|
||||
var srv core.Service
|
||||
@@ -36,6 +46,10 @@ func deployment() apps.Deployment {
|
||||
envMapping := map[string]string{
|
||||
"LD_CSRF_TRUSTED_ORIGINS": "https://link.danicos.me",
|
||||
}
|
||||
secretMapping := map[string]string{
|
||||
"LD_SUPERUSER_NAME": Secret.SuperUserKey,
|
||||
"LD_SUPERUSER_PASSWORD": Secret.SuperUserPasswordKey,
|
||||
}
|
||||
pod_spec := core.PodSpec{
|
||||
SecurityContext: &core.PodSecurityContext{
|
||||
RunAsUser: &root.Linkding.SecurityContextID,
|
||||
@@ -47,7 +61,7 @@ func deployment() apps.Deployment {
|
||||
Name: root.Linkding.Name,
|
||||
Image: root.Linkding.Image,
|
||||
SecurityContext: root.ContainerSecurityContext,
|
||||
Env: kube.NewEnvVar(envMapping),
|
||||
Env: kube.NewEnvVarWithSecret(envMapping, secretMapping, Secret.Name),
|
||||
Ports: []core.ContainerPort{{
|
||||
ContainerPort: root.Linkding.Port,
|
||||
}},
|
||||
@@ -64,4 +78,4 @@ func deployment() apps.Deployment {
|
||||
return kube.NewDeployment(meta, pod_spec)
|
||||
}
|
||||
|
||||
// kubectl --kubeconfig ~/.kube/hydra -n linkding exec -it linking-67f686679d-2tfrk -- python manage.py createsuperuser --username=daniel --email=danicosme@pm.me
|
||||
// kubectl -n linkding exec -it linking-67f686679d-2tfrk -- python manage.py createsuperuser --username=daniel --email=danicosme@pm.me
|
||||
|
||||
@@ -5,15 +5,21 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
HYDRA_CLUSTER = "hydra"
|
||||
HYDRA_HOSTNAME = "hydra-0" // VPN Host
|
||||
GITEA_HOST = "danicos.dev"
|
||||
HYDRA_CLUSTER = "hydra"
|
||||
HYDRA_HOSTNAME = "hydra-0" // VPN Host
|
||||
GITEA_HOST = "danicos.dev"
|
||||
TMP_FOLDER = "./tmp"
|
||||
SECRETS_FOLDER = TMP_FOLDER + "/secrets"
|
||||
GO_SECRETS_FOLDER = "./pkg/secrets"
|
||||
GO_ENC_SECRETS_FOLDER = "./pkg/enc"
|
||||
)
|
||||
|
||||
const (
|
||||
FLUX_NAMESPACE = "flux-system"
|
||||
FLUX_APPS_HYDRA_PATH = "./apps/" + HYDRA_CLUSTER
|
||||
FLUX_CLUSTER_HYDRA_PATH = "./clusters/" + HYDRA_CLUSTER
|
||||
FLUX_NAMESPACE = "flux-system"
|
||||
FLUX_APPS_HYDRA_PATH = "./apps/" + HYDRA_CLUSTER
|
||||
FLUX_APPS_SECRETS_HYDRA_PATH = "./apps/" + HYDRA_CLUSTER + "/secrets"
|
||||
FLUX_CLUSTER_HYDRA_PATH = "./clusters/" + HYDRA_CLUSTER
|
||||
FLUX_DECRYPTION_PROVIDER = "sops"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
13
scripts/create_flux_secret.sh
Executable file
13
scripts/create_flux_secret.sh
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
if [ -z "${AGE_KEY}" ]; then
|
||||
echo "unbound variable"
|
||||
fi
|
||||
if [ ! -f "${AGE_KEY}" ]; then
|
||||
echo "Error: ${AGE_KEY} file does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat $AGE_KEY | kubectl --kubeconfig ~/.kube/hydra create secret generic sops-age --namespace=flux-system --from-file=age.agekey=/dev/stdin
|
||||
35
scripts/enc_dec_go.sh
Executable file
35
scripts/enc_dec_go.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
if [ -z "${AGE_KEY}" ]; then
|
||||
echo "unbound variable"
|
||||
fi
|
||||
if [ ! -f "${AGE_KEY}" ]; then
|
||||
echo "Error: ${AGE_KEY} file does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $ENC_SECRETS_PATH
|
||||
if [ "$1" = "enc" ]; then
|
||||
for FILE in $GO_SECRETS/*; do
|
||||
FILENAME="${FILE##*/}"
|
||||
age --encrypt \
|
||||
--output $ENC_SECRETS_PATH/$FILENAME.age \
|
||||
--identity $AGE_KEY \
|
||||
$FILE
|
||||
done
|
||||
elif [ "$1" = "dec" ]; then
|
||||
mkdir -p $GO_SECRETS
|
||||
for FILE in $ENC_SECRETS_PATH/*; do
|
||||
FILENAME="${FILE##*/}" # Cut the directories path
|
||||
FILENAME="${FILENAME%.age}" # Cut the .age
|
||||
echo $GO_SECRETS/$FILENAME
|
||||
age --decrypt \
|
||||
--identity $AGE_KEY \
|
||||
$FILE > $GO_SECRETS/$FILENAME
|
||||
done
|
||||
else
|
||||
echo "Error: Invalid argument. Use 'enc' or 'dec'." >&2
|
||||
exit 1
|
||||
fi
|
||||
24
scripts/encrypt_flux.sh
Executable file
24
scripts/encrypt_flux.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
if [ -z "${AGE_KEY}" ]; then
|
||||
echo "unbound variable"
|
||||
fi
|
||||
if [ ! -f "${AGE_KEY}" ]; then
|
||||
echo "Error: ${AGE_KEY} file does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
PUBLIC_KEY=$(age-keygen -y $AGE_KEY)
|
||||
|
||||
SECRETS_ENC_PATH=$HYDRA_SECRETS_PATH
|
||||
mkdir -p $SECRETS_ENC_PATH
|
||||
for FILE in $SECRETS_FOLDER/*; do
|
||||
sops --encrypt --in-place $FILE
|
||||
|
||||
FILENAME="${FILE##*/}"
|
||||
DEST=$SECRETS_ENC_PATH/$FILENAME
|
||||
echo Moving encrypted file to $DEST
|
||||
mv $FILE $DEST
|
||||
done
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
set -eu
|
||||
|
||||
echo CLUSTER NAME: $CLUSTER_NAME
|
||||
echo HOST: $CLUSTER_HOST
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
set -eu
|
||||
|
||||
echo CLUSTER NAME: $CLUSTER_NAME
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -euo pipefail
|
||||
set -eu
|
||||
|
||||
echo HOST: $CLUSTER_HOST
|
||||
echo USER: $LINUX_ADMIN
|
||||
|
||||
Reference in New Issue
Block a user