Refactor kustomization file generation
This commit is contained in:
parent
87d071d47b
commit
b00a841162
|
|
@ -40,11 +40,8 @@ import (
|
|||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/kustomize/api/filesys"
|
||||
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
kustypes "sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/fluxcd/pkg/lockedfile"
|
||||
"github.com/fluxcd/pkg/recorder"
|
||||
|
|
@ -282,7 +279,7 @@ func (r *KustomizationReconciler) reconcile(
|
|||
}
|
||||
|
||||
// generate kustomization.yaml
|
||||
err = r.generate(kustomization, source.GetArtifact().Revision, dirPath)
|
||||
err = KustomizeGenerator{kustomization, source.GetArtifact().Revision}.WriteFile(dirPath)
|
||||
if err != nil {
|
||||
return kustomizev1.KustomizationNotReady(
|
||||
kustomization,
|
||||
|
|
@ -387,177 +384,13 @@ func (r *KustomizationReconciler) download(kustomization kustomizev1.Kustomizati
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *KustomizationReconciler) generate(kustomization kustomizev1.Kustomization, revision, dirPath string) error {
|
||||
kfile := filepath.Join(dirPath, kustomizationFileName)
|
||||
|
||||
if err := r.generateKustomization(dirPath); err != nil {
|
||||
return fmt.Errorf("kustomize create failed: %w", err)
|
||||
}
|
||||
|
||||
if err := r.generateLabelTransformer(kustomization, revision, dirPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(kfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kus := kustypes.Kustomization{
|
||||
TypeMeta: kustypes.TypeMeta{
|
||||
APIVersion: kustypes.KustomizationVersion,
|
||||
Kind: kustypes.KustomizationKind,
|
||||
},
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(data, &kus); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(kus.Transformers) == 0 {
|
||||
kus.Transformers = []string{transformerFileName}
|
||||
} else {
|
||||
var exists bool
|
||||
for _, transformer := range kus.Transformers {
|
||||
if transformer == transformerFileName {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
kus.Transformers = append(kus.Transformers, transformerFileName)
|
||||
}
|
||||
}
|
||||
|
||||
kd, err := yaml.Marshal(kus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(kfile, kd, os.ModePerm)
|
||||
}
|
||||
|
||||
func (r *KustomizationReconciler) generateKustomization(dirPath string) error {
|
||||
fs := filesys.MakeFsOnDisk()
|
||||
kfile := filepath.Join(dirPath, kustomizationFileName)
|
||||
|
||||
scan := func(base string) ([]string, error) {
|
||||
var paths []string
|
||||
uf := kunstruct.NewKunstructuredFactoryImpl()
|
||||
err := fs.Walk(base, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if path == base {
|
||||
return nil
|
||||
}
|
||||
if info.IsDir() {
|
||||
// If a sub-directory contains an existing kustomization file add the
|
||||
// directory as a resource and do not decend into it.
|
||||
for _, kfilename := range konfig.RecognizedKustomizationFileNames() {
|
||||
if fs.Exists(filepath.Join(path, kfilename)) {
|
||||
paths = append(paths, path)
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
fContents, err := fs.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := uf.SliceFromBytes(fContents); err != nil {
|
||||
return nil
|
||||
}
|
||||
paths = append(paths, path)
|
||||
return nil
|
||||
})
|
||||
return paths, err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(kfile); err != nil {
|
||||
abs, err := filepath.Abs(dirPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
files, err := scan(abs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := fs.Create(kfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
|
||||
kus := kustypes.Kustomization{
|
||||
TypeMeta: kustypes.TypeMeta{
|
||||
APIVersion: kustypes.KustomizationVersion,
|
||||
Kind: kustypes.KustomizationKind,
|
||||
},
|
||||
}
|
||||
|
||||
var resources []string
|
||||
for _, file := range files {
|
||||
resources = append(resources, strings.Replace(file, abs, ".", 1))
|
||||
}
|
||||
|
||||
kus.Resources = resources
|
||||
kd, err := yaml.Marshal(kus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(kfile, kd, os.ModePerm)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *KustomizationReconciler) generateLabelTransformer(kustomization kustomizev1.Kustomization, revision, dirPath string) error {
|
||||
var lt = struct {
|
||||
ApiVersion string `json:"apiVersion" yaml:"apiVersion"`
|
||||
Kind string `json:"kind" yaml:"kind"`
|
||||
Metadata struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
} `json:"metadata" yaml:"metadata"`
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
FieldSpecs []kustypes.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
|
||||
}{
|
||||
ApiVersion: "builtin",
|
||||
Kind: "LabelTransformer",
|
||||
Metadata: struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
}{
|
||||
Name: kustomization.GetName(),
|
||||
},
|
||||
Labels: gcLabels(kustomization.GetName(), kustomization.GetNamespace(), revision),
|
||||
FieldSpecs: []kustypes.FieldSpec{
|
||||
{Path: "metadata/labels", CreateIfNotPresent: true},
|
||||
},
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(lt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
labelsFile := filepath.Join(dirPath, transformerFileName)
|
||||
if err := ioutil.WriteFile(labelsFile, data, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *KustomizationReconciler) build(kustomization kustomizev1.Kustomization, revision, dirPath string) (*kustomizev1.Snapshot, error) {
|
||||
fs := filesys.MakeFsOnDisk()
|
||||
manifestsFile := filepath.Join(dirPath, fmt.Sprintf("%s.yaml", kustomization.GetUID()))
|
||||
|
||||
opt := krusty.MakeDefaultOptions()
|
||||
opt.LoadRestrictions = kustypes.LoadRestrictionsNone
|
||||
opt.DoLegacyResourceSort = true
|
||||
k := krusty.MakeKustomizer(fs, opt)
|
||||
m, err := k.Run(dirPath)
|
||||
if err != nil {
|
||||
|
|
@ -982,8 +815,3 @@ func removeString(slice []string, s string) (result []string) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
kustomizationFileName = "kustomization.yaml"
|
||||
transformerFileName = "kustomization-gc-labels.yaml"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,192 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/filesys"
|
||||
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
kustypes "sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
kustomizationFileName = "kustomization.yaml"
|
||||
transformerFileName = "kustomization-gc-labels.yaml"
|
||||
)
|
||||
|
||||
type KustomizeGenerator struct {
|
||||
Kustomization kustomizev1.Kustomization
|
||||
Revision string
|
||||
}
|
||||
|
||||
func (kg KustomizeGenerator) WriteFile(dirPath string) error {
|
||||
kfile := filepath.Join(dirPath, kustomizationFileName)
|
||||
|
||||
if err := kg.generateKustomization(dirPath); err != nil {
|
||||
return fmt.Errorf("kustomize create failed: %w", err)
|
||||
}
|
||||
|
||||
if err := kg.generateLabelTransformer(dirPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadFile(kfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
kus := kustypes.Kustomization{
|
||||
TypeMeta: kustypes.TypeMeta{
|
||||
APIVersion: kustypes.KustomizationVersion,
|
||||
Kind: kustypes.KustomizationKind,
|
||||
},
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(data, &kus); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(kus.Transformers) == 0 {
|
||||
kus.Transformers = []string{transformerFileName}
|
||||
} else {
|
||||
var exists bool
|
||||
for _, transformer := range kus.Transformers {
|
||||
if transformer == transformerFileName {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !exists {
|
||||
kus.Transformers = append(kus.Transformers, transformerFileName)
|
||||
}
|
||||
}
|
||||
|
||||
kd, err := yaml.Marshal(kus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(kfile, kd, os.ModePerm)
|
||||
}
|
||||
|
||||
func (kg KustomizeGenerator) generateKustomization(dirPath string) error {
|
||||
fs := filesys.MakeFsOnDisk()
|
||||
kfile := filepath.Join(dirPath, kustomizationFileName)
|
||||
|
||||
scan := func(base string) ([]string, error) {
|
||||
var paths []string
|
||||
uf := kunstruct.NewKunstructuredFactoryImpl()
|
||||
err := fs.Walk(base, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if path == base {
|
||||
return nil
|
||||
}
|
||||
if info.IsDir() {
|
||||
// If a sub-directory contains an existing kustomization file add the
|
||||
// directory as a resource and do not decend into it.
|
||||
for _, kfilename := range konfig.RecognizedKustomizationFileNames() {
|
||||
if fs.Exists(filepath.Join(path, kfilename)) {
|
||||
paths = append(paths, path)
|
||||
return filepath.SkipDir
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
fContents, err := fs.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := uf.SliceFromBytes(fContents); err != nil {
|
||||
return nil
|
||||
}
|
||||
paths = append(paths, path)
|
||||
return nil
|
||||
})
|
||||
return paths, err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(kfile); err != nil {
|
||||
abs, err := filepath.Abs(dirPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
files, err := scan(abs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := fs.Create(kfile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Close()
|
||||
|
||||
kus := kustypes.Kustomization{
|
||||
TypeMeta: kustypes.TypeMeta{
|
||||
APIVersion: kustypes.KustomizationVersion,
|
||||
Kind: kustypes.KustomizationKind,
|
||||
},
|
||||
}
|
||||
|
||||
var resources []string
|
||||
for _, file := range files {
|
||||
resources = append(resources, strings.Replace(file, abs, ".", 1))
|
||||
}
|
||||
|
||||
kus.Resources = resources
|
||||
kd, err := yaml.Marshal(kus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return ioutil.WriteFile(kfile, kd, os.ModePerm)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (kg KustomizeGenerator) generateLabelTransformer(dirPath string) error {
|
||||
var lt = struct {
|
||||
ApiVersion string `json:"apiVersion" yaml:"apiVersion"`
|
||||
Kind string `json:"kind" yaml:"kind"`
|
||||
Metadata struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
} `json:"metadata" yaml:"metadata"`
|
||||
Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
|
||||
FieldSpecs []kustypes.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
|
||||
}{
|
||||
ApiVersion: "builtin",
|
||||
Kind: "LabelTransformer",
|
||||
Metadata: struct {
|
||||
Name string `json:"name" yaml:"name"`
|
||||
}{
|
||||
Name: kg.Kustomization.GetName(),
|
||||
},
|
||||
Labels: gcLabels(kg.Kustomization.GetName(), kg.Kustomization.GetNamespace(), kg.Revision),
|
||||
FieldSpecs: []kustypes.FieldSpec{
|
||||
{Path: "metadata/labels", CreateIfNotPresent: true},
|
||||
},
|
||||
}
|
||||
|
||||
data, err := yaml.Marshal(lt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
labelsFile := filepath.Join(dirPath, transformerFileName)
|
||||
if err := ioutil.WriteFile(labelsFile, data, os.ModePerm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Reference in New Issue