From 93ad3389b254a6526a1cc91d90f9d092993a50ae Mon Sep 17 00:00:00 2001 From: Nikolai Rodionov Date: Fri, 13 Oct 2023 18:02:11 +0200 Subject: [PATCH] WIP: Trying to diff --- cmd/sync.go | 6 ++- internal/controller/controller.go | 16 +++++- internal/utils/helmhelper/helm.go | 84 ++++++++++++++++++++++++------ internal/utils/helmhelper/mock.go | 17 +++++- internal/utils/helmhelper/types.go | 2 + pkg/release/release.go | 3 ++ shoebill.yaml | 1 + 7 files changed, 109 insertions(+), 20 deletions(-) diff --git a/cmd/sync.go b/cmd/sync.go index 97c7d50..bb3a5c3 100644 --- a/cmd/sync.go +++ b/cmd/sync.go @@ -19,7 +19,8 @@ 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 no push changes to git") + sync.Flags().Bool("dry-run", false, "If set to false, will not push changes to git") + sync.Flags().Bool("diff", false, "If set to false, will show helm diffs for not preserved charts") sync.Flags().String("sops-bin", "/usr/bin/sops", "A path to the sops binary in your system") rootCmd.AddCommand(sync) @@ -31,6 +32,7 @@ func syncCmd(cmd *cobra.Command, args []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().GetBool("diff") if err != nil { logrus.Fatal(err) } @@ -41,7 +43,7 @@ func syncCmd(cmd *cobra.Command, args []string) { } configObj.SopsBin = sopsBin - err = controller.Reconcile(workdir, sshKey, configObj, dryRun) + err = controller.Sync(workdir, sshKey, configObj, dryRun, diff) if err != nil { logrus.Fatal(err) } diff --git a/internal/controller/controller.go b/internal/controller/controller.go index 03e892d..27a1682 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -24,7 +24,7 @@ func ReadTheConfig(path string) (*config.Config, error) { return conf, nil } -func Reconcile(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry bool) error { +func Sync(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry, diffArg bool) error { // Start by creating a directory where everything should be happening configPath := filepath.Dir(conf.ConfigPath) workdirPath, err := workdir.CreateWorkdir(definedWorkdirPath) @@ -88,6 +88,14 @@ func Reconcile(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry b return err } + if diffArg { + _, err := hh.PullChart(workdirPath, *release.RepositoryObj, release.Chart, release.Version) + if err != nil { + return err + } + hh.RenderChart(workdirPath, *release.RepositoryObj, release.Chart, release.Version) + } + if err := release.ValuesHandler(configPath); err != nil { return err } @@ -105,6 +113,12 @@ func Reconcile(definedWorkdirPath, sshKeyPath string, conf *config.Config, dry b return err } + if diffArg { + for _, releaseCurrent := range releasesCurrent { + hh.PullChart(workdirPath, *releaseCurrent.RepositoryObj, releaseCurrent.Chart, releaseCurrent.Version) + } + } + // Compare releases from the lockfile to ones from the current cluster config diffReleases, err := diff.DiffReleases(releasesCurrent, cluster.ReleasesObj) if err != nil { diff --git a/internal/utils/helmhelper/helm.go b/internal/utils/helmhelper/helm.go index 57cf499..908c870 100644 --- a/internal/utils/helmhelper/helm.go +++ b/internal/utils/helmhelper/helm.go @@ -8,7 +8,9 @@ import ( "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/cli" + "helm.sh/helm/v3/pkg/engine" "helm.sh/helm/v3/pkg/getter" "helm.sh/helm/v3/pkg/registry" "helm.sh/helm/v3/pkg/repo" @@ -24,23 +26,32 @@ type ChartData struct { Version string } -func (h *Helm) FindLatestVersion(dir, chart string, repository repository.Repository) (version string, err error) { - downloadDir := fmt.Sprintf("%s/.charts", dir) - if err := os.MkdirAll(downloadDir, 0777); err != nil { +func getDownloadDirPath(workdirPath string) string { + return fmt.Sprintf("%s/.charts", workdirPath) +} + +func getChartDirPath(downloadDirPath, repository, chart, version string) string { + return fmt.Sprintf("%s/%s-%s-%s", downloadDirPath, repository, chart, version) + +} + +func (h *Helm) PullChart(workdirPath string, repository repository.Repository, chart, version string) (path string, err error) { + downloadDirPath := getDownloadDirPath(workdirPath) + if err := os.MkdirAll(downloadDirPath, 0777); err != nil { return "", err } - // If file doesn't exist + config := new(action.Configuration) cl := cli.New() - chartDir := fmt.Sprintf("%s/%s-%s", downloadDir, repository.Name, chart) + chartDir := getChartDirPath(downloadDirPath, repository.Name, chart, version) _, err = os.Stat(chartDir) + if err != nil && !os.IsNotExist(err) { return "", nil } else if os.IsNotExist(err) { if err := os.Mkdir(chartDir, 0777); err != nil { return "", err } - registry, err := registry.NewClient() if err != nil { return "", err @@ -72,16 +83,32 @@ func (h *Helm) FindLatestVersion(dir, chart string, repository repository.Reposi if _, err = client.Run(chartRemote); err != nil { return "", err } - } - - showAction := action.NewShowWithConfig(action.ShowChart, config) - - chartPath, err := getChartPathFromDir(chartDir) + path, err = getChartPathFromDir(chartDir) if err != nil { return "", err } + return path, nil +} + +func (h *Helm) FindLatestVersion(workdirPath, chart string, repository repository.Repository) (version string, err error) { + downloadDirPath := getDownloadDirPath(workdirPath) + if err := os.MkdirAll(downloadDirPath, 0777); err != nil { + return "", err + } + + config := new(action.Configuration) + cl := cli.New() + chartDir := getChartDirPath(downloadDirPath, repository.Name, chart, "latest") + chartPath, err := h.PullChart(workdirPath, repository, chart, "latest") + if err != nil { + return "", err + } + + showAction := action.NewShowWithConfig(action.ShowChart, config) + action.New + res, err := showAction.LocateChart(fmt.Sprintf("%s/%s", chartDir, chartPath), cl) if err != nil { return "", err @@ -96,17 +123,44 @@ func (h *Helm) FindLatestVersion(dir, chart string, repository repository.Reposi return "", err } logrus.Infof("the latest version of %s is %s", chart, chartData.Version) + versionedChartDir := getChartDirPath(downloadDirPath, repository.Name, chart, chartData.Version) + os.Rename(chartDir, versionedChartDir) return chartData.Version, err } -func getChartPathFromDir(dir string) (file string, err error) { - files, err := os.ReadDir(dir) +func (h *Helm) RenderChart(workdirPath string, repository repository.Repository, ch2art, version string) error { + downloadDirPath := getDownloadDirPath(workdirPath) + chartDirPath := getChartDirPath(downloadDirPath, repository.Name, ch2art, version) + chartPath, err := getChartPathFromDir(chartDirPath) + if err != nil { + return nil + } + logrus.Info(fmt.Sprintf("%s/%s", chartDirPath, chartPath)) + chartObj, err := loader.Load(fmt.Sprintf("%s/%s", chartDirPath, chartPath)) + if err != nil { + return err + } + config := new(action.Configuration) + client := action.NewInstall(config) + client.RepoURL = repository.URL + client.ReleaseName = ch2art + + res, err := engine.Render(chartObj, nil) + if err != nil { + return err + } + logrus.Infof("%v", res) + return nil +} + +func getChartPathFromDir(downloadDir string) (file string, err error) { + files, err := os.ReadDir(downloadDir) if err != nil { return "", err } else if len(files) == 0 { - return "", fmt.Errorf("expected to have one file, got zero in a dir %s", dir) + return "", fmt.Errorf("expected to have one file, got zero in a dir %s", downloadDir) } else if len(files) > 1 { - return "", fmt.Errorf("expected to have only one file in a dir %s", dir) + return "", fmt.Errorf("expected to have only one file in a dir %s", downloadDir) } return files[0].Name(), nil } diff --git a/internal/utils/helmhelper/mock.go b/internal/utils/helmhelper/mock.go index 2ab94cd..0b08859 100644 --- a/internal/utils/helmhelper/mock.go +++ b/internal/utils/helmhelper/mock.go @@ -1,8 +1,13 @@ package helmhelper -import "git.badhouseplants.net/allanger/shoebill/pkg/repository" +import ( + "git.badhouseplants.net/allanger/shoebill/pkg/repository" +) -const MOCK_LATEST_VERSION = "v1.12.1" +const ( + MOCK_LATEST_VERSION = "v1.12.1" + MOCK_CHART_PATH = ".charts/repo-release-latest/release-latest.gz" +) type Mock struct{} @@ -13,3 +18,11 @@ func NewHelmMock() Helmhelper { func (h *Mock) FindLatestVersion(dir, chart string, repository repository.Repository) (version string, err error) { return MOCK_LATEST_VERSION, nil } + +func (h *Mock) PullChart(workdirPath string, repository repository.Repository, chart, version string) (path string, err error) { + return MOCK_CHART_PATH, nil +} + +func (h *Mock) RenderChart(workdirPath string, repository repository.Repository, ch2art, version string) error { + return nil +} diff --git a/internal/utils/helmhelper/types.go b/internal/utils/helmhelper/types.go index 55d55ef..b2bcbd6 100644 --- a/internal/utils/helmhelper/types.go +++ b/internal/utils/helmhelper/types.go @@ -4,4 +4,6 @@ import "git.badhouseplants.net/allanger/shoebill/pkg/repository" type Helmhelper interface { FindLatestVersion(dir, chart string, repository repository.Repository) (string, error) + PullChart(workdirPath string, repository repository.Repository, chart, version string) (string, error) + RenderChart(workdirPath string, repository repository.Repository, ch2art, version string) error } diff --git a/pkg/release/release.go b/pkg/release/release.go index 9692ab9..3fa7370 100644 --- a/pkg/release/release.go +++ b/pkg/release/release.go @@ -73,6 +73,9 @@ const ( // 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.Chart, *r.RepositoryObj) diff --git a/shoebill.yaml b/shoebill.yaml index 9cd02c7..2f7f3ca 100644 --- a/shoebill.yaml +++ b/shoebill.yaml @@ -64,6 +64,7 @@ releases: - name: istiod repository: istio + version: latest chart: istiod installed: true namespace: istio-system