source-controller/controllers/helmrepository_controller_t...

176 lines
5.0 KiB
Go

package controllers
import (
"context"
"fmt"
"io/ioutil"
"os"
"path"
"path/filepath"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo/repotest"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
)
var _ = Describe("HelmRepositoryReconciler", func() {
const (
timeout = time.Second * 30
interval = time.Second * 1
)
var (
namespace *corev1.Namespace
storage *Storage
helmRepoSrv *repotest.Server
err error
)
BeforeEach(func() {
namespace = &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{Name: "helm-repository-" + randStringRunes(5)},
}
err = k8sClient.Create(context.Background(), namespace)
Expect(err).NotTo(HaveOccurred(), "failed to create test namespace")
tmpStoragePath, err := ioutil.TempDir("", "helmrepository")
Expect(err).NotTo(HaveOccurred(), "failed to create tmp storage dir")
storage, err = NewStorage(tmpStoragePath, "localhost", timeout)
Expect(err).NotTo(HaveOccurred(), "failed to create tmp storage")
helmRepoSrv, err = makeHelmRepoSrv()
Expect(err).NotTo(HaveOccurred(), "failed to setup tmp helm repository server")
helmRepoSrv.Start()
err = (&HelmRepositoryReconciler{
Client: k8sClient,
Log: ctrl.Log.WithName("controllers").WithName("HelmRepository"),
Scheme: scheme.Scheme,
Storage: storage,
Getters: getter.Providers{getter.Provider{
Schemes: []string{"http", "https"},
New: getter.NewHTTPGetter,
}},
}).SetupWithManager(k8sManager)
Expect(err).ToNot(HaveOccurred(), "failed to setup reconciler")
go func() {
err = k8sManager.Start(ctrl.SetupSignalHandler())
Expect(err).ToNot(HaveOccurred())
}()
})
AfterEach(func() {
if storage != nil {
os.RemoveAll(storage.BasePath)
}
if helmRepoSrv != nil {
helmRepoSrv.Stop()
os.RemoveAll(filepath.Dir(helmRepoSrv.Root()))
}
err := k8sClient.Delete(context.Background(), namespace)
Expect(err).NotTo(HaveOccurred(), "failed to delete test namespace")
})
Context("HelmRepository", func() {
It("Should create successfully", func() {
key := types.NamespacedName{
Name: "helmrepository-sample-" + randStringRunes(5),
Namespace: namespace.Name,
}
created := &sourcev1.HelmRepository{
ObjectMeta: metav1.ObjectMeta{
Name: key.Name,
Namespace: key.Namespace,
},
Spec: sourcev1.HelmRepositorySpec{
URL: helmRepoSrv.URL(),
Interval: metav1.Duration{Duration: interval},
},
}
Expect(k8sClient.Create(context.Background(), created)).Should(Succeed())
got := &sourcev1.HelmRepository{}
By("Expecting artifact")
Eventually(func() bool {
_ = k8sClient.Get(context.Background(), key, got)
return got.Status.Artifact != nil
}, timeout, interval).Should(BeTrue())
Eventually(func() bool {
return storage.ArtifactExist(*got.Status.Artifact)
}).Should(BeTrue())
By("Updating the chart index")
// Regenerating the index is sufficient to make the revision change
Expect(helmRepoSrv.CreateIndex()).Should(Succeed())
Eventually(func() bool {
r := &sourcev1.HelmRepository{}
_ = k8sClient.Get(context.Background(), key, r)
if r.Status.Artifact == nil {
return false
}
return r.Status.Artifact.Revision != got.Status.Artifact.Revision
}, timeout, interval).Should(BeTrue())
updated := &sourcev1.HelmRepository{}
Expect(k8sClient.Get(context.Background(), key, updated)).Should(Succeed())
updated.Spec.Interval = metav1.Duration{Duration: 60 * time.Second}
Expect(k8sClient.Update(context.Background(), updated)).Should(Succeed())
By("Expecting to delete successfully")
got = &sourcev1.HelmRepository{}
Eventually(func() error {
_ = k8sClient.Get(context.Background(), key, got)
return k8sClient.Delete(context.Background(), got)
}, timeout, interval).Should(Succeed())
By("Expecting delete to finish")
Eventually(func() error {
r := &sourcev1.HelmRepository{}
return k8sClient.Get(context.Background(), key, r)
}).ShouldNot(Succeed())
Eventually(func() bool {
return storage.ArtifactExist(*got.Status.Artifact)
}).ShouldNot(BeTrue())
})
})
})
func makeHelmRepoSrv() (*repotest.Server, error) {
tmpDir, err := ioutil.TempDir("", "helm-repo-srv")
if err != nil {
return nil, fmt.Errorf("failed to create tmp helm repository dir: %w", err)
}
pkg := action.NewPackage()
pkg.Destination = tmpDir
_, err = pkg.Run("testdata/helmchart", nil)
if err != nil {
os.RemoveAll(tmpDir)
return nil, fmt.Errorf("failed to package helm chart: %w", err)
}
srv := repotest.NewServer(path.Join(tmpDir, "*.tgz"))
if err = srv.CreateIndex(); err != nil {
os.RemoveAll(tmpDir)
return nil, fmt.Errorf("failed to create index for tmp helm repository: %w", err)
}
return srv, nil
}