//go:generate mockery --name HelmManager
type HelmManager interface {
- AddToRepo(repoName, url string) error
+ SetUpRepo(repoName, url string) error
InstallHelmChart(namespace, repoName, chartName, releaseName string) error
UninstallHelmChart(namespace, chartName string)
}
type helmManagerImpl struct {
settings *cli.EnvSettings
+ repo *repo.ChartRepository
}
func NewHelmManager(s *cli.EnvSettings) *helmManagerImpl {
}
}
-func (hm *helmManagerImpl) AddToRepo(repoName, url string) error {
+func (hm *helmManagerImpl) SetUpRepo(repoName, url string) error {
repoFile := hm.settings.RepositoryConfig
//Ensure the file directory exists as it is required for file locking
URL: url,
}
- r, err := repo.NewChartRepository(&c, getter.All(hm.settings))
- if err != nil {
- return err
+ r := hm.repo
+ if r == nil {
+ r, err = repo.NewChartRepository(&c, getter.All(hm.settings))
+ if err != nil {
+ return err
+ }
}
if _, err := r.DownloadIndexFile(); err != nil {
--- /dev/null
+// -
+// ========================LICENSE_START=================================
+// O-RAN-SC
+// %%
+// Copyright (C) 2022: Nordix Foundation
+// %%
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// ========================LICENSE_END===================================
+//
+
+package helmmanagement
+
+import (
+ "bufio"
+ "bytes"
+ "log"
+ "os"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/mock"
+ "gopkg.in/yaml.v2"
+ "helm.sh/helm/v3/pkg/cli"
+ "helm.sh/helm/v3/pkg/getter"
+ "helm.sh/helm/v3/pkg/repo"
+ "helm.sh/helm/v3/pkg/time"
+ "oransc.org/nonrtric/capifcore/internal/helmmanagement/mocks"
+)
+
+func TestSetUpRepo_repoShouldBeAddedToReposFile(t *testing.T) {
+ settings := createReposFile(t)
+
+ managerUnderTest := NewHelmManager(settings)
+
+ repoName := "repoName"
+ repoURL := "http://url"
+ managerUnderTest.repo = getChartRepo(settings)
+
+ res := managerUnderTest.SetUpRepo(repoName, repoURL)
+
+ assert.Nil(t, res)
+ assert.True(t, containsRepo(settings.RepositoryConfig, repoName))
+}
+
+func createReposFile(t *testing.T) *cli.EnvSettings {
+ reposDir, err := os.MkdirTemp("", "helm")
+ if err != nil {
+ t.Errorf("Unable to create temporary directory for repos due to: %v", err)
+ }
+ t.Cleanup(func() {
+ os.RemoveAll(reposDir)
+ })
+
+ reposFile := reposDir + "/repositories.yaml"
+ settings := &cli.EnvSettings{
+ RepositoryConfig: reposFile,
+ }
+
+ repoData := repo.File{
+ Generated: time.Now().Time,
+ Repositories: []*repo.Entry{},
+ }
+ data, err := yaml.Marshal(&repoData)
+ if err != nil {
+ assert.Fail(t, "Unable to marshal repo config yaml")
+ }
+ err2 := os.WriteFile(settings.RepositoryConfig, data, 0666)
+ if err2 != nil {
+ assert.Fail(t, "Unable to write repo config file")
+ }
+ return settings
+}
+
+func getChartRepo(settings *cli.EnvSettings) *repo.ChartRepository {
+ repoURL := "http://repoURL"
+ c := repo.Entry{
+ Name: "",
+ URL: repoURL,
+ }
+ r, _ := repo.NewChartRepository(&c, getter.All(settings))
+ r.Client = getCLientMock(repoURL)
+ return r
+}
+
+func getCLientMock(repoURL string) *mocks.Getter {
+ clientMock := &mocks.Getter{}
+ b := []byte("apiVersion: v1\nentries: {}\ngenerated: \"2022-10-28T09:14:08+02:00\"\nserverInfo: {}\n")
+ z := bytes.NewBuffer(b)
+ clientMock.On("Get", repoURL+"/index.yaml", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(z, nil)
+ return clientMock
+}
+
+func containsRepo(repoFile, repoName string) bool {
+ file, err := os.Open(repoFile)
+ if err != nil {
+ log.Fatalf("Error opening repository file: %v", err)
+ }
+ defer func(file *os.File) {
+ _ = file.Close()
+ }(file)
+
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ row := scanner.Text()
+ if strings.Contains(row, repoName) {
+ return true
+ }
+ }
+ return false
+}
--- /dev/null
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import (
+ bytes "bytes"
+
+ getter "helm.sh/helm/v3/pkg/getter"
+
+ mock "github.com/stretchr/testify/mock"
+)
+
+// Getter is an autogenerated mock type for the Getter type
+type Getter struct {
+ mock.Mock
+}
+
+// Get provides a mock function with given fields: url, options
+func (_m *Getter) Get(url string, options ...getter.Option) (*bytes.Buffer, error) {
+ _va := make([]interface{}, len(options))
+ for _i := range options {
+ _va[_i] = options[_i]
+ }
+ var _ca []interface{}
+ _ca = append(_ca, url)
+ _ca = append(_ca, _va...)
+ ret := _m.Called(_ca...)
+
+ var r0 *bytes.Buffer
+ if rf, ok := ret.Get(0).(func(string, ...getter.Option) *bytes.Buffer); ok {
+ r0 = rf(url, options...)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*bytes.Buffer)
+ }
+ }
+
+ var r1 error
+ if rf, ok := ret.Get(1).(func(string, ...getter.Option) error); ok {
+ r1 = rf(url, options...)
+ } else {
+ r1 = ret.Error(1)
+ }
+
+ return r0, r1
+}
+
+type mockConstructorTestingTNewGetter interface {
+ mock.TestingT
+ Cleanup(func())
+}
+
+// NewGetter creates a new instance of Getter. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewGetter(t mockConstructorTestingTNewGetter) *Getter {
+ mock := &Getter{}
+ mock.Mock.Test(t)
+
+ t.Cleanup(func() { mock.AssertExpectations(t) })
+
+ return mock
+}
mock.Mock
}
-// AddToRepo provides a mock function with given fields: repoName, url
-func (_m *HelmManager) AddToRepo(repoName string, url string) error {
- ret := _m.Called(repoName, url)
+// InstallHelmChart provides a mock function with given fields: namespace, repoName, chartName, releaseName
+func (_m *HelmManager) InstallHelmChart(namespace string, repoName string, chartName string, releaseName string) error {
+ ret := _m.Called(namespace, repoName, chartName, releaseName)
var r0 error
- if rf, ok := ret.Get(0).(func(string, string) error); ok {
- r0 = rf(repoName, url)
+ if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok {
+ r0 = rf(namespace, repoName, chartName, releaseName)
} else {
r0 = ret.Error(0)
}
return r0
}
-// InstallHelmChart provides a mock function with given fields: namespace, repoName, chartName, releaseName
-func (_m *HelmManager) InstallHelmChart(namespace string, repoName string, chartName string, releaseName string) error {
- ret := _m.Called(namespace, repoName, chartName, releaseName)
+// SetUpRepo provides a mock function with given fields: repoName, url
+func (_m *HelmManager) SetUpRepo(repoName string, url string) error {
+ ret := _m.Called(repoName, url)
var r0 error
- if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok {
- r0 = rf(namespace, repoName, chartName, releaseName)
+ if rf, ok := ret.Get(0).(func(string, string) error); ok {
+ r0 = rf(repoName, url)
} else {
r0 = ret.Error(0)
}
func main() {
var port = flag.Int("port", 8090, "Port for CAPIF Core Function HTTP server")
- flag.StringVar(&url, "url", "http://chartmuseum:8080", "ChartMuseum url")
- flag.StringVar(&repoName, "repoName", "local-dev", "Repository name")
+ flag.StringVar(&url, "url", "http://localhost:8080", "ChartMuseum url")
+ flag.StringVar(&repoName, "repoName", "capifcore", "Repository name")
var logLevelStr = flag.String("loglevel", "Info", "Log level")
flag.Parse()
// Add repo
fmt.Printf("Adding %s to Helm Repo\n", url)
helmManager = helmmanagement.NewHelmManager(cli.New())
- err := helmManager.AddToRepo(repoName, url)
+ err := helmManager.SetUpRepo(repoName, url)
if err != nil {
log.Fatal(err.Error())
}