package controller import ( "fmt" "path/filepath" "git.badhouseplants.net/allanger/shoebill/internal/providers" "git.badhouseplants.net/allanger/shoebill/internal/utils/diff" "git.badhouseplants.net/allanger/shoebill/internal/utils/githelper" "git.badhouseplants.net/allanger/shoebill/internal/utils/helmhelper" "git.badhouseplants.net/allanger/shoebill/internal/utils/kustomize" "git.badhouseplants.net/allanger/shoebill/internal/utils/sopshelper" "git.badhouseplants.net/allanger/shoebill/internal/utils/workdir" "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" ) func ReadTheConfig(path string) (*config.Config, error) { conf, err := config.NewConfigFromFile(path) if err != nil { return nil, err } 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 // } 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) workdirPath, err := workdir.CreateWorkdir(definedWorkdirPath) if err != nil { return err } // Prepare helm repositories for _, repository := range conf.Repositories { if err := repository.KindFromUrl(); err != nil { return err } } 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 { err := ch.VersionHandler(workdirPath, hh) if 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) // if len(diffArg) > 0 { // snapshotDir := fmt.Sprint("%s/.snapshot", workdirPath) // cloneSnapshoot(gh, snapshotDir, diffArg) // } // The main logic starts here for _, cluster := range conf.Clusters { // Create a dir for the cluster git repo clusterWorkdirPath := fmt.Sprintf("%s/%s", workdirPath, cluster.Name) // Init a gitops provider (Currently onle flux is supported) provider, err := providers.NewProvider(cluster.Provider, clusterWorkdirPath, conf.SopsBin, gh) if err != nil { return err } if err := cluster.CloneRepo(gh, clusterWorkdirPath, dry); err != nil { return err } if err := cluster.BootstrapRepo(gh, clusterWorkdirPath, dry); err != nil { return err } // Read the lockfile generated by the shoebill lockfileData, err := lockfile.NewFromFile(clusterWorkdirPath) if err != nil { return err } currentRepositories, err := lockfileData.ReposFromLockfile() if err != nil { return err } if err := conf.Releases.PopulateRepositories(conf.Repositories); err != nil { return err } // 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 // } // } if err := release.ValuesHandler(configPath); err != nil { return err } if err := release.SecretsHandler(configPath, sops); err != nil { return err } } releaseObj := release.FindReleaseByNames(cluster.Releases, conf.Releases) cluster.PopulateReleases(releaseObj) releasesCurrent, err := release.ReleasesFromLockfile(lockfileData, conf.Repositories) if err != nil { return err } // Compare releases from the lockfile to ones from the current cluster config diffReleases, err := diff.DiffReleases(releasesCurrent, cluster.ReleasesObj) if err != nil { return err } lockfile, diffRepos, err := diffReleases.Resolve(currentRepositories, clusterWorkdirPath) if err != nil { return err } hashesPerRelease, err := provider.SyncState(diffReleases, diffRepos) if err != nil { return err } if err := kustomize.Generate(clusterWorkdirPath, gh); err != nil { return err } lockfile.AddHashes(hashesPerRelease) if err := lockfile.WriteToFile(clusterWorkdirPath); err != nil { return err } if _, err := gh.AddAllAndCommit(clusterWorkdirPath, "Update the lockfile"); err != nil { return err } if !dry { if err := gh.Push(clusterWorkdirPath); err != nil { return err } } } if !dry { if err := workdir.RemoveWorkdir(workdirPath); err != nil { return err } } return nil }