2023-07-20 09:26:25 +00:00
|
|
|
package controller
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2023-08-02 15:00:34 +00:00
|
|
|
"git.badhouseplants.net/allanger/shoebill/internal/config"
|
|
|
|
"git.badhouseplants.net/allanger/shoebill/internal/config/release"
|
|
|
|
"git.badhouseplants.net/allanger/shoebill/internal/lockfile"
|
|
|
|
"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/workdir"
|
2023-07-20 09:26:25 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func ReadTheConfig(path string) (*config.Config, error) {
|
|
|
|
conf, err := config.NewConfigFromFile(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return conf, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* First it must prepare the workdir
|
|
|
|
* It must create a directorry and clone all the repos that are listed in the config
|
|
|
|
*/
|
|
|
|
func Reconcile(workdirPath, sshKeyPath string, conf *config.Config, dry bool) error {
|
|
|
|
dir, err := workdir.CreateWorkdir(workdirPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, repository := range conf.Repositories {
|
|
|
|
if err := repository.ValidateURL(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := repository.KindFromUrl(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gh := githelper.NewGit(sshKeyPath)
|
|
|
|
for _, cluster := range conf.Clusters {
|
|
|
|
/*
|
|
|
|
* 1. Clone the cluster repo
|
|
|
|
* 2. Check if repo is already configured
|
|
|
|
* Yes -> Bootsrap the repo if it's not configured
|
|
|
|
* - Create the lockfile
|
|
|
|
* - ...
|
|
|
|
* No -> Get the current state
|
|
|
|
* 3. Turn the config file into the lockfile format and compare the actual to the desired
|
|
|
|
*/
|
|
|
|
fullPath := fmt.Sprintf("%s/%s", dir, cluster.Name)
|
|
|
|
provider, err := providers.NewProvider(cluster.Provider, fullPath, gh)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := cluster.CloneRepo(gh, fullPath, dry); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
err = cluster.BootstrapRepo(gh, fullPath, dry)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
lockfileData, err := lockfile.NewFromFile(fullPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
reposExisting, err := lockfileData.ReposFromLockfile()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := conf.Releases.PopulateRepositories(conf.Repositories); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
hh := helmhelper.NewHelm()
|
|
|
|
for _, release := range conf.Releases {
|
|
|
|
err := release.VersionHandler(workdirPath, hh)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rsObj := release.FindReleaseByNames(cluster.Releases, conf.Releases)
|
|
|
|
cluster.PopulateReleases(rsObj)
|
|
|
|
releasesCurrent, err := release.ReleasesFromLockfile(lockfileData, conf.Repositories)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
diffRls, err := diff.DiffReleases(releasesCurrent, cluster.ReleasesObj)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
lockfile, err := diffRls.Resolve(reposExisting, fullPath)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := provider.SyncState(*diffRls); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := kustomize.Generate(fullPath, gh); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := lockfile.WriteToFile(fullPath); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := gh.AddAllAndCommit(fullPath, "Update the lockfile"); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !dry {
|
|
|
|
if err := gh.Push(fullPath); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if !dry {
|
|
|
|
if err := workdir.RemoveWorkdir(dir); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|