4 Commits
init ... main

Author SHA1 Message Date
7e0050b02c Pull charts 2024-09-03 15:27:44 +02:00
5b6a503fd1 Add a chart directory 2024-07-25 19:34:10 +02:00
6e08510b3d A lot of changes 2024-07-25 18:44:58 +02:00
625450ca25 Initial logic is implemented 2024-01-18 01:03:23 +01:00
40 changed files with 474 additions and 1161 deletions

5
.sops.yaml Normal file
View File

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

View File

@ -1,4 +1,4 @@
rrCreative Commons Attribution 4.0 International
Creative Commons Attribution 4.0 International
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.

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,30 +0,0 @@
{{- if .Values.virtualservice.enabled -}}
{{- $fullName := include "vaultwarden.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if $.Capabilities.APIVersions.Has "networking.istio.io/v1beta1" }}
apiVersion: networking.istio.io/v1beta1
kind: VirtalService
metadata:
name: {{ $fullName }}
labels:
{{- include "vaultwarden.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
gateways:
- {{ .Values.virtaulservice.gatewayRef }}
hosts:
- ci.badhouseplants.ne
http:
- match:
- uri:
prefix: /
route:
- destination:
host: woodpecker-ci-server
port:
number: 80
{{- end }}
{{- end }}

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,13 +0,0 @@
---
name: Replace image in default values
targets:
- ./templates/deployment.yaml
- ./templates/pvc.yaml
- ./templates/secret.yaml
- ./templates/service.yaml
before: |-
..labels:
after: |-
labels:
"giantswarm.io/team": honeybudger

View File

@ -1,8 +0,0 @@
---
name: Replace image in default values
targets:
- values.yaml
after: |-
virtualservice:
enables: false

View File

@ -1,17 +0,0 @@
---
name: Replace image in default values
targets:
- values.yaml
before: |-
image:
repository: registry.hub.docker.com/vaultwarden/server
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
after: |-
image:
repository: registry.hub.docker.com/vaultwarden/server
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: ""

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

51
go.mod
View File

@ -9,20 +9,22 @@ replace (
)
require (
github.com/fluxcd/helm-controller/api v0.37.2
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
k8s.io/apimachinery v0.29.0-alpha.0
k8s.io/utils v0.0.0-20231127182322-b307cd553661
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3
sigs.k8s.io/yaml v1.4.0
sigs.k8s.io/yaml v1.3.0
)
require (
@ -80,22 +82,20 @@ require (
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fluxcd/pkg/apis/acl v0.1.0 // indirect
github.com/fluxcd/pkg/apis/kustomize v1.2.0 // indirect
github.com/fluxcd/pkg/apis/meta v1.2.0 // indirect
github.com/frankban/quicktest v1.14.6 // indirect
github.com/fluxcd/pkg/apis/kustomize v1.1.1 // indirect
github.com/fluxcd/pkg/apis/meta v1.1.1 // indirect
github.com/getsops/gopgagent v0.0.0-20170926210634-4d7ea76ff71a // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
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.3.0 // 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
@ -107,7 +107,7 @@ require (
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
@ -171,7 +171,6 @@ require (
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rubenv/sql-migrate v1.3.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/ryanuber/go-glob v1.0.0 // indirect
@ -179,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
@ -190,16 +190,18 @@ 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
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/net v0.26.0 // 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
golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/term v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/term v0.12.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.22.1-0.20240628205440-9c895dd76b34 // indirect
golang.org/x/tools v0.9.1 // indirect
google.golang.org/api v0.141.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
@ -211,17 +213,18 @@ require (
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.28.4 // indirect
k8s.io/apiserver v0.28.4 // indirect
k8s.io/apiextensions-apiserver v0.27.3 // indirect
k8s.io/apiserver v0.27.3 // indirect
k8s.io/cli-runtime v0.29.0-alpha.0 // indirect
k8s.io/client-go v0.29.0-alpha.0 // indirect
k8s.io/component-base v0.29.0-alpha.0 // indirect
k8s.io/klog/v2 v2.110.1 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
k8s.io/kubectl v0.27.2 // indirect
k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect
oras.land/oras-go v1.2.3 // indirect
sigs.k8s.io/controller-runtime v0.16.3 // indirect
sigs.k8s.io/controller-runtime v0.15.0 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/kyaml v0.14.3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)

112
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=
@ -208,8 +214,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4=
github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@ -229,20 +235,19 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/fluxcd/helm-controller/api v0.37.2 h1:tkLezpRdqPDz7HoKHFu92sV+ppOCVDxkjFTh8/lpff8=
github.com/fluxcd/helm-controller/api v0.37.2/go.mod h1:BuXZhAX9blQviil6yUN5zNM4RB753yhyBTJXxXff7Mo=
github.com/fluxcd/helm-controller/api v0.35.0 h1:UyhKXPni5z69DzPW7GtECGGdUwKsB+OTI0A/wc7HmFY=
github.com/fluxcd/helm-controller/api v0.35.0/go.mod h1:CdHMtr5wM0xgDt/PS147H7QQS+zDxAFgDW3ZN8MnUlU=
github.com/fluxcd/pkg/apis/acl v0.1.0 h1:EoAl377hDQYL3WqanWCdifauXqXbMyFuK82NnX6pH4Q=
github.com/fluxcd/pkg/apis/acl v0.1.0/go.mod h1:zfEZzz169Oap034EsDhmCAGgnWlcWmIObZjYMusoXS8=
github.com/fluxcd/pkg/apis/kustomize v1.2.0 h1:vkVs+OumxaWso0jNCqdgFFfMHdh+qtZhykTkjl7OgmA=
github.com/fluxcd/pkg/apis/kustomize v1.2.0/go.mod h1:VF7tR/WuVFeum+HaMTHwp+eCtsHiiQlY6ihgqtAnW/M=
github.com/fluxcd/pkg/apis/meta v1.2.0 h1:O766PzGAdMdQKybSflGL8oV0+GgCNIkdsxfalRyzeO8=
github.com/fluxcd/pkg/apis/meta v1.2.0/go.mod h1:fU/Az9AoVyIxC0oI4ihG0NVMNnvrcCzdEym3wxjIQsc=
github.com/fluxcd/pkg/apis/kustomize v1.1.1 h1:MSGn4z0R9PptmoPFHnx2nEZ8Jtl1sKfw0cuDQY2HYwM=
github.com/fluxcd/pkg/apis/kustomize v1.1.1/go.mod h1:0pCu0ecIY+ZM0iE/hOHYwCMZ3b0SpBrjJ1SH3FFyYdE=
github.com/fluxcd/pkg/apis/meta v1.1.1 h1:sLAKLbEu7rRzJ+Mytffu3NcpfdbOBTa6hcpOQzFWm+M=
github.com/fluxcd/pkg/apis/meta v1.1.1/go.mod h1:soCfzjFWbm1mqybDcOywWKTCEYlH3skpoNGTboVk234=
github.com/fluxcd/source-controller/api v1.0.1 h1:nycylbNBnQd+EO4UHpqXqAQJ1cGAPxgBbrfERCQ1pp8=
github.com/fluxcd/source-controller/api v1.0.1/go.mod h1:rAY5FRFGZUKpIFNyYANHIgPgJPvbALBHWsq/zHw/cXQ=
github.com/foxcpp/go-mockdns v1.0.0 h1:7jBqxd3WDWwi/6WhDvacvH1XsN3rOLXyHM1uhvIx6FI=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/getsops/gopgagent v0.0.0-20170926210634-4d7ea76ff71a h1:qc+7TV35Pq/FlgqECyS5ywq8cSN9j1fwZg6uyZ7G0B0=
@ -271,11 +276,14 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
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=
@ -358,9 +366,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@ -454,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=
@ -603,8 +611,8 @@ github.com/nelsam/hel/v2 v2.3.3/go.mod h1:1ZTGfU2PFTOd5mx22i5O0Lc2GY933lQ2wb/ggy
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
github.com/onsi/gomega v1.27.7 h1:fVih9JD6ogIiHUN6ePK7HJidyEDpWGVB5mzM7cWNXoU=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
@ -664,8 +672,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rubenv/sql-migrate v1.3.1 h1:Vx+n4Du8X8VTYuXbhNxdEUoh6wiJERA0GlWocR5FrbA=
github.com/rubenv/sql-migrate v1.3.1/go.mod h1:YzG/Vh82CwyhTFXy+Mf5ahAiiEOpAlHurg+23VEzcsk=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -775,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=
@ -797,8 +812,8 @@ golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -836,8 +851,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -885,8 +900,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -914,8 +929,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -981,8 +996,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -990,8 +1005,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1005,8 +1020,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1065,11 +1080,12 @@ 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=
golang.org/x/tools v0.22.1-0.20240628205440-9c895dd76b34 h1:Kd+Z5Pm6uwYx3T2KEkeHMHUMZxDPb/q6b1m+zEcy62c=
golang.org/x/tools v0.22.1-0.20240628205440-9c895dd76b34/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1231,40 +1247,40 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.29.0-alpha.0 h1:U+fNSD93YX8KFeYu2mOsKP+AhktiEDw6VdvQ/pQN2kU=
k8s.io/api v0.29.0-alpha.0/go.mod h1:4nKPvoLiBp8GFtH8PBBiOu6dyLq1RQ6RLJvYwohLeQg=
k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU=
k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM=
k8s.io/apiextensions-apiserver v0.27.3 h1:xAwC1iYabi+TDfpRhxh4Eapl14Hs2OftM2DN5MpgKX4=
k8s.io/apiextensions-apiserver v0.27.3/go.mod h1:BH3wJ5NsB9XE1w+R6SSVpKmYNyIiyIz9xAmBl8Mb+84=
k8s.io/apimachinery v0.29.0-alpha.0 h1:0hjEznQCsjbYaMG5uDQhoPtc0SBE+AdN88jmuIBuJUI=
k8s.io/apimachinery v0.29.0-alpha.0/go.mod h1:xhQIsaL3hXneGluH+0pzF7kr+VYuLS/VcYJxF1xQf+g=
k8s.io/apiserver v0.28.4 h1:BJXlaQbAU/RXYX2lRz+E1oPe3G3TKlozMMCZWu5GMgg=
k8s.io/apiserver v0.28.4/go.mod h1:Idq71oXugKZoVGUUL2wgBCTHbUR+FYTWa4rq9j4n23w=
k8s.io/apiserver v0.27.3 h1:AxLvq9JYtveYWK+D/Dz/uoPCfz8JC9asR5z7+I/bbQ4=
k8s.io/apiserver v0.27.3/go.mod h1:Y61+EaBMVWUBJtxD5//cZ48cHZbQD+yIyV/4iEBhhNA=
k8s.io/cli-runtime v0.29.0-alpha.0 h1:wmgJxe+CGibgNLjA9TnRpbeew8Gog/YgdHV90/kCGCk=
k8s.io/cli-runtime v0.29.0-alpha.0/go.mod h1:iMl8eX2927CD3CSeKt1LzI+hsSdC7vZfqQiPrRHdpgg=
k8s.io/client-go v0.29.0-alpha.0 h1:PlJ1deDfJsBFw/s1Mu4mInfcpr/whkKjI/0QVzLU+hE=
k8s.io/client-go v0.29.0-alpha.0/go.mod h1:xyOOIROVCmzmrGdtA0t5PDvzZbH3HqzmJJP6L8T+cNw=
k8s.io/component-base v0.29.0-alpha.0 h1:+hX9QBqjYWW+KZ11huIDj9/QEUwXyEz7VNBGZ76OWFw=
k8s.io/component-base v0.29.0-alpha.0/go.mod h1:00ns6qrLaWg6ZjB0SMfcaFBDNNa90yQZnxW6e76t8JQ=
k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0=
k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/kubectl v0.29.0-alpha.0 h1:jArkBRTnFo3/K1OhxAepHP10/XKJlDNY1C+av22HKdg=
k8s.io/kubectl v0.29.0-alpha.0/go.mod h1:AUg3N14Q3240uySxK1MLKQ/c3GH9a2/uO6J/dWqmX9I=
k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI=
k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU=
k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
oras.land/oras-go v1.2.3 h1:v8PJl+gEAntI1pJ/LCrDgsuk+1PKVavVEPsYIHFE5uY=
oras.land/oras-go v1.2.3/go.mod h1:M/uaPdYklze0Vf3AakfarnpoEckvw0ESbRdN8Z1vdJg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
sigs.k8s.io/controller-runtime v0.15.0 h1:ML+5Adt3qZnMSYxZ7gAverBLNPSMQEibtzAgp0UPojU=
sigs.k8s.io/controller-runtime v0.15.0/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0=
sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY=
sigs.k8s.io/kustomize/kyaml v0.14.3 h1:WpabVAKZe2YEp/irTSHwD6bfjwZnTtSDewd2BVJGMZs=
sigs.k8s.io/kustomize/kyaml v0.14.3/go.mod h1:npvh9epWysfQ689Rtt/U+dpOJDTBn8kUnF1O6VzvmZA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=

View File

@ -1,6 +1,7 @@
package controller
import (
"context"
"fmt"
"path/filepath"
@ -14,7 +15,7 @@ import (
"git.badhouseplants.net/allanger/shoebill/pkg/config"
"git.badhouseplants.net/allanger/shoebill/pkg/lockfile"
"git.badhouseplants.net/allanger/shoebill/pkg/release"
"github.com/sirupsen/logrus"
"github.com/go-logr/logr"
)
func ReadTheConfig(path string) (*config.Config, error) {
@ -25,67 +26,54 @@ func ReadTheConfig(path string) (*config.Config, error) {
return conf, nil
}
func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool, diffArg string) error {
// Start by creating a directory where everything should be happening
configPath := filepath.Dir(conf.ConfigPath)
type SyncOptions struct {
Workdir string
SSHKey string
Dry bool
Config *config.Config
SopsBin string
}
workdirPath, err := workdir.CreateWorkdir(definedWorkdirPath)
type SyncController struct{}
func Sync(ctx context.Context, opts *SyncOptions) error {
log, err := logr.FromContext(ctx)
if err != nil {
return err
}
//for _, release := range conf.Releases {
// // repo := release.PopulateRepository(Repo)
// // release.Pull(repo)
//
//}
//if err := conf.Charts.PopulateRepositories(conf.Repositories); err != nil {
// return err
//}
if err := conf.Releases.PopulateCharts(conf.Charts); err != nil {
return err
}
// Init the helm client
hh := helmhelper.NewHelm()
for _, ch := range conf.Charts {
ch.ExtensionsHandler(configPath)
err := ch.VersionHandler(workdirPath, hh)
if err != nil {
// Start by creating a directory where everything should be happening
configPath := filepath.Dir(opts.Config.ConfigPath)
// Prepare helm repositories
for _, repository := range opts.Config.Repositories {
if err := repository.KindFromUrl(); err != nil {
return err
}
logrus.Info("BEFORE")
if err := ch.SyncMirrors(workdirPath, conf.Mirrors, hh); err != nil {
return err
}
logrus.Info("AFTER")
}
// 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)
// }
// 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
}
@ -100,25 +88,21 @@ func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool,
return err
}
if err := conf.Releases.PopulateRepositories(conf.Repositories, conf.Mirrors); err != nil {
if err := opts.Config.Releases.PopulateRepositories(opts.Config.Repositories); err != nil {
return err
}
// Init the helm client
hh := helmhelper.NewHelm()
// Init the sops client
sops := sopshelper.NewSops()
for _, release := range conf.Releases {
// 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
// }
//
// }
for _, release := range opts.Config.Releases {
err := release.VersionHandler(opts.Workdir, hh)
if err != nil {
return err
}
if err := release.ValuesHandler(configPath); err != nil {
return err
@ -129,10 +113,15 @@ 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)
for _, oneRelease := range releaseObj {
log.Info("Pullin a helm chart to the git repo", "chart", oneRelease.Chart)
if _, err := hh.PullChart(clusterWorkdirPath, oneRelease.ToHelmReleaseData()); err != nil {
return err
}
}
releasesCurrent, err := release.ReleasesFromLockfile(lockfileData, opts.Config.Repositories)
if err != nil {
return err
}
@ -165,15 +154,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

@ -7,7 +7,6 @@ import (
"os"
"os/exec"
"path/filepath"
"time"
"git.badhouseplants.net/allanger/shoebill/internal/utils/diff"
"git.badhouseplants.net/allanger/shoebill/internal/utils/githelper"
@ -189,14 +188,12 @@ func (f *Flux) SyncState(releasesDiffs diff.ReleasesDiffs, repoDiffs diff.Reposi
default:
return nil, fmt.Errorf("unknown action is requests: %s", release.Action)
}
if release.Wished != nil {
hashPerRelease := &lockfile.HashPerRelease{
Release: release.Wished.Release,
Namespace: release.Wished.Namespace,
CommitHash: hash,
}
hashesPerReleases = append(hashesPerReleases, hashPerRelease)
hashPerRelease := &lockfile.HashPerRelease{
Release: release.Wished.Release,
Namespace: release.Wished.Namespace,
CommitHash: hash,
}
hashesPerReleases = append(hashesPerReleases, hashPerRelease)
}
@ -217,9 +214,6 @@ func GenerateRepository(repo *repository.Repository) ([]byte, error) {
Spec: helmrepo_v1beta2.HelmRepositorySpec{
URL: repo.URL,
Type: repo.Kind,
Interval: v1.Duration{
Duration: time.Minute,
},
},
}
return yaml.Marshal(&fluxRepo)
@ -237,9 +231,6 @@ func GenerateRelease(release *release.Release) ([]byte, error) {
Namespace: "flux-system",
},
Spec: release_v2beta1.HelmReleaseSpec{
Interval: v1.Duration{
Duration: time.Minute,
},
Chart: release_v2beta1.HelmChartTemplate{
Spec: release_v2beta1.HelmChartTemplateSpec{
Chart: release.Chart,
@ -261,7 +252,7 @@ func GenerateRelease(release *release.Release) ([]byte, error) {
},
}
for _, v := range release.Values {
filename := fmt.Sprintf("%s-%s-%s", release.Namespace, release.Release, filepath.Base(v))
filename := fmt.Sprintf("%s-%s", release.Release, filepath.Base(v))
fluxRelease.Spec.ValuesFrom = append(fluxRelease.Spec.ValuesFrom, release_v2beta1.ValuesReference{
Kind: "ConfigMap",
Name: filename,
@ -270,7 +261,7 @@ func GenerateRelease(release *release.Release) ([]byte, error) {
}
for _, v := range release.Secrets {
filename := fmt.Sprintf("%s-%s-%s", release.Namespace, release.Release, filepath.Base(v))
filename := fmt.Sprintf("%s-%s", release.Release, filepath.Base(v))
fluxRelease.Spec.ValuesFrom = append(fluxRelease.Spec.ValuesFrom, release_v2beta1.ValuesReference{
Kind: "Secret",
Name: filename,
@ -351,9 +342,6 @@ func SyncValues(currentRelease, wishedRelease *release.Release, secDirPath strin
func SyncSecrets(currentRelease, wishedRelease *release.Release, workdirPath, sopsBin string) error {
secretsDirPath := fmt.Sprintf("%s/src/secrets", workdirPath)
if err := os.MkdirAll(secretsDirPath, os.ModePerm); err != nil {
return err
}
if currentRelease != nil {
for _, secrets := range currentRelease.DestSecrets {
secretsFilePath := fmt.Sprintf("%s/%s", secretsDirPath, secrets.DestPath)
@ -368,6 +356,9 @@ func SyncSecrets(currentRelease, wishedRelease *release.Release, workdirPath, so
// Prepare a dir for secrets
secretsFilePath := fmt.Sprintf("%s/%s", secretsDirPath, secrets.DestPath)
logrus.Infof("trying to create secrets file: %s", secretsFilePath)
if err := os.MkdirAll(secretsDirPath, os.ModePerm); err != nil {
return err
}
var secretsFile *os.File
if _, err := os.Stat(secretsFilePath); err == nil {
secretsFile, err = os.Open(secretsFilePath)

View File

@ -35,6 +35,9 @@ func (g *Git) CloneRepo(workdir, gitURL string, dry bool) error {
if err != nil {
return err
}
if err := os.Mkdir(workdir+"/charts", os.ModePerm); err != nil {
return err
}
r, err := git.PlainInit(workdir, false)
if err != nil {
return err

View File

@ -3,15 +3,16 @@ package helmhelper
import (
"fmt"
"os"
"strings"
"path/filepath"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/engine"
"helm.sh/helm/v3/pkg/registry"
"helm.sh/helm/v3/pkg/repo"
)
type Helm struct{}
@ -24,12 +25,11 @@ func getDownloadDirPath(workdirPath string) string {
return fmt.Sprintf("%s/.charts", workdirPath)
}
func getChartDirPath(downloadDirPath string, release *ChartData) string {
return fmt.Sprintf("%s/%s-%s-%s", downloadDirPath, release.RepositoryName, release.Name, release.Version)
func getChartDirPath(downloadDirPath string, release *ReleaseData) string {
return fmt.Sprintf("%s/%s-%s", downloadDirPath, release.Chart, release.Name)
}
func (h *Helm) PullChart(workdirPath string, release *ChartData) (path string, err error) {
func (h *Helm) PullChart(workdirPath string, release *ReleaseData) (path string, err error) {
downloadDirPath := getDownloadDirPath(workdirPath)
if err := os.MkdirAll(downloadDirPath, 0777); err != nil {
return "", err
@ -51,30 +51,21 @@ func (h *Helm) PullChart(workdirPath string, release *ChartData) (path string, e
return "", err
}
client := action.NewPullWithOpts(action.WithConfig(config))
var path string
var chartRemote string
// Download the chart to the workdir
if release.RepositoryKind != "oci" {
r, err := repo.NewChartRepository(&repo.Entry{
Name: release.RepositoryName,
URL: release.RepositoryURL,
}, getter.All(cl))
if err != nil {
return "", err
}
path = r.Config.Name
client.RepoURL = release.RepositoryURL
chartRemote = fmt.Sprintf(release.Chart)
} else {
path = release.RepositoryURL
}
client := action.NewPullWithOpts(action.WithConfig(config))
chartRemote = fmt.Sprintf("%s/%s", path, release.Chart)
client.SetRegistryClient(registry)
client.Untar = true
client.DestDir = chartDir
}
client.Settings = cl
chartRemote := fmt.Sprintf("%s/%s", path, release.Name)
logrus.Infof("trying to pull: %s", chartRemote)
client.Untar = true
client.UntarDir = chartDir
if _, err = client.Run(chartRemote); err != nil {
return "", err
}
@ -83,14 +74,11 @@ func (h *Helm) PullChart(workdirPath string, release *ChartData) (path string, e
if err != nil {
return "", err
}
logrus.Info(path)
logrus.Info(chartDir)
chartPath := fmt.Sprintf("%s/%s", chartDir, path)
logrus.Info(chartPath)
return chartPath, nil
return path, nil
}
func (h *Helm) FindLatestVersion(workdirPath string, release *ChartData) (version string, err error) {
func (h *Helm) FindLatestVersion(workdirPath string, release *ReleaseData) (version string, err error) {
downloadDirPath := getDownloadDirPath(workdirPath)
if err := os.MkdirAll(downloadDirPath, 0777); err != nil {
return "", err
@ -106,7 +94,7 @@ func (h *Helm) FindLatestVersion(workdirPath string, release *ChartData) (versio
showAction := action.NewShowWithConfig(action.ShowChart, config)
res, err := showAction.LocateChart(chartPath, cl)
res, err := showAction.LocateChart(fmt.Sprintf("%s/%s", chartDir, chartPath), cl)
if err != nil {
return "", err
}
@ -119,92 +107,60 @@ func (h *Helm) FindLatestVersion(workdirPath string, release *ChartData) (versio
if err != nil {
return "", err
}
logrus.Infof("the latest version of %s is %s", release.Name, chartData.Version)
release.Version = chartData.Version
logrus.Infof("the latest version of %s is %s", release.Chart, chartData.Version)
versionedChartDir := getChartDirPath(downloadDirPath, release)
if err := os.Rename(chartDir, versionedChartDir); err != nil {
return "", err
}
os.Rename(chartDir, versionedChartDir)
return chartData.Version, err
}
func (h *Helm) PushChart(chartPath string, server, prefix, username, password string, chartdata *ChartData) (err error) {
_, err = os.Stat(chartPath)
if err != nil && !os.IsNotExist(err) {
return err
} else if os.IsNotExist(err) {
if err := os.Mkdir(chartPath, 0777); err != nil {
return err
}
}
regclient, err := registry.NewClient()
options := registry.LoginOptBasicAuth("allanger", "")
tls := registry.LoginOptInsecure(true)
serverClean := strings.ReplaceAll(server, "oci://", "")
if err :=regclient.Login(serverClean, options, tls); err != nil {
return err
}
if err != nil {
return err
}
tar := action.NewPackage()
tar.Destination = chartPath
tarname, err := tar.Run(chartPath, nil)
// tarpath := fmt.Sprintf("%s/%s", versionedChartDir, tarname)
if err != nil {
return err
}
client := action.NewPushWithOpts(action.WithPushConfig(&action.Configuration{}))
logrus.Infof("trying to push: %s", tarname)
client.Settings = &cli.EnvSettings{}
smth, err := client.Run(tarname, fmt.Sprintf("%s/%s", server, prefix))
if err != nil {
return err
}
logrus.Info(smth)
return nil
}
func (h *Helm) RenderChart(workdirPath string, release *ReleaseData) error {
downloadDirPath := getDownloadDirPath(workdirPath)
chartDirPath := getChartDirPath(downloadDirPath, release)
chartPath, err := getChartPathFromDir(chartDirPath)
if err != nil {
return err
}
logrus.Info(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
chartObj, err := loader.Load(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
if err != nil {
return err
}
values := chartutil.Values{}
values["Values"] = chartObj.Values
values["Release"] = map[string]string{
"Name": release.Name,
"Namespace": release.Namespace,
}
values["Capabilities"] = map[string]map[string]string{
"KubeVersion": {
"Version": "v1.27.9",
"GitVersion": "v1.27.9",
},
}
files, err := engine.Engine{Strict: false}.Render(chartObj, values)
if err != nil {
return err
}
logrus.Info(files)
for file, data := range files {
logrus.Infof("%s - %s", file, data)
}
logrus.Info("I'm here")
return nil
// downloadDirPath := getDownloadDirPath(workdirPath)
// chartDirPath := getChartDirPath(downloadDirPath, release)
// chartPath, err := getChartPathFromDir(chartDirPath)
// if err != nil {
// return err
// }
// logrus.Info(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
// chartObj, err := loader.Load(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
// if err != nil {
// return err
// }
// values := chartutil.Values{}
// values["Values"] = chartObj.Values
// values["Release"] = map[string]string{
// "Name": release.Name,
// "Namespace": release.Namespace,
// }
// values["Capabilities"] = map[string]map[string]string{
// "KubeVersion": {
// "Version": "v1.27.9",
// "GitVersion": "v1.27.9",
// },
// }
// files, err := engine.Engine{Strict: false}.Render(chartObj, values)
// if err != nil {
// return err
// }
// logrus.Info(files)
// for file, data := range files {
// logrus.Infof("%s - %s", file, data)
// }
// logrus.Info("I'm here")
// return nil
}
func getChartPathFromDir(downloadDir string) (file string, err error) {
filesRM, err := filepath.Glob(fmt.Sprintf("%s/*.tgz", downloadDir))
if err != nil {
return "", err
}
for _, f := range filesRM {
if err := os.Remove(f); err != nil {
return "", err
}
}
files, err := os.ReadDir(downloadDir)
if err != nil {
return "", err
} else if len(files) == 0 {
@ -215,8 +171,8 @@ func getChartPathFromDir(downloadDir string) (file string, err error) {
return files[0].Name(), nil
}
func chartFromString(info string) (*ChartData, error) {
releaseData := new(ChartData)
func chartFromString(info string) (*ReleaseData, error) {
releaseData := new(ReleaseData)
if err := yaml.Unmarshal([]byte(info), &releaseData); err != nil {
return nil, err
}

View File

@ -11,18 +11,14 @@ func NewHelmMock() Helmhelper {
return &Mock{}
}
func (h *Mock) FindLatestVersion(workdir string, release *ChartData) (version string, err error) {
func (h *Mock) FindLatestVersion(workdir string, release *ReleaseData) (version string, err error) {
return MOCK_LATEST_VERSION, nil
}
func (h *Mock) PullChart(workdirPath string, release *ChartData) (path string, err error) {
func (h *Mock) PullChart(workdirPath string, release *ReleaseData) (path string, err error) {
return MOCK_CHART_PATH, nil
}
func (h *Mock) RenderChart(workdirPath string, release *ReleaseData) error {
return nil
}
func (h *Mock) PushChart(chartDir string, server, prefix, username, password string, chartdata *ChartData) (err error) {
return nil
}

View File

@ -1,10 +1,9 @@
package helmhelper
type Helmhelper interface {
FindLatestVersion(workdirPath string, release *ChartData) (string, error)
PullChart(workdirPath string, release *ChartData) (string, error)
FindLatestVersion(workdirPath string, release *ReleaseData) (string, error)
PullChart(workdirPath string, release *ReleaseData) (string, error)
RenderChart(workdirPath string, release *ReleaseData) error
PushChart(chartDir, server, prefix, username, password string, chart *ChartData) error
}
type ReleaseData struct {
@ -17,12 +16,3 @@ type ReleaseData struct {
RepositoryKind string
ValuesData string
}
type ChartData struct {
Name string
Version string
RepositoryName string
RepositoryURL string
RepositoryKind string
}

View File

@ -1,22 +1,38 @@
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
}
return path, nil
// 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 {
return "", err
return workdir, err
}
return workdir, nil
}
if err := os.Mkdir(workdir+"/.charts", os.ModePerm); err != nil {
return "", err
}
return workdir, nil
}
func RemoveWorkdir(path string) (err error) {

87
main.go
View File

@ -1,16 +1,83 @@
package main
import (
"context"
"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"
)
// asfasdf
func main() {
var ctx context.Context
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

@ -1,171 +0,0 @@
package chart
import (
"fmt"
"os"
"strings"
"git.badhouseplants.net/allanger/shoebill/internal/utils/helmhelper"
"git.badhouseplants.net/allanger/shoebill/pkg/chart/patches"
"git.badhouseplants.net/allanger/shoebill/pkg/mirror"
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
"github.com/sirupsen/logrus"
"k8s.io/utils/strings/slices"
)
type Chart struct {
// Internal name of the chart
Name string
// Official name of the chart
Chart string
// Name of the repository to pull from
// Defined in repositories
Repository string
// Version of a chart
Version string
Mirrors []string
Extensions []string
Patches []string
// Private fields that should be pupulated during the run-time
RepositoryObj *repository.Repository `yaml:"-"`
MirrorObjs mirror.Mirrors `yaml:"-"`
}
type Charts []*Chart
// Possible version placeholders
const (
VERSION_LATEST = "latest"
)
func (r *Chart) MirrorObjsFromName(mirrors mirror.Mirrors) {
var mirObj mirror.Mirrors
for _, mir := range mirrors{
if slices.Contains(r.Mirrors, mir.Name){
mirObj = append(mirObj, mir)
}
}
r.MirrorObjs = mirObj
}
func (ch *Chart) SyncMirrors(workDir string, mirrors mirror.Mirrors, hh helmhelper.Helmhelper) error {
if len(ch.Mirrors) > 0 {
ch.MirrorObjsFromName(mirrors)
path, err := hh.PullChart(workDir, ch.ToHelmReleaseData())
if err != nil {
return err
}
for _, ext := range ch.Extensions {
files, err := os.ReadDir(ext)
if err != nil {
return err
}
for _, filePath := range files {
extensionFilePath := fmt.Sprintf("%s/%s", ext, filePath.Name())
file, err := os.ReadFile(extensionFilePath)
if err != nil {
return err
}
logrus.Info(path)
extenrsionTargetDir := fmt.Sprintf("%s/templates/extensions", path)
if err := os.MkdirAll(extenrsionTargetDir, os.ModePerm); err != nil {
return err
}
extensionTargetPath := fmt.Sprintf("%s/%s", extenrsionTargetDir, filePath.Name())
if err := os.WriteFile(extensionTargetPath, file, os.ModePerm); err != nil {
return err
}
}
}
for _, patch := range ch.Patches {
files, err := os.ReadDir(patch)
if err != nil {
return err
}
for _, filePath := range files {
fullPatchPath := fmt.Sprintf("%s/%s", patch, filePath.Name())
ptch, err := patches.NewPatchFromFile(fullPatchPath)
if err != nil {
return err
}
if err := ptch.Apply(path); err != nil {
return err
}
}
}
for _, mr := range ch.MirrorObjs {
err := hh.PushChart(path, mr.OCI.URL, mr.OCI.Prefix, "", "", ch.ToHelmReleaseData())
if err != nil {
return err
}
}
}
return nil
}
// RepositoryObjFromName gather the whole repository object by its name
func (r *Chart) RepositoryObjFromName(repos repository.Repositories) error {
for _, repo := range repos {
if repo.Name == r.Repository {
r.RepositoryObj = repo
}
}
if r.RepositoryObj == nil {
return fmt.Errorf("couldn't gather the RepositoryObj for %s", r.Repository)
}
return nil
}
func (chs *Charts) PopulateRepositories(repos repository.Repositories) error {
for _, ch := range *chs {
if err := ch.RepositoryObjFromName(repos); err != nil {
return err
}
}
return nil
}
// Replace the version placeholder with the fixed version
func (r *Chart) VersionHandler(dir string, hh helmhelper.Helmhelper) error {
if len(r.Version) == 0 {
r.Version = VERSION_LATEST
}
switch r.Version {
case VERSION_LATEST:
version, err := hh.FindLatestVersion(dir, r.ToHelmReleaseData())
if err != nil {
return err
}
r.Version = version
}
return nil
}
func (r *Chart) ExtensionsHandler(dir string) {
for i := range r.Extensions {
r.Extensions[i] = fmt.Sprintf("%s/%s", dir, strings.ReplaceAll(r.Extensions[i], "./", ""))
}
}
func (r *Chart) PatchesHandler(dir string) {
for i := range r.Patches {
r.Patches[i] = fmt.Sprintf("%s/%s", dir, strings.ReplaceAll(r.Patches[i], "./", ""))
}
}
func (r *Chart) ToHelmReleaseData() *helmhelper.ChartData {
// valuesData =
// for _, data := range r.DestValues {
// }
logrus.Info(r)
return &helmhelper.ChartData{
Name: r.Chart,
Version: r.Version,
RepositoryName: r.RepositoryObj.Name,
RepositoryURL: r.RepositoryObj.URL,
RepositoryKind: r.RepositoryObj.Kind,
}
}

View File

@ -1,72 +0,0 @@
package patches
import (
"fmt"
"os"
"regexp"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
)
type Patch struct {
Name string
Targets []string
Before string
After string
}
type Patches []*Patch
func NewPatchFromFile(filePath string) (*Patch, error){
var patch Patch
logrus.Infof("reading a new patch file: %s", filePath)
patchFile, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
if err := yaml.Unmarshal(patchFile, &patch); err != nil {
return nil, err
}
return &patch, nil
}
func(p *Patch) Apply(chartDir string) error {
logrus.Infof("Applying patch: %s", p.Name)
if len(p.Before) > 0 {
beforeCompiled, err := regexp.Compile(p.Before)
if err != nil {
return err
}
for _, target := range p.Targets {
fullTarget := fmt.Sprintf("%s/%s", chartDir, target)
file, err := os.ReadFile(fullTarget)
if err != nil {
return err
}
newfile := beforeCompiled.ReplaceAll(file, []byte(p.After))
err = os.WriteFile(fullTarget, newfile, os.ModePerm)
if err != nil {
return err
}
}
} else {
for _, target := range p.Targets {
fullTarget := fmt.Sprintf("%s/%s", chartDir, target)
f, err := os.OpenFile(fullTarget, os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm)
if err != nil {
return err
}
defer f.Close()
if _, err := f.Write([]byte(p.After + "\n")); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
}
}
return nil
}

View File

@ -3,20 +3,16 @@ package config
import (
"os"
"git.badhouseplants.net/allanger/shoebill/pkg/chart"
"git.badhouseplants.net/allanger/shoebill/pkg/cluster"
"git.badhouseplants.net/allanger/shoebill/pkg/mirror"
"git.badhouseplants.net/allanger/shoebill/pkg/release"
"github.com/sirupsen/logrus"
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
"gopkg.in/yaml.v2"
)
type Config struct {
Repositories Repositories
Repositories repository.Repositories
Releases release.Releases
Clusters cluster.Clusters
Charts chart.Charts
Mirrors mirror.Mirrors
ConfigPath string `yaml:"-"`
SopsBin string `yaml:"-"`
}
@ -24,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

@ -1,40 +0,0 @@
package config
import (
"fmt"
)
/*
* Helm repo kinds: default/oci
*/
const (
HELM_REPO_OCI = "oci"
HELM_REPO_DEFAULT = "default"
)
type Repository struct {
Name string
Helm *RepositoryHelm
Git *RepositoryGit
}
type RepositoryHelm struct {
URL string
}
type RepositoryGit struct {
URL string
// Git ref
Ref string
// Path inside a git repo
Path string
}
type Repositories []*Repository
func (r *Repository) ValidateConfig() error {
if r.Helm != nil && r.Git != nil {
return fmt.Errorf("repo %s is invalid, only one repo kind can be specified", r.Name)
}
return nil
}

View File

@ -1,56 +0,0 @@
package config_test
import (
"fmt"
"testing"
"git.badhouseplants.net/allanger/shoebill/pkg/config"
"github.com/stretchr/testify/assert"
)
func TestBothRepoKindsError(t *testing.T) {
repo := &config.Repository{
Name: "test",
Helm: &config.RepositoryHelm{
URL: "test",
},
Git: &config.RepositoryGit{
URL: "test",
Ref: "test",
Path: "test",
},
}
err := repo.ValidateConfig()
assert.ErrorContains(t, err,
"repo test is invalid, only one repo kind can be specified",
fmt.Sprintf("haven't got an unexpected err: %s", err))
}
func TestHelmRepoNoError(t *testing.T) {
repo := &config.Repository{
Name: "test",
Helm: &config.RepositoryHelm{
URL: "test",
},
}
err := repo.ValidateConfig()
assert.NoError(t, err,
fmt.Sprintf("got an unexpected err: %s", err))
}
func TestGitRepoNoError(t *testing.T) {
repo := &config.Repository{
Name: "test",
Git: &config.RepositoryGit{
URL: "test",
Ref: "test",
Path: "test",
},
}
err := repo.ValidateConfig()
assert.NoError(t, err,
fmt.Sprintf("got an unexpected err: %s", 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,22 +0,0 @@
package mirror
import (
"git.badhouseplants.net/allanger/shoebill/internal/utils/helmhelper"
)
type Mirror struct {
Name string
OCI *OCIMirror
}
type OCIMirror struct {
URL string
Prefix string
}
type Mirrors []*Mirror
func (m *Mirror) Auth(dir string, hh helmhelper.Helmhelper) error{
return nil
}

View File

@ -1,6 +1,8 @@
package release
import (
"crypto/sha1"
"encoding/base64"
"fmt"
"os"
"path/filepath"
@ -9,10 +11,7 @@ import (
"git.badhouseplants.net/allanger/shoebill/internal/utils/helmhelper"
"git.badhouseplants.net/allanger/shoebill/internal/utils/sopshelper"
"git.badhouseplants.net/allanger/shoebill/pkg/chart"
"git.badhouseplants.net/allanger/shoebill/pkg/config"
"git.badhouseplants.net/allanger/shoebill/pkg/lockfile"
"git.badhouseplants.net/allanger/shoebill/pkg/mirror"
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
"github.com/sirupsen/logrus"
)
@ -32,10 +31,8 @@ type Release struct {
Values []string
// Secrets SOPS encrypted
Secrets []string
Mirror string
// Private fields that should be pupulated during the run-time
RepositoryObj *repository.Repository `yaml:"-"`
ChartObj *chart.Chart `yaml:"-"`
DestValues ValuesHolders `yaml:"-"`
DestSecrets ValuesHolders `yaml:"-"`
}
@ -87,39 +84,29 @@ func (r *Release) RepositoryObjFromName(repos repository.Repositories) error {
return nil
}
// RepositoryObjFromName gather the whole repository object by its name
func (r *Release) MirrorObjFromName(mirrors mirror.Mirrors) error {
for _, mir := range mirrors {
if mir.Name == r.Mirror {
r.RepositoryObj = &repository.Repository{
Name: mir.Name,
URL: fmt.Sprintf("%s/%s", mir.OCI.URL, mir.OCI.Prefix),
}
}
}
if r.RepositoryObj == nil {
return fmt.Errorf("couldn't gather the RepositoryObj from mirror for %s", r.Repository)
}
return nil
}
func (r *Release) ChartObjFromName(chs chart.Charts) error {
for _, ch := range chs {
if ch.Name == r.Chart {
r.ChartObj = ch
}
}
if r.ChartObj == nil {
return fmt.Errorf("couldn't gather the ChartObj for %s", r.Chart)
}
return nil
}
// Possible version placeholders
const (
VERSION_LATEST = "latest"
)
// Replace the version placeholder with the fixed version
func (r *Release) VersionHandler(dir string, hh helmhelper.Helmhelper) error {
if len(r.Version) == 0 {
r.Version = VERSION_LATEST
}
switch r.Version {
case VERSION_LATEST:
version, err := hh.FindLatestVersion(dir, r.ToHelmReleaseData())
if err != nil {
return err
}
logrus.Info(version)
r.Version = version
}
return nil
}
func (r *Release) ValuesHandler(dir string) error {
for i := range r.Values {
r.Values[i] = fmt.Sprintf("%s/%s", dir, strings.ReplaceAll(r.Values[i], "./", ""))
@ -195,6 +182,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,
@ -202,8 +203,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,
}
}
@ -249,24 +250,9 @@ func (src Releases) Diff(dest Releases) Diff {
return diff
}
func (rs *Releases) PopulateRepositories(repos config.Repositories, mirrors mirror.Mirrors) error {
func (rs *Releases) PopulateRepositories(repos repository.Repositories) error {
for _, r := range *rs {
if len(r.Mirror) > 0 {
if err := r.MirrorObjFromName(mirrors); err != nil {
return err
}
} else {
if err := r.RepositoryObjFromName(repos); err != nil {
return err
}
}
}
return nil
}
func (rs *Releases) PopulateCharts(chs chart.Charts) error {
for _, r := range *rs {
if err := r.ChartObjFromName(chs); err != nil {
if err := r.RepositoryObjFromName(repos); err != nil {
return err
}
}

View File

@ -1,25 +1,73 @@
---
repositories:
- name: metrics-server
url: https://kubernetes-sigs.github.io/metrics-server/
- name: jetstack
helm:
url: https://charts.jetstack.io
url: https://charts.jetstack.io
- name: istio
url: https://istio-release.storage.googleapis.com/charts
- name: bitnami-oci
url: oci://registry-1.docker.io/bitnamicharts
releases:
- name: cert-manager
release: cert-manager
repository: jetstack
- name: metrics-server
repository: metrics-server
chart: metrics-server
version: 3.11.0
installed: true
namespace: kube-system
createNamespace: false
- name: istio-base
repository: istio
chart: base
installed: true
namespace: istio-system
createNamespace: false
version: 1.19.2
- name: istio-ingressgateway
repository: istio
chart: gateway
version: 1.19.2
installed: true
namespace: istio-system
createNamespace: false
- name: istiod
repository: istio
version: latest
chart: istiod
installed: true
namespace: istio-system
createNamespace: false
- name: postgresql-server
chart: postgresql
repository: bitnami-oci
namespace: postgresql-server
version: latest
values:
- ./examples/values.postgres.yaml
secrets:
- ./examples/secrets.postgres.yaml
environments:
- name: cluster-shoebill-test
clusters:
- 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
reconcileRef: main
releases:
- name: vaultwarden
- metrics-server
- istio-base
- istio-ingressgateway
- istiod
- postgresql-server