A lot of changes

This commit is contained in:
Nikolai Rodionov 2024-07-25 18:44:58 +02:00
parent 625450ca25
commit 6e08510b3d
No known key found for this signature in database
GPG Key ID: B874DEE37A0C17DB
25 changed files with 225 additions and 443 deletions

5
.sops.yaml Normal file
View File

@ -0,0 +1,5 @@
creation_rules:
- path_regex: examples/.*.yaml
key_groups:
- age:
- age1htrz6hfc29ww5mypa3hy3ds6558ydgjletsrahj3h3mrgc2xgcwqpe2c7p

View File

@ -2,3 +2,19 @@
A templater for the gitops setup
## Age keys for development
### Source
```
# created: 2024-07-25T16:12:51+02:00
# public key: age1htrz6hfc29ww5mypa3hy3ds6558ydgjletsrahj3h3mrgc2xgcwqpe2c7p
AGE-SECRET-KEY-1SZRD3TU328L8LHZGNT6WTG6J5GPSJS693CD5P9ZCKD3776DNG5HQ54Y0NF
```
### Destination
```
# created: 2024-07-25T16:13:14+02:00
# public key: age1hcpgy4yy4psp6y2jt8waemzgg7crtlpxf3a48l6jvl6zmxll3vjsxj75vu
AGE-SECRET-KEY-1SXVFW2PM6WDC2P68EZQ4L2MVVQHC337FDRCRNLNJA4UAK82ATDFSKNG9PV
```

View File

@ -1,47 +0,0 @@
package cmd
import (
"context"
"fmt"
"os"
"git.badhouseplants.net/allanger/shoebill/internal/build"
"github.com/spf13/cobra"
)
var fullVersion = fmt.Sprintf("%s - %s", build.Version, build.CommitHash)
var longDescription = `---
shoebill is just GitOps with a glottal T
It's a tool that is supposed to help engineers follow the GitOps practies
without fighting with GitOps being inapplicable to the real world.
Yeah, I quite hate this GitOps obsession, but since it's already there,
I think it makes sense to make it work.
---
Information about the build:
Version: %s (build on %s)
---
`
var (
rootCmd = &cobra.Command{
Use: "shoebill",
Short: "shoebill GitOps without pain, kinda",
Long: fmt.Sprintf(longDescription, fullVersion, build.BuildTime),
SilenceErrors: true,
SilenceUsage: true,
Version: build.Version,
}
)
func Execute(ctx context.Context) error {
rootCmd.PersistentFlags().Bool("server", false, "Set to true, if you want to start it in the deamon mode")
if err := rootCmd.ExecuteContext(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Whoops. There was an error while executing your CLI '%s'", err)
os.Exit(1)
}
return nil
}

View File

@ -1,52 +0,0 @@
package cmd
import (
"git.badhouseplants.net/allanger/shoebill/internal/controller"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var (
sync = &cobra.Command{
Use: "sync",
Short: "sync does something",
Long: ``,
Run: syncCmd,
}
)
func init() {
sync.Flags().StringP("config", "c", "config.yaml", "A path to the configuration file")
sync.Flags().String("workdir", "", "A path to the workdir. On the moment of running, it should be an empty dir")
sync.Flags().String("ssh-key", "", "A path to the pricate ssh key")
sync.Flags().Bool("dry-run", false, "If set to false, will not push changes to git")
sync.Flags().String("diff", "main", "If values us set, will show helm diffs for not preserved charts, values will be taken from the target branch")
sync.Flags().String("sops-bin", "/usr/bin/sops", "A path to the sops binary in your system")
rootCmd.AddCommand(sync)
}
func syncCmd(cmd *cobra.Command, args []string) {
config := cmd.Flag("config").Value.String()
workdir := cmd.Flag("workdir").Value.String()
sshKey := cmd.Flag("ssh-key").Value.String()
sopsBin := cmd.Flag("sops-bin").Value.String()
dryRun, err := cmd.Flags().GetBool("dry-run")
diff, err := cmd.Flags().GetString("diff")
if err != nil {
logrus.Fatal(err)
}
configObj, err := controller.ReadTheConfig(config)
if err != nil {
logrus.Fatal(err)
}
configObj.SopsBin = sopsBin
err = controller.Sync(workdir, sshKey, configObj, dryRun, diff)
if err != nil {
logrus.Fatal(err)
}
logrus.Info("your config is synced")
}

View File

@ -1,28 +0,0 @@
---
import:
- ./repos-oci.yaml
- ./repos.yaml
repos:
- name: jetstack
url: https://charts.jetstack.io
- name: bitnami-oci
url: oci://registry-1.docker.io/bitnamicharts
releases:
- name: cert-manager
chart: jetstack
repo: jetstack
version: latest
namespace: cert-manager
- name: postgresql-server
chart: postgresql
repo: bitnami-oci
namespace: postgresql-server
version: latest
clusters:
- name: cluster-1
git: git@git.badhouseplants.net:giant-swarm-task/cluster-1.git
releases:
- cert-manager
- postgresql-server

View File

@ -1,4 +0,0 @@
---
repos:
- name: bitnami-oci
url: oci://registry-1.docker.io/bitnamicharts

View File

@ -1,4 +0,0 @@
---
repos:
- name: jetstack
url: https://charts.jetstack.io

View File

@ -1,5 +0,0 @@
creation_rules:
- path_regex: secrets/.*.yaml
key_groups:
- age:
- age16svfskd8x75g62f5uwpmgqzth52rr3wgv9m6rxchqv6v6kzmzf0qvhr2pk

View File

@ -1,38 +0,0 @@
---
repositories:
- name: bitnami-oci
url: oci://registry-1.docker.io/bitnamicharts
releases:
- name: postgresql-server-2
chart: postgresql
repository: bitnami-oci
namespace: postgresql-server
version: latest
values:
- ./values/postgresql.yaml
secrets:
- ./secrets/postgresql.yaml
- name: postgresql-server
chart: postgresql
repository: bitnami-oci
namespace: postgresql-server
version: latest
values:
- ./values/postgresql.yaml
secrets:
- ./secrets/postgresql.yaml
clusters:
- name: cluster-shoebill-test
git: git@git.badhouseplants.net:allanger/shoebill-test.git
dotsops: |
creation_rules:
- path_regex: secrets/.*.yaml
key_groups:
- age:
- age16svfskd8x75g62f5uwpmgqzth52rr3wgv9m6rxchqv6v6kzmzf0qvhr2pk
provider: flux
releases:
- postgresql-server-2
- postgresql-server

View File

@ -1,140 +0,0 @@
---
repositories:
- name: fluxcd-community
url: https://fluxcd-community.github.io/helm-charts
releases:
# ---------------------------------
# -- FLUX
# ---------------------------------
- name: flux
namespace: flux-system
installed: true
createNamespace: true
chart: fluxcd-community/flux2
- <<: *metrics-server
installed: true
namespace: kube-system
createNamespace: false
- <<: *istio-base
installed: true
namespace: istio-system
createNamespace: false
- <<: *istio-gateway
installed: true
namespace: istio-system
createNamespace: false
- <<: *istiod
installed: true
namespace: istio-system
createNamespace: false
- <<: *cert-manager
installed: true
namespace: cert-manager
createNamespace: false
- <<: *minio
installed: true
namespace: minio-service
createNamespace: false
- <<: *openvpn
installed: true
namespace: openvpn-service
createNamespace: false
- <<: *metallb
installed: true
namespace: metallb-system
createNamespace: true
- <<: *drone
installed: true
namespace: drone-service
createNamespace: false
- <<: *drone-runner-docker
installed: true
namespace: drone-service
createNamespace: false
- <<: *longhorn
installed: true
namespace: longhorn-system
createNamespace: false
- <<: *argocd
installed: true
namespace: argo-system
createNamespace: false
- <<: *nrodionov
installed: true
namespace: nrodionov-application
createNamespace: false
- <<: *minecraft
installed: true
namespace: minecraft-application
createNamespace: false
- <<: *gitea
installed: true
namespace: gitea-service
createNamespace: false
- <<: *funkwhale
installed: true
namespace: funkwhale-application
createNamespace: false
- <<: *prometheus
installed: true
namespace: monitoring-system
createNamespace: true
- <<: *loki
installed: false
namespace: monitoring-system
createNamespace: false
- <<: *promtail
installed: false
namespace: monitoring-system
createNamespace: false
- <<: *bitwarden
installed: true
namespace: bitwarden-application
createNamespace: true
- <<: *redis
installed: true
namespace: database-service
createNamespace: true
- <<: *postgres16
installed: true
namespace: database-service
createNamespace: true
- <<: *db-operator
installed: true
namespace: database-service
createNamespace: true
- <<: *db-instances
installed: true
namespace: database-service
createNamespace: true
- <<: *mysql
installed: true
namespace: database-service
createNamespace: true

View File

@ -1,3 +0,0 @@
# created: 2023-09-25T10:45:28+02:00
# public key: age16svfskd8x75g62f5uwpmgqzth52rr3wgv9m6rxchqv6v6kzmzf0qvhr2pk
AGE-SECRET-KEY-1Y3FGYSHKWSSZ3G8DJ3QD7WKE5J0TTYDWSSD95EXL4A308ZWW0L9SN99ASP

View File

@ -1,24 +0,0 @@
global:
postgresql:
auth:
password: ENC[AES256_GCM,data:5QV6a1A=,iv:utR62wuLTzwihVwXXPw8DA2Ul7kfU1YgAKteRA+WKm0=,tag:EYuIa6TDmxaR0PSuaJBeBA==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age16svfskd8x75g62f5uwpmgqzth52rr3wgv9m6rxchqv6v6kzmzf0qvhr2pk
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2SUJpdUtYWjF3K1dzbGc3
Z2U0UDVpWmVkYXVvT1V3UWVDM2VTQ1hBU1RBCmFZMlI4ZWxWTTdCd05lVFVCN2hN
QkZKRmlFVStXT2kxSVlUNmU0VkZCUDQKLS0tIEQ2aXZ0ZDVXcGc4RE1WMmtOaTV3
TDloa0dHTFhyUWhid1V0aEFydmtQbU0Kwkw914se9cGEN4FKNphuJErdC1QlYqRQ
+CInCnoy8m0/MZNhehZ/JVReEys6KDNxJ7RhnoRfs7P7wfAgBg984A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2023-10-11T11:13:13Z"
mac: ENC[AES256_GCM,data:olaWkaoqqoStswMNNUY6IljoriMgpWxhQ4f0AiRkiujat7ySjuUlS/gwBO1FQp+iB1XGnZKznOWDmZn8XEoFY6q+2dgrtA+h5fTI/EshPgX8xONsGH25Chhg2ER1FMKj8jOYEzxSJfW9s3oKyFGXAH/OgLMpZBkq2uc+eM83J2w=,iv:3fs4BEeFuWU2Nd8yC9iM89a6sz11izIfx3fLI5+1eJU=,tag:Y6ESSNnm2t9zGHG57qrQaQ==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.0

View File

@ -1,6 +0,0 @@
---
global:
postgresql:
auth:
username: check
database: check

View File

@ -0,0 +1,24 @@
global:
postgresql:
auth:
postgresPassword: ENC[AES256_GCM,data:PC+kyanM5L3/ztbA+LY=,iv:LEKwP9iImZdZ+TBfRrgkkwGefFFwSnWmxAWRoTgfzyE=,tag:YkxzpTwV6Dp4onPLmKBWdQ==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age1htrz6hfc29ww5mypa3hy3ds6558ydgjletsrahj3h3mrgc2xgcwqpe2c7p
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWTzFhdHZ6dDNnN3pGRU1V
b0NjWFpwZkRnZUhNMjEra2dsbGZMV1M3NTBrCm9nTnZ6aUpJOXMwN3NDME9XdStL
Y2dJQ1E5TDl0T2JuZFhuSmxVUU9Sd2cKLS0tIEV3KzU1M20zdFVPOGFibTVHVDM5
YXUzdDl1WDlBeno3OHBDN0FqeVdFM0EKtEWO6z5zPK5kEoRqyNovxW67bdxc2evZ
9EzpmzIjwVoW91Ji7CPO4so12SPd0fqZ1C2sOr8KHf6v88oWknTmTQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-07-25T15:20:34Z"
mac: ENC[AES256_GCM,data:8qvcmX0WeROQEiQkkoFk+mY8Ze0sePKLmCKeDwBqvLge/c3oDXzWf07qMmiErDxWtCME9eQpzZkjC9dTvBgYYpfHz24cBfoH4swlXkhPbk26iKYXQIOK1+1SSf6rtsmFjkjylmM1u4yRXuwJZ8pGCu5av1h0edo5jMJLWBS78cA=,iv:OImdF6MvYSliA/OapIGtIX3pbvUFKgfvNCQYBQmwwVc=,tag:qos90QWOn2p5QOZLZMtoOw==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.0

View File

@ -1,20 +0,0 @@
---
repositories:
- name: bitnami-oci
url: oci://registry-1.docker.io/bitnamicharts
releases:
- name: postgresql-server
chart: postgresql
repository: bitnami-oci
namespace: postgresql-server
version: latest
values:
- ./values/postgresql.yaml
clusters:
- name: cluster-shoebill-test
git: git@git.badhouseplants.net:allanger/shoebill-test.git
provider: flux
releases:
- postgresql-server

View File

@ -0,0 +1,12 @@
architecture: standalone
auth:
database: postgres
primary:
persistence:
size: 1Gi
metrics:
enabled: false

9
go.mod
View File

@ -9,13 +9,16 @@ replace (
)
require (
github.com/alecthomas/kong v0.9.0
github.com/fluxcd/helm-controller/api v0.35.0
github.com/fluxcd/source-controller/api v1.0.1
github.com/getsops/sops/v3 v3.8.0
github.com/go-git/go-git/v5 v5.8.1
github.com/go-logr/logr v1.2.4
github.com/go-logr/zapr v1.2.4
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
go.uber.org/zap v1.24.0
gopkg.in/yaml.v2 v2.4.0
helm.sh/helm/v3 v3.12.2
k8s.io/api v0.29.0-alpha.0
@ -93,7 +96,6 @@ require (
github.com/go-git/go-billy/v5 v5.4.1 // indirect
github.com/go-gorp/gorp/v3 v3.0.5 // indirect
github.com/go-jose/go-jose/v3 v3.0.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
@ -176,6 +178,7 @@ require (
github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.2.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/urfave/cli v1.22.14 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
@ -187,6 +190,8 @@ require (
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.15.0 // indirect

18
go.sum
View File

@ -96,6 +96,10 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/O
github.com/a8m/expect v1.0.0/go.mod h1:4IwSCMumY49ScypDnjNbYEjgVeqy1/U2cEs3Lat96eA=
github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
github.com/alecthomas/kong v0.9.0 h1:G5diXxc85KvoV2f0ZRVuMsi45IrBgx9zDNGNj165aPA=
github.com/alecthomas/kong v0.9.0/go.mod h1:Y47y5gKfHp1hDc7CH7OeXgLIpp+Q2m1Ni0L5s3bI8Os=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
@ -134,6 +138,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.21.5 h1:CQBFElb0LS8RojMJlxRSo/HXipvT
github.com/aws/aws-sdk-go-v2/service/sts v1.21.5/go.mod h1:VC7JDqsqiwXukYEDjoHh9U0fOJtNWh04FPQz4ct4GGU=
github.com/aws/smithy-go v1.14.2 h1:MJU9hqBGbvWZdApzpvoF2WAIJDbtjK2NDJSiJP7HblQ=
github.com/aws/smithy-go v1.14.2/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -276,6 +282,8 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo=
github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
@ -453,6 +461,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/vault/api v1.10.0 h1:/US7sIjWN6Imp4o/Rj1Ce2Nr5bki/AXi9vAW3p2tOJQ=
github.com/hashicorp/vault/api v1.10.0/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@ -773,10 +782,18 @@ go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93V
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -1063,6 +1080,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=

View File

@ -1,6 +1,7 @@
package controller
import (
"context"
"fmt"
"path/filepath"
@ -24,51 +25,49 @@ func ReadTheConfig(path string) (*config.Config, error) {
return conf, nil
}
// func cloneSnapshoot(gh githelper.Githelper, snapshotDir, snapshotBranch string) error {
// if err := gh.CloneRepo(snapshotBranch, snapshotUrl, false); err != nil {
// return err
// }
// return nil
// }
type SyncOptions struct {
Workdir string
SSHKey string
Dry bool
Config *config.Config
SopsBin string
}
func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool, diffArg string) error {
type SyncController struct{}
func Sync(ctx context.Context, opts *SyncOptions) error {
// Start by creating a directory where everything should be happening
configPath := filepath.Dir(conf.ConfigPath)
workdirPath, err := workdir.CreateWorkdir(definedWorkdirPath)
if err != nil {
return err
}
configPath := filepath.Dir(opts.Config.ConfigPath)
// Prepare helm repositories
for _, repository := range conf.Repositories {
for _, repository := range opts.Config.Repositories {
if err := repository.KindFromUrl(); err != nil {
return err
}
}
// Configure a git client
gh := githelper.NewGit(sshKeyPath)
gh := githelper.NewGit(opts.SSHKey)
// if len(diffArg) > 0 {
// snapshotDir := fmt.Sprint("%s/.snapshot", workdirPath)
// cloneSnapshoot(gh, snapshotDir, diffArg)
// snapshotDir := fmt.Sprint("%s/.snapshot", workdirPath)
// cloneSnapshoot(gh, snapshotDir, diffArg)
// }
// The main logic starts here
for _, cluster := range conf.Clusters {
for _, cluster := range opts.Config.Clusters {
// Create a dir for the cluster git repo
clusterWorkdirPath := fmt.Sprintf("%s/%s", workdirPath, cluster.Name)
clusterWorkdirPath := fmt.Sprintf("%s/%s", opts.Workdir, cluster.Name)
// Init a gitops provider (Currently onle flux is supported)
provider, err := providers.NewProvider(cluster.Provider, clusterWorkdirPath, conf.SopsBin, gh)
provider, err := providers.NewProvider(cluster.Provider, clusterWorkdirPath, opts.SopsBin, gh)
if err != nil {
return err
}
if err := cluster.CloneRepo(gh, clusterWorkdirPath, dry); err != nil {
if err := cluster.CloneRepo(gh, clusterWorkdirPath, opts.Dry); err != nil {
return err
}
if err := cluster.BootstrapRepo(gh, clusterWorkdirPath, dry); err != nil {
if err := cluster.BootstrapRepo(gh, clusterWorkdirPath, opts.Dry); err != nil {
return err
}
@ -83,7 +82,7 @@ func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool,
return err
}
if err := conf.Releases.PopulateRepositories(conf.Repositories); err != nil {
if err := opts.Config.Releases.PopulateRepositories(opts.Config.Repositories); err != nil {
return err
}
@ -93,23 +92,12 @@ func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool,
// Init the sops client
sops := sopshelper.NewSops()
for _, release := range conf.Releases {
err := release.VersionHandler(workdirPath, hh)
for _, release := range opts.Config.Releases {
err := release.VersionHandler(opts.Workdir, hh)
if err != nil {
return err
}
if len(diffArg) > 0 {
_, err := hh.PullChart(workdirPath, release.ToHelmReleaseData())
if err != nil {
return err
}
if err := hh.RenderChart(workdirPath, release.ToHelmReleaseData()); err != nil {
return err
}
}
if err := release.ValuesHandler(configPath); err != nil {
return err
}
@ -119,20 +107,14 @@ func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool,
}
}
releaseObj := release.FindReleaseByNames(cluster.Releases, conf.Releases)
releaseObj := release.FindReleaseByNames(cluster.Releases, opts.Config.Releases)
cluster.PopulateReleases(releaseObj)
releasesCurrent, err := release.ReleasesFromLockfile(lockfileData, conf.Repositories)
releasesCurrent, err := release.ReleasesFromLockfile(lockfileData, opts.Config.Repositories)
if err != nil {
return err
}
if len(diffArg) > 0 {
for _, releaseCurrent := range releasesCurrent {
hh.PullChart(workdirPath, releaseCurrent.ToHelmReleaseData())
}
}
// Compare releases from the lockfile to ones from the current cluster config
diffReleases, err := diff.DiffReleases(releasesCurrent, cluster.ReleasesObj)
if err != nil {
@ -161,15 +143,15 @@ func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool,
if _, err := gh.AddAllAndCommit(clusterWorkdirPath, "Update the lockfile"); err != nil {
return err
}
if !dry {
if !opts.Dry {
if err := gh.Push(clusterWorkdirPath); err != nil {
return err
}
}
}
if !dry {
if err := workdir.RemoveWorkdir(workdirPath); err != nil {
if !opts.Dry {
if err := workdir.RemoveWorkdir(opts.Workdir); err != nil {
return err
}
}

View File

@ -1,9 +1,19 @@
package workdir
import "os"
import (
"context"
"os"
func CreateWorkdir(path string) (workdir string, err error) {
"github.com/go-logr/logr"
)
func CreateWorkdir(ctx context.Context, path string) (workdir string, err error) {
log, err := logr.FromContext(ctx)
if err != nil {
return "", err
}
if len(path) > 0 {
log.Info("Creating a new directory", "path", path)
// Create a dir using the path
if err := os.Mkdir(path, 0777); err != nil {
return path, err
@ -11,6 +21,7 @@ func CreateWorkdir(path string) (workdir string, err error) {
// TODO(@allanger): I've got a feeling that it doesn't have to look that bad
workdir = path
} else {
log.Info("Path is not set, creating a temporary directory")
// Create a temporary dir
workdir, err = os.MkdirTemp("", "shoebill")
if err != nil {

82
main.go
View File

@ -2,14 +2,82 @@ package main
import (
"context"
"fmt"
"git.badhouseplants.net/allanger/shoebill/cmd"
"github.com/sirupsen/logrus"
"git.badhouseplants.net/allanger/shoebill/internal/controller"
"git.badhouseplants.net/allanger/shoebill/internal/utils/workdir"
"github.com/alecthomas/kong"
"github.com/go-logr/logr"
"github.com/go-logr/zapr"
"go.uber.org/zap"
)
func main() {
ctx := context.Background()
if err := cmd.Execute(ctx); err != nil {
logrus.Fatal(err)
}
type Sync struct {
Config string `short:"c" default:"config.yaml" help:"A path to the configuration file"`
Workdir string `short:"w" default:"" help:"A path to a workdir"`
SshKey string `help:"A path to the ssh key that should be used for git operations"`
DryRun bool `help:"Run the generation without pushing to repos"`
SopsBin string `default:"/usr/bin/sops" help:"A path to the sops binary"`
}
var CLI struct {
Sync Sync `cmd:"" help:"Sync gitops configs"`
}
func main() {
var log logr.Logger
zapLog, err := zap.NewDevelopment()
if err != nil {
panic(fmt.Sprintf("who watches the watchmen (%v)?", err))
}
log = zapr.NewLogger(zapLog)
ctx := logr.NewContext(context.Background(), log)
cmd := kong.Parse(&CLI)
switch cmd.Command() {
case "sync":
if err := syncCmd(ctx, CLI.Sync); err != nil {
log.Error(err, "Error occured during the execution")
}
default:
panic(cmd.Command())
}
}
func syncCmd(ctx context.Context, args Sync) error {
log, err := logr.FromContext(ctx)
if err != nil {
return err
}
log.Info("Setting up the sync command")
log.Info("Trying to read the config file", "path", args.Config)
configObj, err := controller.ReadTheConfig(args.Config)
if err != nil {
log.Error(err, "Couldn't read the config file")
return err
}
log.Info("Preparing the workdir")
workdirPath, err := workdir.CreateWorkdir(ctx, args.Workdir)
if err != nil {
log.Error(err, "Couldn't prepare a working directory")
return err
}
syncOptions := &controller.SyncOptions{
SSHKey: args.SshKey,
Dry: args.DryRun,
Config: configObj,
Workdir: workdirPath,
SopsBin: args.SopsBin,
}
if err := controller.Sync(ctx, syncOptions); err != nil {
log.Error(err, "Couldn't sync the config")
return err
}
return nil
}

View File

@ -6,7 +6,6 @@ import (
"git.badhouseplants.net/allanger/shoebill/pkg/cluster"
"git.badhouseplants.net/allanger/shoebill/pkg/release"
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
@ -21,7 +20,6 @@ type Config struct {
// NewConfigFromFile populates the config struct from a configuration yaml file
func NewConfigFromFile(path string) (*Config, error) {
var config Config
logrus.Infof("readig the config file: %s", path)
configFile, err := os.ReadFile(path)
if err != nil {
return nil, err

View File

@ -19,8 +19,8 @@ type LockEntry struct {
RepoUrl string
RepoName string
GitCommit string
Values []string
Secrets []string
Values map[string]string
Secrets map[string]string
}
type HashPerRelease struct {

View File

@ -1,6 +1,8 @@
package release
import (
"crypto/sha1"
"encoding/base64"
"fmt"
"os"
"path/filepath"
@ -36,9 +38,9 @@ type Release struct {
}
func (r *Release) ToHelmReleaseData() *helmhelper.ReleaseData {
// valuesData =
// valuesData =
// for _, data := range r.DestValues {
// }
return &helmhelper.ReleaseData{
Name: r.Release,
@ -179,6 +181,20 @@ func ReleasesFromLockfile(lockfile lockfile.LockFile, repos repository.Repositor
}
func (r *Release) LockEntry() *lockfile.LockEntry {
valuesHashes := map[string]string{}
for _, valueHolder := range r.DestValues {
hasher := sha1.New()
hasher.Write(valueHolder.Data)
sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
valuesHashes[valueHolder.DestPath] = sha
}
secretHashes := map[string]string{}
for _, valueHolder := range r.DestSecrets {
hasher := sha1.New()
hasher.Write(valueHolder.Data)
sha := base64.URLEncoding.EncodeToString(hasher.Sum(nil))
secretHashes[valueHolder.DestPath] = sha
}
return &lockfile.LockEntry{
Chart: r.Chart,
Release: r.Release,
@ -186,8 +202,8 @@ func (r *Release) LockEntry() *lockfile.LockEntry {
Namespace: r.Namespace,
RepoUrl: r.RepositoryObj.URL,
RepoName: r.RepositoryObj.Name,
Values: r.DestValues.ToStrings(),
Secrets: r.DestSecrets.ToStrings(),
Values: valuesHashes,
Secrets: secretHashes,
}
}

View File

@ -49,20 +49,20 @@ releases:
namespace: postgresql-server
version: latest
values:
- ./examples/one-config/values/postgresql.yaml
- ./examples/values.postgres.yaml
secrets:
- ./examples/one-config/secrets/postgresql.yaml
- ./examples/secrets.postgres.yaml
clusters:
- name: cluster-shoebill-test
- name: cluster-shoebill-tes
git: git@git.badhouseplants.net:allanger/shoebill-test.git
dotsops: |
creation_rules:
- path_regex: secrets/.*.yaml
key_groups:
- age:
- age16svfskd8x75g62f5uwpmgqzth52rr3wgv9m6rxchqv6v6kzmzf0qvhr2pk
- age1hcpgy4yy4psp6y2jt8waemzgg7crtlpxf3a48l6jvl6zmxll3vjsxj75vu
provider: flux
releases:
- metrics-server
@ -70,5 +70,3 @@ clusters:
- istio-ingressgateway
- istiod
- postgresql-server