From 8c894f8c65fb6b337279709ef9ec02050b014bb3 Mon Sep 17 00:00:00 2001 From: "Miskiewicz, Piotr" Date: Wed, 7 Aug 2019 09:45:49 +0200 Subject: [PATCH] Add DocsEnabled flag --- internal/config/controller_config.go | 1 + ...steraddonsconfiguration_controller_test.go | 83 +++++++++++ internal/controller/docs/dummy_provider.go | 27 ++++ .../{docs_provider.go => docs/provider.go} | 26 ++-- .../provider_test.go} | 22 +-- internal/controller/ext.go | 5 + internal/controller/setup.go | 9 +- .../crds/{ => docs}/clusterdocstopic.yaml | 0 .../crds/{ => docs}/docstopic.yaml | 0 test/integration/crds/{ => hb}/ac.yaml | 0 test/integration/crds/{ => hb}/cac.yaml | 0 .../crds/{ => sc}/clusterservicebroker.yaml | 0 .../crds/{ => sc}/servicebroker.yaml | 0 test/integration/integration_test.go | 137 ++++++------------ test/integration/source_test.go | 83 ----------- test/integration/suite_test.go | 73 +++++++--- 16 files changed, 249 insertions(+), 217 deletions(-) create mode 100644 internal/controller/docs/dummy_provider.go rename internal/controller/{docs_provider.go => docs/provider.go} (84%) rename internal/controller/{docs_provider_test.go => docs/provider_test.go} (94%) rename test/integration/crds/{ => docs}/clusterdocstopic.yaml (100%) rename test/integration/crds/{ => docs}/docstopic.yaml (100%) rename test/integration/crds/{ => hb}/ac.yaml (100%) rename test/integration/crds/{ => hb}/cac.yaml (100%) rename test/integration/crds/{ => sc}/clusterservicebroker.yaml (100%) rename test/integration/crds/{ => sc}/servicebroker.yaml (100%) delete mode 100644 test/integration/source_test.go diff --git a/internal/config/controller_config.go b/internal/config/controller_config.go index c82859c3..85f8f8a8 100644 --- a/internal/config/controller_config.go +++ b/internal/config/controller_config.go @@ -34,6 +34,7 @@ type ControllerConfig struct { Storage []storage.Config `valid:"required"` DevelopMode bool UploadServiceURL string `default:"http://assetstore-asset-upload-service.kyma-system.svc.cluster.local:3000"` + DocumentationEnabled bool } // LoadControllerConfig method has following strategy: diff --git a/internal/controller/clusteraddonsconfiguration_controller_test.go b/internal/controller/clusteraddonsconfiguration_controller_test.go index 9456e1c2..9508bf10 100644 --- a/internal/controller/clusteraddonsconfiguration_controller_test.go +++ b/internal/controller/clusteraddonsconfiguration_controller_test.go @@ -12,16 +12,19 @@ import ( "github.com/Masterminds/semver" "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1" "github.com/kyma-project/helm-broker/internal" + "github.com/kyma-project/helm-broker/internal/addon" "github.com/kyma-project/helm-broker/internal/controller/automock" "github.com/kyma-project/helm-broker/pkg/apis" "github.com/kyma-project/helm-broker/pkg/apis/addons/v1alpha1" "github.com/kyma-project/helm-broker/platform/logger/spy" + cms "github.com/kyma-project/kyma/components/cms-controller-manager/pkg/apis/cms/v1alpha1" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/helm/pkg/proto/hapi/chart" "sigs.k8s.io/controller-runtime/pkg/client/fake" "sigs.k8s.io/controller-runtime/pkg/manager" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -449,3 +452,83 @@ func fixDeletedClusterAddonsConfiguration() *v1alpha1.ClusterAddonsConfiguration }, } } + +func fixAddonWithDocsURL(id, name, url, docsURL string) addon.CompleteAddon { + chartName := fmt.Sprintf("chart-%s", name) + chartVersion := semver.MustParse("1.0.0") + return addon.CompleteAddon{ + Addon: &internal.Addon{ + ID: internal.AddonID(id), + Name: internal.AddonName(name), + Description: "simple description", + Version: *semver.MustParse("0.0.1"), + RepositoryURL: url, + Plans: map[internal.AddonPlanID]internal.AddonPlan{ + internal.AddonPlanID(fmt.Sprintf("plan-%s", name)): { + ChartRef: internal.ChartRef{ + Name: internal.ChartName(chartName), + Version: *chartVersion, + }, + }, + }, + Docs: []internal.AddonDocs{ + { + Template: cms.CommonDocsTopicSpec{ + Sources: []cms.Source{ + { + URL: docsURL, + }, + }, + }, + }, + }, + }, + Charts: []*chart.Chart{ + { + Metadata: &chart.Metadata{ + Name: chartName, + Version: chartVersion.String(), + }, + }, + }, + } +} + +func fixAddonWithEmptyDocs(id, name, url string) addon.CompleteAddon { + chartName := fmt.Sprintf("chart-%s", name) + chartVersion := semver.MustParse("1.0.0") + return addon.CompleteAddon{ + Addon: &internal.Addon{ + ID: internal.AddonID(id), + Name: internal.AddonName(name), + Description: "simple description", + Version: *semver.MustParse("0.0.1"), + RepositoryURL: url, + Plans: map[internal.AddonPlanID]internal.AddonPlan{ + internal.AddonPlanID(fmt.Sprintf("plan-%s", name)): { + ChartRef: internal.ChartRef{ + Name: internal.ChartName(chartName), + Version: *chartVersion, + }, + }, + }, + Docs: []internal.AddonDocs{ + { + Template: cms.CommonDocsTopicSpec{ + Sources: []cms.Source{ + {}, + }, + }, + }, + }, + }, + Charts: []*chart.Chart{ + { + Metadata: &chart.Metadata{ + Name: chartName, + Version: chartVersion.String(), + }, + }, + }, + } +} diff --git a/internal/controller/docs/dummy_provider.go b/internal/controller/docs/dummy_provider.go new file mode 100644 index 00000000..c82f88de --- /dev/null +++ b/internal/controller/docs/dummy_provider.go @@ -0,0 +1,27 @@ +package docs + +import "github.com/kyma-project/helm-broker/internal" + +// DummyProvider is an implementation which does not perform any work but have the same interface as the Provider +type DummyProvider struct { +} + +// EnsureDocsTopic fulfills the docsFacade interface +func (s *DummyProvider) EnsureDocsTopic(addon *internal.Addon, namespace string) error { + return nil +} + +// EnsureDocsTopicRemoved fulfills the docsFacade interface +func (*DummyProvider) EnsureDocsTopicRemoved(id string, namespace string) error { + return nil +} + +// EnsureClusterDocsTopic fulfills the docsFacade interface +func (*DummyProvider) EnsureClusterDocsTopic(addon *internal.Addon) error { + return nil +} + +// EnsureClusterDocsTopicRemoved fulfills the docsFacade interface +func (*DummyProvider) EnsureClusterDocsTopicRemoved(id string) error { + return nil +} diff --git a/internal/controller/docs_provider.go b/internal/controller/docs/provider.go similarity index 84% rename from internal/controller/docs_provider.go rename to internal/controller/docs/provider.go index f0e976e0..809ef2bc 100644 --- a/internal/controller/docs_provider.go +++ b/internal/controller/docs/provider.go @@ -1,4 +1,4 @@ -package controller +package docs import ( "context" @@ -14,14 +14,14 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -// DocsProvider allows to maintain the addons documentation -type DocsProvider struct { +// Provider allows to maintain the addons documentation +type Provider struct { dynamicClient client.Client } -// NewDocsProvider creates a new DocsProvider -func NewDocsProvider(dynamicClient client.Client) *DocsProvider { - return &DocsProvider{ +// NewProvider creates a new Provider +func NewProvider(dynamicClient client.Client) *Provider { + return &Provider{ dynamicClient: dynamicClient, } } @@ -32,7 +32,7 @@ const ( ) // EnsureClusterDocsTopic creates ClusterDocsTopic for a given addon or updates it in case it already exists -func (d *DocsProvider) EnsureClusterDocsTopic(addon *internal.Addon) error { +func (d *Provider) EnsureClusterDocsTopic(addon *internal.Addon) error { addon.Docs[0].Template.Sources = d.defaultDocsSourcesURLs(addon) cdt := &v1alpha1.ClusterDocsTopic{ ObjectMeta: v1.ObjectMeta{ @@ -60,7 +60,7 @@ func (d *DocsProvider) EnsureClusterDocsTopic(addon *internal.Addon) error { } // EnsureClusterDocsTopicRemoved removes ClusterDocsTopic for a given addon -func (d *DocsProvider) EnsureClusterDocsTopicRemoved(id string) error { +func (d *Provider) EnsureClusterDocsTopicRemoved(id string) error { cdt := &v1alpha1.ClusterDocsTopic{ ObjectMeta: v1.ObjectMeta{ Name: id, @@ -74,7 +74,7 @@ func (d *DocsProvider) EnsureClusterDocsTopicRemoved(id string) error { } // EnsureDocsTopic creates ClusterDocsTopic for a given addon or updates it in case it already exists -func (d *DocsProvider) EnsureDocsTopic(addon *internal.Addon, namespace string) error { +func (d *Provider) EnsureDocsTopic(addon *internal.Addon, namespace string) error { addon.Docs[0].Template.Sources = d.defaultDocsSourcesURLs(addon) dt := &v1alpha1.DocsTopic{ ObjectMeta: v1.ObjectMeta{ @@ -103,7 +103,7 @@ func (d *DocsProvider) EnsureDocsTopic(addon *internal.Addon, namespace string) } // EnsureDocsTopicRemoved removes ClusterDocsTopic for a given addon -func (d *DocsProvider) EnsureDocsTopicRemoved(id string, namespace string) error { +func (d *Provider) EnsureDocsTopicRemoved(id string, namespace string) error { dt := &v1alpha1.DocsTopic{ ObjectMeta: v1.ObjectMeta{ Name: id, @@ -117,7 +117,7 @@ func (d *DocsProvider) EnsureDocsTopicRemoved(id string, namespace string) error return nil } -func (d *DocsProvider) defaultDocsSourcesURLs(addon *internal.Addon) []v1alpha1.Source { +func (d *Provider) defaultDocsSourcesURLs(addon *internal.Addon) []v1alpha1.Source { // we use repositoryURL as the default sourceURL if its not provided var sources []v1alpha1.Source for _, source := range addon.Docs[0].Template.Sources { @@ -129,7 +129,7 @@ func (d *DocsProvider) defaultDocsSourcesURLs(addon *internal.Addon) []v1alpha1. return sources } -func (d *DocsProvider) updateClusterDocsTopic(addon *internal.Addon) error { +func (d *Provider) updateClusterDocsTopic(addon *internal.Addon) error { cdt := &v1alpha1.ClusterDocsTopic{} if err := d.dynamicClient.Get(context.Background(), types.NamespacedName{Name: string(addon.ID)}, cdt); err != nil { return errors.Wrapf(err, "while getting ClusterDocsTopic %s", addon.ID) @@ -146,7 +146,7 @@ func (d *DocsProvider) updateClusterDocsTopic(addon *internal.Addon) error { return nil } -func (d *DocsProvider) updateDocsTopic(addon *internal.Addon, namespace string) error { +func (d *Provider) updateDocsTopic(addon *internal.Addon, namespace string) error { dt := &v1alpha1.DocsTopic{} if err := d.dynamicClient.Get(context.Background(), types.NamespacedName{Name: string(addon.ID), Namespace: namespace}, dt); err != nil { return errors.Wrapf(err, "while getting DocsTopic %s", addon.ID) diff --git a/internal/controller/docs_provider_test.go b/internal/controller/docs/provider_test.go similarity index 94% rename from internal/controller/docs_provider_test.go rename to internal/controller/docs/provider_test.go index da11b0a7..8f7b0ec7 100644 --- a/internal/controller/docs_provider_test.go +++ b/internal/controller/docs/provider_test.go @@ -1,4 +1,4 @@ -package controller +package docs import ( "context" @@ -20,7 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -func TestDocsProvider_EnsureClusterDocsTopic(t *testing.T) { +func TestProvider_EnsureClusterDocsTopic(t *testing.T) { // given err := v1alpha1.AddToScheme(scheme.Scheme) require.NoError(t, err) @@ -35,7 +35,7 @@ func TestDocsProvider_EnsureClusterDocsTopic(t *testing.T) { t.Run(tn, func(t *testing.T) { c := fake.NewFakeClient() cdt := fixClusterDocsTopic(id) - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureClusterDocsTopic(tc.givenAddon.Addon) @@ -49,7 +49,7 @@ func TestDocsProvider_EnsureClusterDocsTopic(t *testing.T) { } } -func TestDocsProvider_EnsureClusterDocsTopic_UpdateIfExist(t *testing.T) { +func TestProvider_EnsureClusterDocsTopic_UpdateIfExist(t *testing.T) { // given err := v1alpha1.AddToScheme(scheme.Scheme) require.NoError(t, err) @@ -60,7 +60,7 @@ func TestDocsProvider_EnsureClusterDocsTopic_UpdateIfExist(t *testing.T) { addonWithEmptyDocsURL.Addon.Docs[0].Template.Description = "new description" c := fake.NewFakeClient(cdt) - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureClusterDocsTopic(addonWithEmptyDocsURL.Addon) @@ -80,7 +80,7 @@ func TestDocsProvider_EnsureClusterDocsTopicRemoved(t *testing.T) { const id = "123" cdt := fixClusterDocsTopic(id) c := fake.NewFakeClient(cdt) - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureClusterDocsTopicRemoved(id) @@ -99,7 +99,7 @@ func TestDocsProvider_EnsureClusterDocsTopicRemoved_NotExists(t *testing.T) { const id = "123" cdt := fixClusterDocsTopic(id) c := fake.NewFakeClient() - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureClusterDocsTopicRemoved(id) @@ -124,7 +124,7 @@ func TestDocsProvider_EnsureDocsTopic(t *testing.T) { } { t.Run(tn, func(t *testing.T) { c := fake.NewFakeClient(dt) - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureDocsTopic(tc.givenAddon.Addon, dt.Namespace) @@ -150,7 +150,7 @@ func TestDocsProvider_EnsureDocsTopic_UpdateIfExist(t *testing.T) { addonWithEmptyDocsURL.Addon.Docs[0].Template.Description = "new description" c := fake.NewFakeClient(dt) - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureDocsTopic(addonWithEmptyDocsURL.Addon, dt.Namespace) @@ -170,7 +170,7 @@ func TestDocsProvider_EnsureDocsTopicRemoved(t *testing.T) { dt := fixDocsTopic() c := fake.NewFakeClient(dt) - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureDocsTopicRemoved(dt.Name, dt.Namespace) @@ -189,7 +189,7 @@ func TestDocsProvider_EnsureDocsTopicRemoved_NotExists(t *testing.T) { dt := fixDocsTopic() c := fake.NewFakeClient() - docsProvider := NewDocsProvider(c) + docsProvider := NewProvider(c) // when err = docsProvider.EnsureDocsTopicRemoved(dt.Name, dt.Namespace) diff --git a/internal/controller/ext.go b/internal/controller/ext.go index 670c8820..dee91972 100644 --- a/internal/controller/ext.go +++ b/internal/controller/ext.go @@ -69,3 +69,8 @@ type clusterDocsProvider interface { type clusterBrokerSyncer interface { Sync() error } + +type docsFacade interface { + clusterDocsProvider + docsProvider +} diff --git a/internal/controller/setup.go b/internal/controller/setup.go index 33170293..d4e1dd97 100644 --- a/internal/controller/setup.go +++ b/internal/controller/setup.go @@ -10,6 +10,7 @@ import ( "github.com/kyma-project/helm-broker/internal/assetstore" "github.com/kyma-project/helm-broker/internal/config" "github.com/kyma-project/helm-broker/internal/controller/broker" + "github.com/kyma-project/helm-broker/internal/controller/docs" "github.com/kyma-project/helm-broker/internal/storage" "github.com/kyma-project/helm-broker/pkg/apis" "github.com/kyma-project/kyma/components/cms-controller-manager/pkg/apis/cms/v1alpha1" @@ -41,7 +42,13 @@ func SetupAndStartController(cfg *rest.Config, ctrCfg *config.ControllerConfig, fatalOnError(v1alpha1.AddToScheme(mgr.GetScheme()), "while adding CMS scheme") // Setup dependencies - docsProvider := NewDocsProvider(mgr.GetClient()) + + var docsProvider docsFacade + docsProvider = docs.NewProvider(mgr.GetClient()) + if !ctrCfg.DocumentationEnabled { + docsProvider = &docs.DummyProvider{} + } + brokerSyncer := broker.NewServiceBrokerSyncer(mgr.GetClient(), ctrCfg.ClusterServiceBrokerName, lg) sbFacade := broker.NewBrokersFacade(mgr.GetClient(), brokerSyncer, ctrCfg.Namespace, ctrCfg.ServiceName, lg) csbFacade := broker.NewClusterBrokersFacade(mgr.GetClient(), brokerSyncer, ctrCfg.Namespace, ctrCfg.ServiceName, ctrCfg.ClusterServiceBrokerName, lg) diff --git a/test/integration/crds/clusterdocstopic.yaml b/test/integration/crds/docs/clusterdocstopic.yaml similarity index 100% rename from test/integration/crds/clusterdocstopic.yaml rename to test/integration/crds/docs/clusterdocstopic.yaml diff --git a/test/integration/crds/docstopic.yaml b/test/integration/crds/docs/docstopic.yaml similarity index 100% rename from test/integration/crds/docstopic.yaml rename to test/integration/crds/docs/docstopic.yaml diff --git a/test/integration/crds/ac.yaml b/test/integration/crds/hb/ac.yaml similarity index 100% rename from test/integration/crds/ac.yaml rename to test/integration/crds/hb/ac.yaml diff --git a/test/integration/crds/cac.yaml b/test/integration/crds/hb/cac.yaml similarity index 100% rename from test/integration/crds/cac.yaml rename to test/integration/crds/hb/cac.yaml diff --git a/test/integration/crds/clusterservicebroker.yaml b/test/integration/crds/sc/clusterservicebroker.yaml similarity index 100% rename from test/integration/crds/clusterservicebroker.yaml rename to test/integration/crds/sc/clusterservicebroker.yaml diff --git a/test/integration/crds/servicebroker.yaml b/test/integration/crds/sc/servicebroker.yaml similarity index 100% rename from test/integration/crds/servicebroker.yaml rename to test/integration/crds/sc/servicebroker.yaml diff --git a/test/integration/integration_test.go b/test/integration/integration_test.go index be4e71a1..8e86adac 100644 --- a/test/integration/integration_test.go +++ b/test/integration/integration_test.go @@ -6,12 +6,11 @@ import ( "testing" "github.com/kyma-project/helm-broker/pkg/apis/addons/v1alpha1" - "github.com/stretchr/testify/assert" ) func TestGetCatalogHappyPath(t *testing.T) { // given - suite := newTestSuite(t) + suite := newTestSuite(t, true) defer suite.tearDown() for name, c := range map[string]struct { @@ -34,20 +33,10 @@ func TestGetCatalogHappyPath(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - var repository *gitRepo - if c.kind == sourceGit { - repo, err := newGitRepository(t, addonSource) - assert.NoError(t, err) - - defer repo.removeTmpDir() - repository = repo - } - suite.assertNoServicesInCatalogEndpoint("ns/stage") // when - source := newSource(c.kind, suite, repository, []string{redisAndAccTestRepo}) - suite.createAddonsConfiguration("stage", c.addonName, source) + suite.createAddonsConfiguration("stage", c.addonName, []string{redisAndAccTestRepo}, c.kind) // then suite.waitForAddonsConfigurationPhase("stage", c.addonName, v1alpha1.AddonsConfigurationReady) @@ -56,14 +45,13 @@ func TestGetCatalogHappyPath(t *testing.T) { suite.assertNoServicesInCatalogEndpoint("cluster") // when - suite.createAddonsConfiguration("prod", c.addonName, source) + suite.createAddonsConfiguration("prod", c.addonName, []string{redisAndAccTestRepo}, c.kind) suite.waitForAddonsConfigurationPhase("prod", c.addonName, v1alpha1.AddonsConfigurationReady) suite.waitForServicesInCatalogEndpoint("ns/prod", []string{c.redisID, c.testID}) // when - source.removeURL(redisAndAccTestRepo) - suite.updateAddonsConfigurationRepositories("stage", c.addonName, source) - suite.updateAddonsConfigurationRepositories("prod", c.addonName, source) + suite.updateAddonsConfigurationRepositories("stage", c.addonName, []string{}, c.kind) + suite.updateAddonsConfigurationRepositories("prod", c.addonName, []string{}, c.kind) // then suite.waitForEmptyCatalogResponse("ns/stage") @@ -89,28 +77,17 @@ func TestGetCatalogHappyPath(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - var repository *gitRepo - if c.kind == sourceGit { - repo, err := newGitRepository(t, addonSource) - assert.NoError(t, err) - - defer repo.removeTmpDir() - repository = repo - } - suite.assertNoServicesInCatalogEndpoint("cluster") // when - source := newSource(c.kind, suite, repository, []string{redisRepo}) - suite.createClusterAddonsConfiguration(c.addonName, source) + suite.createClusterAddonsConfiguration(c.addonName, []string{redisRepo}, c.kind) // then suite.waitForClusterAddonsConfigurationPhase(c.addonName, v1alpha1.AddonsConfigurationReady) suite.waitForServicesInCatalogEndpoint("cluster", []string{c.redisID}) // when - source.removeURL(redisRepo) - suite.updateClusterAddonsConfigurationRepositories(c.addonName, source) + suite.updateClusterAddonsConfigurationRepositories(c.addonName, []string{}, c.kind) // then suite.waitForEmptyCatalogResponse("cluster") @@ -120,7 +97,7 @@ func TestGetCatalogHappyPath(t *testing.T) { func TestAddonsConflicts(t *testing.T) { // given - suite := newTestSuite(t) + suite := newTestSuite(t, true) defer suite.tearDown() for name, c := range map[string]struct { @@ -140,22 +117,13 @@ func TestAddonsConflicts(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - var repository *gitRepo - if c.kind == sourceGit { - repo, err := newGitRepository(t, addonSource) - assert.NoError(t, err) - - defer repo.removeTmpDir() - repository = repo - } first := "first-" + c.kind second := "second-" + c.kind third := "third-" + c.kind // when // - create an addons configuration with repo with redis addon - source := newSource(c.kind, suite, repository, []string{redisRepo}) - suite.createAddonsConfiguration("stage", first, source) + suite.createAddonsConfiguration("stage", first, []string{redisRepo}, c.kind) // then // - wait for readiness and wait for service redis at the catalog endpoint @@ -164,8 +132,7 @@ func TestAddonsConflicts(t *testing.T) { // when // - create second addons configuration with a repo with redis and acc-test addons - sourceFull := newSource(c.kind, suite, repository, []string{redisAndAccTestRepo}) - suite.createAddonsConfiguration("stage", second, sourceFull) + suite.createAddonsConfiguration("stage", second, []string{redisAndAccTestRepo}, c.kind) // then // - expect phase "failed", still redis service at the catalog endpoint @@ -174,8 +141,7 @@ func TestAddonsConflicts(t *testing.T) { // when // - remove repo with redis from the first (cluster) addon - source.removeURL(redisRepo) - suite.updateAddonsConfigurationRepositories("stage", first, source) + suite.updateAddonsConfigurationRepositories("stage", first, []string{}, c.kind) // then // - expect for readiness and 2 services at the catalog endpoint @@ -184,8 +150,7 @@ func TestAddonsConflicts(t *testing.T) { // when // - create third addons configuration with a repo with acc-test addons - sourceTesting := newSource(c.kind, suite, repository, []string{accTestRepo}) - suite.createAddonsConfiguration("stage", third, sourceTesting) + suite.createAddonsConfiguration("stage", third, []string{accTestRepo}, c.kind) // then // - expect failed (because of the conflict) @@ -219,22 +184,13 @@ func TestAddonsConflicts(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - var repository *gitRepo - if c.kind == sourceGit { - repo, err := newGitRepository(t, addonSource) - assert.NoError(t, err) - - defer repo.removeTmpDir() - repository = repo - } first := "first-" + c.kind second := "second-" + c.kind third := "third-" + c.kind // when // - create an cluster addons configuration with repo with redis addon - source := newSource(c.kind, suite, repository, []string{redisRepo}) - suite.createClusterAddonsConfiguration(first, source) + suite.createClusterAddonsConfiguration(first, []string{redisRepo}, c.kind) // then // - wait for readiness and wait for service redis at the catalog endpoint @@ -243,8 +199,7 @@ func TestAddonsConflicts(t *testing.T) { // when // - create second cluster addons configuration with a repo with redis and acc-test addons - sourceFull := newSource(c.kind, suite, repository, []string{redisAndAccTestRepo}) - suite.createClusterAddonsConfiguration(second, sourceFull) + suite.createClusterAddonsConfiguration(second, []string{redisAndAccTestRepo}, c.kind) // then // - expect phase "failed", still redis service at the catalog endpoint @@ -253,8 +208,7 @@ func TestAddonsConflicts(t *testing.T) { // when // - remove repo with redis from the first (cluster) addon - source.removeURL(redisRepo) - suite.updateClusterAddonsConfigurationRepositories(first, source) + suite.updateClusterAddonsConfigurationRepositories(first, []string{}, c.kind) // then // - expect for readiness and 2 services at the catalog endpoint @@ -263,8 +217,7 @@ func TestAddonsConflicts(t *testing.T) { // when // - create third cluster addons configuration with a repo with acc-test addons - sourceTesting := newSource(c.kind, suite, repository, []string{accTestRepo}) - suite.createClusterAddonsConfiguration(third, sourceTesting) + suite.createClusterAddonsConfiguration(third, []string{accTestRepo}, c.kind) // then // - expect failed (because of the conflict) @@ -284,7 +237,7 @@ func TestAddonsConflicts(t *testing.T) { func TestDocsTopic(t *testing.T) { // given - suite := newTestSuite(t) + suite := newTestSuite(t, true) defer suite.tearDown() for name, c := range map[string]struct { @@ -304,26 +257,15 @@ func TestDocsTopic(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - var repository *gitRepo - if c.kind == sourceGit { - repo, err := newGitRepository(t, addonSource) - assert.NoError(t, err) - - defer repo.removeTmpDir() - repository = repo - } - // when - source := newSource(c.kind, suite, repository, []string{redisAndAccTestRepo}) - suite.createAddonsConfiguration("stage", c.addonName, source) + suite.createAddonsConfiguration("stage", c.addonName, []string{redisAndAccTestRepo}, c.kind) // then suite.waitForAddonsConfigurationPhase("stage", c.addonName, v1alpha1.AddonsConfigurationReady) suite.assertDocsTopicExist("stage", c.docsTopicID) // when - source.replaceURL(redisRepo) - suite.updateAddonsConfigurationRepositories("stage", c.addonName, source) + suite.updateAddonsConfigurationRepositories("stage", c.addonName, []string{redisRepo}, c.kind) // then suite.assertDocsTopicListIsEmpty() @@ -347,29 +289,42 @@ func TestDocsTopic(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - var repository *gitRepo - if c.kind == sourceGit { - repo, err := newGitRepository(t, addonSource) - assert.NoError(t, err) - - defer repo.removeTmpDir() - repository = repo - } - - // when - source := newSource(c.kind, suite, repository, []string{redisAndAccTestRepo}) - suite.createClusterAddonsConfiguration(c.addonName, source) + suite.createClusterAddonsConfiguration(c.addonName, []string{redisAndAccTestRepo}, c.kind) // then suite.waitForClusterAddonsConfigurationPhase(c.addonName, v1alpha1.AddonsConfigurationReady) suite.assertClusterDocsTopicExist(c.docsTopicID) // when - source.replaceURL(redisRepo) - suite.updateClusterAddonsConfigurationRepositories(c.addonName, source) + suite.updateClusterAddonsConfigurationRepositories(c.addonName, []string{redisRepo}, c.kind) // then suite.assertClusterDocsTopicListIsEmpty() }) } } + +func TestDisabledDocs(t *testing.T) { + suite := newTestSuite(t, false) + defer suite.tearDown() + + t.Run("namespaced", func(t *testing.T) { + suite.assertNoServicesInCatalogEndpoint("ns/stage") + + // when + suite.createAddonsConfiguration("stage", "addon1", []string{accTestRepo}, sourceHTTP) + + // then + suite.waitForAddonsConfigurationPhase("stage", "addon1", v1alpha1.AddonsConfigurationReady) + }) + + t.Run("cluster", func(t *testing.T) { + suite.assertNoServicesInCatalogEndpoint("cluster") + + // when + suite.createClusterAddonsConfiguration("addon1", []string{accTestRepo}, sourceHTTP) + + // then + suite.waitForClusterAddonsConfigurationPhase("addon1", v1alpha1.AddonsConfigurationReady) + }) +} diff --git a/test/integration/source_test.go b/test/integration/source_test.go deleted file mode 100644 index 31a648eb..00000000 --- a/test/integration/source_test.go +++ /dev/null @@ -1,83 +0,0 @@ -// +build integration - -package integration_test - -import ( - "github.com/kyma-project/helm-broker/pkg/apis/addons/v1alpha1" -) - -const ( - sourceHTTP = "http" - sourceGit = "git" -) - -type repositorySource struct { - kind string - ts *testSuite - gitRepo *gitRepo - urls []string -} - -func newSource(kind string, ts *testSuite, repository *gitRepo, urls []string) *repositorySource { - rs := &repositorySource{ - ts: ts, - gitRepo: repository, - kind: kind, - } - - sourceUrls := []string{} - for _, url := range urls { - sourceUrls = append(sourceUrls, rs.generateURL(url)) - } - rs.urls = sourceUrls - - return rs -} - -func (rs *repositorySource) generateURL(url string) string { - switch rs.kind { - case sourceHTTP: - return rs.ts.repoServer.URL + "/" + url - case sourceGit: - return "git::" + rs.gitRepo.path(url) - default: - rs.ts.t.Fatalf("Unsupported source kind: %s", rs.kind) - } - - return "" -} - -func (rs *repositorySource) removeURL(url string) { - path := rs.generateURL(url) - newUrls := []string{} - - for _, u := range rs.urls { - if u == path { - rs.ts.t.Logf("URL %q was removed from repository source", u) - continue - } - newUrls = append(newUrls, u) - } - - rs.urls = newUrls -} - -func (rs *repositorySource) replaceURL(url string) { - rs.urls = []string{rs.generateURL(url)} -} - -func (rs *repositorySource) generateAddonRepositories() []v1alpha1.SpecRepository { - var repositories []v1alpha1.SpecRepository - - // v1alpha1.SpecRepository cannot be null, needs to be empty array - if len(rs.urls) == 0 { - repositories = append(repositories, v1alpha1.SpecRepository{}) - return repositories - } - - for _, url := range rs.urls { - repositories = append(repositories, v1alpha1.SpecRepository{URL: url}) - } - - return repositories -} diff --git a/test/integration/suite_test.go b/test/integration/suite_test.go index 601cad70..9ddc1925 100644 --- a/test/integration/suite_test.go +++ b/test/integration/suite_test.go @@ -56,9 +56,12 @@ const ( redisRepo = "index-redis.yaml" accTestRepo = "index-acc-testing.yaml" redisAndAccTestRepo = "index.yaml" + + sourceHTTP = "http" + sourceGit = "git" ) -func newTestSuite(t *testing.T) *testSuite { +func newTestSuite(t *testing.T, docsEnabled bool) *testSuite { sch, err := v1alpha1.SchemeBuilder.Build() require.NoError(t, err) require.NoError(t, apis.AddToScheme(sch)) @@ -94,10 +97,17 @@ func newTestSuite(t *testing.T) *testSuite { restConfig, err := environment.Start() require.NoError(t, err) _, err = envtest.InstallCRDs(restConfig, envtest.CRDInstallOptions{ - Paths: []string{"crds/"}, + Paths: []string{"crds/hb/", "crds/sc/"}, ErrorIfPathMissing: true, }) require.NoError(t, err) + if docsEnabled { + _, err = envtest.InstallCRDs(restConfig, envtest.CRDInstallOptions{ + Paths: []string{"crds/docs/"}, + ErrorIfPathMissing: true, + }) + require.NoError(t, err) + } uploadClient := &automock.Client{} uploadClient.On("Upload", mock.AnythingOfType("string"), mock.Anything).Return(assetstore.UploadedFile{}, nil) @@ -106,6 +116,7 @@ func newTestSuite(t *testing.T) *testSuite { DevelopMode: true, // DevelopMode allows "http" urls ClusterServiceBrokerName: "helm-broker", TmpDir: cfg.TmpDir, + DocumentationEnabled: docsEnabled, }, ":8001", sFact, uploadClient, logger.WithField("svc", "broker")) stopCh := make(chan struct{}) @@ -118,6 +129,10 @@ func newTestSuite(t *testing.T) *testSuite { // create a client for managing (cluster) addons configurations dynamicClient, err := client.New(restConfig, client.Options{Scheme: sch}) + // initialize git repositoryDirName + gitRepository, err := newGitRepository(t, addonSource) + require.NoError(t, err) + return &testSuite{ t: t, @@ -126,7 +141,8 @@ func newTestSuite(t *testing.T) *testSuite { server: server, k8sClient: k8sClientset, - stopCh: stopCh, + stopCh: stopCh, + gitRepository: gitRepository, } } @@ -144,9 +160,10 @@ func newOSBClient(url string) (osb.Client, error) { } type testSuite struct { - t *testing.T - server *httptest.Server - repoServer *httptest.Server + t *testing.T + server *httptest.Server + repoServer *httptest.Server + gitRepository *gitRepo osbClient osb.Client dynamicClient client.Client @@ -159,6 +176,7 @@ func (ts *testSuite) tearDown() { ts.server.Close() ts.repoServer.Close() close(ts.stopCh) + ts.gitRepository.removeTmpDir() } func (ts *testSuite) assertNoServicesInCatalogEndpoint(prefix string) { @@ -279,7 +297,7 @@ func (ts *testSuite) deleteClusterAddonsConfiguration(name string) { }})) } -func (ts *testSuite) createAddonsConfiguration(namespace, name string, source *repositorySource) { +func (ts *testSuite) createAddonsConfiguration(namespace, name string, urls []string, repoKind string) { err := ts.dynamicClient.Create(context.TODO(), &v1alpha1.AddonsConfiguration{ ObjectMeta: v1.ObjectMeta{ Name: name, @@ -287,7 +305,7 @@ func (ts *testSuite) createAddonsConfiguration(namespace, name string, source *r }, Spec: v1alpha1.AddonsConfigurationSpec{ CommonAddonsConfigurationSpec: v1alpha1.CommonAddonsConfigurationSpec{ - Repositories: source.generateAddonRepositories(), + Repositories: ts.createSpecRepositories(urls, repoKind), }, }, }) @@ -297,36 +315,55 @@ func (ts *testSuite) createAddonsConfiguration(namespace, name string, source *r } } -func (ts *testSuite) createClusterAddonsConfiguration(name string, source *repositorySource) { - err := ts.dynamicClient.Create(context.TODO(), &v1alpha1.ClusterAddonsConfiguration{ +func (ts *testSuite) createClusterAddonsConfiguration(name string, urls []string, repoKind string) { + ts.dynamicClient.Create(context.TODO(), &v1alpha1.ClusterAddonsConfiguration{ ObjectMeta: v1.ObjectMeta{ Name: name, }, Spec: v1alpha1.ClusterAddonsConfigurationSpec{ CommonAddonsConfigurationSpec: v1alpha1.CommonAddonsConfigurationSpec{ - Repositories: source.generateAddonRepositories(), + Repositories: ts.createSpecRepositories(urls, repoKind), }, }, }) +} - if err != nil { - ts.t.Logf("Failed during creating ClusterAddonsConfiguration: %s", err) +func (ts *testSuite) createSpecRepositories(urls []string, repoKind string) []v1alpha1.SpecRepository { + // v1alpha1.SpecRepository cannot be null, needs to be empty array + if len(urls) == 0 { + return []v1alpha1.SpecRepository{{}} + } + var repositories []v1alpha1.SpecRepository + for _, url := range urls { + + var fullURL string + switch repoKind { + case sourceHTTP: + fullURL = ts.repoServer.URL + "/" + url + case sourceGit: + fullURL = "git::" + ts.gitRepository.path(url) + default: + ts.t.Fatalf("Unsupported source kind: %s", repoKind) + } + + repositories = append(repositories, v1alpha1.SpecRepository{URL: fullURL}) } + return repositories } -func (ts *testSuite) updateAddonsConfigurationRepositories(namespace, name string, source *repositorySource) { +func (ts *testSuite) updateAddonsConfigurationRepositories(namespace, name string, urls []string, repoKind string) { var addonsConfiguration v1alpha1.AddonsConfiguration - require.NoError(ts.t, ts.dynamicClient.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: namespace}, &addonsConfiguration)) + require.NoError(ts.t, ts.dynamicClient.Get(context.TODO(), types.NamespacedName{Namespace: namespace, Name: name}, &addonsConfiguration)) - addonsConfiguration.Spec.Repositories = source.generateAddonRepositories() + addonsConfiguration.Spec.Repositories = ts.createSpecRepositories(urls, repoKind) require.NoError(ts.t, ts.dynamicClient.Update(context.TODO(), &addonsConfiguration)) } -func (ts *testSuite) updateClusterAddonsConfigurationRepositories(name string, source *repositorySource) { +func (ts *testSuite) updateClusterAddonsConfigurationRepositories(name string, urls []string, repoKind string) { var clusterAddonsConfiguration v1alpha1.ClusterAddonsConfiguration require.NoError(ts.t, ts.dynamicClient.Get(context.TODO(), types.NamespacedName{Name: name}, &clusterAddonsConfiguration)) - clusterAddonsConfiguration.Spec.Repositories = source.generateAddonRepositories() + clusterAddonsConfiguration.Spec.Repositories = ts.createSpecRepositories(urls, repoKind) require.NoError(ts.t, ts.dynamicClient.Update(context.TODO(), &clusterAddonsConfiguration)) }