Create an app
This commit is contained in:
		
							
								
								
									
										349
									
								
								internal/controllers/applications.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										349
									
								
								internal/controllers/applications.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,349 @@
 | 
			
		||||
package controllers
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	b64 "encoding/base64"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"git.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/helmhelper"
 | 
			
		||||
	"git.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/helmrelease"
 | 
			
		||||
	"git.badhouseplants.net/softplayer/softplayer-backend/internal/helpers/kube"
 | 
			
		||||
	"github.com/google/uuid"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/yaml.v2"
 | 
			
		||||
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
			
		||||
 | 
			
		||||
	corev1 "k8s.io/api/core/v1"
 | 
			
		||||
	"k8s.io/client-go/rest"
 | 
			
		||||
	ctrl "sigs.k8s.io/controller-runtime"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Application struct {
 | 
			
		||||
	Controller ctrl.Manager
 | 
			
		||||
	UserID     string
 | 
			
		||||
	Data       *ApplicationData
 | 
			
		||||
	Token      string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ApplicationData struct {
 | 
			
		||||
	UUID        string
 | 
			
		||||
	Name        string
 | 
			
		||||
	Description string
 | 
			
		||||
	Application string
 | 
			
		||||
	Version     string
 | 
			
		||||
	Environemnt string
 | 
			
		||||
	Config      map[string]string
 | 
			
		||||
	RawConfig   string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Create environment should create a new configmap in the user's namespace
 | 
			
		||||
// using a token that belongs to the user.
 | 
			
		||||
func (app *Application) Create(ctx context.Context) error {
 | 
			
		||||
	app.Data.UUID = uuid.New().String()
 | 
			
		||||
	// if err := app.isNsVerified(ctx); err != nil {
 | 
			
		||||
	// log.Println("Can't verify ns")
 | 
			
		||||
	// return err
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	app.Controller.GetClient()
 | 
			
		||||
	conf := &rest.Config{
 | 
			
		||||
		Host:        "https://kubernetes.default.svc.cluster.local:443",
 | 
			
		||||
		BearerToken: app.Token,
 | 
			
		||||
		TLSClientConfig: rest.TLSClientConfig{
 | 
			
		||||
			Insecure: true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	controller, err := ctrl.NewManager(conf, ctrl.Options{})
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	helm := helmhelper.NewHelm()
 | 
			
		||||
	release := &helmhelper.ReleaseData{
 | 
			
		||||
		Name:           app.Data.Name,
 | 
			
		||||
		Chart:          app.Data.Application,
 | 
			
		||||
		Version:        app.Data.Version,
 | 
			
		||||
		RepositoryURL:  "oci://git.badhouseplants.net/softplayer/helm",
 | 
			
		||||
		RepositoryKind: "oci",
 | 
			
		||||
		RepositoryName: "softplayer",
 | 
			
		||||
	}
 | 
			
		||||
	goPath := os.TempDir() + "softplayer"
 | 
			
		||||
	if err := os.MkdirAll(goPath, 0777); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	path, err := helm.PullChart(goPath, release)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Error("0")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfgSchemaPath, err := os.ReadFile(fmt.Sprintf("%s/%s/config.yaml", goPath, path))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Errorf("yamlFile.Get err   #%v ", err)
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Info(string(cfgSchemaPath))
 | 
			
		||||
	cfgSchema := map[string]*helmrelease.PrettyConfigSchema{}
 | 
			
		||||
	err = yaml.Unmarshal(cfgSchemaPath, cfgSchema)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Error("1")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfg := &helmrelease.HelmRelease{
 | 
			
		||||
		Helm: helmrelease.Helm{
 | 
			
		||||
			Release: app.Data.Name,
 | 
			
		||||
			Chart: helmrelease.Chart{
 | 
			
		||||
				Name:    app.Data.Application,
 | 
			
		||||
				Version: app.Data.Version,
 | 
			
		||||
			},
 | 
			
		||||
			Repo: helmrelease.Repo{
 | 
			
		||||
				URL:  "oci://git.badhouseplants.net/softplayer/helm",
 | 
			
		||||
				Type: "oci",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		Config: helmrelease.Config{},
 | 
			
		||||
	}
 | 
			
		||||
	if len(app.Data.Config) > 0 {
 | 
			
		||||
		for key, val := range app.Data.Config {
 | 
			
		||||
			logrus.Info(key)
 | 
			
		||||
			logrus.Info(val)
 | 
			
		||||
			logrus.Info(cfgSchema)
 | 
			
		||||
			value, ok := cfgSchema[key]
 | 
			
		||||
			if !ok {
 | 
			
		||||
				return fmt.Errorf("unsuported config entry: %s", key)
 | 
			
		||||
			}
 | 
			
		||||
			cfg.Config.Pretty = append(cfg.Config.Pretty, helmrelease.PrettyConfig{
 | 
			
		||||
				Key:   key,
 | 
			
		||||
				Path:  value.Path,
 | 
			
		||||
				Value: val,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	} else if len(app.Data.RawConfig) > 0 {
 | 
			
		||||
		cfg.Config.Raw = app.Data.RawConfig
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cfgYaml, err := yaml.Marshal(cfg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logrus.Error("2")
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Info(string(cfgYaml))
 | 
			
		||||
 | 
			
		||||
	formattedName := b64.StdEncoding.EncodeToString([]byte(app.Data.Application + app.Data.Name))
 | 
			
		||||
	appSecret := corev1.Secret{
 | 
			
		||||
		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
			Name:      formattedName[0:10],
 | 
			
		||||
			Namespace: app.UserID,
 | 
			
		||||
			Labels: map[string]string{
 | 
			
		||||
				"component": "install",
 | 
			
		||||
				"kind":      "action",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		StringData: map[string]string{
 | 
			
		||||
			"values": string(cfgYaml),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := kube.Create(ctx, controller.GetClient(), &appSecret, true); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// func (env *Environemnt) Update(ctx context.Context) error {
 | 
			
		||||
// 	if err := env.isNsVerified(ctx); err != nil {
 | 
			
		||||
// 		log.Println("Can't verify ns")
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	env.Controller.GetClient()
 | 
			
		||||
// 	conf := &rest.Config{
 | 
			
		||||
// 		Host:        "https://kubernetes.default.svc.cluster.local:443",
 | 
			
		||||
// 		BearerToken: env.Token,
 | 
			
		||||
// 		TLSClientConfig: rest.TLSClientConfig{
 | 
			
		||||
// 			Insecure: true,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	controller, err := ctrl.NewManager(conf, ctrl.Options{})
 | 
			
		||||
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
// 	oldEnv := &Environemnt{
 | 
			
		||||
// 		Controller: env.Controller,
 | 
			
		||||
// 		UserID:     env.UserID,
 | 
			
		||||
// 		Token:      env.Token,
 | 
			
		||||
// 		Data: &ApplicationData{
 | 
			
		||||
// 			UUID: env.Data.UUID,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	if err := oldEnv.Get(ctx); err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	// Check whter immutable fields are changed
 | 
			
		||||
 | 
			
		||||
// 	if oldEnv.Data.Provider != env.Data.Provider {
 | 
			
		||||
// 		return errors.New("provider can't be changed")
 | 
			
		||||
// 	}
 | 
			
		||||
// 	if oldEnv.Data.Location != env.Data.Location {
 | 
			
		||||
// 		return errors.New("location can't be changed")
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	vars, err := env.Data.buildVars()
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
// 	obj := corev1.ConfigMap{
 | 
			
		||||
// 		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
// 			Name:      env.Data.UUID,
 | 
			
		||||
// 			Namespace: env.UserID,
 | 
			
		||||
// 			Labels: map[string]string{
 | 
			
		||||
// 				"component": "bootstrap",
 | 
			
		||||
// 				"kind":      "environment",
 | 
			
		||||
// 			},
 | 
			
		||||
// 		},
 | 
			
		||||
// 		Data: map[string]string{
 | 
			
		||||
// 			"name":        env.Data.Name,
 | 
			
		||||
// 			"description": env.Data.Description,
 | 
			
		||||
// 			"vars":        vars,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	if err := kube.Update(ctx, controller.GetClient(), &obj); err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	return nil
 | 
			
		||||
// }
 | 
			
		||||
// func (env *Environemnt) Delete(ctx context.Context) error {
 | 
			
		||||
// 	env.Controller.GetClient()
 | 
			
		||||
// 	conf := &rest.Config{
 | 
			
		||||
// 		Host:        "https://kubernetes.default.svc.cluster.local:443",
 | 
			
		||||
// 		BearerToken: env.Token,
 | 
			
		||||
// 		TLSClientConfig: rest.TLSClientConfig{
 | 
			
		||||
// 			Insecure: true,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	controller, err := ctrl.NewManager(conf, ctrl.Options{})
 | 
			
		||||
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
// 	obj := corev1.ConfigMap{
 | 
			
		||||
// 		ObjectMeta: metav1.ObjectMeta{
 | 
			
		||||
// 			Name:      env.Data.UUID,
 | 
			
		||||
// 			Namespace: env.UserID,
 | 
			
		||||
// 			Labels: map[string]string{
 | 
			
		||||
// 				"component": "bootstrap",
 | 
			
		||||
// 			},
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
// 	if err := kube.Delete(ctx, controller.GetClient(), &obj, false); err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	return nil
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// func (env *Environemnt) ListEnvs(ctx context.Context) ([]*Environemnt, error) {
 | 
			
		||||
// 	env.Controller.GetClient()
 | 
			
		||||
// 	conf := &rest.Config{
 | 
			
		||||
// 		Host:        "https://kubernetes.default.svc.cluster.local:443",
 | 
			
		||||
// 		BearerToken: env.Token,
 | 
			
		||||
// 		TLSClientConfig: rest.TLSClientConfig{
 | 
			
		||||
// 			Insecure: true,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
// 	clientset, err := kubernetes.NewForConfig(conf)
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return nil, err
 | 
			
		||||
// 	}
 | 
			
		||||
// 	configmaps, err := clientset.CoreV1().ConfigMaps(env.UserID).List(ctx, metav1.ListOptions{LabelSelector: "kind=environment"})
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return nil, err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	result := []*Environemnt{}
 | 
			
		||||
// 	for _, cm := range configmaps.Items {
 | 
			
		||||
// 		i := &Environemnt{}
 | 
			
		||||
// 		data := &ApplicationData{
 | 
			
		||||
// 			UUID: cm.GetName(),
 | 
			
		||||
// 		}
 | 
			
		||||
// 		i.Token = env.Token
 | 
			
		||||
// 		i.UserID = env.UserID
 | 
			
		||||
// 		i.Data = data
 | 
			
		||||
// 		i.Controller = env.Controller
 | 
			
		||||
// 		if err := i.Get(ctx); err != nil {
 | 
			
		||||
// 			return nil, err
 | 
			
		||||
// 		}
 | 
			
		||||
// 		result = append(result, i)
 | 
			
		||||
// 	}
 | 
			
		||||
// 	return result, nil
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// func (env *Environemnt) Get(ctx context.Context) error {
 | 
			
		||||
// 	env.Controller.GetClient()
 | 
			
		||||
// 	conf := &rest.Config{
 | 
			
		||||
// 		Host:        "https://kubernetes.default.svc.cluster.local:443",
 | 
			
		||||
// 		BearerToken: env.Token,
 | 
			
		||||
// 		TLSClientConfig: rest.TLSClientConfig{
 | 
			
		||||
// 			Insecure: true,
 | 
			
		||||
// 		},
 | 
			
		||||
// 	}
 | 
			
		||||
// 	clientset, err := kubernetes.NewForConfig(conf)
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
// 	envData, err := clientset.CoreV1().ConfigMaps(env.UserID).Get(ctx, env.Data.UUID, metav1.GetOptions{})
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	res, err := godotenv.Unmarshal(envData.Data["vars"])
 | 
			
		||||
// 	if err != nil {
 | 
			
		||||
// 		return err
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	if val, ok := envData.Data["name"]; ok {
 | 
			
		||||
// 		env.Data.Name = val
 | 
			
		||||
// 	} else {
 | 
			
		||||
// 		env.Data.Name = ""
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	if val, ok := envData.Data["description"]; ok {
 | 
			
		||||
// 		env.Data.Description = val
 | 
			
		||||
// 	} else {
 | 
			
		||||
// 		env.Data.Description = ""
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	if val, ok := res["SP_PROVIDER"]; ok {
 | 
			
		||||
// 		env.Data.Provider = val
 | 
			
		||||
// 	} else {
 | 
			
		||||
// 		env.Data.Provider = ""
 | 
			
		||||
// 	}
 | 
			
		||||
// 	if val, ok := res["SP_KUBERNETES"]; ok {
 | 
			
		||||
// 		env.Data.Kubernetes = val
 | 
			
		||||
// 	} else {
 | 
			
		||||
// 		env.Data.Kubernetes = ""
 | 
			
		||||
// 	}
 | 
			
		||||
// 	if val, ok := res["SP_SERVER_TYPE"]; ok {
 | 
			
		||||
// 		env.Data.ServerType = val
 | 
			
		||||
// 	} else {
 | 
			
		||||
// 		env.Data.ServerType = ""
 | 
			
		||||
// 	}
 | 
			
		||||
// 	if val, ok := res["SP_SERVER_LOCATION"]; ok {
 | 
			
		||||
// 		env.Data.Location = val
 | 
			
		||||
// 	} else {
 | 
			
		||||
// 		env.Data.Location = ""
 | 
			
		||||
// 	}
 | 
			
		||||
 | 
			
		||||
// 	return nil
 | 
			
		||||
// }
 | 
			
		||||
							
								
								
									
										177
									
								
								internal/helpers/helmhelper/helm.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								internal/helpers/helmhelper/helm.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,177 @@
 | 
			
		||||
package helmhelper
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/yaml.v2"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/action"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/chart/loader"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/chartutil"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/cli"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/engine"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/getter"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/registry"
 | 
			
		||||
	"helm.sh/helm/v3/pkg/repo"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Helm struct{}
 | 
			
		||||
 | 
			
		||||
func NewHelm() Helmhelper {
 | 
			
		||||
	return &Helm{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getDownloadDirPath(workdirPath string) string {
 | 
			
		||||
	return fmt.Sprintf("%s/.charts", workdirPath)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getChartDirPath(downloadDirPath string, release *ReleaseData) string {
 | 
			
		||||
	return fmt.Sprintf("%s/%s-%s-%s", downloadDirPath, release.RepositoryName, release.Chart, release.Version)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Helm) PullChart(workdirPath string, release *ReleaseData) (path string, err error) {
 | 
			
		||||
	downloadDirPath := getDownloadDirPath(workdirPath)
 | 
			
		||||
	if err := os.MkdirAll(downloadDirPath, 0777); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config := new(action.Configuration)
 | 
			
		||||
	cl := cli.New()
 | 
			
		||||
	chartDir := getChartDirPath(downloadDirPath, release)
 | 
			
		||||
	_, err = os.Stat(chartDir)
 | 
			
		||||
 | 
			
		||||
	if err != nil && !os.IsNotExist(err) {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	} else if os.IsNotExist(err) {
 | 
			
		||||
		if err := os.Mkdir(chartDir, 0777); err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		registry, err := registry.NewClient()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var path string
 | 
			
		||||
		// Download the chart to the workdir
 | 
			
		||||
		if release.RepositoryKind != "oci" {
 | 
			
		||||
			r, err := repo.NewChartRepository(&repo.Entry{
 | 
			
		||||
				Name: release.RepositoryName,
 | 
			
		||||
				URL:  release.RepositoryURL,
 | 
			
		||||
			}, getter.All(cl))
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", err
 | 
			
		||||
			}
 | 
			
		||||
			path = r.Config.Name
 | 
			
		||||
 | 
			
		||||
		} else {
 | 
			
		||||
			path = release.RepositoryURL
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		client := action.NewPullWithOpts(action.WithConfig(config))
 | 
			
		||||
		client.Untar = true
 | 
			
		||||
		client.UntarDir = workdirPath
 | 
			
		||||
		client.SetRegistryClient(registry)
 | 
			
		||||
		client.DestDir = workdirPath
 | 
			
		||||
		client.Settings = cl
 | 
			
		||||
 | 
			
		||||
		chartRemote := fmt.Sprintf("%s/%s", path, release.Chart)
 | 
			
		||||
		logrus.Infof("trying to pull: %s", chartRemote)
 | 
			
		||||
		if _, err = client.Run(chartRemote); err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return release.Chart, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Helm) FindLatestVersion(workdirPath string, release *ReleaseData) (version string, err error) {
 | 
			
		||||
	downloadDirPath := getDownloadDirPath(workdirPath)
 | 
			
		||||
	if err := os.MkdirAll(downloadDirPath, 0777); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config := new(action.Configuration)
 | 
			
		||||
	cl := cli.New()
 | 
			
		||||
	chartDir := getChartDirPath(downloadDirPath, release)
 | 
			
		||||
	chartPath, err := h.PullChart(workdirPath, release)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	showAction := action.NewShowWithConfig(action.ShowChart, config)
 | 
			
		||||
 | 
			
		||||
	res, err := showAction.LocateChart(fmt.Sprintf("%s/%s", chartDir, chartPath), cl)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	res, err = showAction.Run(res)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	chartData, err := chartFromString(res)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Infof("the latest version of %s is %s", release.Chart, chartData.Version)
 | 
			
		||||
	versionedChartDir := getChartDirPath(downloadDirPath, release)
 | 
			
		||||
	os.Rename(chartDir, versionedChartDir)
 | 
			
		||||
	return chartData.Version, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Helm) RenderChart(workdirPath string, release *ReleaseData) error {
 | 
			
		||||
	downloadDirPath := getDownloadDirPath(workdirPath)
 | 
			
		||||
	chartDirPath := getChartDirPath(downloadDirPath, release)
 | 
			
		||||
	chartPath, err := getChartPathFromDir(chartDirPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Info(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
 | 
			
		||||
	chartObj, err := loader.Load(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	values := chartutil.Values{}
 | 
			
		||||
	values["Values"] = chartObj.Values
 | 
			
		||||
	values["Release"] = map[string]string{
 | 
			
		||||
		"Name":      release.Name,
 | 
			
		||||
		"Namespace": release.Namespace,
 | 
			
		||||
	}
 | 
			
		||||
	values["Capabilities"] = map[string]map[string]string{
 | 
			
		||||
		"KubeVersion": {
 | 
			
		||||
			"Version":    "v1.27.9",
 | 
			
		||||
			"GitVersion": "v1.27.9",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	files, err := engine.Engine{Strict: false}.Render(chartObj, values)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Info(files)
 | 
			
		||||
	for file, data := range files {
 | 
			
		||||
		logrus.Infof("%s - %s", file, data)
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Info("I'm here")
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getChartPathFromDir(downloadDir string) (file string, err error) {
 | 
			
		||||
	files, err := os.ReadDir(downloadDir)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	} else if len(files) == 0 {
 | 
			
		||||
		return "", fmt.Errorf("expected to have one file, got zero in a dir %s", downloadDir)
 | 
			
		||||
	} else if len(files) > 1 {
 | 
			
		||||
		return "", fmt.Errorf("expected to have only one file in a dir %s", downloadDir)
 | 
			
		||||
	}
 | 
			
		||||
	return files[0].Name(), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func chartFromString(info string) (*ReleaseData, error) {
 | 
			
		||||
	releaseData := new(ReleaseData)
 | 
			
		||||
	if err := yaml.Unmarshal([]byte(info), &releaseData); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return releaseData, nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								internal/helpers/helmhelper/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								internal/helpers/helmhelper/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
package helmhelper
 | 
			
		||||
 | 
			
		||||
type Helmhelper interface {
 | 
			
		||||
	FindLatestVersion(workdirPath string, release *ReleaseData) (string, error)
 | 
			
		||||
	PullChart(workdirPath string, release *ReleaseData) (string, error)
 | 
			
		||||
	RenderChart(workdirPath string, release *ReleaseData) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ReleaseData struct {
 | 
			
		||||
	Name           string
 | 
			
		||||
	Chart          string
 | 
			
		||||
	Namespace      string
 | 
			
		||||
	Version        string
 | 
			
		||||
	RepositoryName string
 | 
			
		||||
	RepositoryURL  string
 | 
			
		||||
	RepositoryKind string
 | 
			
		||||
	ValuesData     string
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								internal/helpers/helmrelease/helmrelease.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								internal/helpers/helmrelease/helmrelease.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
package helmrelease
 | 
			
		||||
 | 
			
		||||
type Chart struct {
 | 
			
		||||
	Name    string
 | 
			
		||||
	Version string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Repo struct {
 | 
			
		||||
	URL  string
 | 
			
		||||
	Type string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PrettyConfig struct {
 | 
			
		||||
	Key   string
 | 
			
		||||
	Path  string
 | 
			
		||||
	Value string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Helm struct {
 | 
			
		||||
	Release string
 | 
			
		||||
	Chart   Chart
 | 
			
		||||
	Repo    Repo
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Config struct {
 | 
			
		||||
	Pretty []PrettyConfig
 | 
			
		||||
	Raw    string
 | 
			
		||||
}
 | 
			
		||||
type HelmRelease struct {
 | 
			
		||||
	Helm   Helm
 | 
			
		||||
	Config Config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PrettyConfigSchema struct {
 | 
			
		||||
	Description string
 | 
			
		||||
	Path        string
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user