WIP: start adding values support
This commit is contained in:
parent
b2a43af042
commit
beef71b128
@ -1,26 +1,16 @@
|
|||||||
---
|
---
|
||||||
repositories:
|
repositories:
|
||||||
- name: jetstack
|
|
||||||
url: https://charts.jetstack.io
|
|
||||||
- name: bitnami-oci
|
- name: bitnami-oci
|
||||||
url: oci://registry-1.docker.io/bitnamicharts
|
url: oci://registry-1.docker.io/bitnamicharts
|
||||||
|
|
||||||
releases:
|
releases:
|
||||||
- name: cert-manager
|
|
||||||
chart: cert-manager
|
|
||||||
repository: jetstack
|
|
||||||
version: latest
|
|
||||||
namespace: cert-manager
|
|
||||||
- name: cert-manager-2
|
|
||||||
chart: cert-manager
|
|
||||||
repository: jetstack
|
|
||||||
version: latest
|
|
||||||
namespace: cert-manager
|
|
||||||
- name: postgresql-server
|
- name: postgresql-server
|
||||||
chart: postgresql
|
chart: postgresql
|
||||||
repository: bitnami-oci
|
repository: bitnami-oci
|
||||||
namespace: postgresql-server
|
namespace: postgresql-server
|
||||||
version: latest
|
version: latest
|
||||||
|
values:
|
||||||
|
- ./values/postgresql.yaml
|
||||||
|
|
||||||
clusters:
|
clusters:
|
||||||
- name: cluster-shoebill-test
|
- name: cluster-shoebill-test
|
||||||
@ -28,5 +18,3 @@ clusters:
|
|||||||
provider: flux
|
provider: flux
|
||||||
releases:
|
releases:
|
||||||
- postgresql-server
|
- postgresql-server
|
||||||
- cert-manager
|
|
||||||
# - cert-manager-2
|
|
||||||
|
6
examples/one-config/values/postgresql.yaml
Normal file
6
examples/one-config/values/postgresql.yaml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
global:
|
||||||
|
postgresql:
|
||||||
|
auth:
|
||||||
|
username: check
|
||||||
|
password: check
|
@ -14,6 +14,7 @@ type Config struct {
|
|||||||
Repositories repository.Repositories
|
Repositories repository.Repositories
|
||||||
Releases release.Releases
|
Releases release.Releases
|
||||||
Clusters cluster.Clusters
|
Clusters cluster.Clusters
|
||||||
|
ConfigPath string `yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewConfigFromFile populates the config struct from a configuration yaml file
|
// NewConfigFromFile populates the config struct from a configuration yaml file
|
||||||
@ -27,5 +28,6 @@ func NewConfigFromFile(path string) (*Config, error) {
|
|||||||
if err := yaml.Unmarshal(configFile, &config); err != nil {
|
if err := yaml.Unmarshal(configFile, &config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
config.ConfigPath = path
|
||||||
return &config, nil
|
return &config, nil
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package release
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/config/repository"
|
"git.badhouseplants.net/allanger/shoebill/internal/config/repository"
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/lockfile"
|
"git.badhouseplants.net/allanger/shoebill/internal/lockfile"
|
||||||
@ -21,6 +22,8 @@ type Release struct {
|
|||||||
Version string
|
Version string
|
||||||
// Namespace to install release
|
// Namespace to install release
|
||||||
Namespace string
|
Namespace string
|
||||||
|
// Value files
|
||||||
|
Values []string
|
||||||
// Private fields that should be pupulated during the run-time
|
// Private fields that should be pupulated during the run-time
|
||||||
RepositoryObj *repository.Repository `yaml:"-"`
|
RepositoryObj *repository.Repository `yaml:"-"`
|
||||||
}
|
}
|
||||||
@ -59,6 +62,12 @@ func (r *Release) VersionHandler(dir string, hh helmhelper.Helmhelper) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Release) ValuesHandler(dir string) {
|
||||||
|
for i := range r.Values {
|
||||||
|
r.Values[i] = fmt.Sprintf("%s/%s", dir, strings.ReplaceAll(r.Values[i], "./", ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func FindReleaseByNames(releases []string, releasesObj Releases) Releases {
|
func FindReleaseByNames(releases []string, releasesObj Releases) Releases {
|
||||||
result := Releases{}
|
result := Releases{}
|
||||||
for _, rObj := range releasesObj {
|
for _, rObj := range releasesObj {
|
||||||
|
@ -2,6 +2,7 @@ package controller
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/config"
|
"git.badhouseplants.net/allanger/shoebill/internal/config"
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/config/release"
|
"git.badhouseplants.net/allanger/shoebill/internal/config/release"
|
||||||
@ -22,15 +23,12 @@ func ReadTheConfig(path string) (*config.Config, error) {
|
|||||||
return conf, nil
|
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 {
|
func Reconcile(workdirPath, sshKeyPath string, conf *config.Config, dry bool) error {
|
||||||
dir, err := workdir.CreateWorkdir(workdirPath)
|
dir, err := workdir.CreateWorkdir(workdirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// Prepare repositories
|
||||||
for _, repository := range conf.Repositories {
|
for _, repository := range conf.Repositories {
|
||||||
if err := repository.ValidateURL(); err != nil {
|
if err := repository.ValidateURL(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -39,17 +37,10 @@ func Reconcile(workdirPath, sshKeyPath string, conf *config.Config, dry bool) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gh := githelper.NewGit(sshKeyPath)
|
gh := githelper.NewGit(sshKeyPath)
|
||||||
|
|
||||||
for _, cluster := range conf.Clusters {
|
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)
|
fullPath := fmt.Sprintf("%s/%s", dir, cluster.Name)
|
||||||
provider, err := providers.NewProvider(cluster.Provider, fullPath, gh)
|
provider, err := providers.NewProvider(cluster.Provider, fullPath, gh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -59,10 +50,12 @@ func Reconcile(workdirPath, sshKeyPath string, conf *config.Config, dry bool) er
|
|||||||
if err := cluster.CloneRepo(gh, fullPath, dry); err != nil {
|
if err := cluster.CloneRepo(gh, fullPath, dry); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cluster.BootstrapRepo(gh, fullPath, dry)
|
err = cluster.BootstrapRepo(gh, fullPath, dry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lockfileData, err := lockfile.NewFromFile(fullPath)
|
lockfileData, err := lockfile.NewFromFile(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -78,11 +71,13 @@ func Reconcile(workdirPath, sshKeyPath string, conf *config.Config, dry bool) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
hh := helmhelper.NewHelm()
|
hh := helmhelper.NewHelm()
|
||||||
|
|
||||||
for _, release := range conf.Releases {
|
for _, release := range conf.Releases {
|
||||||
err := release.VersionHandler(workdirPath, hh)
|
err := release.VersionHandler(workdirPath, hh)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
release.ValuesHandler(filepath.Dir(conf.ConfigPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
rsObj := release.FindReleaseByNames(cluster.Releases, conf.Releases)
|
rsObj := release.FindReleaseByNames(cluster.Releases, conf.Releases)
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package providers
|
package providers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/config/release"
|
"git.badhouseplants.net/allanger/shoebill/internal/config/release"
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/config/repository"
|
"git.badhouseplants.net/allanger/shoebill/internal/config/repository"
|
||||||
@ -10,6 +13,7 @@ import (
|
|||||||
"git.badhouseplants.net/allanger/shoebill/internal/utils/githelper"
|
"git.badhouseplants.net/allanger/shoebill/internal/utils/githelper"
|
||||||
release_v2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
|
release_v2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
|
||||||
helmrepo_v1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
|
helmrepo_v1beta2 "github.com/fluxcd/source-controller/api/v1beta2"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"sigs.k8s.io/yaml"
|
"sigs.k8s.io/yaml"
|
||||||
)
|
)
|
||||||
@ -30,6 +34,7 @@ func (f *Flux) SyncState(diff diff.Diff) error {
|
|||||||
entity := "repository"
|
entity := "repository"
|
||||||
srcPath := fmt.Sprintf("%s/src", f.path)
|
srcPath := fmt.Sprintf("%s/src", f.path)
|
||||||
filePath := fmt.Sprintf("%s/%s-", srcPath, entity)
|
filePath := fmt.Sprintf("%s/%s-", srcPath, entity)
|
||||||
|
|
||||||
for _, repo := range diff.DeletedRepositories {
|
for _, repo := range diff.DeletedRepositories {
|
||||||
if err := os.Remove(filePath + repo.Name + ".yaml"); err != nil {
|
if err := os.Remove(filePath + repo.Name + ".yaml"); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -44,6 +49,7 @@ func (f *Flux) SyncState(diff diff.Diff) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, repo := range diff.UpdatedRepositories {
|
for _, repo := range diff.UpdatedRepositories {
|
||||||
manifest, err := GenerateRepository(repo)
|
manifest, err := GenerateRepository(repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -85,9 +91,14 @@ func (f *Flux) SyncState(diff diff.Diff) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entity = "release"
|
entity = "release"
|
||||||
filePath = fmt.Sprintf("%s/%s-", srcPath, entity)
|
filePath = fmt.Sprintf("%s/%s-", srcPath, entity)
|
||||||
|
|
||||||
for _, release := range diff.AddedReleases {
|
for _, release := range diff.AddedReleases {
|
||||||
|
if err := SyncValues(release, srcPath); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
manifest, err := GenerateRelease(release)
|
manifest, err := GenerateRelease(release)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -113,7 +124,9 @@ func (f *Flux) SyncState(diff diff.Diff) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, release := range diff.UpdatedReleases {
|
for _, release := range diff.UpdatedReleases {
|
||||||
|
SyncValues(release, srcPath)
|
||||||
manifest, err := GenerateRelease(release)
|
manifest, err := GenerateRelease(release)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -136,6 +149,7 @@ func (f *Flux) SyncState(diff diff.Diff) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, release := range diff.DeletedReleases {
|
for _, release := range diff.DeletedReleases {
|
||||||
if err := os.Remove(filePath + release.Release + ".yaml"); err != nil {
|
if err := os.Remove(filePath + release.Release + ".yaml"); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -210,3 +224,50 @@ func GenerateRelease(release *release.Release) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return yaml.Marshal(&fluxRelease)
|
return yaml.Marshal(&fluxRelease)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SyncValues(release *release.Release, path string) error {
|
||||||
|
for _, valueFile := range release.Values {
|
||||||
|
// Prepare a dir for values
|
||||||
|
valuesPath := fmt.Sprintf("%s/%s", path, "values")
|
||||||
|
if _, err := os.Stat(valuesPath); errors.Is(err, os.ErrNotExist) {
|
||||||
|
err := os.Mkdir(valuesPath, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
destFileName := fmt.Sprintf("%s/%s-%s", valuesPath, release.Release, filepath.Base(valueFile))
|
||||||
|
logrus.Info(destFileName)
|
||||||
|
logrus.Info(valueFile)
|
||||||
|
var dstValues *os.File
|
||||||
|
var srcValues *os.File
|
||||||
|
var err error
|
||||||
|
srcValues, err = os.Open(valueFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer srcValues.Close()
|
||||||
|
if _, err = os.Stat(destFileName); err == nil {
|
||||||
|
dstValues, err = os.Open(destFileName)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer dstValues.Close()
|
||||||
|
} else if errors.Is(err, os.ErrNotExist) {
|
||||||
|
dstValues, err = os.Create(destFileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
defer dstValues.Close()
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = io.Copy(dstValues, srcValues)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -3,6 +3,8 @@ package kustomize
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.badhouseplants.net/allanger/shoebill/internal/utils/githelper"
|
"git.badhouseplants.net/allanger/shoebill/internal/utils/githelper"
|
||||||
kustomize_types "sigs.k8s.io/kustomize/api/types"
|
kustomize_types "sigs.k8s.io/kustomize/api/types"
|
||||||
@ -10,22 +12,47 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Kusmtomize struct {
|
type Kusmtomize struct {
|
||||||
Files []string
|
Files []string
|
||||||
|
ConfigMaps []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *Kusmtomize) PopulateResources(path string) error {
|
func (k *Kusmtomize) PopulateResources(path string) error {
|
||||||
|
// Main sources
|
||||||
files, err := os.ReadDir(fmt.Sprintf("%s/src", path))
|
files, err := os.ReadDir(fmt.Sprintf("%s/src", path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
if file.Name() != ".gitkeep" {
|
if file.Name() != ".gitkeep" && !file.IsDir() {
|
||||||
k.Files = append(k.Files, fmt.Sprintf("src/%s", file.Name()))
|
k.Files = append(k.Files, fmt.Sprintf("src/%s", file.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Values
|
||||||
|
files, err = os.ReadDir(fmt.Sprintf("%s/src/values", path))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
k.ConfigMaps = append(k.ConfigMaps, fmt.Sprintf("src/values/%s", file.Name()))
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (k *Kusmtomize) CmGeneratorFromFiles() ([]kustomize_types.ConfigMapArgs, error) {
|
||||||
|
cmGens := []kustomize_types.ConfigMapArgs{}
|
||||||
|
for _, cm := range k.ConfigMaps {
|
||||||
|
cmName :=
|
||||||
|
cmGen := &kustomize_types.ConfigMapArgs{
|
||||||
|
GeneratorArgs: kustomize_types.GeneratorArgs{
|
||||||
|
Namespace: "flux-system",
|
||||||
|
Name: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func Generate(path string, gh githelper.Githelper) error {
|
func Generate(path string, gh githelper.Githelper) error {
|
||||||
kustomize := &Kusmtomize{}
|
kustomize := &Kusmtomize{}
|
||||||
if err := kustomize.PopulateResources(path); err != nil {
|
if err := kustomize.PopulateResources(path); err != nil {
|
||||||
@ -42,6 +69,10 @@ func Generate(path string, gh githelper.Githelper) error {
|
|||||||
Namespace: "flux-system",
|
Namespace: "flux-system",
|
||||||
},
|
},
|
||||||
Resources: kustomize.Files,
|
Resources: kustomize.Files,
|
||||||
|
GeneratorOptions: &kustomize_types.GeneratorOptions{
|
||||||
|
DisableNameSuffixHash: true,
|
||||||
|
},
|
||||||
|
ConfigMapGenerator: []kustomize_types.ConfigMapArgs{},
|
||||||
}
|
}
|
||||||
manifest, err := yaml.Marshal(kustomization)
|
manifest, err := yaml.Marshal(kustomization)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -60,5 +91,4 @@ func Generate(path string, gh githelper.Githelper) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user