2023-07-20 09:26:25 +00:00
|
|
|
package helmhelper
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
|
2023-10-12 09:53:58 +00:00
|
|
|
"git.badhouseplants.net/allanger/shoebill/pkg/repository"
|
2023-07-20 09:26:25 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
"gopkg.in/yaml.v2"
|
|
|
|
"helm.sh/helm/v3/pkg/action"
|
2023-10-13 16:02:11 +00:00
|
|
|
"helm.sh/helm/v3/pkg/chart/loader"
|
2023-07-20 09:26:25 +00:00
|
|
|
"helm.sh/helm/v3/pkg/cli"
|
2023-10-13 16:02:11 +00:00
|
|
|
"helm.sh/helm/v3/pkg/engine"
|
2023-07-20 09:26:25 +00:00
|
|
|
"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{}
|
|
|
|
}
|
|
|
|
|
|
|
|
type ChartData struct {
|
|
|
|
Version string
|
|
|
|
}
|
|
|
|
|
2023-10-13 16:02:11 +00:00
|
|
|
func getDownloadDirPath(workdirPath string) string {
|
|
|
|
return fmt.Sprintf("%s/.charts", workdirPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
func getChartDirPath(downloadDirPath, repository, chart, version string) string {
|
|
|
|
return fmt.Sprintf("%s/%s-%s-%s", downloadDirPath, repository, chart, version)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func (h *Helm) PullChart(workdirPath string, repository repository.Repository, chart, version string) (path string, err error) {
|
|
|
|
downloadDirPath := getDownloadDirPath(workdirPath)
|
|
|
|
if err := os.MkdirAll(downloadDirPath, 0777); err != nil {
|
2023-07-20 09:26:25 +00:00
|
|
|
return "", err
|
|
|
|
}
|
2023-10-13 16:02:11 +00:00
|
|
|
|
2023-07-20 09:26:25 +00:00
|
|
|
config := new(action.Configuration)
|
|
|
|
cl := cli.New()
|
2023-10-13 16:02:11 +00:00
|
|
|
chartDir := getChartDirPath(downloadDirPath, repository.Name, chart, version)
|
2023-07-20 09:26:25 +00:00
|
|
|
_, err = os.Stat(chartDir)
|
2023-10-13 16:02:11 +00:00
|
|
|
|
2023-07-20 09:26:25 +00:00
|
|
|
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 repository.Kind != "oci" {
|
|
|
|
r, err := repo.NewChartRepository(&repo.Entry{
|
|
|
|
Name: repository.Name,
|
|
|
|
URL: repository.URL,
|
|
|
|
}, getter.All(cl))
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
path = r.Config.Name
|
|
|
|
|
|
|
|
} else {
|
|
|
|
path = repository.URL
|
|
|
|
}
|
|
|
|
|
|
|
|
client := action.NewPullWithOpts(action.WithConfig(config))
|
|
|
|
client.SetRegistryClient(registry)
|
|
|
|
client.DestDir = chartDir
|
|
|
|
client.Settings = cl
|
|
|
|
|
|
|
|
chartRemote := fmt.Sprintf("%s/%s", path, chart)
|
|
|
|
logrus.Infof("trying to pull: %s", chartRemote)
|
|
|
|
if _, err = client.Run(chartRemote); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2023-10-13 16:02:11 +00:00
|
|
|
}
|
|
|
|
path, err = getChartPathFromDir(chartDir)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
2023-07-20 09:26:25 +00:00
|
|
|
}
|
|
|
|
|
2023-10-13 16:02:11 +00:00
|
|
|
return path, nil
|
|
|
|
}
|
2023-07-20 09:26:25 +00:00
|
|
|
|
2023-10-13 16:02:11 +00:00
|
|
|
func (h *Helm) FindLatestVersion(workdirPath, chart string, repository repository.Repository) (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, repository.Name, chart, "latest")
|
|
|
|
chartPath, err := h.PullChart(workdirPath, repository, chart, "latest")
|
2023-07-20 09:26:25 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2023-10-13 16:02:11 +00:00
|
|
|
showAction := action.NewShowWithConfig(action.ShowChart, config)
|
|
|
|
action.New
|
|
|
|
|
2023-07-20 09:26:25 +00:00
|
|
|
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", chart, chartData.Version)
|
2023-10-13 16:02:11 +00:00
|
|
|
versionedChartDir := getChartDirPath(downloadDirPath, repository.Name, chart, chartData.Version)
|
|
|
|
os.Rename(chartDir, versionedChartDir)
|
2023-07-20 09:26:25 +00:00
|
|
|
return chartData.Version, err
|
|
|
|
}
|
|
|
|
|
2023-10-13 16:02:11 +00:00
|
|
|
func (h *Helm) RenderChart(workdirPath string, repository repository.Repository, ch2art, version string) error {
|
|
|
|
downloadDirPath := getDownloadDirPath(workdirPath)
|
|
|
|
chartDirPath := getChartDirPath(downloadDirPath, repository.Name, ch2art, version)
|
|
|
|
chartPath, err := getChartPathFromDir(chartDirPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
logrus.Info(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
|
|
|
|
chartObj, err := loader.Load(fmt.Sprintf("%s/%s", chartDirPath, chartPath))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
config := new(action.Configuration)
|
|
|
|
client := action.NewInstall(config)
|
|
|
|
client.RepoURL = repository.URL
|
|
|
|
client.ReleaseName = ch2art
|
|
|
|
|
|
|
|
res, err := engine.Render(chartObj, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
logrus.Infof("%v", res)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func getChartPathFromDir(downloadDir string) (file string, err error) {
|
|
|
|
files, err := os.ReadDir(downloadDir)
|
2023-07-20 09:26:25 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
} else if len(files) == 0 {
|
2023-10-13 16:02:11 +00:00
|
|
|
return "", fmt.Errorf("expected to have one file, got zero in a dir %s", downloadDir)
|
2023-07-20 09:26:25 +00:00
|
|
|
} else if len(files) > 1 {
|
2023-10-13 16:02:11 +00:00
|
|
|
return "", fmt.Errorf("expected to have only one file in a dir %s", downloadDir)
|
2023-07-20 09:26:25 +00:00
|
|
|
}
|
|
|
|
return files[0].Name(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func chartFromString(info string) (*ChartData, error) {
|
|
|
|
chartData := new(ChartData)
|
|
|
|
if err := yaml.Unmarshal([]byte(info), &chartData); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return chartData, nil
|
|
|
|
}
|