diff --git a/cmd/smith/app/BUILD.bazel b/cmd/smith/app/BUILD.bazel index 85186d1..8fa3ab4 100644 --- a/cmd/smith/app/BUILD.bazel +++ b/cmd/smith/app/BUILD.bazel @@ -7,7 +7,6 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/apis/smith/v1:go_default_library", - "//pkg/catalog:go_default_library", "//pkg/cleanup:go_default_library", "//pkg/cleanup/types:go_default_library", "//pkg/client:go_default_library", @@ -22,6 +21,7 @@ go_library( "//pkg/store:go_default_library", "//vendor/github.com/ash2k/stager:go_default_library", "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset:go_default_library", + "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/externalversions/servicecatalog/v1beta1:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", "//vendor/go.uber.org/zap:go_default_library", "//vendor/k8s.io/api/core/v1:go_default_library", diff --git a/cmd/smith/app/app.go b/cmd/smith/app/app.go index c082b28..22a65d6 100644 --- a/cmd/smith/app/app.go +++ b/cmd/smith/app/app.go @@ -10,7 +10,6 @@ import ( "time" smith_v1 "github.com/atlassian/smith/pkg/apis/smith/v1" - "github.com/atlassian/smith/pkg/catalog" "github.com/atlassian/smith/pkg/cleanup" clean_types "github.com/atlassian/smith/pkg/cleanup/types" "github.com/atlassian/smith/pkg/client" @@ -26,6 +25,7 @@ import ( "github.com/ash2k/stager" scClientset "github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset" + sc_v1b1inf "github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/externalversions/servicecatalog/v1beta1" "github.com/pkg/errors" "go.uber.org/zap" core_v1 "k8s.io/api/core/v1" @@ -112,15 +112,22 @@ func (a *App) Run(ctx context.Context) error { } // Informers + var infs []cache.SharedIndexInformer + // We don't add these to 'infs' because they're added later as part of + // resourceInfs processing. bundleInf := client.BundleInformer(bundleClient.SmithV1(), a.Namespace, a.ResyncPeriod) crdInf := apiext_v1b1inf.NewCustomResourceDefinitionInformer(crdClient, a.ResyncPeriod, cache.Indexers{}) crdStore, err := store.NewCrd(crdInf) if err != nil { return err } - var catalogger *catalog.Catalog + var catalog *store.Catalog if a.ServiceCatalogSupport { - catalogger = catalog.NewCatalog(scClient, a.ResyncPeriod) + serviceClassInf := sc_v1b1inf.NewClusterServiceClassInformer(scClient, a.ResyncPeriod, cache.Indexers{}) + infs = append(infs, serviceClassInf) + servicePlanInf := sc_v1b1inf.NewClusterServicePlanInformer(scClient, a.ResyncPeriod, cache.Indexers{}) + infs = append(infs, servicePlanInf) + catalog = store.NewCatalog(serviceClassInf, servicePlanInf) } // Ready Checker @@ -192,7 +199,7 @@ func (a *App) Run(ctx context.Context) error { Namespace: a.Namespace, PluginContainers: pluginContainers, Scheme: scheme, - Catalog: catalogger, + Catalog: catalog, } cntrlr.Prepare(ctx, crdInf, resourceInfs) @@ -204,21 +211,20 @@ func (a *App) Run(ctx context.Context) error { defer stgr.Shutdown() stage := stgr.NextStage() - infs := make([]cache.InformerSynced, 0) - // Add all informers to Multi store and start them + // Add resource informers to Multi store (not ServiceClass/Plan informers, ...) for gvk, inf := range resourceInfs { multiStore.AddInformer(gvk, inf) - stage.StartWithChannel(inf.Run) // Must be after AddInformer() - infs = append(infs, inf.HasSynced) + infs = append(infs, inf) } - if catalogger != nil { - for _, inf := range catalogger.InformersToRegister() { - stage.StartWithChannel(inf.Run) - infs = append(infs, inf.HasSynced) - } + + // Start all informers then wait on them + infCacheSyncs := make([]cache.InformerSynced, len(infs)) + for i, inf := range infs { + stage.StartWithChannel(inf.Run) // Must be after AddInformer() + infCacheSyncs[i] = inf.HasSynced } a.Logger.Info("Waiting for informers to sync") - if !cache.WaitForCacheSync(ctx.Done(), infs...) { + if !cache.WaitForCacheSync(ctx.Done(), infCacheSyncs...) { return ctx.Err() } diff --git a/pkg/catalog/BUILD.bazel b/pkg/catalog/BUILD.bazel index 40b0525..e69de29 100644 --- a/pkg/catalog/BUILD.bazel +++ b/pkg/catalog/BUILD.bazel @@ -1,15 +0,0 @@ -load("@io_bazel_rules_go//go:def.bzl", "go_library") - -go_library( - name = "go_default_library", - srcs = ["catalog.go"], - importpath = "github.com/atlassian/smith/pkg/catalog", - visibility = ["//visibility:public"], - deps = [ - "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1:go_default_library", - "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset:go_default_library", - "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/externalversions/servicecatalog/v1beta1:go_default_library", - "//vendor/github.com/pkg/errors:go_default_library", - "//vendor/k8s.io/client-go/tools/cache:go_default_library", - ], -) diff --git a/pkg/controller/BUILD.bazel b/pkg/controller/BUILD.bazel index abbb6eb..7e34d6a 100644 --- a/pkg/controller/BUILD.bazel +++ b/pkg/controller/BUILD.bazel @@ -19,10 +19,10 @@ go_library( deps = [ "//:go_default_library", "//pkg/apis/smith/v1:go_default_library", - "//pkg/catalog:go_default_library", "//pkg/client/clientset_generated/clientset/typed/smith/v1:go_default_library", "//pkg/plugin:go_default_library", "//pkg/resources:go_default_library", + "//pkg/store:go_default_library", "//pkg/util:go_default_library", "//pkg/util/graph:go_default_library", "//pkg/util/logz:go_default_library", diff --git a/pkg/controller/bundle_sync_task.go b/pkg/controller/bundle_sync_task.go index 89b6037..407e5d0 100644 --- a/pkg/controller/bundle_sync_task.go +++ b/pkg/controller/bundle_sync_task.go @@ -5,9 +5,9 @@ import ( "fmt" smith_v1 "github.com/atlassian/smith/pkg/apis/smith/v1" - "github.com/atlassian/smith/pkg/catalog" smithClient_v1 "github.com/atlassian/smith/pkg/client/clientset_generated/clientset/typed/smith/v1" "github.com/atlassian/smith/pkg/plugin" + "github.com/atlassian/smith/pkg/store" "github.com/atlassian/smith/pkg/util/graph" "github.com/atlassian/smith/pkg/util/logz" @@ -31,7 +31,7 @@ type bundleSyncTask struct { processedResources map[smith_v1.ResourceName]*resourceInfo pluginContainers map[smith_v1.PluginName]plugin.PluginContainer scheme *runtime.Scheme - catalog *catalog.Catalog + catalog *store.Catalog } // Parse bundle, build resource graph, traverse graph, assert each resource exists. diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index cf7b039..d13d1be 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -6,9 +6,9 @@ import ( "time" smith_v1 "github.com/atlassian/smith/pkg/apis/smith/v1" - "github.com/atlassian/smith/pkg/catalog" smithClient_v1 "github.com/atlassian/smith/pkg/client/clientset_generated/clientset/typed/smith/v1" "github.com/atlassian/smith/pkg/plugin" + "github.com/atlassian/smith/pkg/store" "github.com/atlassian/smith/pkg/util/logz" "github.com/ash2k/stager/wait" @@ -55,7 +55,7 @@ type BundleController struct { PluginContainers map[smith_v1.PluginName]plugin.PluginContainer Scheme *runtime.Scheme - Catalog *catalog.Catalog + Catalog *store.Catalog } // Prepare prepares the controller to be run. diff --git a/pkg/controller/resource_sync_task.go b/pkg/controller/resource_sync_task.go index 71b0b03..1a76263 100644 --- a/pkg/controller/resource_sync_task.go +++ b/pkg/controller/resource_sync_task.go @@ -3,8 +3,8 @@ package controller import ( "github.com/atlassian/smith" smith_v1 "github.com/atlassian/smith/pkg/apis/smith/v1" - "github.com/atlassian/smith/pkg/catalog" "github.com/atlassian/smith/pkg/plugin" + "github.com/atlassian/smith/pkg/store" "github.com/atlassian/smith/pkg/util" "github.com/atlassian/smith/pkg/util/logz" @@ -74,7 +74,7 @@ type resourceSyncTask struct { processedResources map[smith_v1.ResourceName]*resourceInfo pluginContainers map[smith_v1.PluginName]plugin.PluginContainer scheme *runtime.Scheme - catalog *catalog.Catalog + catalog *store.Catalog } func (st *resourceSyncTask) processResource(res *smith_v1.Resource) resourceInfo { diff --git a/pkg/controller_test/BUILD.bazel b/pkg/controller_test/BUILD.bazel index 6cb5296..53a35aa 100644 --- a/pkg/controller_test/BUILD.bazel +++ b/pkg/controller_test/BUILD.bazel @@ -25,7 +25,6 @@ go_test( "//examples/sleeper:go_default_library", "//examples/sleeper/pkg/apis/sleeper/v1:go_default_library", "//pkg/apis/smith/v1:go_default_library", - "//pkg/catalog:go_default_library", "//pkg/cleanup:go_default_library", "//pkg/cleanup/types:go_default_library", "//pkg/client:go_default_library", @@ -44,6 +43,7 @@ go_test( "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1:go_default_library", "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset:go_default_library", "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset/fake:go_default_library", + "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/externalversions/servicecatalog/v1beta1:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library", diff --git a/pkg/controller_test/zz_plumbing_for_test.go b/pkg/controller_test/zz_plumbing_for_test.go index e8a1187..b433b6b 100644 --- a/pkg/controller_test/zz_plumbing_for_test.go +++ b/pkg/controller_test/zz_plumbing_for_test.go @@ -13,7 +13,6 @@ import ( "github.com/atlassian/smith/examples/sleeper" sleeper_v1 "github.com/atlassian/smith/examples/sleeper/pkg/apis/sleeper/v1" smith_v1 "github.com/atlassian/smith/pkg/apis/smith/v1" - "github.com/atlassian/smith/pkg/catalog" "github.com/atlassian/smith/pkg/cleanup" clean_types "github.com/atlassian/smith/pkg/cleanup/types" "github.com/atlassian/smith/pkg/client" @@ -32,6 +31,7 @@ import ( sc_v1b1 "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1" scClientset "github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset" scFake "github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset/fake" + sc_v1b1inf "github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/externalversions/servicecatalog/v1beta1" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -162,8 +162,12 @@ func (tc *testCase) run(t *testing.T) { for _, reactor := range tc.crdReactors { crdClient.AddReactor(reactor.verb, reactor.resource, reactor.reactor(t)) } + + // Informers + var infs []cache.SharedIndexInformer + var scClient scClientset.Interface - var catalogger *catalog.Catalog + var catalog *store.Catalog if tc.enableServiceCatalog { scClientFake := scFake.NewSimpleClientset(append( tc.scClientObjects, @@ -205,7 +209,11 @@ func (tc *testCase) run(t *testing.T) { for _, reactor := range tc.scReactors { scClientFake.AddReactor(reactor.verb, reactor.resource, reactor.reactor(t)) } - catalogger = catalog.NewCatalog(scClient, 0) + serviceClassInf := sc_v1b1inf.NewClusterServiceClassInformer(scClient, 0, cache.Indexers{}) + infs = append(infs, serviceClassInf) + servicePlanInf := sc_v1b1inf.NewClusterServicePlanInformer(scClient, 0, cache.Indexers{}) + infs = append(infs, servicePlanInf) + catalog = store.NewCatalog(serviceClassInf, servicePlanInf) } crdInf := apiext_v1b1inf.NewCustomResourceDefinitionInformer(crdClient, 0, cache.Indexers{}) @@ -298,27 +306,28 @@ func (tc *testCase) run(t *testing.T) { Namespace: tc.namespace, PluginContainers: pluginContainers, Scheme: scheme, - Catalog: catalogger, + Catalog: catalog, } prepare := func(ctx context.Context) { cntrlr.Prepare(ctx, crdInf, resourceInfs) resourceInfs[apiext_v1b1.SchemeGroupVersion.WithKind("CustomResourceDefinition")] = crdInf resourceInfs[smith_v1.BundleGVK] = bundleInf - infs := make([]cache.InformerSynced, 0, len(resourceInfs)) stage := stgr.NextStage() + + // Add resource informers to Multi store (not ServiceClass/Plan informers, ...) for gvk, inf := range resourceInfs { multiStore.AddInformer(gvk, inf) - stage.StartWithChannel(inf.Run) - infs = append(infs, inf.HasSynced) + infs = append(infs, inf) } - if catalogger != nil { - for _, inf := range catalogger.InformersToRegister() { - stage.StartWithChannel(inf.Run) - infs = append(infs, inf.HasSynced) - } + + // Start all informers then wait on them + infCacheSyncs := make([]cache.InformerSynced, len(infs)) + for i, inf := range infs { + stage.StartWithChannel(inf.Run) // Must be after AddInformer() + infCacheSyncs[i] = inf.HasSynced } - require.True(t, cache.WaitForCacheSync(ctx.Done(), infs...)) + require.True(t, cache.WaitForCacheSync(ctx.Done(), infCacheSyncs...)) } defer tc.verifyActions(t) diff --git a/pkg/store/BUILD.bazel b/pkg/store/BUILD.bazel index 24318e4..78e4962 100644 --- a/pkg/store/BUILD.bazel +++ b/pkg/store/BUILD.bazel @@ -4,6 +4,7 @@ go_library( name = "go_default_library", srcs = [ "bundle.go", + "catalog.go", "crd.go", "multi.go", ], @@ -12,6 +13,7 @@ go_library( deps = [ "//pkg/apis/smith/v1:go_default_library", "//pkg/plugin:go_default_library", + "//vendor/github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1:go_default_library", "//vendor/github.com/pkg/errors:go_default_library", "//vendor/k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1:go_default_library", "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", diff --git a/pkg/catalog/catalog.go b/pkg/store/catalog.go similarity index 70% rename from pkg/catalog/catalog.go rename to pkg/store/catalog.go index f692250..63b29b8 100644 --- a/pkg/catalog/catalog.go +++ b/pkg/store/catalog.go @@ -1,17 +1,17 @@ // Package catalog handles interacting with the OSB catalog endpoint // (i.e. informers/helpers for ClusterServiceClass and ClusterServicePlan) -package catalog +package store import ( - "time" - sc_v1b1 "github.com/kubernetes-incubator/service-catalog/pkg/apis/servicecatalog/v1beta1" - clientset "github.com/kubernetes-incubator/service-catalog/pkg/client/clientset_generated/clientset" - sc_v1b1inf "github.com/kubernetes-incubator/service-catalog/pkg/client/informers_generated/externalversions/servicecatalog/v1beta1" "github.com/pkg/errors" "k8s.io/client-go/tools/cache" ) +type planSchemaAction string +type planSchemaKey string +type planResourceVersionKey string + const ( serviceClassExternalNameIndex = "ServiceClassExternalNameIndex" serviceClassAndPlanExternalNameIndex = "ServiceClassAndPlanExternalNameIndex" @@ -19,24 +19,27 @@ const ( // Catalog is a convenience interface to access OSB catalog information type Catalog struct { - serviceClassInf cache.SharedIndexInformer - servicePlanInf cache.SharedIndexInformer + serviceClassInfIndexer cache.Indexer + servicePlanInfIndexer cache.Indexer } -func NewCatalog(scClient clientset.Interface, resyncPeriod time.Duration) *Catalog { +func NewCatalog(serviceClassInf cache.SharedIndexInformer, servicePlanInf cache.SharedIndexInformer) *Catalog { + serviceClassInf.AddIndexers(cache.Indexers{ + serviceClassExternalNameIndex: func(obj interface{}) ([]string, error) { + serviceClass := obj.(*sc_v1b1.ClusterServiceClass) + return []string{serviceClass.Spec.ExternalName}, nil + }, + }) + servicePlanInf.AddIndexers(cache.Indexers{ + serviceClassAndPlanExternalNameIndex: func(obj interface{}) ([]string, error) { + servicePlan := obj.(*sc_v1b1.ClusterServicePlan) + return []string{serviceClassAndPlanExternalNameIndexKey(servicePlan.Spec.ClusterServiceClassRef.Name, servicePlan.Spec.ExternalName)}, nil + }, + }) + return &Catalog{ - serviceClassInf: sc_v1b1inf.NewClusterServiceClassInformer(scClient, resyncPeriod, cache.Indexers{ - serviceClassExternalNameIndex: func(obj interface{}) ([]string, error) { - serviceClass := obj.(*sc_v1b1.ClusterServiceClass) - return []string{serviceClass.Spec.ExternalName}, nil - }, - }), - servicePlanInf: sc_v1b1inf.NewClusterServicePlanInformer(scClient, resyncPeriod, cache.Indexers{ - serviceClassAndPlanExternalNameIndex: func(obj interface{}) ([]string, error) { - servicePlan := obj.(*sc_v1b1.ClusterServicePlan) - return []string{serviceClassAndPlanExternalNameIndexKey(servicePlan.Spec.ClusterServiceClassRef.Name, servicePlan.Spec.ExternalName)}, nil - }, - }), + serviceClassInfIndexer: serviceClassInf.GetIndexer(), + servicePlanInfIndexer: servicePlanInf.GetIndexer(), } } @@ -44,10 +47,6 @@ func serviceClassAndPlanExternalNameIndexKey(serviceClassName string, servicePla return serviceClassName + "/" + servicePlanExternalName } -func (c *Catalog) InformersToRegister() []cache.SharedIndexInformer { - return []cache.SharedIndexInformer{c.servicePlanInf, c.serviceClassInf} -} - func (c *Catalog) GetClassOf(serviceInstanceSpec *sc_v1b1.ServiceInstanceSpec) (*sc_v1b1.ClusterServiceClass, error) { if serviceInstanceSpec.ClusterServiceClassName == "" && serviceInstanceSpec.ClusterServiceClassExternalName == "" { return nil, errors.Errorf("ServiceInstance must have at least ClusterServiceClassName or ClusterServiceExternalName") @@ -58,7 +57,7 @@ func (c *Catalog) GetClassOf(serviceInstanceSpec *sc_v1b1.ServiceInstanceSpec) ( } if serviceInstanceSpec.ClusterServiceClassName != "" { - item, exists, err := c.serviceClassInf.GetIndexer().GetByKey(serviceInstanceSpec.ClusterServiceClassName) + item, exists, err := c.serviceClassInfIndexer.GetByKey(serviceInstanceSpec.ClusterServiceClassName) if err != nil { return nil, errors.WithStack(err) } @@ -68,7 +67,7 @@ func (c *Catalog) GetClassOf(serviceInstanceSpec *sc_v1b1.ServiceInstanceSpec) ( return item.(*sc_v1b1.ClusterServiceClass), nil } - items, err := c.serviceClassInf.GetIndexer().ByIndex(serviceClassExternalNameIndex, serviceInstanceSpec.ClusterServiceClassExternalName) + items, err := c.serviceClassInfIndexer.ByIndex(serviceClassExternalNameIndex, serviceInstanceSpec.ClusterServiceClassExternalName) if err != nil { return nil, errors.WithStack(err) } @@ -95,7 +94,7 @@ func (c *Catalog) GetPlanOf(serviceInstanceSpec *sc_v1b1.ServiceInstanceSpec) (* } if serviceInstanceSpec.ClusterServicePlanName != "" { - item, exists, err := c.servicePlanInf.GetIndexer().GetByKey(serviceInstanceSpec.ClusterServicePlanName) + item, exists, err := c.servicePlanInfIndexer.GetByKey(serviceInstanceSpec.ClusterServicePlanName) if err != nil { return nil, errors.WithStack(err) } @@ -112,7 +111,7 @@ func (c *Catalog) GetPlanOf(serviceInstanceSpec *sc_v1b1.ServiceInstanceSpec) (* } planKey := serviceClassAndPlanExternalNameIndexKey(serviceClass.Name, serviceInstanceSpec.ClusterServicePlanExternalName) - items, err := c.servicePlanInf.GetIndexer().ByIndex(serviceClassAndPlanExternalNameIndex, planKey) + items, err := c.servicePlanInfIndexer.ByIndex(serviceClassAndPlanExternalNameIndex, planKey) if err != nil { return nil, errors.WithStack(err) }