add general shizzle
(cherry picked from commit 72d164f3960436093d01d00d5ed6d43bc2e4e256)
This commit is contained in:
@@ -0,0 +1,15 @@
|
|||||||
|
module github.com/truecharts/apps
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/Jeffail/gabs v1.4.0
|
||||||
|
github.com/stretchr/testify v1.7.0
|
||||||
|
helm.sh/helm/v3 v3.5.4
|
||||||
|
sigs.k8s.io/yaml v1.2.0
|
||||||
|
)
|
||||||
|
|
||||||
|
replace (
|
||||||
|
github.com/docker/distribution => github.com/docker/distribution v0.0.0-20191216044856-a8371794149d
|
||||||
|
github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
|
||||||
|
)
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
package helmunit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"helm.sh/helm/v3/pkg/action"
|
||||||
|
"helm.sh/helm/v3/pkg/chart/loader"
|
||||||
|
"helm.sh/helm/v3/pkg/cli"
|
||||||
|
v "helm.sh/helm/v3/pkg/cli/values"
|
||||||
|
"helm.sh/helm/v3/pkg/downloader"
|
||||||
|
"helm.sh/helm/v3/pkg/getter"
|
||||||
|
"helm.sh/helm/v3/pkg/releaseutil"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
var settings *cli.EnvSettings
|
||||||
|
|
||||||
|
type HelmChart struct {
|
||||||
|
Name string
|
||||||
|
ChartPath string
|
||||||
|
Manifests manifestCollection
|
||||||
|
Hooks manifestCollection
|
||||||
|
Notes string
|
||||||
|
Values map[string]interface{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(name string, chartPath string) HelmChart {
|
||||||
|
h := HelmChart{
|
||||||
|
Name: name,
|
||||||
|
ChartPath: chartPath,
|
||||||
|
Manifests: make(manifestCollection),
|
||||||
|
Hooks: make(manifestCollection),
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HelmChart) UpdateDependencies() error {
|
||||||
|
settings = cli.New()
|
||||||
|
client := defaultClient(c.Name, settings.Namespace())
|
||||||
|
p := getter.All(&cli.EnvSettings{})
|
||||||
|
|
||||||
|
// Check chart dependencies to make sure all are present in /charts
|
||||||
|
chartRequested, err := loader.Load(c.ChartPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if req := chartRequested.Metadata.Dependencies; req != nil {
|
||||||
|
if err := action.CheckDependencies(chartRequested, req); err != nil {
|
||||||
|
if client.DependencyUpdate {
|
||||||
|
man := &downloader.Manager{
|
||||||
|
Out: io.Discard,
|
||||||
|
ChartPath: c.ChartPath,
|
||||||
|
Keyring: client.ChartPathOptions.Keyring,
|
||||||
|
SkipUpdate: false,
|
||||||
|
Getters: p,
|
||||||
|
}
|
||||||
|
if err := man.Update(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HelmChart) Render(valueFilePaths, stringValues []string, rawYamlValues *string) error {
|
||||||
|
settings = cli.New()
|
||||||
|
client := defaultClient(c.Name, settings.Namespace())
|
||||||
|
c.Manifests.Initialize()
|
||||||
|
c.Hooks.Initialize()
|
||||||
|
|
||||||
|
p := getter.All(&cli.EnvSettings{})
|
||||||
|
valueOpts := &v.Options{
|
||||||
|
ValueFiles: valueFilePaths,
|
||||||
|
Values: stringValues,
|
||||||
|
}
|
||||||
|
|
||||||
|
values, err := valueOpts.MergeValues(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(rawYamlValues == nil) {
|
||||||
|
currentMap := map[string]interface{}{}
|
||||||
|
if err := yaml.Unmarshal([]byte(*rawYamlValues), ¤tMap); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
values = mergeMaps(currentMap, values)
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Values = values
|
||||||
|
|
||||||
|
chartRequested, err := loader.Load(c.ChartPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
release, err := client.Run(chartRequested, values)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, manifest := range releaseutil.SplitManifests(release.Manifest) {
|
||||||
|
err := c.Manifests.Add([]byte(manifest))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, manifest := range release.Hooks {
|
||||||
|
err := c.Hooks.Add([]byte(manifest.Manifest))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Notes = release.Info.Notes
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func defaultClient(name, namespace string) *action.Install {
|
||||||
|
client := action.NewInstall(&action.Configuration{})
|
||||||
|
client.Version = ">0.0.0-0"
|
||||||
|
client.ReleaseName = name
|
||||||
|
client.Namespace = namespace
|
||||||
|
client.ClientOnly = true
|
||||||
|
client.DryRun = true
|
||||||
|
client.DependencyUpdate = true
|
||||||
|
|
||||||
|
return client
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package helmunit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Jeffail/gabs"
|
||||||
|
)
|
||||||
|
|
||||||
|
type manifestCollection map[string]map[string]gabs.Container
|
||||||
|
|
||||||
|
func (c *manifestCollection) Initialize() {
|
||||||
|
*c = make(manifestCollection)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *manifestCollection) Add(yamlInput []byte) error {
|
||||||
|
collection := *c
|
||||||
|
jsonManifest, err := yamlToJson(yamlInput)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
kind := strings.ToLower(jsonManifest.Path("kind").Data().(string))
|
||||||
|
name := strings.ToLower(jsonManifest.Path("metadata.name").Data().(string))
|
||||||
|
|
||||||
|
if kind == "" || name == "" {
|
||||||
|
return errors.New("invalid manifest")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, ok := collection[kind]
|
||||||
|
if !ok {
|
||||||
|
data = make(map[string]gabs.Container)
|
||||||
|
collection[kind] = data
|
||||||
|
}
|
||||||
|
data[name] = *jsonManifest
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *manifestCollection) Get(kind string, name string) *gabs.Container {
|
||||||
|
collection := *c
|
||||||
|
manifest, ok := collection[strings.ToLower(kind)][strings.ToLower(name)]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &manifest
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package helmunit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/Jeffail/gabs"
|
||||||
|
"sigs.k8s.io/yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mergeMaps(a, b map[string]interface{}) map[string]interface{} {
|
||||||
|
out := make(map[string]interface{}, len(a))
|
||||||
|
for k, v := range a {
|
||||||
|
out[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range b {
|
||||||
|
if v, ok := v.(map[string]interface{}); ok {
|
||||||
|
if bv, ok := out[k]; ok {
|
||||||
|
if bv, ok := bv.(map[string]interface{}); ok {
|
||||||
|
out[k] = mergeMaps(bv, v)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[k] = v
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func yamlToJson(yamlInput []byte) (jsonOutput *gabs.Container, err error) {
|
||||||
|
jsonBytes, err := yaml.YAMLToJSON(yamlInput)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
jsonParsed, err := gabs.ParseJSON(jsonBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return jsonParsed, nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user