package helmhelper import ( "fmt" "os" "git.badhouseplants.net/allanger/shoebill/pkg/repository" "github.com/sirupsen/logrus" "gopkg.in/yaml.v2" "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/cli" "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 } func (h *Helm) FindLatestVersion(dir, chart string, repository repository.Repository) (version string, err error) { downloadDir := fmt.Sprintf("%s/.charts", dir) if err := os.MkdirAll(downloadDir, 0777); err != nil { return "", err } // If file doesn't exist config := new(action.Configuration) cl := cli.New() chartDir := fmt.Sprintf("%s/%s-%s", downloadDir, repository.Name, chart) _, 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 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 } } showAction := action.NewShowWithConfig(action.ShowChart, config) chartPath, err := getChartPathFromDir(chartDir) if err != nil { return "", err } 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) return chartData.Version, err } func getChartPathFromDir(dir string) (file string, err error) { files, err := os.ReadDir(dir) if err != nil { return "", err } else if len(files) == 0 { return "", fmt.Errorf("expected to have one file, got zero in a dir %s", dir) } else if len(files) > 1 { return "", fmt.Errorf("expected to have only one file in a dir %s", dir) } 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 }