From 7142e3bd5d9d7f0a1bf3703abbb91480bf4b3408 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Mon, 25 Jun 2018 17:28:36 -0400 Subject: [PATCH 1/7] Cluster scoped Bus Make the Bus resource cluster scpoped instead of namespaced. Bus releated deployments will be put into the knative-eventing namespace and use a shared serviceaccount for all bus provisioners and dispatchers. This PR does not change the name of the Bus resource to ClusterBus. That should happen later if we desire to have both cluster wide and namespaced buses. Subscribers using a short DNS name will automatically be expanded to use the full name.namespace.svc.cluster.local form based on the namespace of the subscription resource. Other bus implementations will also need to make this change. Fixes #106 --- Gopkg.lock | 2 +- config/bus.yaml | 2 +- config/clusterrolebinding.yaml | 14 ++ config/serviceaccount.yaml | 7 + pkg/apis/channels/v1alpha1/bus_types.go | 1 + pkg/buses/stub/main.go | 10 +- .../versioned/typed/channels/v1alpha1/bus.go | 14 +- .../channels/v1alpha1/channels_client.go | 4 +- .../typed/channels/v1alpha1/fake/fake_bus.go | 24 +- .../v1alpha1/fake/fake_channels_client.go | 4 +- .../externalversions/channels/v1alpha1/bus.go | 13 +- .../channels/v1alpha1/interface.go | 2 +- pkg/client/listers/channels/v1alpha1/bus.go | 39 +--- .../channels/v1alpha1/expansion_generated.go | 4 - pkg/controller/bus/controller.go | 221 ++++-------------- pkg/controller/channel/controller.go | 3 +- pkg/controller/names.go | 8 - 17 files changed, 102 insertions(+), 270 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 16b73bda01d..87bd066b63f 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -897,6 +897,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "001aef2bcc7b7a7f3d307748cd9b0615acff2999d22ff7b3fcfc76a807420e69" + inputs-digest = "5454eaa410718fbe47e47174881137d150b654548aaa207c8dfa1d22d10bf64b" solver-name = "gps-cdcl" solver-version = 1 diff --git a/config/bus.yaml b/config/bus.yaml index fb55c1dcad3..3fd9ead7418 100644 --- a/config/bus.yaml +++ b/config/bus.yaml @@ -16,7 +16,7 @@ kind: CustomResourceDefinition metadata: name: buses.channels.knative.dev spec: - scope: Namespaced + scope: Cluster group: channels.knative.dev version: v1alpha1 names: diff --git a/config/clusterrolebinding.yaml b/config/clusterrolebinding.yaml index b6ef6ed08d0..6ff47ba4820 100644 --- a/config/clusterrolebinding.yaml +++ b/config/clusterrolebinding.yaml @@ -23,3 +23,17 @@ roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io + +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: bus-controller-manage +subjects: + - kind: ServiceAccount + name: bus-controller + namespace: knative-eventing +roleRef: + kind: ClusterRole + name: knative-channels-bus + apiGroup: rbac.authorization.k8s.io diff --git a/config/serviceaccount.yaml b/config/serviceaccount.yaml index c4c032a8beb..b7dc382030b 100644 --- a/config/serviceaccount.yaml +++ b/config/serviceaccount.yaml @@ -16,3 +16,10 @@ kind: ServiceAccount metadata: name: bind-controller namespace: knative-eventing + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bus-controller + namespace: knative-eventing diff --git a/pkg/apis/channels/v1alpha1/bus_types.go b/pkg/apis/channels/v1alpha1/bus_types.go index e4137f3c800..261f031c5e2 100644 --- a/pkg/apis/channels/v1alpha1/bus_types.go +++ b/pkg/apis/channels/v1alpha1/bus_types.go @@ -25,6 +25,7 @@ import ( // +genclient // +genclient:noStatus +// +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:defaulter-gen=true diff --git a/pkg/buses/stub/main.go b/pkg/buses/stub/main.go index 6d877acc20a..e665d48e11e 100644 --- a/pkg/buses/stub/main.go +++ b/pkg/buses/stub/main.go @@ -73,7 +73,7 @@ func (b *StubBus) handleEvent(res http.ResponseWriter, req *http.Request) { safeHeaders.Set("x-bus", b.name) safeHeaders.Set("x-channel", channel) for _, subscription := range *subscriptions { - subscriber := subscription.Subscriber + subscriber := b.resolveSubscriber(subscription, namespace) glog.Infof("Sending to %q for %q\n", subscriber, channel) go b.dispatchEvent(subscriber, body, safeHeaders) } @@ -96,6 +96,14 @@ func (b *StubBus) dispatchEvent(subscriber string, body []byte, headers http.Hea } } +func (b *StubBus) resolveSubscriber(subscription channelsv1alpha1.SubscriptionSpec, namespace string) string { + subscriber := subscription.Subscriber + if strings.Index(subscriber, ".") == -1 { + subscriber = fmt.Sprintf("%s.%s.svc.cluster.local", subscriber, namespace) + } + return subscriber +} + func (b *StubBus) splitChannelName(host string) (string, string) { chunks := strings.Split(host, ".") channel := chunks[0] diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go index 12450331d50..9c86a128800 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go @@ -30,7 +30,7 @@ import ( // BusesGetter has a method to return a BusInterface. // A group's client should implement this interface. type BusesGetter interface { - Buses(namespace string) BusInterface + Buses() BusInterface } // BusInterface has methods to work with Bus resources. @@ -49,14 +49,12 @@ type BusInterface interface { // buses implements BusInterface type buses struct { client rest.Interface - ns string } // newBuses returns a Buses -func newBuses(c *ChannelsV1alpha1Client, namespace string) *buses { +func newBuses(c *ChannelsV1alpha1Client) *buses { return &buses{ client: c.RESTClient(), - ns: namespace, } } @@ -64,7 +62,6 @@ func newBuses(c *ChannelsV1alpha1Client, namespace string) *buses { func (c *buses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, err error) { result = &v1alpha1.Bus{} err = c.client.Get(). - Namespace(c.ns). Resource("buses"). Name(name). VersionedParams(&options, scheme.ParameterCodec). @@ -77,7 +74,6 @@ func (c *buses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, e func (c *buses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) { result = &v1alpha1.BusList{} err = c.client.Get(). - Namespace(c.ns). Resource("buses"). VersionedParams(&opts, scheme.ParameterCodec). Do(). @@ -89,7 +85,6 @@ func (c *buses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) func (c *buses) Watch(opts v1.ListOptions) (watch.Interface, error) { opts.Watch = true return c.client.Get(). - Namespace(c.ns). Resource("buses"). VersionedParams(&opts, scheme.ParameterCodec). Watch() @@ -99,7 +94,6 @@ func (c *buses) Watch(opts v1.ListOptions) (watch.Interface, error) { func (c *buses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { result = &v1alpha1.Bus{} err = c.client.Post(). - Namespace(c.ns). Resource("buses"). Body(bus). Do(). @@ -111,7 +105,6 @@ func (c *buses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { func (c *buses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { result = &v1alpha1.Bus{} err = c.client.Put(). - Namespace(c.ns). Resource("buses"). Name(bus.Name). Body(bus). @@ -123,7 +116,6 @@ func (c *buses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { // Delete takes name of the bus and deletes it. Returns an error if one occurs. func (c *buses) Delete(name string, options *v1.DeleteOptions) error { return c.client.Delete(). - Namespace(c.ns). Resource("buses"). Name(name). Body(options). @@ -134,7 +126,6 @@ func (c *buses) Delete(name string, options *v1.DeleteOptions) error { // DeleteCollection deletes a collection of objects. func (c *buses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { return c.client.Delete(). - Namespace(c.ns). Resource("buses"). VersionedParams(&listOptions, scheme.ParameterCodec). Body(options). @@ -146,7 +137,6 @@ func (c *buses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListO func (c *buses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) { result = &v1alpha1.Bus{} err = c.client.Patch(pt). - Namespace(c.ns). Resource("buses"). SubResource(subresources...). Name(name). diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go index cc83d1fd55e..1777882d58f 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go @@ -37,8 +37,8 @@ type ChannelsV1alpha1Client struct { restClient rest.Interface } -func (c *ChannelsV1alpha1Client) Buses(namespace string) BusInterface { - return newBuses(c, namespace) +func (c *ChannelsV1alpha1Client) Buses() BusInterface { + return newBuses(c) } func (c *ChannelsV1alpha1Client) Channels(namespace string) ChannelInterface { diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go index c49b944bf13..8cff2292bb7 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go @@ -31,7 +31,6 @@ import ( // FakeBuses implements BusInterface type FakeBuses struct { Fake *FakeChannelsV1alpha1 - ns string } var busesResource = schema.GroupVersionResource{Group: "channels.knative.dev", Version: "v1alpha1", Resource: "buses"} @@ -41,8 +40,7 @@ var busesKind = schema.GroupVersionKind{Group: "channels.knative.dev", Version: // Get takes name of the bus, and returns the corresponding bus object, and an error if there is any. func (c *FakeBuses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, err error) { obj, err := c.Fake. - Invokes(testing.NewGetAction(busesResource, c.ns, name), &v1alpha1.Bus{}) - + Invokes(testing.NewRootGetAction(busesResource, name), &v1alpha1.Bus{}) if obj == nil { return nil, err } @@ -52,8 +50,7 @@ func (c *FakeBuses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bu // List takes label and field selectors, and returns the list of Buses that match those selectors. func (c *FakeBuses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) { obj, err := c.Fake. - Invokes(testing.NewListAction(busesResource, busesKind, c.ns, opts), &v1alpha1.BusList{}) - + Invokes(testing.NewRootListAction(busesResource, busesKind, opts), &v1alpha1.BusList{}) if obj == nil { return nil, err } @@ -74,15 +71,13 @@ func (c *FakeBuses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err err // Watch returns a watch.Interface that watches the requested buses. func (c *FakeBuses) Watch(opts v1.ListOptions) (watch.Interface, error) { return c.Fake. - InvokesWatch(testing.NewWatchAction(busesResource, c.ns, opts)) - + InvokesWatch(testing.NewRootWatchAction(busesResource, opts)) } // Create takes the representation of a bus and creates it. Returns the server's representation of the bus, and an error, if there is any. func (c *FakeBuses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { obj, err := c.Fake. - Invokes(testing.NewCreateAction(busesResource, c.ns, bus), &v1alpha1.Bus{}) - + Invokes(testing.NewRootCreateAction(busesResource, bus), &v1alpha1.Bus{}) if obj == nil { return nil, err } @@ -92,8 +87,7 @@ func (c *FakeBuses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) // Update takes the representation of a bus and updates it. Returns the server's representation of the bus, and an error, if there is any. func (c *FakeBuses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { obj, err := c.Fake. - Invokes(testing.NewUpdateAction(busesResource, c.ns, bus), &v1alpha1.Bus{}) - + Invokes(testing.NewRootUpdateAction(busesResource, bus), &v1alpha1.Bus{}) if obj == nil { return nil, err } @@ -103,14 +97,13 @@ func (c *FakeBuses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) // Delete takes name of the bus and deletes it. Returns an error if one occurs. func (c *FakeBuses) Delete(name string, options *v1.DeleteOptions) error { _, err := c.Fake. - Invokes(testing.NewDeleteAction(busesResource, c.ns, name), &v1alpha1.Bus{}) - + Invokes(testing.NewRootDeleteAction(busesResource, name), &v1alpha1.Bus{}) return err } // DeleteCollection deletes a collection of objects. func (c *FakeBuses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(busesResource, c.ns, listOptions) + action := testing.NewRootDeleteCollectionAction(busesResource, listOptions) _, err := c.Fake.Invokes(action, &v1alpha1.BusList{}) return err @@ -119,8 +112,7 @@ func (c *FakeBuses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.L // Patch applies the patch and returns the patched bus. func (c *FakeBuses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) { obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(busesResource, c.ns, name, data, subresources...), &v1alpha1.Bus{}) - + Invokes(testing.NewRootPatchSubresourceAction(busesResource, name, data, subresources...), &v1alpha1.Bus{}) if obj == nil { return nil, err } diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go index ad49ab6ad76..d9cc981c8da 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go @@ -28,8 +28,8 @@ type FakeChannelsV1alpha1 struct { *testing.Fake } -func (c *FakeChannelsV1alpha1) Buses(namespace string) v1alpha1.BusInterface { - return &FakeBuses{c, namespace} +func (c *FakeChannelsV1alpha1) Buses() v1alpha1.BusInterface { + return &FakeBuses{c} } func (c *FakeChannelsV1alpha1) Channels(namespace string) v1alpha1.ChannelInterface { diff --git a/pkg/client/informers/externalversions/channels/v1alpha1/bus.go b/pkg/client/informers/externalversions/channels/v1alpha1/bus.go index 43ee3cffb56..642b1f018e7 100644 --- a/pkg/client/informers/externalversions/channels/v1alpha1/bus.go +++ b/pkg/client/informers/externalversions/channels/v1alpha1/bus.go @@ -41,33 +41,32 @@ type BusInformer interface { type busInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string } // NewBusInformer constructs a new informer for Bus type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewBusInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredBusInformer(client, namespace, resyncPeriod, indexers, nil) +func NewBusInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredBusInformer(client, resyncPeriod, indexers, nil) } // NewFilteredBusInformer constructs a new informer for Bus type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewFilteredBusInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredBusInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { return cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ChannelsV1alpha1().Buses(namespace).List(options) + return client.ChannelsV1alpha1().Buses().List(options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ChannelsV1alpha1().Buses(namespace).Watch(options) + return client.ChannelsV1alpha1().Buses().Watch(options) }, }, &channels_v1alpha1.Bus{}, @@ -77,7 +76,7 @@ func NewFilteredBusInformer(client versioned.Interface, namespace string, resync } func (f *busInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredBusInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) + return NewFilteredBusInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } func (f *busInformer) Informer() cache.SharedIndexInformer { diff --git a/pkg/client/informers/externalversions/channels/v1alpha1/interface.go b/pkg/client/informers/externalversions/channels/v1alpha1/interface.go index 7a34535020f..5e3f9466ec1 100644 --- a/pkg/client/informers/externalversions/channels/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/channels/v1alpha1/interface.go @@ -45,7 +45,7 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList // Buses returns a BusInformer. func (v *version) Buses() BusInformer { - return &busInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} + return &busInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} } // Channels returns a ChannelInformer. diff --git a/pkg/client/listers/channels/v1alpha1/bus.go b/pkg/client/listers/channels/v1alpha1/bus.go index 52d0d164e29..9f591e621d4 100644 --- a/pkg/client/listers/channels/v1alpha1/bus.go +++ b/pkg/client/listers/channels/v1alpha1/bus.go @@ -29,8 +29,8 @@ import ( type BusLister interface { // List lists all Buses in the indexer. List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) - // Buses returns an object that can list and get Buses. - Buses(namespace string) BusNamespaceLister + // Get retrieves the Bus from the index for a given name. + Get(name string) (*v1alpha1.Bus, error) BusListerExpansion } @@ -52,38 +52,9 @@ func (s *busLister) List(selector labels.Selector) (ret []*v1alpha1.Bus, err err return ret, err } -// Buses returns an object that can list and get Buses. -func (s *busLister) Buses(namespace string) BusNamespaceLister { - return busNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// BusNamespaceLister helps list and get Buses. -type BusNamespaceLister interface { - // List lists all Buses in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) - // Get retrieves the Bus from the indexer for a given namespace and name. - Get(name string) (*v1alpha1.Bus, error) - BusNamespaceListerExpansion -} - -// busNamespaceLister implements the BusNamespaceLister -// interface. -type busNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all Buses in the indexer for a given namespace. -func (s busNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Bus)) - }) - return ret, err -} - -// Get retrieves the Bus from the indexer for a given namespace and name. -func (s busNamespaceLister) Get(name string) (*v1alpha1.Bus, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) +// Get retrieves the Bus from the index for a given name. +func (s *busLister) Get(name string) (*v1alpha1.Bus, error) { + obj, exists, err := s.indexer.GetByKey(name) if err != nil { return nil, err } diff --git a/pkg/client/listers/channels/v1alpha1/expansion_generated.go b/pkg/client/listers/channels/v1alpha1/expansion_generated.go index 1f925d7e5d6..c2515e17ce4 100644 --- a/pkg/client/listers/channels/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/channels/v1alpha1/expansion_generated.go @@ -22,10 +22,6 @@ package v1alpha1 // BusLister. type BusListerExpansion interface{} -// BusNamespaceListerExpansion allows custom methods to be added to -// BusNamespaceLister. -type BusNamespaceListerExpansion interface{} - // ChannelListerExpansion allows custom methods to be added to // ChannelLister. type ChannelListerExpansion interface{} diff --git a/pkg/controller/bus/controller.go b/pkg/controller/bus/controller.go index d661b9ccfc3..8205fb396f3 100644 --- a/pkg/controller/bus/controller.go +++ b/pkg/controller/bus/controller.go @@ -25,7 +25,6 @@ import ( "github.com/knative/eventing/pkg/controller" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - rbacv1beta1 "k8s.io/api/rbac/v1beta1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" @@ -38,11 +37,11 @@ import ( typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" appslisters "k8s.io/client-go/listers/apps/v1" corelisters "k8s.io/client-go/listers/core/v1" - rbaclisters "k8s.io/client-go/listers/rbac/v1beta1" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/record" "k8s.io/client-go/util/workqueue" + "github.com/knative/eventing/pkg" clientset "github.com/knative/eventing/pkg/client/clientset/versioned" channelscheme "github.com/knative/eventing/pkg/client/clientset/versioned/scheme" informers "github.com/knative/eventing/pkg/client/informers/externalversions" @@ -53,7 +52,10 @@ import ( channelsv1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" ) -const controllerAgentName = "bus-controller" +const ( + controllerAgentName = "bus-controller" + busControllerServiceAccountName = "bus-controller" +) const ( // SuccessSynced is used as part of the Event 'reason' when a Bus is synced @@ -77,16 +79,12 @@ type Controller struct { // busclientset is a clientset for our own API group busclientset clientset.Interface - deploymentsLister appslisters.DeploymentLister - deploymentsSynced cache.InformerSynced - servicesLister corelisters.ServiceLister - servicesSynced cache.InformerSynced - serviceAccountsLister corelisters.ServiceAccountLister - serviceAccountsSynced cache.InformerSynced - clusterRoleBindingsLister rbaclisters.ClusterRoleBindingLister - clusterRoleBindingsSynced cache.InformerSynced - busesLister listers.BusLister - busesSynced cache.InformerSynced + deploymentsLister appslisters.DeploymentLister + deploymentsSynced cache.InformerSynced + servicesLister corelisters.ServiceLister + servicesSynced cache.InformerSynced + busesLister listers.BusLister + busesSynced cache.InformerSynced // workqueue is a rate limited work queue. This is used to queue work to be // processed instead of performing it as soon as a change happens. This @@ -112,8 +110,6 @@ func NewController( busInformer := busInformerFactory.Channels().V1alpha1().Buses() deploymentInformer := kubeInformerFactory.Apps().V1().Deployments() serviceInformer := kubeInformerFactory.Core().V1().Services() - serviceAccountInformer := kubeInformerFactory.Core().V1().ServiceAccounts() - clusterRoleBindingInformer := kubeInformerFactory.Rbac().V1beta1().ClusterRoleBindings() // Create event broadcaster // Add bus-controller types to the default Kubernetes Scheme so Events can be @@ -126,20 +122,16 @@ func NewController( recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName}) controller := &Controller{ - kubeclientset: kubeclientset, - busclientset: busclientset, - deploymentsLister: deploymentInformer.Lister(), - deploymentsSynced: deploymentInformer.Informer().HasSynced, - servicesLister: serviceInformer.Lister(), - servicesSynced: serviceInformer.Informer().HasSynced, - serviceAccountsLister: serviceAccountInformer.Lister(), - serviceAccountsSynced: serviceAccountInformer.Informer().HasSynced, - clusterRoleBindingsLister: clusterRoleBindingInformer.Lister(), - clusterRoleBindingsSynced: clusterRoleBindingInformer.Informer().HasSynced, - busesLister: busInformer.Lister(), - busesSynced: busInformer.Informer().HasSynced, - workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Buses"), - recorder: recorder, + kubeclientset: kubeclientset, + busclientset: busclientset, + deploymentsLister: deploymentInformer.Lister(), + deploymentsSynced: deploymentInformer.Informer().HasSynced, + servicesLister: serviceInformer.Lister(), + servicesSynced: serviceInformer.Informer().HasSynced, + busesLister: busInformer.Lister(), + busesSynced: busInformer.Informer().HasSynced, + workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Buses"), + recorder: recorder, } glog.Info("Setting up event handlers") @@ -270,14 +262,14 @@ func (c *Controller) processNextWorkItem() bool { // with the current status of the resource. func (c *Controller) syncHandler(key string) error { // Convert the namespace/name string into a distinct namespace and name - namespace, name, err := cache.SplitMetaNamespaceKey(key) + _, name, err := cache.SplitMetaNamespaceKey(key) if err != nil { runtime.HandleError(fmt.Errorf("invalid resource key: %s", key)) return nil } - // Get the Bus resource with this namespace/name - bus, err := c.busesLister.Buses(namespace).Get(name) + // Get the Bus resource with this name + bus, err := c.busesLister.Get(name) if err != nil { // The Bus resource may no longer exist, in which case we stop // processing. @@ -289,18 +281,6 @@ func (c *Controller) syncHandler(key string) error { return err } - // Sync ServiceAccount derived from the Bus - serviceAccount, err := c.syncBusServiceAccount(bus) - if err != nil { - return err - } - - // Sync ClusterRoleBinding derived from the Bus - clusterRoleBinding, err := c.syncBusClusterRoleBinding(bus) - if err != nil { - return err - } - // Sync Service derived from the Bus dispatcherService, err := c.syncBusDispatcherService(bus) if err != nil { @@ -321,7 +301,7 @@ func (c *Controller) syncHandler(key string) error { // Finally, we update the status block of the Bus resource to reflect the // current state of the world - err = c.updateBusStatus(bus, dispatcherService, dispatcherDeployment, provisionerDeployment, serviceAccount, clusterRoleBinding) + err = c.updateBusStatus(bus, dispatcherService, dispatcherDeployment, provisionerDeployment) if err != nil { return err } @@ -333,10 +313,10 @@ func (c *Controller) syncHandler(key string) error { func (c *Controller) syncBusDispatcherService(bus *channelsv1alpha1.Bus) (*corev1.Service, error) { // Get the service with the specified service name serviceName := controller.BusDispatcherServiceName(bus.ObjectMeta.Name) - service, err := c.servicesLister.Services(bus.Namespace).Get(serviceName) + service, err := c.servicesLister.Services(pkg.GetEventingSystemNamespace()).Get(serviceName) // If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { - service, err = c.kubeclientset.CoreV1().Services(bus.Namespace).Create(newDispatcherService(bus)) + service, err = c.kubeclientset.CoreV1().Services(pkg.GetEventingSystemNamespace()).Create(newDispatcherService(bus)) } // If an error occurs during Get/Create, we'll requeue the item so we can @@ -360,10 +340,10 @@ func (c *Controller) syncBusDispatcherService(bus *channelsv1alpha1.Bus) (*corev func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*appsv1.Deployment, error) { // Get the deployment with the specified deployment name deploymentName := controller.BusDispatcherDeploymentName(bus.ObjectMeta.Name) - deployment, err := c.deploymentsLister.Deployments(bus.Namespace).Get(deploymentName) + deployment, err := c.deploymentsLister.Deployments(pkg.GetEventingSystemNamespace()).Get(deploymentName) // If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { - deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Create(newDispatcherDeployment(bus)) + deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Create(newDispatcherDeployment(bus)) } // If an error occurs during Get/Create, we'll requeue the item so we can @@ -386,7 +366,7 @@ func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*ap proposedDeployment := newDispatcherDeployment(bus) if !reflect.DeepEqual(proposedDeployment.Spec, deployment.Spec) { glog.V(4).Infof("Bus %s dispatcher spec updated", bus.Name) - deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Update(proposedDeployment) + deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Update(proposedDeployment) if err != nil { return nil, err @@ -396,85 +376,18 @@ func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*ap return deployment, nil } -func (c *Controller) syncBusServiceAccount(bus *channelsv1alpha1.Bus) (*corev1.ServiceAccount, error) { - // Get the serviceAccount with the specified serviceAccount name - serviceAccountName := controller.BusServiceAccountName(bus.ObjectMeta.Name) - serviceAccount, err := c.serviceAccountsLister.ServiceAccounts(bus.Namespace).Get(serviceAccountName) - // If the resource doesn't exist, we'll create it - if errors.IsNotFound(err) { - serviceAccount, err = c.kubeclientset.CoreV1().ServiceAccounts(bus.Namespace).Create(newServiceAccount(bus)) - } - - // If an error occurs during Get/Create, we'll requeue the item so we can - // attempt processing again later. This could have been caused by a - // temporary network failure, or any other transient reason. - if err != nil { - return nil, err - } - - // If the ServiceAccount is not controlled by this Bus resource, we should log - // a warning to the event recorder and return - if !metav1.IsControlledBy(serviceAccount, bus) { - msg := fmt.Sprintf(MessageResourceExists, serviceAccount.Name) - c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) - return nil, fmt.Errorf(msg) - } - - return serviceAccount, nil -} - -func (c *Controller) syncBusClusterRoleBinding(bus *channelsv1alpha1.Bus) (*rbacv1beta1.ClusterRoleBinding, error) { - // Get the clusterRoleBinding with the specified clusterRoleBinding name - clusterRoleBindingName := controller.BusClusterRoleBindingName(bus.ObjectMeta.Name) - clusterRoleBinding, err := c.clusterRoleBindingsLister.Get(clusterRoleBindingName) - // If the resource doesn't exist, we'll create it - if errors.IsNotFound(err) { - clusterRoleBinding, err = c.kubeclientset.RbacV1beta1().ClusterRoleBindings().Create(newClusterRoleBinding(bus)) - } - - // If an error occurs during Get/Create, we'll requeue the item so we can - // attempt processing again later. This could have been caused by a - // temporary network failure, or any other transient reason. - if err != nil { - return nil, err - } - - // If the ClusterRoleBinding is not controlled by this Bus resource, we should log - // a warning to the event recorder and return - if !metav1.IsControlledBy(clusterRoleBinding, bus) { - msg := fmt.Sprintf(MessageResourceExists, clusterRoleBinding.Name) - c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) - return nil, fmt.Errorf(msg) - } - - // If the ClusterRoleBinding does not match the Bus's proposed ClusterRoleBinding we - // should update the ClusterRoleBinding resource. - proposedClusterRoleBinding := newClusterRoleBinding(bus) - if !reflect.DeepEqual(proposedClusterRoleBinding.Subjects, clusterRoleBinding.Subjects) && - !reflect.DeepEqual(proposedClusterRoleBinding.RoleRef, clusterRoleBinding.RoleRef) { - glog.V(4).Infof("Bus %s provisioner spec updated", bus.Name) - clusterRoleBinding, err = c.kubeclientset.RbacV1beta1().ClusterRoleBindings().Update(proposedClusterRoleBinding) - - if err != nil { - return nil, err - } - } - - return clusterRoleBinding, nil -} - func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*appsv1.Deployment, error) { provisioner := bus.Spec.Provisioner // Get the deployment with the specified deployment name deploymentName := controller.BusProvisionerDeploymentName(bus.ObjectMeta.Name) - deployment, err := c.deploymentsLister.Deployments(bus.Namespace).Get(deploymentName) + deployment, err := c.deploymentsLister.Deployments(pkg.GetEventingSystemNamespace()).Get(deploymentName) // If the resource shouldn't exists if provisioner == nil { // If the resource exists, we'll delete it if deployment != nil { - err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Delete(deploymentName, nil) + err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Delete(deploymentName, nil) } if errors.IsNotFound(err) { return nil, nil @@ -484,7 +397,7 @@ func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*a // If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { - deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Create(newProvisionerDeployment(bus)) + deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Create(newProvisionerDeployment(bus)) } // If an error occurs during Get/Create, we'll requeue the item so we can @@ -507,7 +420,7 @@ func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*a proposedDeployment := newProvisionerDeployment(bus) if !reflect.DeepEqual(proposedDeployment.Spec, deployment.Spec) { glog.V(4).Infof("Bus %s provisioner spec updated", bus.Name) - deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Update(proposedDeployment) + deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Update(proposedDeployment) if err != nil { return nil, err @@ -522,8 +435,6 @@ func (c *Controller) updateBusStatus( dispatcherService *corev1.Service, dispatcherDeployment *appsv1.Deployment, provisionerDeployment *appsv1.Deployment, - serviceAccount *corev1.ServiceAccount, - clusterRoleBinding *rbacv1beta1.ClusterRoleBinding, ) error { // NEVER modify objects from the store. It's a read-only, local cache. // You can use DeepCopy() to make a deep copy of original object and modify this copy @@ -533,7 +444,7 @@ func (c *Controller) updateBusStatus( // we must use Update instead of UpdateStatus to update the Status block of the Bus resource. // UpdateStatus will not allow changes to the Spec of the resource, // which is ideal for ensuring nothing other than resource status has been updated. - _, err := c.busclientset.ChannelsV1alpha1().Buses(bus.Namespace).Update(busCopy) + _, err := c.busclientset.ChannelsV1alpha1().Buses().Update(busCopy) return err } @@ -579,7 +490,7 @@ func (c *Controller) handleObject(obj interface{}) { return } - bus, err := c.busesLister.Buses(object.GetNamespace()).Get(ownerRef.Name) + bus, err := c.busesLister.Get(ownerRef.Name) if err != nil { glog.V(4).Infof("ignoring orphaned object '%s' of bus '%s'", object.GetSelfLink(), ownerRef.Name) return @@ -601,7 +512,7 @@ func newDispatcherService(bus *channelsv1alpha1.Bus) *corev1.Service { return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: controller.BusDispatcherServiceName(bus.ObjectMeta.Name), - Namespace: bus.Namespace, + Namespace: pkg.GetEventingSystemNamespace(), Labels: labels, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(bus, schema.GroupVersionKind{ @@ -655,7 +566,7 @@ func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: controller.BusDispatcherDeploymentName(bus.ObjectMeta.Name), - Namespace: bus.Namespace, + Namespace: pkg.GetEventingSystemNamespace(), OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(bus, schema.GroupVersionKind{ Group: channelsv1alpha1.SchemeGroupVersion.Group, @@ -674,7 +585,7 @@ func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { Labels: labels, }, Spec: corev1.PodSpec{ - ServiceAccountName: controller.BusServiceAccountName(bus.Name), + ServiceAccountName: busControllerServiceAccountName, Containers: []corev1.Container{ *container, }, @@ -685,56 +596,6 @@ func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { } } -// newServiceAccount creates a new ServiceAccount for a Bus resource. It also sets -// the appropriate OwnerReferences on the resource so handleObject can discover -// the Bus resource that 'owns' it. -func newServiceAccount(bus *channelsv1alpha1.Bus) *corev1.ServiceAccount { - return &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: controller.BusServiceAccountName(bus.ObjectMeta.Name), - Namespace: bus.Namespace, - OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(bus, schema.GroupVersionKind{ - Group: channelsv1alpha1.SchemeGroupVersion.Group, - Version: channelsv1alpha1.SchemeGroupVersion.Version, - Kind: "Bus", - }), - }, - }, - } -} - -// newClusterRoleBinding creates a new ClusterRoleBinding for a Bus resource. It also sets -// the appropriate OwnerReferences on the resource so handleObject can discover -// the Bus resource that 'owns' it. -func newClusterRoleBinding(bus *channelsv1alpha1.Bus) *rbacv1beta1.ClusterRoleBinding { - return &rbacv1beta1.ClusterRoleBinding{ - ObjectMeta: metav1.ObjectMeta{ - Name: controller.BusClusterRoleBindingName(bus.ObjectMeta.Name), - Namespace: bus.Namespace, - OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(bus, schema.GroupVersionKind{ - Group: channelsv1alpha1.SchemeGroupVersion.Group, - Version: channelsv1alpha1.SchemeGroupVersion.Version, - Kind: "Bus", - }), - }, - }, - Subjects: []rbacv1beta1.Subject{ - { - Kind: "ServiceAccount", - Name: controller.BusServiceAccountName(bus.ObjectMeta.Name), - Namespace: bus.Namespace, - }, - }, - RoleRef: rbacv1beta1.RoleRef{ - Kind: "ClusterRole", - Name: "knative-channels-bus", - APIGroup: "rbac.authorization.k8s.io", - }, - } -} - // newProvisionerDeployment creates a new Deployment for a Bus resource. It also sets // the appropriate OwnerReferences on the resource so handleObject can discover // the Bus resource that 'owns' it. @@ -762,7 +623,7 @@ func newProvisionerDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: controller.BusProvisionerDeploymentName(bus.ObjectMeta.Name), - Namespace: bus.Namespace, + Namespace: pkg.GetEventingSystemNamespace(), OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(bus, schema.GroupVersionKind{ Group: channelsv1alpha1.SchemeGroupVersion.Group, @@ -781,7 +642,7 @@ func newProvisionerDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { Labels: labels, }, Spec: corev1.PodSpec{ - ServiceAccountName: controller.BusServiceAccountName(bus.Name), + ServiceAccountName: busControllerServiceAccountName, Containers: []corev1.Container{ *container, }, diff --git a/pkg/controller/channel/controller.go b/pkg/controller/channel/controller.go index deb5dc2b492..bf7833b54e0 100644 --- a/pkg/controller/channel/controller.go +++ b/pkg/controller/channel/controller.go @@ -38,6 +38,7 @@ import ( "k8s.io/client-go/tools/record" "k8s.io/client-go/util/workqueue" + "github.com/knative/eventing/pkg" clientset "github.com/knative/eventing/pkg/client/clientset/versioned" channelscheme "github.com/knative/eventing/pkg/client/clientset/versioned/scheme" informers "github.com/knative/eventing/pkg/client/informers/externalversions" @@ -484,7 +485,7 @@ func newVirtualService(channel *channelsv1alpha1.Channel) *istiov1alpha3.Virtual Route: []istiov1alpha3.DestinationWeight{ { Destination: istiov1alpha3.Destination{ - Host: controller.ServiceHostName(controller.BusDispatcherServiceName(channel.Spec.Bus), channel.Namespace), + Host: controller.ServiceHostName(controller.BusDispatcherServiceName(channel.Spec.Bus), pkg.GetEventingSystemNamespace()), }, }, }, diff --git a/pkg/controller/names.go b/pkg/controller/names.go index d59e99a05ef..d3b72e21e0b 100644 --- a/pkg/controller/names.go +++ b/pkg/controller/names.go @@ -26,14 +26,6 @@ func BusDispatcherDeploymentName(busName string) string { return fmt.Sprintf("%s-bus", busName) } -func BusServiceAccountName(busName string) string { - return fmt.Sprintf("%s-bus", busName) -} - -func BusClusterRoleBindingName(busName string) string { - return fmt.Sprintf("%s-bus", busName) -} - func BusDispatcherServiceName(busName string) string { return fmt.Sprintf("%s-bus", busName) } From fcd4bb9e0ede2d1b1c5fac54bb3e49b35f418350 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Mon, 25 Jun 2018 18:57:22 -0400 Subject: [PATCH 2/7] Rename Bus to ClusterBus --- Gopkg.lock | 2 +- cmd/controller/main.go | 4 +- config/buses/stub.yaml | 2 +- config/{bus.yaml => clusterbus.yaml} | 8 +- config/clusterrole.yaml | 4 +- config/clusterrolebinding.yaml | 6 +- config/serviceaccount.yaml | 2 +- pkg/apis/channels/v1alpha1/channel_types.go | 4 +- .../{bus_types.go => clusterbus_types.go} | 40 +-- pkg/apis/channels/v1alpha1/register.go | 4 +- .../v1alpha1/zz_generated.deepcopy.go | 234 +++++++-------- pkg/buses/monitor.go | 134 ++++----- pkg/buses/stub/main.go | 11 +- .../versioned/typed/channels/v1alpha1/bus.go | 147 --------- .../channels/v1alpha1/channels_client.go | 10 +- .../typed/channels/v1alpha1/clusterbus.go | 147 +++++++++ .../typed/channels/v1alpha1/fake/fake_bus.go | 120 -------- .../v1alpha1/fake/fake_channels_client.go | 8 +- .../channels/v1alpha1/fake/fake_clusterbus.go | 120 ++++++++ .../channels/v1alpha1/generated_expansion.go | 4 +- .../v1alpha1/{bus.go => clusterbus.go} | 38 +-- .../channels/v1alpha1/interface.go | 14 +- .../informers/externalversions/generic.go | 4 +- pkg/client/listers/channels/v1alpha1/bus.go | 65 ---- .../listers/channels/v1alpha1/clusterbus.go | 65 ++++ .../channels/v1alpha1/expansion_generated.go | 8 +- pkg/controller/channel/controller.go | 6 +- .../{bus => clusterbus}/controller.go | 278 +++++++++--------- pkg/controller/names.go | 12 +- pkg/webhook/channel.go | 14 +- pkg/webhook/channel_test.go | 10 +- pkg/webhook/webhook_test.go | 16 +- sample/hello/hello-channel.yaml | 3 +- 33 files changed, 767 insertions(+), 777 deletions(-) rename config/{bus.yaml => clusterbus.yaml} (86%) rename pkg/apis/channels/v1alpha1/{bus_types.go => clusterbus_types.go} (58%) delete mode 100644 pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go create mode 100644 pkg/client/clientset/versioned/typed/channels/v1alpha1/clusterbus.go delete mode 100644 pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go create mode 100644 pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_clusterbus.go rename pkg/client/informers/externalversions/channels/v1alpha1/{bus.go => clusterbus.go} (58%) delete mode 100644 pkg/client/listers/channels/v1alpha1/bus.go create mode 100644 pkg/client/listers/channels/v1alpha1/clusterbus.go rename pkg/controller/{bus => clusterbus}/controller.go (65%) diff --git a/Gopkg.lock b/Gopkg.lock index 87bd066b63f..59fbf3f80c5 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -897,6 +897,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "5454eaa410718fbe47e47174881137d150b654548aaa207c8dfa1d22d10bf64b" + inputs-digest = "dfe6a86a6b4b2e5617ee80431b66faa49acd84654f854782313924cfc14bc79f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 79ad4434e70..2ee291fe292 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -36,8 +36,8 @@ import ( informers "github.com/knative/eventing/pkg/client/informers/externalversions" "github.com/knative/eventing/pkg/controller" "github.com/knative/eventing/pkg/controller/bind" - "github.com/knative/eventing/pkg/controller/bus" "github.com/knative/eventing/pkg/controller/channel" + "github.com/knative/eventing/pkg/controller/clusterbus" "github.com/knative/eventing/pkg/signals" "github.com/prometheus/client_golang/prometheus/promhttp" @@ -87,7 +87,7 @@ func main() { // Add new controllers here. ctors := []controller.Constructor{ bind.NewController, - bus.NewController, + clusterbus.NewController, channel.NewController, } diff --git a/config/buses/stub.yaml b/config/buses/stub.yaml index d39f4c37aa7..e3e0f66c89e 100644 --- a/config/buses/stub.yaml +++ b/config/buses/stub.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. apiVersion: channels.knative.dev/v1alpha1 -kind: Bus +kind: ClusterBus metadata: name: stub spec: diff --git a/config/bus.yaml b/config/clusterbus.yaml similarity index 86% rename from config/bus.yaml rename to config/clusterbus.yaml index 3fd9ead7418..ab68f6e6fc3 100644 --- a/config/bus.yaml +++ b/config/clusterbus.yaml @@ -14,12 +14,12 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: buses.channels.knative.dev + name: clusterbuses.channels.knative.dev spec: scope: Cluster group: channels.knative.dev version: v1alpha1 names: - kind: Bus - plural: buses - singular: bus + kind: ClusterBus + plural: clusterbuses + singular: clusterbus diff --git a/config/clusterrole.yaml b/config/clusterrole.yaml index 2a64ff9c6c8..e8b018ce9e9 100644 --- a/config/clusterrole.yaml +++ b/config/clusterrole.yaml @@ -14,10 +14,10 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: knative-channels-bus + name: knative-channels-clusterbus rules: - apiGroups: ["channels.knative.dev"] - resources: ["buses", "channels", "subscriptions"] + resources: ["clusterbuses", "channels", "subscriptions"] verbs: ["get", "watch", "list"] - apiGroups: [""] resources: ["events"] diff --git a/config/clusterrolebinding.yaml b/config/clusterrolebinding.yaml index 6ff47ba4820..13ec94f65fd 100644 --- a/config/clusterrolebinding.yaml +++ b/config/clusterrolebinding.yaml @@ -28,12 +28,12 @@ roleRef: apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: - name: bus-controller-manage + name: clusterbus-controller-manage subjects: - kind: ServiceAccount - name: bus-controller + name: clusterbus-controller namespace: knative-eventing roleRef: kind: ClusterRole - name: knative-channels-bus + name: knative-channels-clusterbus apiGroup: rbac.authorization.k8s.io diff --git a/config/serviceaccount.yaml b/config/serviceaccount.yaml index b7dc382030b..5facc458ea6 100644 --- a/config/serviceaccount.yaml +++ b/config/serviceaccount.yaml @@ -21,5 +21,5 @@ metadata: apiVersion: v1 kind: ServiceAccount metadata: - name: bus-controller + name: clusterbus-controller namespace: knative-eventing diff --git a/pkg/apis/channels/v1alpha1/channel_types.go b/pkg/apis/channels/v1alpha1/channel_types.go index 01123e43733..f1d4329d71e 100644 --- a/pkg/apis/channels/v1alpha1/channel_types.go +++ b/pkg/apis/channels/v1alpha1/channel_types.go @@ -38,8 +38,8 @@ type Channel struct { // ChannelSpec (what the user wants) for a channel type ChannelSpec struct { - // Name of the bus backing this channel (optional) - Bus string `json:"bus` + // ClusterBus name of the clusterbus backing this channel + ClusterBus string `json:"clusterBus"` // Arguments configuration arguments for the channel Arguments *[]Argument `json:"arguments,omitempty"` diff --git a/pkg/apis/channels/v1alpha1/bus_types.go b/pkg/apis/channels/v1alpha1/clusterbus_types.go similarity index 58% rename from pkg/apis/channels/v1alpha1/bus_types.go rename to pkg/apis/channels/v1alpha1/clusterbus_types.go index 261f031c5e2..48b65071c40 100644 --- a/pkg/apis/channels/v1alpha1/bus_types.go +++ b/pkg/apis/channels/v1alpha1/clusterbus_types.go @@ -29,53 +29,53 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:defaulter-gen=true -// Bus represents the buses.channels.knative.dev CRD -type Bus struct { +// ClusterBus represents the clusterbuses.channels.knative.dev CRD +type ClusterBus struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ObjectMeta `json:"metadata"` - Spec BusSpec `json:"spec"` - Status *BusStatus `json:"status,omitempty"` + Spec ClusterBusSpec `json:"spec"` + Status *ClusterBusStatus `json:"status,omitempty"` } -// BusSpec (what the user wants) for a bus -type BusSpec struct { +// ClusterBusSpec (what the user wants) for a clusterbus +type ClusterBusSpec struct { - // Parameters exposed by the bus for channels and subscriptions - Parameters *BusParameters `json:"parameters,omitempty"` + // Parameters exposed by the clusterbus for channels and subscriptions + Parameters *ClusterBusParameters `json:"parameters,omitempty"` - // Provisioner container definition to manage channels on the bus. + // Provisioner container definition to manage channels on the clusterbus. Provisioner *kapi.Container `json:"provisioner,omitempty"` - // Dispatcher container definition to use for the bus data plane. + // Dispatcher container definition to use for the clusterbus data plane. Dispatcher kapi.Container `json:"dispatcher"` // Volumes to be mounted inside the provisioner or dispatcher containers Volumes *[]kapi.Volume `json:"volumes,omitempty"` } -// BusParameters parameters exposed by the bus -type BusParameters struct { +// ClusterBusParameters parameters exposed by the clusterbus +type ClusterBusParameters struct { - // Channel configuration params for channels on the bus + // Channel configuration params for channels on the clusterbus Channel *[]Parameter `json:"channel,omitempty"` - // Subscription configuration params for subscriptions on the bus + // Subscription configuration params for subscriptions on the clusterbus Subscription *[]Parameter `json:"subscription,omitempty"` } -// BusStatus (computed) for a bus -type BusStatus struct { +// ClusterBusStatus (computed) for a clusterbus +type ClusterBusStatus struct { } -func (b *Bus) GetSpecJSON() ([]byte, error) { +func (b *ClusterBus) GetSpecJSON() ([]byte, error) { return json.Marshal(b.Spec) } // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// BusList returned in list operations -type BusList struct { +// ClusterBusList returned in list operations +type ClusterBusList struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ListMeta `json:"metadata"` - Items []Bus `json:"items"` + Items []ClusterBus `json:"items"` } diff --git a/pkg/apis/channels/v1alpha1/register.go b/pkg/apis/channels/v1alpha1/register.go index b39481399cf..821e451651f 100644 --- a/pkg/apis/channels/v1alpha1/register.go +++ b/pkg/apis/channels/v1alpha1/register.go @@ -45,8 +45,8 @@ var ( // Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, - &Bus{}, - &BusList{}, + &ClusterBus{}, + &ClusterBusList{}, &Channel{}, &ChannelList{}, &Subscription{}, diff --git a/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go index a93df7a0c63..65ad3328959 100644 --- a/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go @@ -42,7 +42,7 @@ func (in *Argument) DeepCopy() *Argument { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Bus) DeepCopyInto(out *Bus) { +func (in *Channel) DeepCopyInto(out *Channel) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -52,25 +52,25 @@ func (in *Bus) DeepCopyInto(out *Bus) { if *in == nil { *out = nil } else { - *out = new(BusStatus) + *out = new(ChannelStatus) **out = **in } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bus. -func (in *Bus) DeepCopy() *Bus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Channel. +func (in *Channel) DeepCopy() *Channel { if in == nil { return nil } - out := new(Bus) + out := new(Channel) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Bus) DeepCopyObject() runtime.Object { +func (in *Channel) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -78,13 +78,13 @@ func (in *Bus) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusList) DeepCopyInto(out *BusList) { +func (in *ChannelList) DeepCopyInto(out *ChannelList) { *out = *in out.TypeMeta = in.TypeMeta out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]Bus, len(*in)) + *out = make([]Channel, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -92,18 +92,18 @@ func (in *BusList) DeepCopyInto(out *BusList) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusList. -func (in *BusList) DeepCopy() *BusList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelList. +func (in *ChannelList) DeepCopy() *ChannelList { if in == nil { return nil } - out := new(BusList) + out := new(ChannelList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *BusList) DeepCopyObject() runtime.Object { +func (in *ChannelList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -111,119 +111,52 @@ func (in *BusList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusParameters) DeepCopyInto(out *BusParameters) { - *out = *in - if in.Channel != nil { - in, out := &in.Channel, &out.Channel - if *in == nil { - *out = nil - } else { - *out = new([]Parameter) - if **in != nil { - in, out := *in, *out - *out = make([]Parameter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - } - } - if in.Subscription != nil { - in, out := &in.Subscription, &out.Subscription - if *in == nil { - *out = nil - } else { - *out = new([]Parameter) - if **in != nil { - in, out := *in, *out - *out = make([]Parameter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusParameters. -func (in *BusParameters) DeepCopy() *BusParameters { - if in == nil { - return nil - } - out := new(BusParameters) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusSpec) DeepCopyInto(out *BusSpec) { +func (in *ChannelSpec) DeepCopyInto(out *ChannelSpec) { *out = *in - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters - if *in == nil { - *out = nil - } else { - *out = new(BusParameters) - (*in).DeepCopyInto(*out) - } - } - if in.Provisioner != nil { - in, out := &in.Provisioner, &out.Provisioner - if *in == nil { - *out = nil - } else { - *out = new(v1.Container) - (*in).DeepCopyInto(*out) - } - } - in.Dispatcher.DeepCopyInto(&out.Dispatcher) - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes + if in.Arguments != nil { + in, out := &in.Arguments, &out.Arguments if *in == nil { *out = nil } else { - *out = new([]v1.Volume) + *out = new([]Argument) if **in != nil { in, out := *in, *out - *out = make([]v1.Volume, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + *out = make([]Argument, len(*in)) + copy(*out, *in) } } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusSpec. -func (in *BusSpec) DeepCopy() *BusSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelSpec. +func (in *ChannelSpec) DeepCopy() *ChannelSpec { if in == nil { return nil } - out := new(BusSpec) + out := new(ChannelSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *BusStatus) DeepCopyInto(out *BusStatus) { +func (in *ChannelStatus) DeepCopyInto(out *ChannelStatus) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusStatus. -func (in *BusStatus) DeepCopy() *BusStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelStatus. +func (in *ChannelStatus) DeepCopy() *ChannelStatus { if in == nil { return nil } - out := new(BusStatus) + out := new(ChannelStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Channel) DeepCopyInto(out *Channel) { +func (in *ClusterBus) DeepCopyInto(out *ClusterBus) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -233,25 +166,25 @@ func (in *Channel) DeepCopyInto(out *Channel) { if *in == nil { *out = nil } else { - *out = new(ChannelStatus) + *out = new(ClusterBusStatus) **out = **in } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Channel. -func (in *Channel) DeepCopy() *Channel { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBus. +func (in *ClusterBus) DeepCopy() *ClusterBus { if in == nil { return nil } - out := new(Channel) + out := new(ClusterBus) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Channel) DeepCopyObject() runtime.Object { +func (in *ClusterBus) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -259,13 +192,13 @@ func (in *Channel) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelList) DeepCopyInto(out *ChannelList) { +func (in *ClusterBusList) DeepCopyInto(out *ClusterBusList) { *out = *in out.TypeMeta = in.TypeMeta out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]Channel, len(*in)) + *out = make([]ClusterBus, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -273,18 +206,18 @@ func (in *ChannelList) DeepCopyInto(out *ChannelList) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelList. -func (in *ChannelList) DeepCopy() *ChannelList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusList. +func (in *ClusterBusList) DeepCopy() *ClusterBusList { if in == nil { return nil } - out := new(ChannelList) + out := new(ClusterBusList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ChannelList) DeepCopyObject() runtime.Object { +func (in *ClusterBusList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -292,46 +225,113 @@ func (in *ChannelList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelSpec) DeepCopyInto(out *ChannelSpec) { +func (in *ClusterBusParameters) DeepCopyInto(out *ClusterBusParameters) { *out = *in - if in.Arguments != nil { - in, out := &in.Arguments, &out.Arguments + if in.Channel != nil { + in, out := &in.Channel, &out.Channel if *in == nil { *out = nil } else { - *out = new([]Argument) + *out = new([]Parameter) if **in != nil { in, out := *in, *out - *out = make([]Argument, len(*in)) - copy(*out, *in) + *out = make([]Parameter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + } + if in.Subscription != nil { + in, out := &in.Subscription, &out.Subscription + if *in == nil { + *out = nil + } else { + *out = new([]Parameter) + if **in != nil { + in, out := *in, *out + *out = make([]Parameter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelSpec. -func (in *ChannelSpec) DeepCopy() *ChannelSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusParameters. +func (in *ClusterBusParameters) DeepCopy() *ClusterBusParameters { if in == nil { return nil } - out := new(ChannelSpec) + out := new(ClusterBusParameters) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelStatus) DeepCopyInto(out *ChannelStatus) { +func (in *ClusterBusSpec) DeepCopyInto(out *ClusterBusSpec) { + *out = *in + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + if *in == nil { + *out = nil + } else { + *out = new(ClusterBusParameters) + (*in).DeepCopyInto(*out) + } + } + if in.Provisioner != nil { + in, out := &in.Provisioner, &out.Provisioner + if *in == nil { + *out = nil + } else { + *out = new(v1.Container) + (*in).DeepCopyInto(*out) + } + } + in.Dispatcher.DeepCopyInto(&out.Dispatcher) + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + if *in == nil { + *out = nil + } else { + *out = new([]v1.Volume) + if **in != nil { + in, out := *in, *out + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusSpec. +func (in *ClusterBusSpec) DeepCopy() *ClusterBusSpec { + if in == nil { + return nil + } + out := new(ClusterBusSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBusStatus) DeepCopyInto(out *ClusterBusStatus) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelStatus. -func (in *ChannelStatus) DeepCopy() *ChannelStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusStatus. +func (in *ClusterBusStatus) DeepCopy() *ClusterBusStatus { if in == nil { return nil } - out := new(ChannelStatus) + out := new(ClusterBusStatus) in.DeepCopyInto(out) return out } diff --git a/pkg/buses/monitor.go b/pkg/buses/monitor.go index 16c1dfdc450..eb565653f8c 100644 --- a/pkg/buses/monitor.go +++ b/pkg/buses/monitor.go @@ -47,7 +47,7 @@ const ( Dispatcher = "dispatcher" Provisioner = "provisioner" - busKind = "Bus" + clusterBusKind = "ClusterBus" channelKind = "Channel" subscriptionKind = "Subscription" @@ -58,13 +58,13 @@ const ( errResourceSync = "ErrResourceSync" ) -// Monitor utility to manage channels and subscriptions for a bus +// Monitor utility to manage channels and subscriptions for a clusterbus type Monitor struct { - bus *channelsv1alpha1.Bus + clusterBus *channelsv1alpha1.ClusterBus handler MonitorEventHandlerFuncs informerFactory informers.SharedInformerFactory - busesLister listers.BusLister - busesSynced cache.InformerSynced + clusterBusesLister listers.ClusterBusLister + clusterBusesSynced cache.InformerSynced channelsLister listers.ChannelLister channelsSynced cache.InformerSynced subscriptionsLister listers.SubscriptionLister @@ -89,20 +89,20 @@ type Attributes = map[string]string // MonitorEventHandlerFuncs handler functions for channel and subscription provisioning type MonitorEventHandlerFuncs struct { - BusFunc func(bus *channelsv1alpha1.Bus) error + ClusterBusFunc func(clusterBus *channelsv1alpha1.ClusterBus) error ProvisionFunc func(channel *channelsv1alpha1.Channel, attributes Attributes) error UnprovisionFunc func(channel *channelsv1alpha1.Channel) error SubscribeFunc func(subscription *channelsv1alpha1.Subscription, attributes Attributes) error UnsubscribeFunc func(subscription *channelsv1alpha1.Subscription) error } -func (h MonitorEventHandlerFuncs) onBus(bus *channelsv1alpha1.Bus, monitor *Monitor) error { - if h.BusFunc != nil { - err := h.BusFunc(bus) +func (h MonitorEventHandlerFuncs) onClusterBus(clusterBus *channelsv1alpha1.ClusterBus, monitor *Monitor) error { + if h.ClusterBusFunc != nil { + err := h.ClusterBusFunc(clusterBus) if err != nil { - monitor.recorder.Eventf(bus, corev1.EventTypeWarning, errResourceSync, "Error syncing bus: %s", err) + monitor.recorder.Eventf(clusterBus, corev1.EventTypeWarning, errResourceSync, "Error syncing ClusterBus: %s", err) } else { - monitor.recorder.Event(bus, corev1.EventTypeNormal, successSynced, "Bus synched successfully") + monitor.recorder.Event(clusterBus, corev1.EventTypeNormal, successSynced, "ClusterBus synched successfully") } return err } @@ -178,7 +178,7 @@ type subscriptionSummary struct { Subscription channelsv1alpha1.SubscriptionSpec } -// NewMonitor creates a monitor for a bus +// NewMonitor creates a monitor for a clusterbus func NewMonitor( component, masterURL, kubeconfig string, handler MonitorEventHandlerFuncs, @@ -199,13 +199,13 @@ func NewMonitor( } informerFactory := informers.NewSharedInformerFactory(client, time.Second*30) - busInformer := informerFactory.Channels().V1alpha1().Buses() + clusterBusInformer := informerFactory.Channels().V1alpha1().ClusterBuses() channelInformer := informerFactory.Channels().V1alpha1().Channels() subscriptionInformer := informerFactory.Channels().V1alpha1().Subscriptions() // Create event broadcaster - // Add bus-controller types to the default Kubernetes Scheme so Events can be - // logged for bus-controller types. + // Add clusterbus-controller types to the default Kubernetes Scheme so Events can be + // logged for clusterbus-controller types. channelscheme.AddToScheme(scheme.Scheme) glog.V(4).Info("Creating event broadcaster") eventBroadcaster := record.NewBroadcaster() @@ -214,12 +214,12 @@ func NewMonitor( recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: component}) monitor := &Monitor{ - bus: nil, - handler: handler, + clusterBus: nil, + handler: handler, informerFactory: informerFactory, - busesLister: busInformer.Lister(), - busesSynced: busInformer.Informer().HasSynced, + clusterBusesLister: clusterBusInformer.Lister(), + clusterBusesSynced: clusterBusInformer.Informer().HasSynced, channelsLister: channelInformer.Lister(), channelsSynced: channelInformer.Informer().HasSynced, subscriptionsLister: subscriptionInformer.Lister(), @@ -234,23 +234,23 @@ func NewMonitor( } glog.Info("Setting up event handlers") - // Set up an event handler for when Bus resources change - busInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + // Set up an event handler for when ClusterBus resources change + clusterBusInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { - bus := obj.(*channelsv1alpha1.Bus) - monitor.workqueue.AddRateLimited(makeWorkqueueKeyForBus(bus)) + clusterBus := obj.(*channelsv1alpha1.ClusterBus) + monitor.workqueue.AddRateLimited(makeWorkqueueKeyForClusterBus(clusterBus)) }, UpdateFunc: func(old, new interface{}) { - oldBus := old.(*channelsv1alpha1.Bus) - newBus := new.(*channelsv1alpha1.Bus) + oldClusterBus := old.(*channelsv1alpha1.ClusterBus) + newClusterBus := new.(*channelsv1alpha1.ClusterBus) - if oldBus.ResourceVersion == newBus.ResourceVersion { - // Periodic resync will send update events for all known Buses. - // Two different versions of the same Bus will always have different RVs. + if oldClusterBus.ResourceVersion == newClusterBus.ResourceVersion { + // Periodic resync will send update events for all known ClusterBuses. + // Two different versions of the same ClusterBus will always have different RVs. return } - monitor.workqueue.AddRateLimited(makeWorkqueueKeyForBus(newBus)) + monitor.workqueue.AddRateLimited(makeWorkqueueKeyForClusterBus(newClusterBus)) }, }) // Set up an event handler for when Channel resources change @@ -331,8 +331,8 @@ func (m *Monitor) Subscriptions(channel string, namespace string) *[]channelsv1a return nil } - if summary.Channel.Bus != m.bus.Name { - // the channel is not for this bus + if summary.Channel.ClusterBus != m.clusterBus.Name { + // the channel is not for this clusterbus return nil } @@ -347,19 +347,19 @@ func (m *Monitor) Subscriptions(channel string, namespace string) *[]channelsv1a } func (m *Monitor) channelAttributes(channel channelsv1alpha1.ChannelSpec) (Attributes, error) { - busParameters := m.bus.Spec.Parameters + clusterBusParameters := m.clusterBus.Spec.Parameters var parameters *[]channelsv1alpha1.Parameter - if busParameters != nil { - parameters = busParameters.Channel + if clusterBusParameters != nil { + parameters = clusterBusParameters.Channel } return m.resolveAttributes(parameters, channel.Arguments) } func (m *Monitor) subscriptionAttributes(subscription channelsv1alpha1.SubscriptionSpec) (Attributes, error) { - busParameters := m.bus.Spec.Parameters + clusterBusParameters := m.clusterBus.Spec.Parameters var parameters *[]channelsv1alpha1.Parameter - if busParameters != nil { - parameters = busParameters.Subscription + if clusterBusParameters != nil { + parameters = clusterBusParameters.Subscription } return m.resolveAttributes(parameters, subscription.Arguments) } @@ -414,7 +414,7 @@ func (m *Monitor) RequeueSubscription(subscription *channelsv1alpha1.Subscriptio // as syncing informer caches and starting workers. It will block until stopCh // is closed, at which point it will shutdown the workqueue and wait for // workers to finish processing their current work items. -func (m *Monitor) Run(namespace, name string, threadiness int, stopCh <-chan struct{}) error { +func (m *Monitor) Run(clusterBusName string, threadiness int, stopCh <-chan struct{}) error { defer runtime.HandleCrash() defer m.workqueue.ShutDown() @@ -424,18 +424,18 @@ func (m *Monitor) Run(namespace, name string, threadiness int, stopCh <-chan str // Wait for the caches to be synced before starting workers glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, m.busesSynced, m.channelsSynced, m.subscriptionsSynced); !ok { + if ok := cache.WaitForCacheSync(stopCh, m.clusterBusesSynced, m.channelsSynced, m.subscriptionsSynced); !ok { return fmt.Errorf("failed to wait for caches to sync") } - bus, err := m.busesLister.Buses(namespace).Get(name) + clusterBus, err := m.clusterBusesLister.Get(clusterBusName) if err != nil { - glog.Fatalf("Unknown bus '%s/%s'", namespace, name) + glog.Fatalf("Unknown clusterbus %q", clusterBusName) } - m.bus = bus + m.clusterBus = clusterBus glog.Info("Starting workers") - // Launch two workers to process Bus resources + // Launch two workers to process ClusterBus resources for i := 0; i < threadiness; i++ { go wait.Until(m.runWorker, time.Second, stopCh) } @@ -488,8 +488,8 @@ func (m *Monitor) processNextWorkItem() bool { runtime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) return nil } - // Run the syncHandler, passing it the namespace/name string of the - // Bus resource to be synced. + // Run the syncHandler, passing it the name string of the + // ClusterBus resource to be synced. if err := m.syncHandler(key); err != nil { m.workqueue.AddRateLimited(obj) return fmt.Errorf("error syncing monitor '%s': %s", key, err.Error()) @@ -510,7 +510,7 @@ func (m *Monitor) processNextWorkItem() bool { } // syncHandler compares the actual state with the desired, and attempts to -// converge the two. It then updates the Status block of the Bus resource +// converge the two. It then updates the Status block of the ClusterBus resource // with the current status of the resource. func (m *Monitor) syncHandler(key string) error { // Convert the namespace/name string into a distinct namespace and name @@ -520,14 +520,14 @@ func (m *Monitor) syncHandler(key string) error { return nil } - if m.bus == nil && kind != busKind { - // don't attempt tp sync until we have seen the bus for this monitor - return fmt.Errorf("Unknown bus for monitor") + if m.clusterBus == nil && kind != clusterBusKind { + // don't attempt tp sync until we have seen the clusterbus for this monitor + return fmt.Errorf("Unknown clusterbus for monitor") } switch kind { - case busKind: - err = m.syncBus(namespace, name) + case clusterBusKind: + err = m.syncClusterBus(name) case channelKind: err = m.syncChannel(namespace, name) case subscriptionKind: @@ -544,11 +544,11 @@ func (m *Monitor) syncHandler(key string) error { return nil } -func (m *Monitor) syncBus(namespace string, name string) error { - // Get the Bus resource with this namespace/name - bus, err := m.busesLister.Buses(namespace).Get(name) +func (m *Monitor) syncClusterBus(name string) error { + // Get the ClusterBus resource with this name + clusterBus, err := m.clusterBusesLister.Get(name) if err != nil { - // The Bus resource may no longer exist + // The ClusterBus resource may no longer exist if errors.IsNotFound(err) { // nothing to do return nil @@ -557,8 +557,8 @@ func (m *Monitor) syncBus(namespace string, name string) error { return err } - // Sync the Bus - err = m.createOrUpdateBus(bus) + // Sync the ClusterBus + err = m.createOrUpdateClusterBus(clusterBus) if err != nil { return err } @@ -635,15 +635,15 @@ func (m *Monitor) getOrCreateChannelSummary(key channelKey) *channelSummary { return summary } -func (m *Monitor) createOrUpdateBus(bus *channelsv1alpha1.Bus) error { - if bus.Name != m.bus.Name { - // this is not our bus +func (m *Monitor) createOrUpdateClusterBus(clusterBus *channelsv1alpha1.ClusterBus) error { + if clusterBus.Name != m.clusterBus.Name { + // this is not our clusterbus return nil } - if !reflect.DeepEqual(m.bus.Spec, bus.Spec) { - m.bus = bus - err := m.handler.onBus(bus, m) + if !reflect.DeepEqual(m.clusterBus.Spec, clusterBus.Spec) { + m.clusterBus = clusterBus + err := m.handler.onClusterBus(clusterBus, m) if err != nil { return err } @@ -653,7 +653,7 @@ func (m *Monitor) createOrUpdateBus(bus *channelsv1alpha1.Bus) error { } func (m *Monitor) isChannelForBus(channel *channelsv1alpha1.Channel) bool { - return channel.Spec.Bus == m.bus.Name + return channel.Spec.ClusterBus == m.clusterBus.Name } func (m *Monitor) createOrUpdateChannel(channel *channelsv1alpha1.Channel) error { @@ -714,7 +714,7 @@ func (m *Monitor) isSubscriptionProvisioned(subscription *channelsv1alpha1.Subsc func (m *Monitor) isSubscriptionForBus(subscription *channelsv1alpha1.Subscription) bool { channelKey := makeChannelKeyFromSubscription(subscription) summary := m.getChannelSummary(channelKey) - return summary != nil && summary.Channel != nil && summary.Channel.Bus == m.bus.Name + return summary != nil && summary.Channel != nil && summary.Channel.ClusterBus == m.clusterBus.Name } func (m *Monitor) createOrUpdateSubscription(subscription *channelsv1alpha1.Subscription) error { @@ -807,8 +807,8 @@ func makeSubscriptionKeyWithNames(namespace string, name string) subscriptionKey } } -func makeWorkqueueKeyForBus(bus *channelsv1alpha1.Bus) string { - return makeWorkqueueKey(busKind, bus.Namespace, bus.Name) +func makeWorkqueueKeyForClusterBus(clusterBus *channelsv1alpha1.ClusterBus) string { + return makeWorkqueueKey(clusterBusKind, "", clusterBus.Name) } func makeWorkqueueKeyForChannel(channel *channelsv1alpha1.Channel) string { diff --git a/pkg/buses/stub/main.go b/pkg/buses/stub/main.go index e665d48e11e..d69ab7b9983 100644 --- a/pkg/buses/stub/main.go +++ b/pkg/buses/stub/main.go @@ -70,7 +70,7 @@ func (b *StubBus) handleEvent(res http.ResponseWriter, req *http.Request) { } safeHeaders := b.safeHeaders(req.Header) - safeHeaders.Set("x-bus", b.name) + safeHeaders.Set("x-clusterbus", b.name) safeHeaders.Set("x-channel", channel) for _, subscription := range *subscriptions { subscriber := b.resolveSubscriber(subscription, namespace) @@ -149,9 +149,8 @@ func main() { // set up signals so we handle the first shutdown signal gracefully stopCh := signals.SetupSignalHandler() - namespace := os.Getenv("BUS_NAMESPACE") - name := os.Getenv("BUS_NAME") - component := fmt.Sprintf("%s-%s", name, buses.Dispatcher) + clusterBusName := os.Getenv("CLUSTER_BUS_NAME") + component := fmt.Sprintf("%s-%s", clusterBusName, buses.Dispatcher) monitor := buses.NewMonitor(component, masterURL, kubeconfig, buses.MonitorEventHandlerFuncs{ ProvisionFunc: func(channel *channelsv1alpha1.Channel, attributes buses.Attributes) error { @@ -171,10 +170,10 @@ func main() { return nil }, }) - bus := NewStubBus(name, monitor) + bus := NewStubBus(clusterBusName, monitor) go func() { - if err := monitor.Run(namespace, name, threadsPerMonitor, stopCh); err != nil { + if err := monitor.Run(clusterBusName, threadsPerMonitor, stopCh); err != nil { glog.Fatalf("Error running monitor: %s", err.Error()) } }() diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go deleted file mode 100644 index 9c86a128800..00000000000 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go +++ /dev/null @@ -1,147 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" - scheme "github.com/knative/eventing/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" -) - -// BusesGetter has a method to return a BusInterface. -// A group's client should implement this interface. -type BusesGetter interface { - Buses() BusInterface -} - -// BusInterface has methods to work with Bus resources. -type BusInterface interface { - Create(*v1alpha1.Bus) (*v1alpha1.Bus, error) - Update(*v1alpha1.Bus) (*v1alpha1.Bus, error) - Delete(name string, options *v1.DeleteOptions) error - DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*v1alpha1.Bus, error) - List(opts v1.ListOptions) (*v1alpha1.BusList, error) - Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) - BusExpansion -} - -// buses implements BusInterface -type buses struct { - client rest.Interface -} - -// newBuses returns a Buses -func newBuses(c *ChannelsV1alpha1Client) *buses { - return &buses{ - client: c.RESTClient(), - } -} - -// Get takes name of the bus, and returns the corresponding bus object, and an error if there is any. -func (c *buses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, err error) { - result = &v1alpha1.Bus{} - err = c.client.Get(). - Resource("buses"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of Buses that match those selectors. -func (c *buses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) { - result = &v1alpha1.BusList{} - err = c.client.Get(). - Resource("buses"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested buses. -func (c *buses) Watch(opts v1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.client.Get(). - Resource("buses"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch() -} - -// Create takes the representation of a bus and creates it. Returns the server's representation of the bus, and an error, if there is any. -func (c *buses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { - result = &v1alpha1.Bus{} - err = c.client.Post(). - Resource("buses"). - Body(bus). - Do(). - Into(result) - return -} - -// Update takes the representation of a bus and updates it. Returns the server's representation of the bus, and an error, if there is any. -func (c *buses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { - result = &v1alpha1.Bus{} - err = c.client.Put(). - Resource("buses"). - Name(bus.Name). - Body(bus). - Do(). - Into(result) - return -} - -// Delete takes name of the bus and deletes it. Returns an error if one occurs. -func (c *buses) Delete(name string, options *v1.DeleteOptions) error { - return c.client.Delete(). - Resource("buses"). - Name(name). - Body(options). - Do(). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *buses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - return c.client.Delete(). - Resource("buses"). - VersionedParams(&listOptions, scheme.ParameterCodec). - Body(options). - Do(). - Error() -} - -// Patch applies the patch and returns the patched bus. -func (c *buses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) { - result = &v1alpha1.Bus{} - err = c.client.Patch(pt). - Resource("buses"). - SubResource(subresources...). - Name(name). - Body(data). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go index 1777882d58f..280c8e88e40 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go @@ -27,8 +27,8 @@ import ( type ChannelsV1alpha1Interface interface { RESTClient() rest.Interface - BusesGetter ChannelsGetter + ClusterBusesGetter SubscriptionsGetter } @@ -37,14 +37,14 @@ type ChannelsV1alpha1Client struct { restClient rest.Interface } -func (c *ChannelsV1alpha1Client) Buses() BusInterface { - return newBuses(c) -} - func (c *ChannelsV1alpha1Client) Channels(namespace string) ChannelInterface { return newChannels(c, namespace) } +func (c *ChannelsV1alpha1Client) ClusterBuses() ClusterBusInterface { + return newClusterBuses(c) +} + func (c *ChannelsV1alpha1Client) Subscriptions(namespace string) SubscriptionInterface { return newSubscriptions(c, namespace) } diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/clusterbus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/clusterbus.go new file mode 100644 index 00000000000..707d2e04e4e --- /dev/null +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/clusterbus.go @@ -0,0 +1,147 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + scheme "github.com/knative/eventing/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ClusterBusesGetter has a method to return a ClusterBusInterface. +// A group's client should implement this interface. +type ClusterBusesGetter interface { + ClusterBuses() ClusterBusInterface +} + +// ClusterBusInterface has methods to work with ClusterBus resources. +type ClusterBusInterface interface { + Create(*v1alpha1.ClusterBus) (*v1alpha1.ClusterBus, error) + Update(*v1alpha1.ClusterBus) (*v1alpha1.ClusterBus, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.ClusterBus, error) + List(opts v1.ListOptions) (*v1alpha1.ClusterBusList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ClusterBus, err error) + ClusterBusExpansion +} + +// clusterBuses implements ClusterBusInterface +type clusterBuses struct { + client rest.Interface +} + +// newClusterBuses returns a ClusterBuses +func newClusterBuses(c *ChannelsV1alpha1Client) *clusterBuses { + return &clusterBuses{ + client: c.RESTClient(), + } +} + +// Get takes name of the clusterBus, and returns the corresponding clusterBus object, and an error if there is any. +func (c *clusterBuses) Get(name string, options v1.GetOptions) (result *v1alpha1.ClusterBus, err error) { + result = &v1alpha1.ClusterBus{} + err = c.client.Get(). + Resource("clusterbuses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ClusterBuses that match those selectors. +func (c *clusterBuses) List(opts v1.ListOptions) (result *v1alpha1.ClusterBusList, err error) { + result = &v1alpha1.ClusterBusList{} + err = c.client.Get(). + Resource("clusterbuses"). + VersionedParams(&opts, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested clusterBuses. +func (c *clusterBuses) Watch(opts v1.ListOptions) (watch.Interface, error) { + opts.Watch = true + return c.client.Get(). + Resource("clusterbuses"). + VersionedParams(&opts, scheme.ParameterCodec). + Watch() +} + +// Create takes the representation of a clusterBus and creates it. Returns the server's representation of the clusterBus, and an error, if there is any. +func (c *clusterBuses) Create(clusterBus *v1alpha1.ClusterBus) (result *v1alpha1.ClusterBus, err error) { + result = &v1alpha1.ClusterBus{} + err = c.client.Post(). + Resource("clusterbuses"). + Body(clusterBus). + Do(). + Into(result) + return +} + +// Update takes the representation of a clusterBus and updates it. Returns the server's representation of the clusterBus, and an error, if there is any. +func (c *clusterBuses) Update(clusterBus *v1alpha1.ClusterBus) (result *v1alpha1.ClusterBus, err error) { + result = &v1alpha1.ClusterBus{} + err = c.client.Put(). + Resource("clusterbuses"). + Name(clusterBus.Name). + Body(clusterBus). + Do(). + Into(result) + return +} + +// Delete takes name of the clusterBus and deletes it. Returns an error if one occurs. +func (c *clusterBuses) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Resource("clusterbuses"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *clusterBuses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + return c.client.Delete(). + Resource("clusterbuses"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched clusterBus. +func (c *clusterBuses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ClusterBus, err error) { + result = &v1alpha1.ClusterBus{} + err = c.client.Patch(pt). + Resource("clusterbuses"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go deleted file mode 100644 index 8cff2292bb7..00000000000 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go +++ /dev/null @@ -1,120 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -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. -*/ - -// Code generated by client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" -) - -// FakeBuses implements BusInterface -type FakeBuses struct { - Fake *FakeChannelsV1alpha1 -} - -var busesResource = schema.GroupVersionResource{Group: "channels.knative.dev", Version: "v1alpha1", Resource: "buses"} - -var busesKind = schema.GroupVersionKind{Group: "channels.knative.dev", Version: "v1alpha1", Kind: "Bus"} - -// Get takes name of the bus, and returns the corresponding bus object, and an error if there is any. -func (c *FakeBuses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootGetAction(busesResource, name), &v1alpha1.Bus{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Bus), err -} - -// List takes label and field selectors, and returns the list of Buses that match those selectors. -func (c *FakeBuses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootListAction(busesResource, busesKind, opts), &v1alpha1.BusList{}) - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.BusList{} - for _, item := range obj.(*v1alpha1.BusList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested buses. -func (c *FakeBuses) Watch(opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewRootWatchAction(busesResource, opts)) -} - -// Create takes the representation of a bus and creates it. Returns the server's representation of the bus, and an error, if there is any. -func (c *FakeBuses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootCreateAction(busesResource, bus), &v1alpha1.Bus{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Bus), err -} - -// Update takes the representation of a bus and updates it. Returns the server's representation of the bus, and an error, if there is any. -func (c *FakeBuses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootUpdateAction(busesResource, bus), &v1alpha1.Bus{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Bus), err -} - -// Delete takes name of the bus and deletes it. Returns an error if one occurs. -func (c *FakeBuses) Delete(name string, options *v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewRootDeleteAction(busesResource, name), &v1alpha1.Bus{}) - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeBuses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewRootDeleteCollectionAction(busesResource, listOptions) - - _, err := c.Fake.Invokes(action, &v1alpha1.BusList{}) - return err -} - -// Patch applies the patch and returns the patched bus. -func (c *FakeBuses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) { - obj, err := c.Fake. - Invokes(testing.NewRootPatchSubresourceAction(busesResource, name, data, subresources...), &v1alpha1.Bus{}) - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.Bus), err -} diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go index d9cc981c8da..a345ec17a3c 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go @@ -28,14 +28,14 @@ type FakeChannelsV1alpha1 struct { *testing.Fake } -func (c *FakeChannelsV1alpha1) Buses() v1alpha1.BusInterface { - return &FakeBuses{c} -} - func (c *FakeChannelsV1alpha1) Channels(namespace string) v1alpha1.ChannelInterface { return &FakeChannels{c, namespace} } +func (c *FakeChannelsV1alpha1) ClusterBuses() v1alpha1.ClusterBusInterface { + return &FakeClusterBuses{c} +} + func (c *FakeChannelsV1alpha1) Subscriptions(namespace string) v1alpha1.SubscriptionInterface { return &FakeSubscriptions{c, namespace} } diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_clusterbus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_clusterbus.go new file mode 100644 index 00000000000..c73436022d6 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_clusterbus.go @@ -0,0 +1,120 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeClusterBuses implements ClusterBusInterface +type FakeClusterBuses struct { + Fake *FakeChannelsV1alpha1 +} + +var clusterbusesResource = schema.GroupVersionResource{Group: "channels.knative.dev", Version: "v1alpha1", Resource: "clusterbuses"} + +var clusterbusesKind = schema.GroupVersionKind{Group: "channels.knative.dev", Version: "v1alpha1", Kind: "ClusterBus"} + +// Get takes name of the clusterBus, and returns the corresponding clusterBus object, and an error if there is any. +func (c *FakeClusterBuses) Get(name string, options v1.GetOptions) (result *v1alpha1.ClusterBus, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootGetAction(clusterbusesResource, name), &v1alpha1.ClusterBus{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterBus), err +} + +// List takes label and field selectors, and returns the list of ClusterBuses that match those selectors. +func (c *FakeClusterBuses) List(opts v1.ListOptions) (result *v1alpha1.ClusterBusList, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootListAction(clusterbusesResource, clusterbusesKind, opts), &v1alpha1.ClusterBusList{}) + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ClusterBusList{} + for _, item := range obj.(*v1alpha1.ClusterBusList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested clusterBuses. +func (c *FakeClusterBuses) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewRootWatchAction(clusterbusesResource, opts)) +} + +// Create takes the representation of a clusterBus and creates it. Returns the server's representation of the clusterBus, and an error, if there is any. +func (c *FakeClusterBuses) Create(clusterBus *v1alpha1.ClusterBus) (result *v1alpha1.ClusterBus, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootCreateAction(clusterbusesResource, clusterBus), &v1alpha1.ClusterBus{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterBus), err +} + +// Update takes the representation of a clusterBus and updates it. Returns the server's representation of the clusterBus, and an error, if there is any. +func (c *FakeClusterBuses) Update(clusterBus *v1alpha1.ClusterBus) (result *v1alpha1.ClusterBus, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootUpdateAction(clusterbusesResource, clusterBus), &v1alpha1.ClusterBus{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterBus), err +} + +// Delete takes name of the clusterBus and deletes it. Returns an error if one occurs. +func (c *FakeClusterBuses) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewRootDeleteAction(clusterbusesResource, name), &v1alpha1.ClusterBus{}) + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeClusterBuses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewRootDeleteCollectionAction(clusterbusesResource, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.ClusterBusList{}) + return err +} + +// Patch applies the patch and returns the patched clusterBus. +func (c *FakeClusterBuses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.ClusterBus, err error) { + obj, err := c.Fake. + Invokes(testing.NewRootPatchSubresourceAction(clusterbusesResource, name, data, subresources...), &v1alpha1.ClusterBus{}) + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ClusterBus), err +} diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go index 5d6be8ae3c0..32b96d444e4 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go @@ -18,8 +18,8 @@ limitations under the License. package v1alpha1 -type BusExpansion interface{} - type ChannelExpansion interface{} +type ClusterBusExpansion interface{} + type SubscriptionExpansion interface{} diff --git a/pkg/client/informers/externalversions/channels/v1alpha1/bus.go b/pkg/client/informers/externalversions/channels/v1alpha1/clusterbus.go similarity index 58% rename from pkg/client/informers/externalversions/channels/v1alpha1/bus.go rename to pkg/client/informers/externalversions/channels/v1alpha1/clusterbus.go index 642b1f018e7..109af846e71 100644 --- a/pkg/client/informers/externalversions/channels/v1alpha1/bus.go +++ b/pkg/client/informers/externalversions/channels/v1alpha1/clusterbus.go @@ -31,58 +31,58 @@ import ( cache "k8s.io/client-go/tools/cache" ) -// BusInformer provides access to a shared informer and lister for -// Buses. -type BusInformer interface { +// ClusterBusInformer provides access to a shared informer and lister for +// ClusterBuses. +type ClusterBusInformer interface { Informer() cache.SharedIndexInformer - Lister() v1alpha1.BusLister + Lister() v1alpha1.ClusterBusLister } -type busInformer struct { +type clusterBusInformer struct { factory internalinterfaces.SharedInformerFactory tweakListOptions internalinterfaces.TweakListOptionsFunc } -// NewBusInformer constructs a new informer for Bus type. +// NewClusterBusInformer constructs a new informer for ClusterBus type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewBusInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredBusInformer(client, resyncPeriod, indexers, nil) +func NewClusterBusInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredClusterBusInformer(client, resyncPeriod, indexers, nil) } -// NewFilteredBusInformer constructs a new informer for Bus type. +// NewFilteredClusterBusInformer constructs a new informer for ClusterBus type. // Always prefer using an informer factory to get a shared informer instead of getting an independent // one. This reduces memory footprint and number of connections to the server. -func NewFilteredBusInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { +func NewFilteredClusterBusInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { return cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ChannelsV1alpha1().Buses().List(options) + return client.ChannelsV1alpha1().ClusterBuses().List(options) }, WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { if tweakListOptions != nil { tweakListOptions(&options) } - return client.ChannelsV1alpha1().Buses().Watch(options) + return client.ChannelsV1alpha1().ClusterBuses().Watch(options) }, }, - &channels_v1alpha1.Bus{}, + &channels_v1alpha1.ClusterBus{}, resyncPeriod, indexers, ) } -func (f *busInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredBusInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +func (f *clusterBusInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredClusterBusInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) } -func (f *busInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&channels_v1alpha1.Bus{}, f.defaultInformer) +func (f *clusterBusInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&channels_v1alpha1.ClusterBus{}, f.defaultInformer) } -func (f *busInformer) Lister() v1alpha1.BusLister { - return v1alpha1.NewBusLister(f.Informer().GetIndexer()) +func (f *clusterBusInformer) Lister() v1alpha1.ClusterBusLister { + return v1alpha1.NewClusterBusLister(f.Informer().GetIndexer()) } diff --git a/pkg/client/informers/externalversions/channels/v1alpha1/interface.go b/pkg/client/informers/externalversions/channels/v1alpha1/interface.go index 5e3f9466ec1..6dd9ddc97a0 100644 --- a/pkg/client/informers/externalversions/channels/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/channels/v1alpha1/interface.go @@ -24,10 +24,10 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { - // Buses returns a BusInformer. - Buses() BusInformer // Channels returns a ChannelInformer. Channels() ChannelInformer + // ClusterBuses returns a ClusterBusInformer. + ClusterBuses() ClusterBusInformer // Subscriptions returns a SubscriptionInformer. Subscriptions() SubscriptionInformer } @@ -43,16 +43,16 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } -// Buses returns a BusInformer. -func (v *version) Buses() BusInformer { - return &busInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} -} - // Channels returns a ChannelInformer. func (v *version) Channels() ChannelInformer { return &channelInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// ClusterBuses returns a ClusterBusInformer. +func (v *version) ClusterBuses() ClusterBusInformer { + return &clusterBusInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} +} + // Subscriptions returns a SubscriptionInformer. func (v *version) Subscriptions() SubscriptionInformer { return &subscriptionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index b8680d85c8a..dc0541981f5 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -55,10 +55,10 @@ func (f *genericInformer) Lister() cache.GenericLister { func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { // Group=channels.knative.dev, Version=v1alpha1 - case v1alpha1.SchemeGroupVersion.WithResource("buses"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Channels().V1alpha1().Buses().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("channels"): return &genericInformer{resource: resource.GroupResource(), informer: f.Channels().V1alpha1().Channels().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("clusterbuses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Channels().V1alpha1().ClusterBuses().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("subscriptions"): return &genericInformer{resource: resource.GroupResource(), informer: f.Channels().V1alpha1().Subscriptions().Informer()}, nil diff --git a/pkg/client/listers/channels/v1alpha1/bus.go b/pkg/client/listers/channels/v1alpha1/bus.go deleted file mode 100644 index 9f591e621d4..00000000000 --- a/pkg/client/listers/channels/v1alpha1/bus.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2018 The Knative Authors - -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. -*/ - -// Code generated by lister-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// BusLister helps list Buses. -type BusLister interface { - // List lists all Buses in the indexer. - List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) - // Get retrieves the Bus from the index for a given name. - Get(name string) (*v1alpha1.Bus, error) - BusListerExpansion -} - -// busLister implements the BusLister interface. -type busLister struct { - indexer cache.Indexer -} - -// NewBusLister returns a new BusLister. -func NewBusLister(indexer cache.Indexer) BusLister { - return &busLister{indexer: indexer} -} - -// List lists all Buses in the indexer. -func (s *busLister) List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.Bus)) - }) - return ret, err -} - -// Get retrieves the Bus from the index for a given name. -func (s *busLister) Get(name string) (*v1alpha1.Bus, error) { - obj, exists, err := s.indexer.GetByKey(name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("bus"), name) - } - return obj.(*v1alpha1.Bus), nil -} diff --git a/pkg/client/listers/channels/v1alpha1/clusterbus.go b/pkg/client/listers/channels/v1alpha1/clusterbus.go new file mode 100644 index 00000000000..5415692f299 --- /dev/null +++ b/pkg/client/listers/channels/v1alpha1/clusterbus.go @@ -0,0 +1,65 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ClusterBusLister helps list ClusterBuses. +type ClusterBusLister interface { + // List lists all ClusterBuses in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.ClusterBus, err error) + // Get retrieves the ClusterBus from the index for a given name. + Get(name string) (*v1alpha1.ClusterBus, error) + ClusterBusListerExpansion +} + +// clusterBusLister implements the ClusterBusLister interface. +type clusterBusLister struct { + indexer cache.Indexer +} + +// NewClusterBusLister returns a new ClusterBusLister. +func NewClusterBusLister(indexer cache.Indexer) ClusterBusLister { + return &clusterBusLister{indexer: indexer} +} + +// List lists all ClusterBuses in the indexer. +func (s *clusterBusLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterBus, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ClusterBus)) + }) + return ret, err +} + +// Get retrieves the ClusterBus from the index for a given name. +func (s *clusterBusLister) Get(name string) (*v1alpha1.ClusterBus, error) { + obj, exists, err := s.indexer.GetByKey(name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("clusterbus"), name) + } + return obj.(*v1alpha1.ClusterBus), nil +} diff --git a/pkg/client/listers/channels/v1alpha1/expansion_generated.go b/pkg/client/listers/channels/v1alpha1/expansion_generated.go index c2515e17ce4..bac2ac3182b 100644 --- a/pkg/client/listers/channels/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/channels/v1alpha1/expansion_generated.go @@ -18,10 +18,6 @@ limitations under the License. package v1alpha1 -// BusListerExpansion allows custom methods to be added to -// BusLister. -type BusListerExpansion interface{} - // ChannelListerExpansion allows custom methods to be added to // ChannelLister. type ChannelListerExpansion interface{} @@ -30,6 +26,10 @@ type ChannelListerExpansion interface{} // ChannelNamespaceLister. type ChannelNamespaceListerExpansion interface{} +// ClusterBusListerExpansion allows custom methods to be added to +// ClusterBusLister. +type ClusterBusListerExpansion interface{} + // SubscriptionListerExpansion allows custom methods to be added to // SubscriptionLister. type SubscriptionListerExpansion interface{} diff --git a/pkg/controller/channel/controller.go b/pkg/controller/channel/controller.go index bf7833b54e0..750606928fd 100644 --- a/pkg/controller/channel/controller.go +++ b/pkg/controller/channel/controller.go @@ -456,8 +456,8 @@ func newService(channel *channelsv1alpha1.Channel) *corev1.Service { // the Channel resource that 'owns' it. func newVirtualService(channel *channelsv1alpha1.Channel) *istiov1alpha3.VirtualService { labels := map[string]string{ - "bus": channel.Spec.Bus, - "channel": channel.Name, + "clusterBus": channel.Spec.ClusterBus, + "channel": channel.Name, } return &istiov1alpha3.VirtualService{ ObjectMeta: metav1.ObjectMeta{ @@ -485,7 +485,7 @@ func newVirtualService(channel *channelsv1alpha1.Channel) *istiov1alpha3.Virtual Route: []istiov1alpha3.DestinationWeight{ { Destination: istiov1alpha3.Destination{ - Host: controller.ServiceHostName(controller.BusDispatcherServiceName(channel.Spec.Bus), pkg.GetEventingSystemNamespace()), + Host: controller.ServiceHostName(controller.ClusterBusDispatcherServiceName(channel.Spec.ClusterBus), pkg.GetEventingSystemNamespace()), }, }, }, diff --git a/pkg/controller/bus/controller.go b/pkg/controller/clusterbus/controller.go similarity index 65% rename from pkg/controller/bus/controller.go rename to pkg/controller/clusterbus/controller.go index 8205fb396f3..9419c725c56 100644 --- a/pkg/controller/bus/controller.go +++ b/pkg/controller/clusterbus/controller.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package bus +package clusterbus import ( "fmt" @@ -53,38 +53,38 @@ import ( ) const ( - controllerAgentName = "bus-controller" - busControllerServiceAccountName = "bus-controller" + controllerAgentName = "clusterbus-controller" + clusterBusControllerServiceAccountName = "clusterbus-controller" ) const ( - // SuccessSynced is used as part of the Event 'reason' when a Bus is synced + // SuccessSynced is used as part of the Event 'reason' when a ClusterBus is synced SuccessSynced = "Synced" - // ErrResourceExists is used as part of the Event 'reason' when a Bus fails + // ErrResourceExists is used as part of the Event 'reason' when a ClusterBus fails // to sync due to a Service of the same name already existing. ErrResourceExists = "ErrResourceExists" // MessageResourceExists is the message used for Events when a resource // fails to sync due to a Service already existing - MessageResourceExists = "Resource %q already exists and is not managed by Bus" - // MessageResourceSynced is the message used for an Event fired when a Bus + MessageResourceExists = "Resource %q already exists and is not managed by ClusterBus" + // MessageResourceSynced is the message used for an Event fired when a ClusterBus // is synced successfully - MessageResourceSynced = "Bus synced successfully" + MessageResourceSynced = "ClusterBus synced successfully" ) -// Controller is the controller implementation for Bus resources +// Controller is the controller implementation for ClusterBus resources type Controller struct { // kubeclientset is a standard kubernetes clientset kubeclientset kubernetes.Interface - // busclientset is a clientset for our own API group - busclientset clientset.Interface + // clusterbusclientset is a clientset for our own API group + clusterbusclientset clientset.Interface - deploymentsLister appslisters.DeploymentLister - deploymentsSynced cache.InformerSynced - servicesLister corelisters.ServiceLister - servicesSynced cache.InformerSynced - busesLister listers.BusLister - busesSynced cache.InformerSynced + deploymentsLister appslisters.DeploymentLister + deploymentsSynced cache.InformerSynced + servicesLister corelisters.ServiceLister + servicesSynced cache.InformerSynced + clusterBusesLister listers.ClusterBusLister + clusterBusesSynced cache.InformerSynced // workqueue is a rate limited work queue. This is used to queue work to be // processed instead of performing it as soon as a change happens. This @@ -97,23 +97,23 @@ type Controller struct { recorder record.EventRecorder } -// NewController returns a new bus controller +// NewController returns a new clusterbus controller func NewController( kubeclientset kubernetes.Interface, - busclientset clientset.Interface, + clusterbusclientset clientset.Interface, kubeInformerFactory kubeinformers.SharedInformerFactory, - busInformerFactory informers.SharedInformerFactory, + clusterBusInformerFactory informers.SharedInformerFactory, routeInformerFactory servinginformers.SharedInformerFactory) controller.Interface { - // obtain references to shared index informers for the Bus, Deployment and Service + // obtain references to shared index informers for the ClusterBus, Deployment and Service // types. - busInformer := busInformerFactory.Channels().V1alpha1().Buses() + clusterBusInformer := clusterBusInformerFactory.Channels().V1alpha1().ClusterBuses() deploymentInformer := kubeInformerFactory.Apps().V1().Deployments() serviceInformer := kubeInformerFactory.Core().V1().Services() // Create event broadcaster - // Add bus-controller types to the default Kubernetes Scheme so Events can be - // logged for bus-controller types. + // Add clusterbus-controller types to the default Kubernetes Scheme so Events can be + // logged for clusterbus-controller types. channelscheme.AddToScheme(scheme.Scheme) glog.V(4).Info("Creating event broadcaster") eventBroadcaster := record.NewBroadcaster() @@ -122,29 +122,29 @@ func NewController( recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName}) controller := &Controller{ - kubeclientset: kubeclientset, - busclientset: busclientset, - deploymentsLister: deploymentInformer.Lister(), - deploymentsSynced: deploymentInformer.Informer().HasSynced, - servicesLister: serviceInformer.Lister(), - servicesSynced: serviceInformer.Informer().HasSynced, - busesLister: busInformer.Lister(), - busesSynced: busInformer.Informer().HasSynced, - workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Buses"), - recorder: recorder, + kubeclientset: kubeclientset, + clusterbusclientset: clusterbusclientset, + deploymentsLister: deploymentInformer.Lister(), + deploymentsSynced: deploymentInformer.Informer().HasSynced, + servicesLister: serviceInformer.Lister(), + servicesSynced: serviceInformer.Informer().HasSynced, + clusterBusesLister: clusterBusInformer.Lister(), + clusterBusesSynced: clusterBusInformer.Informer().HasSynced, + workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "ClusterBuses"), + recorder: recorder, } glog.Info("Setting up event handlers") - // Set up an event handler for when Bus resources change - busInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ - AddFunc: controller.enqueueBus, + // Set up an event handler for when ClusterBus resources change + clusterBusInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.enqueueClusterBus, UpdateFunc: func(old, new interface{}) { - controller.enqueueBus(new) + controller.enqueueClusterBus(new) }, }) // Set up an event handler for when Service resources change. This // handler will lookup the owner of the given Service, and if it is - // owned by a Bus resource will enqueue that Bus resource for + // owned by a ClusterBus resource will enqueue that ClusterBus resource for // processing. This way, we don't need to implement custom logic for // handling Service resources. More info on this pattern: // https://github.com/kubernetes/community/blob/8cafef897a22026d42f5e5bb3f104febe7e29830/contributors/devel/controllers.md @@ -175,16 +175,16 @@ func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error { defer c.workqueue.ShutDown() // Start the informer factories to begin populating the informer caches - glog.Info("Starting Bus controller") + glog.Info("Starting ClusterBus controller") // Wait for the caches to be synced before starting workers glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, c.deploymentsSynced, c.servicesSynced, c.busesSynced); !ok { + if ok := cache.WaitForCacheSync(stopCh, c.deploymentsSynced, c.servicesSynced, c.clusterBusesSynced); !ok { return fmt.Errorf("failed to wait for caches to sync") } glog.Info("Starting workers") - // Launch two workers to process Bus resources + // Launch two workers to process ClusterBus resources for i := 0; i < threadiness; i++ { go wait.Until(c.runWorker, time.Second, stopCh) } @@ -238,14 +238,14 @@ func (c *Controller) processNextWorkItem() bool { return nil } // Run the syncHandler, passing it the namespace/name string of the - // Bus resource to be synced. + // ClusterBus resource to be synced. if err := c.syncHandler(key); err != nil { - return fmt.Errorf("error syncing bus '%s': %s", key, err.Error()) + return fmt.Errorf("error syncing clusterbus '%s': %s", key, err.Error()) } // Finally, if no error occurs we Forget this item so it does not // get queued again until another change happens. c.workqueue.Forget(obj) - glog.Infof("Successfully synced bus '%s'", key) + glog.Infof("Successfully synced clusterbus '%s'", key) return nil }(obj) @@ -258,7 +258,7 @@ func (c *Controller) processNextWorkItem() bool { } // syncHandler compares the actual state with the desired, and attempts to -// converge the two. It then updates the Status block of the Bus resource +// converge the two. It then updates the Status block of the ClusterBus resource // with the current status of the resource. func (c *Controller) syncHandler(key string) error { // Convert the namespace/name string into a distinct namespace and name @@ -268,55 +268,55 @@ func (c *Controller) syncHandler(key string) error { return nil } - // Get the Bus resource with this name - bus, err := c.busesLister.Get(name) + // Get the ClusterBus resource with this name + clusterBus, err := c.clusterBusesLister.Get(name) if err != nil { - // The Bus resource may no longer exist, in which case we stop + // The ClusterBus resource may no longer exist, in which case we stop // processing. if errors.IsNotFound(err) { - runtime.HandleError(fmt.Errorf("bus '%s' in work queue no longer exists", key)) + runtime.HandleError(fmt.Errorf("clusterbus '%s' in work queue no longer exists", key)) return nil } return err } - // Sync Service derived from the Bus - dispatcherService, err := c.syncBusDispatcherService(bus) + // Sync Service derived from the ClusterBus + dispatcherService, err := c.syncClusterBusDispatcherService(clusterBus) if err != nil { return err } - // Sync Deployment derived from the Bus - dispatcherDeployment, err := c.syncBusDispatcherDeployment(bus) + // Sync Deployment derived from the ClusterBus + dispatcherDeployment, err := c.syncClusterBusDispatcherDeployment(clusterBus) if err != nil { return err } - // Sync Deployment derived from the Bus - provisionerDeployment, err := c.syncBusProvisionerDeployment(bus) + // Sync Deployment derived from the ClusterBus + provisionerDeployment, err := c.syncClusterBusProvisionerDeployment(clusterBus) if err != nil { return err } - // Finally, we update the status block of the Bus resource to reflect the + // Finally, we update the status block of the ClusterBus resource to reflect the // current state of the world - err = c.updateBusStatus(bus, dispatcherService, dispatcherDeployment, provisionerDeployment) + err = c.updateClusterBusStatus(clusterBus, dispatcherService, dispatcherDeployment, provisionerDeployment) if err != nil { return err } - c.recorder.Event(bus, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced) + c.recorder.Event(clusterBus, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced) return nil } -func (c *Controller) syncBusDispatcherService(bus *channelsv1alpha1.Bus) (*corev1.Service, error) { +func (c *Controller) syncClusterBusDispatcherService(clusterBus *channelsv1alpha1.ClusterBus) (*corev1.Service, error) { // Get the service with the specified service name - serviceName := controller.BusDispatcherServiceName(bus.ObjectMeta.Name) + serviceName := controller.ClusterBusDispatcherServiceName(clusterBus.ObjectMeta.Name) service, err := c.servicesLister.Services(pkg.GetEventingSystemNamespace()).Get(serviceName) // If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { - service, err = c.kubeclientset.CoreV1().Services(pkg.GetEventingSystemNamespace()).Create(newDispatcherService(bus)) + service, err = c.kubeclientset.CoreV1().Services(pkg.GetEventingSystemNamespace()).Create(newDispatcherService(clusterBus)) } // If an error occurs during Get/Create, we'll requeue the item so we can @@ -326,24 +326,24 @@ func (c *Controller) syncBusDispatcherService(bus *channelsv1alpha1.Bus) (*corev return nil, err } - // If the Service is not controlled by this Bus resource, we should log + // If the Service is not controlled by this ClusterBus resource, we should log // a warning to the event recorder and return - if !metav1.IsControlledBy(service, bus) { + if !metav1.IsControlledBy(service, clusterBus) { msg := fmt.Sprintf(MessageResourceExists, service.Name) - c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + c.recorder.Event(clusterBus, corev1.EventTypeWarning, ErrResourceExists, msg) return nil, fmt.Errorf(msg) } return service, nil } -func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*appsv1.Deployment, error) { +func (c *Controller) syncClusterBusDispatcherDeployment(clusterBus *channelsv1alpha1.ClusterBus) (*appsv1.Deployment, error) { // Get the deployment with the specified deployment name - deploymentName := controller.BusDispatcherDeploymentName(bus.ObjectMeta.Name) + deploymentName := controller.ClusterBusDispatcherDeploymentName(clusterBus.ObjectMeta.Name) deployment, err := c.deploymentsLister.Deployments(pkg.GetEventingSystemNamespace()).Get(deploymentName) // If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { - deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Create(newDispatcherDeployment(bus)) + deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Create(newDispatcherDeployment(clusterBus)) } // If an error occurs during Get/Create, we'll requeue the item so we can @@ -353,19 +353,19 @@ func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*ap return nil, err } - // If the Deployment is not controlled by this Bus resource, we should log + // If the Deployment is not controlled by this ClusterBus resource, we should log // a warning to the event recorder and return - if !metav1.IsControlledBy(deployment, bus) { + if !metav1.IsControlledBy(deployment, clusterBus) { msg := fmt.Sprintf(MessageResourceExists, deployment.Name) - c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + c.recorder.Event(clusterBus, corev1.EventTypeWarning, ErrResourceExists, msg) return nil, fmt.Errorf(msg) } - // If the Deployment does not match the Bus's proposed Deployment we should update + // If the Deployment does not match the ClusterBus's proposed Deployment we should update // the Deployment resource. - proposedDeployment := newDispatcherDeployment(bus) + proposedDeployment := newDispatcherDeployment(clusterBus) if !reflect.DeepEqual(proposedDeployment.Spec, deployment.Spec) { - glog.V(4).Infof("Bus %s dispatcher spec updated", bus.Name) + glog.V(4).Infof("ClusterBus %s dispatcher spec updated", clusterBus.Name) deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Update(proposedDeployment) if err != nil { @@ -376,11 +376,11 @@ func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*ap return deployment, nil } -func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*appsv1.Deployment, error) { - provisioner := bus.Spec.Provisioner +func (c *Controller) syncClusterBusProvisionerDeployment(clusterBus *channelsv1alpha1.ClusterBus) (*appsv1.Deployment, error) { + provisioner := clusterBus.Spec.Provisioner // Get the deployment with the specified deployment name - deploymentName := controller.BusProvisionerDeploymentName(bus.ObjectMeta.Name) + deploymentName := controller.ClusterBusProvisionerDeploymentName(clusterBus.ObjectMeta.Name) deployment, err := c.deploymentsLister.Deployments(pkg.GetEventingSystemNamespace()).Get(deploymentName) // If the resource shouldn't exists @@ -397,7 +397,7 @@ func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*a // If the resource doesn't exist, we'll create it if errors.IsNotFound(err) { - deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Create(newProvisionerDeployment(bus)) + deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Create(newProvisionerDeployment(clusterBus)) } // If an error occurs during Get/Create, we'll requeue the item so we can @@ -407,19 +407,19 @@ func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*a return nil, err } - // If the Deployment is not controlled by this Bus resource, we should log + // If the Deployment is not controlled by this ClusterBus resource, we should log // a warning to the event recorder and return - if !metav1.IsControlledBy(deployment, bus) { + if !metav1.IsControlledBy(deployment, clusterBus) { msg := fmt.Sprintf(MessageResourceExists, deployment.Name) - c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + c.recorder.Event(clusterBus, corev1.EventTypeWarning, ErrResourceExists, msg) return nil, fmt.Errorf(msg) } - // If the Deployment does not match the Bus's proposed Deployment we should update + // If the Deployment does not match the ClusterBus's proposed Deployment we should update // the Deployment resource. - proposedDeployment := newProvisionerDeployment(bus) + proposedDeployment := newProvisionerDeployment(clusterBus) if !reflect.DeepEqual(proposedDeployment.Spec, deployment.Spec) { - glog.V(4).Infof("Bus %s provisioner spec updated", bus.Name) + glog.V(4).Infof("ClusterBus %s provisioner spec updated", clusterBus.Name) deployment, err = c.kubeclientset.AppsV1().Deployments(pkg.GetEventingSystemNamespace()).Update(proposedDeployment) if err != nil { @@ -430,8 +430,8 @@ func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*a return deployment, nil } -func (c *Controller) updateBusStatus( - bus *channelsv1alpha1.Bus, +func (c *Controller) updateClusterBusStatus( + clusterBus *channelsv1alpha1.ClusterBus, dispatcherService *corev1.Service, dispatcherDeployment *appsv1.Deployment, provisionerDeployment *appsv1.Deployment, @@ -439,19 +439,19 @@ func (c *Controller) updateBusStatus( // NEVER modify objects from the store. It's a read-only, local cache. // You can use DeepCopy() to make a deep copy of original object and modify this copy // Or create a copy manually for better performance - busCopy := bus.DeepCopy() + clusterBusCopy := clusterBus.DeepCopy() // If the CustomResourceSubresources feature gate is not enabled, - // we must use Update instead of UpdateStatus to update the Status block of the Bus resource. + // we must use Update instead of UpdateStatus to update the Status block of the ClusterBus resource. // UpdateStatus will not allow changes to the Spec of the resource, // which is ideal for ensuring nothing other than resource status has been updated. - _, err := c.busclientset.ChannelsV1alpha1().Buses().Update(busCopy) + _, err := c.clusterbusclientset.ChannelsV1alpha1().ClusterBuses().Update(clusterBusCopy) return err } -// enqueueBus takes a Bus resource and converts it into a namespace/name +// enqueueClusterBus takes a ClusterBus resource and converts it into a namespace/name // string which is then put onto the work queue. This method should *not* be -// passed resources of any type other than Bus. -func (c *Controller) enqueueBus(obj interface{}) { +// passed resources of any type other than ClusterBus. +func (c *Controller) enqueueClusterBus(obj interface{}) { var key string var err error if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { @@ -462,9 +462,9 @@ func (c *Controller) enqueueBus(obj interface{}) { } // handleObject will take any resource implementing metav1.Object and attempt -// to find the Bus resource that 'owns' it. It does this by looking at the +// to find the ClusterBus resource that 'owns' it. It does this by looking at the // objects metadata.ownerReferences field for an appropriate OwnerReference. -// It then enqueues that Bus resource to be processed. If the object does not +// It then enqueues that ClusterBus resource to be processed. If the object does not // have an appropriate OwnerReference, it will simply be skipped. func (c *Controller) handleObject(obj interface{}) { var object metav1.Object @@ -484,41 +484,41 @@ func (c *Controller) handleObject(obj interface{}) { } glog.V(4).Infof("Processing object: %s", object.GetName()) if ownerRef := metav1.GetControllerOf(object); ownerRef != nil { - // If this object is not owned by a Bus, we should not do anything more + // If this object is not owned by a ClusterBus, we should not do anything more // with it. - if ownerRef.Kind != "Bus" { + if ownerRef.Kind != "ClusterBus" { return } - bus, err := c.busesLister.Get(ownerRef.Name) + clusterBus, err := c.clusterBusesLister.Get(ownerRef.Name) if err != nil { - glog.V(4).Infof("ignoring orphaned object '%s' of bus '%s'", object.GetSelfLink(), ownerRef.Name) + glog.V(4).Infof("ignoring orphaned object '%s' of clusterbus '%s'", object.GetSelfLink(), ownerRef.Name) return } - c.enqueueBus(bus) + c.enqueueClusterBus(clusterBus) return } } -// newDispatcherService creates a new Service for a Bus resource. It also sets +// newDispatcherService creates a new Service for a ClusterBus resource. It also sets // the appropriate OwnerReferences on the resource so handleObject can discover -// the Bus resource that 'owns' it. -func newDispatcherService(bus *channelsv1alpha1.Bus) *corev1.Service { +// the ClusterBus resource that 'owns' it. +func newDispatcherService(clusterBus *channelsv1alpha1.ClusterBus) *corev1.Service { labels := map[string]string{ - "bus": bus.Name, - "role": "dispatcher", + "clusterBus": clusterBus.Name, + "role": "dispatcher", } return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: controller.BusDispatcherServiceName(bus.ObjectMeta.Name), + Name: controller.ClusterBusDispatcherServiceName(clusterBus.ObjectMeta.Name), Namespace: pkg.GetEventingSystemNamespace(), Labels: labels, OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + *metav1.NewControllerRef(clusterBus, schema.GroupVersionKind{ Group: channelsv1alpha1.SchemeGroupVersion.Group, Version: channelsv1alpha1.SchemeGroupVersion.Version, - Kind: "Bus", + Kind: "ClusterBus", }), }, }, @@ -535,43 +535,39 @@ func newDispatcherService(bus *channelsv1alpha1.Bus) *corev1.Service { } } -// newDispatcherDeployment creates a new Deployment for a Bus resource. It also sets +// newDispatcherDeployment creates a new Deployment for a ClusterBus resource. It also sets // the appropriate OwnerReferences on the resource so handleObject can discover -// the Bus resource that 'owns' it. -func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { +// the ClusterBus resource that 'owns' it. +func newDispatcherDeployment(clusterBus *channelsv1alpha1.ClusterBus) *appsv1.Deployment { labels := map[string]string{ - "bus": bus.Name, - "role": "dispatcher", + "clusterBus": clusterBus.Name, + "role": "dispatcher", } one := int32(1) - container := bus.Spec.Dispatcher.DeepCopy() + container := clusterBus.Spec.Dispatcher.DeepCopy() container.Env = append(container.Env, corev1.EnvVar{ Name: "PORT", Value: "8080", }, corev1.EnvVar{ - Name: "BUS_NAMESPACE", - Value: bus.Namespace, - }, - corev1.EnvVar{ - Name: "BUS_NAME", - Value: bus.Name, + Name: "CLUSTER_BUS_NAME", + Value: clusterBus.Name, }, ) volumes := []corev1.Volume{} - if bus.Spec.Volumes != nil { - volumes = *bus.Spec.Volumes + if clusterBus.Spec.Volumes != nil { + volumes = *clusterBus.Spec.Volumes } return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: controller.BusDispatcherDeploymentName(bus.ObjectMeta.Name), + Name: controller.ClusterBusDispatcherDeploymentName(clusterBus.ObjectMeta.Name), Namespace: pkg.GetEventingSystemNamespace(), OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + *metav1.NewControllerRef(clusterBus, schema.GroupVersionKind{ Group: channelsv1alpha1.SchemeGroupVersion.Group, Version: channelsv1alpha1.SchemeGroupVersion.Version, - Kind: "Bus", + Kind: "ClusterBus", }), }, }, @@ -585,7 +581,7 @@ func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { Labels: labels, }, Spec: corev1.PodSpec{ - ServiceAccountName: busControllerServiceAccountName, + ServiceAccountName: clusterBusControllerServiceAccountName, Containers: []corev1.Container{ *container, }, @@ -596,39 +592,35 @@ func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { } } -// newProvisionerDeployment creates a new Deployment for a Bus resource. It also sets +// newProvisionerDeployment creates a new Deployment for a ClusterBus resource. It also sets // the appropriate OwnerReferences on the resource so handleObject can discover -// the Bus resource that 'owns' it. -func newProvisionerDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { +// the ClusterBus resource that 'owns' it. +func newProvisionerDeployment(clusterBus *channelsv1alpha1.ClusterBus) *appsv1.Deployment { labels := map[string]string{ - "bus": bus.Name, - "role": "provisioner", + "clusterBus": clusterBus.Name, + "role": "provisioner", } one := int32(1) - container := bus.Spec.Provisioner.DeepCopy() + container := clusterBus.Spec.Provisioner.DeepCopy() container.Env = append(container.Env, corev1.EnvVar{ - Name: "BUS_NAMESPACE", - Value: bus.Namespace, - }, - corev1.EnvVar{ - Name: "BUS_NAME", - Value: bus.Name, + Name: "CLUSTER_BUS_NAME", + Value: clusterBus.Name, }, ) volumes := []corev1.Volume{} - if bus.Spec.Volumes != nil { - volumes = *bus.Spec.Volumes + if clusterBus.Spec.Volumes != nil { + volumes = *clusterBus.Spec.Volumes } return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: controller.BusProvisionerDeploymentName(bus.ObjectMeta.Name), + Name: controller.ClusterBusProvisionerDeploymentName(clusterBus.ObjectMeta.Name), Namespace: pkg.GetEventingSystemNamespace(), OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + *metav1.NewControllerRef(clusterBus, schema.GroupVersionKind{ Group: channelsv1alpha1.SchemeGroupVersion.Group, Version: channelsv1alpha1.SchemeGroupVersion.Version, - Kind: "Bus", + Kind: "ClusterBus", }), }, }, @@ -642,7 +634,7 @@ func newProvisionerDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { Labels: labels, }, Spec: corev1.PodSpec{ - ServiceAccountName: busControllerServiceAccountName, + ServiceAccountName: clusterBusControllerServiceAccountName, Containers: []corev1.Container{ *container, }, diff --git a/pkg/controller/names.go b/pkg/controller/names.go index d3b72e21e0b..a92450f2c14 100644 --- a/pkg/controller/names.go +++ b/pkg/controller/names.go @@ -18,16 +18,16 @@ package controller import "fmt" -func BusProvisionerDeploymentName(busName string) string { - return fmt.Sprintf("%s-bus-provisioner", busName) +func ClusterBusProvisionerDeploymentName(clusterBusName string) string { + return fmt.Sprintf("%s-clusterbus-provisioner", clusterBusName) } -func BusDispatcherDeploymentName(busName string) string { - return fmt.Sprintf("%s-bus", busName) +func ClusterBusDispatcherDeploymentName(clusterBusName string) string { + return fmt.Sprintf("%s-clusterbus", clusterBusName) } -func BusDispatcherServiceName(busName string) string { - return fmt.Sprintf("%s-bus", busName) +func ClusterBusDispatcherServiceName(clusterBusName string) string { + return fmt.Sprintf("%s-clusterbus", clusterBusName) } func ChannelVirtualServiceName(channelName string) string { diff --git a/pkg/webhook/channel.go b/pkg/webhook/channel.go index 88879705580..19f6422267d 100644 --- a/pkg/webhook/channel.go +++ b/pkg/webhook/channel.go @@ -25,9 +25,9 @@ import ( ) var ( - errInvalidChannelInput = errors.New("failed to convert input into Channel") - errInvalidChannelBusMissing = errors.New("the Channel must reference a Bus") - errInvalidChannelBusMutation = errors.New("the Channel's Bus may not change") + errInvalidChannelInput = errors.New("failed to convert input into Channel") + errInvalidChannelClusterBusMissing = errors.New("the Channel must reference a ClusterBus") + errInvalidChannelClusterBusMutation = errors.New("the Channel's ClusterBus may not change") ) // ValidateChannel is Channel resource specific validation and mutation handler @@ -43,11 +43,11 @@ func ValidateChannel(ctx context.Context) ResourceCallback { } func validateChannel(old, new *v1alpha1.Channel) error { - if len(new.Spec.Bus) == 0 { - return errInvalidChannelBusMissing + if len(new.Spec.ClusterBus) == 0 { + return errInvalidChannelClusterBusMissing } - if old != nil && old.Spec.Bus != new.Spec.Bus { - return errInvalidChannelBusMutation + if old != nil && old.Spec.ClusterBus != new.Spec.ClusterBus { + return errInvalidChannelClusterBusMutation } return nil } diff --git a/pkg/webhook/channel_test.go b/pkg/webhook/channel_test.go index 21fc229eb2e..328cf3743d9 100644 --- a/pkg/webhook/channel_test.go +++ b/pkg/webhook/channel_test.go @@ -20,7 +20,7 @@ import ( ) func TestNewChannel(t *testing.T) { - c := createChannel(testChannelName, testBusName) + c := createChannel(testChannelName, testClusterBusName) if err := ValidateChannel(testCtx)(nil, nil, &c); err != nil { t.Errorf("Expected success, but failed with: %s", err) } @@ -32,26 +32,26 @@ func TestNewEmptyChannel(t *testing.T) { if err == nil { t.Errorf("Expected failure, but succeeded with: %+v", c) } - if e, a := errInvalidChannelBusMissing, err; e != a { + if e, a := errInvalidChannelClusterBusMissing, err; e != a { t.Errorf("Expected %s got %s", e, a) } } func TestChannelMutation(t *testing.T) { - c := createChannel(testChannelName, testBusName) + c := createChannel(testChannelName, testClusterBusName) if err := ValidateChannel(testCtx)(nil, &c, &c); err != nil { t.Errorf("Expected success, but failed with: %s", err) } } -func TestChannelBusMutation(t *testing.T) { +func TestChannelClusterBusMutation(t *testing.T) { old := createChannel(testChannelName, "stub") new := createChannel(testChannelName, "pubsub") err := ValidateChannel(testCtx)(nil, &old, &new) if err == nil { t.Errorf("Expected failure, but succeeded with: %+v %+v", old, new) } - if e, a := errInvalidChannelBusMutation, err; e != a { + if e, a := errInvalidChannelClusterBusMutation, err; e != a { t.Errorf("Expected %s got %s", e, a) } } diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go index bd24d1d19e8..59aa60268da 100644 --- a/pkg/webhook/webhook_test.go +++ b/pkg/webhook/webhook_test.go @@ -46,7 +46,7 @@ func newDefaultOptions() ControllerOptions { const ( testNamespace = "test-namespace" - testBusName = "test-bus" + testClusterBusName = "test-clusterbus" testChannelName = "test-channel" testSubscriptionName = "test-subscription" ) @@ -133,7 +133,7 @@ func TestInvalidNewChannelNameFails(t *testing.T) { Kind: metav1.GroupVersionKind{Kind: "Channel"}, } invalidName := "channel.example" - channel := createChannel(invalidName, "bus-name") + channel := createChannel(invalidName, testClusterBusName) marshaled, err := json.Marshal(channel) if err != nil { t.Fatalf("Failed to marshal channel: %s", err) @@ -142,7 +142,7 @@ func TestInvalidNewChannelNameFails(t *testing.T) { expectFailsWith(t, ac.admit(testCtx, req), "Invalid resource name") invalidName = strings.Repeat("a", 64) - channel = createChannel(invalidName, "bus-name") + channel = createChannel(invalidName, testClusterBusName) marshaled, err = json.Marshal(channel) if err != nil { t.Fatalf("Failed to marshal channel: %s", err) @@ -160,8 +160,8 @@ func TestValidNewChannelObject(t *testing.T) { func TestValidChannelNoChanges(t *testing.T) { _, ac := newNonRunningTestAdmissionController(t, newDefaultOptions()) - old := createChannel(testChannelName, testBusName) - new := createChannel(testChannelName, testBusName) + old := createChannel(testChannelName, testClusterBusName) + new := createChannel(testChannelName, testClusterBusName) resp := ac.admit(testCtx, createUpdateChannel(&old, &new)) expectAllowed(t, resp) expectPatches(t, resp.Patch, []jsonpatch.JsonPatchOperation{}) @@ -345,17 +345,17 @@ func createCreateChannel(channel v1alpha1.Channel) *admissionv1beta1.AdmissionRe } func createValidCreateChannel() *admissionv1beta1.AdmissionRequest { - return createCreateChannel(createChannel(testChannelName, testBusName)) + return createCreateChannel(createChannel(testChannelName, testClusterBusName)) } -func createChannel(channelName string, busName string) v1alpha1.Channel { +func createChannel(channelName string, clusterBusName string) v1alpha1.Channel { return v1alpha1.Channel{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: channelName, }, Spec: v1alpha1.ChannelSpec{ - Bus: busName, + ClusterBus: clusterBusName, }, } } diff --git a/sample/hello/hello-channel.yaml b/sample/hello/hello-channel.yaml index 7791e7168ed..849d1ccfc88 100644 --- a/sample/hello/hello-channel.yaml +++ b/sample/hello/hello-channel.yaml @@ -3,5 +3,4 @@ kind: Channel metadata: name: aloha spec: - bus: stub - \ No newline at end of file + clusterBus: stub From 651121432a3192eca7878139ef2c1fc9efc2f134 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Tue, 26 Jun 2018 20:27:03 -0400 Subject: [PATCH 3/7] Restore namespaced Bus support Channels can target either a Bus or a ClusterBus, but never both. --- cmd/controller/main.go | 2 + config/bus.yaml | 25 + config/buses/stub.yaml | 2 +- config/clusterrole.yaml | 4 +- config/clusterrolebinding.yaml | 2 +- pkg/apis/channels/v1alpha1/bus_types.go | 97 +++ pkg/apis/channels/v1alpha1/channel_types.go | 5 +- .../channels/v1alpha1/clusterbus_types.go | 30 +- pkg/apis/channels/v1alpha1/register.go | 2 + .../v1alpha1/zz_generated.deepcopy.go | 269 ++++-- pkg/buses/monitor.go | 144 ++-- pkg/buses/stub/main.go | 11 +- .../versioned/typed/channels/v1alpha1/bus.go | 157 ++++ .../channels/v1alpha1/channels_client.go | 5 + .../typed/channels/v1alpha1/fake/fake_bus.go | 128 +++ .../v1alpha1/fake/fake_channels_client.go | 4 + .../channels/v1alpha1/generated_expansion.go | 2 + .../externalversions/channels/v1alpha1/bus.go | 89 ++ .../channels/v1alpha1/interface.go | 7 + .../informers/externalversions/generic.go | 2 + pkg/client/listers/channels/v1alpha1/bus.go | 94 +++ .../channels/v1alpha1/expansion_generated.go | 8 + pkg/controller/bus/controller.go | 793 ++++++++++++++++++ pkg/controller/channel/controller.go | 14 +- pkg/controller/clusterbus/controller.go | 4 +- pkg/controller/names.go | 20 + pkg/webhook/channel.go | 16 +- pkg/webhook/channel_test.go | 35 +- pkg/webhook/webhook_test.go | 25 +- 29 files changed, 1795 insertions(+), 201 deletions(-) create mode 100644 config/bus.yaml create mode 100644 pkg/apis/channels/v1alpha1/bus_types.go create mode 100644 pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go create mode 100644 pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go create mode 100644 pkg/client/informers/externalversions/channels/v1alpha1/bus.go create mode 100644 pkg/client/listers/channels/v1alpha1/bus.go create mode 100644 pkg/controller/bus/controller.go diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 2ee291fe292..a79b1cd7bc1 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -36,6 +36,7 @@ import ( informers "github.com/knative/eventing/pkg/client/informers/externalversions" "github.com/knative/eventing/pkg/controller" "github.com/knative/eventing/pkg/controller/bind" + "github.com/knative/eventing/pkg/controller/bus" "github.com/knative/eventing/pkg/controller/channel" "github.com/knative/eventing/pkg/controller/clusterbus" "github.com/knative/eventing/pkg/signals" @@ -87,6 +88,7 @@ func main() { // Add new controllers here. ctors := []controller.Constructor{ bind.NewController, + bus.NewController, clusterbus.NewController, channel.NewController, } diff --git a/config/bus.yaml b/config/bus.yaml new file mode 100644 index 00000000000..fb55c1dcad3 --- /dev/null +++ b/config/bus.yaml @@ -0,0 +1,25 @@ +# Copyright 2018 The Knative Authors +# +# 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. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: buses.channels.knative.dev +spec: + scope: Namespaced + group: channels.knative.dev + version: v1alpha1 + names: + kind: Bus + plural: buses + singular: bus diff --git a/config/buses/stub.yaml b/config/buses/stub.yaml index e3e0f66c89e..d39f4c37aa7 100644 --- a/config/buses/stub.yaml +++ b/config/buses/stub.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. apiVersion: channels.knative.dev/v1alpha1 -kind: ClusterBus +kind: Bus metadata: name: stub spec: diff --git a/config/clusterrole.yaml b/config/clusterrole.yaml index e8b018ce9e9..e17c9fc5576 100644 --- a/config/clusterrole.yaml +++ b/config/clusterrole.yaml @@ -14,10 +14,10 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: knative-channels-clusterbus + name: knative-channels-bus rules: - apiGroups: ["channels.knative.dev"] - resources: ["clusterbuses", "channels", "subscriptions"] + resources: ["buses", "clusterbuses", "channels", "subscriptions"] verbs: ["get", "watch", "list"] - apiGroups: [""] resources: ["events"] diff --git a/config/clusterrolebinding.yaml b/config/clusterrolebinding.yaml index 13ec94f65fd..5cb663a2fcf 100644 --- a/config/clusterrolebinding.yaml +++ b/config/clusterrolebinding.yaml @@ -35,5 +35,5 @@ subjects: namespace: knative-eventing roleRef: kind: ClusterRole - name: knative-channels-clusterbus + name: knative-channels-bus apiGroup: rbac.authorization.k8s.io diff --git a/pkg/apis/channels/v1alpha1/bus_types.go b/pkg/apis/channels/v1alpha1/bus_types.go new file mode 100644 index 00000000000..51aa76e68c8 --- /dev/null +++ b/pkg/apis/channels/v1alpha1/bus_types.go @@ -0,0 +1,97 @@ +/* + * Copyright 2018 The Knative Authors + * + * 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. + */ + +package v1alpha1 + +import ( + "encoding/json" + + kapi "k8s.io/api/core/v1" + meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// +genclient +// +genclient:noStatus +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:defaulter-gen=true + +// Bus represents the clusterbuses.channels.knative.dev CRD +type Bus struct { + meta_v1.TypeMeta `json:",inline"` + meta_v1.ObjectMeta `json:"metadata"` + Spec BusSpec `json:"spec"` + Status *BusStatus `json:"status,omitempty"` +} + +// BusSpec (what the user wants) for a clusterbus +type BusSpec struct { + + // Parameters exposed by the clusterbus for channels and subscriptions + Parameters *BusParameters `json:"parameters,omitempty"` + + // Provisioner container definition to manage channels on the clusterbus. + Provisioner *kapi.Container `json:"provisioner,omitempty"` + + // Dispatcher container definition to use for the clusterbus data plane. + Dispatcher kapi.Container `json:"dispatcher"` + + // Volumes to be mounted inside the provisioner or dispatcher containers + Volumes *[]kapi.Volume `json:"volumes,omitempty"` +} + +// BusParameters parameters exposed by the clusterbus +type BusParameters struct { + + // Channel configuration params for channels on the clusterbus + Channel *[]Parameter `json:"channel,omitempty"` + + // Subscription configuration params for subscriptions on the clusterbus + Subscription *[]Parameter `json:"subscription,omitempty"` +} + +// BusStatus (computed) for a clusterbus +type BusStatus struct { +} + +func (b *Bus) BacksChannel(channel *Channel) bool { + return b.Namespace == channel.Namespace && b.Name == channel.Spec.Bus +} + +func (b *Bus) GetSpec() *BusSpec { + return &b.Spec +} + +func (b *Bus) GetSpecJSON() ([]byte, error) { + return json.Marshal(b.Spec) +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// BusList returned in list operations +type BusList struct { + meta_v1.TypeMeta `json:",inline"` + meta_v1.ListMeta `json:"metadata"` + Items []Bus `json:"items"` +} + +// GenericBus may be backed by Bus or ClusterBus +type GenericBus interface { + runtime.Object + meta_v1.ObjectMetaAccessor + BacksChannel(channel *Channel) bool + GetSpec() *BusSpec +} diff --git a/pkg/apis/channels/v1alpha1/channel_types.go b/pkg/apis/channels/v1alpha1/channel_types.go index f1d4329d71e..72064ed74b6 100644 --- a/pkg/apis/channels/v1alpha1/channel_types.go +++ b/pkg/apis/channels/v1alpha1/channel_types.go @@ -38,7 +38,10 @@ type Channel struct { // ChannelSpec (what the user wants) for a channel type ChannelSpec struct { - // ClusterBus name of the clusterbus backing this channel + // Bus name of the bus backing this channel (mutually exclusive with ClusterBus) + Bus string `json:"bus"` + + // ClusterBus name of the clusterbus backing this channel (mutually exclusive with Bus) ClusterBus string `json:"clusterBus"` // Arguments configuration arguments for the channel diff --git a/pkg/apis/channels/v1alpha1/clusterbus_types.go b/pkg/apis/channels/v1alpha1/clusterbus_types.go index 48b65071c40..ce74f791268 100644 --- a/pkg/apis/channels/v1alpha1/clusterbus_types.go +++ b/pkg/apis/channels/v1alpha1/clusterbus_types.go @@ -19,7 +19,6 @@ package v1alpha1 import ( "encoding/json" - kapi "k8s.io/api/core/v1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -38,33 +37,18 @@ type ClusterBus struct { } // ClusterBusSpec (what the user wants) for a clusterbus -type ClusterBusSpec struct { +type ClusterBusSpec = BusSpec - // Parameters exposed by the clusterbus for channels and subscriptions - Parameters *ClusterBusParameters `json:"parameters,omitempty"` - - // Provisioner container definition to manage channels on the clusterbus. - Provisioner *kapi.Container `json:"provisioner,omitempty"` - - // Dispatcher container definition to use for the clusterbus data plane. - Dispatcher kapi.Container `json:"dispatcher"` - - // Volumes to be mounted inside the provisioner or dispatcher containers - Volumes *[]kapi.Volume `json:"volumes,omitempty"` +// ClusterBusStatus (computed) for a clusterbus +type ClusterBusStatus struct { } -// ClusterBusParameters parameters exposed by the clusterbus -type ClusterBusParameters struct { - - // Channel configuration params for channels on the clusterbus - Channel *[]Parameter `json:"channel,omitempty"` - - // Subscription configuration params for subscriptions on the clusterbus - Subscription *[]Parameter `json:"subscription,omitempty"` +func (b *ClusterBus) BacksChannel(channel *Channel) bool { + return len(b.Namespace) == 0 && b.Name == channel.Spec.ClusterBus } -// ClusterBusStatus (computed) for a clusterbus -type ClusterBusStatus struct { +func (b *ClusterBus) GetSpec() *BusSpec { + return &b.Spec } func (b *ClusterBus) GetSpecJSON() ([]byte, error) { diff --git a/pkg/apis/channels/v1alpha1/register.go b/pkg/apis/channels/v1alpha1/register.go index 821e451651f..32ce1eb5370 100644 --- a/pkg/apis/channels/v1alpha1/register.go +++ b/pkg/apis/channels/v1alpha1/register.go @@ -45,6 +45,8 @@ var ( // Adds the list of known types to Scheme. func addKnownTypes(scheme *runtime.Scheme) error { scheme.AddKnownTypes(SchemeGroupVersion, + &Bus{}, + &BusList{}, &ClusterBus{}, &ClusterBusList{}, &Channel{}, diff --git a/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go index 65ad3328959..0adb2a6cb19 100644 --- a/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go @@ -42,7 +42,7 @@ func (in *Argument) DeepCopy() *Argument { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Channel) DeepCopyInto(out *Channel) { +func (in *Bus) DeepCopyInto(out *Bus) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -52,25 +52,25 @@ func (in *Channel) DeepCopyInto(out *Channel) { if *in == nil { *out = nil } else { - *out = new(ChannelStatus) + *out = new(BusStatus) **out = **in } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Channel. -func (in *Channel) DeepCopy() *Channel { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Bus. +func (in *Bus) DeepCopy() *Bus { if in == nil { return nil } - out := new(Channel) + out := new(Bus) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Channel) DeepCopyObject() runtime.Object { +func (in *Bus) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -78,13 +78,13 @@ func (in *Channel) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelList) DeepCopyInto(out *ChannelList) { +func (in *BusList) DeepCopyInto(out *BusList) { *out = *in out.TypeMeta = in.TypeMeta out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]Channel, len(*in)) + *out = make([]Bus, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -92,18 +92,18 @@ func (in *ChannelList) DeepCopyInto(out *ChannelList) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelList. -func (in *ChannelList) DeepCopy() *ChannelList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusList. +func (in *BusList) DeepCopy() *BusList { if in == nil { return nil } - out := new(ChannelList) + out := new(BusList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ChannelList) DeepCopyObject() runtime.Object { +func (in *BusList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -111,52 +111,119 @@ func (in *ChannelList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelSpec) DeepCopyInto(out *ChannelSpec) { +func (in *BusParameters) DeepCopyInto(out *BusParameters) { *out = *in - if in.Arguments != nil { - in, out := &in.Arguments, &out.Arguments + if in.Channel != nil { + in, out := &in.Channel, &out.Channel if *in == nil { *out = nil } else { - *out = new([]Argument) + *out = new([]Parameter) if **in != nil { in, out := *in, *out - *out = make([]Argument, len(*in)) - copy(*out, *in) + *out = make([]Parameter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + } + if in.Subscription != nil { + in, out := &in.Subscription, &out.Subscription + if *in == nil { + *out = nil + } else { + *out = new([]Parameter) + if **in != nil { + in, out := *in, *out + *out = make([]Parameter, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } } } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelSpec. -func (in *ChannelSpec) DeepCopy() *ChannelSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusParameters. +func (in *BusParameters) DeepCopy() *BusParameters { if in == nil { return nil } - out := new(ChannelSpec) + out := new(BusParameters) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ChannelStatus) DeepCopyInto(out *ChannelStatus) { +func (in *BusSpec) DeepCopyInto(out *BusSpec) { + *out = *in + if in.Parameters != nil { + in, out := &in.Parameters, &out.Parameters + if *in == nil { + *out = nil + } else { + *out = new(BusParameters) + (*in).DeepCopyInto(*out) + } + } + if in.Provisioner != nil { + in, out := &in.Provisioner, &out.Provisioner + if *in == nil { + *out = nil + } else { + *out = new(v1.Container) + (*in).DeepCopyInto(*out) + } + } + in.Dispatcher.DeepCopyInto(&out.Dispatcher) + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + if *in == nil { + *out = nil + } else { + *out = new([]v1.Volume) + if **in != nil { + in, out := *in, *out + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusSpec. +func (in *BusSpec) DeepCopy() *BusSpec { + if in == nil { + return nil + } + out := new(BusSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BusStatus) DeepCopyInto(out *BusStatus) { *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelStatus. -func (in *ChannelStatus) DeepCopy() *ChannelStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BusStatus. +func (in *BusStatus) DeepCopy() *BusStatus { if in == nil { return nil } - out := new(ChannelStatus) + out := new(BusStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterBus) DeepCopyInto(out *ClusterBus) { +func (in *Channel) DeepCopyInto(out *Channel) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -166,25 +233,25 @@ func (in *ClusterBus) DeepCopyInto(out *ClusterBus) { if *in == nil { *out = nil } else { - *out = new(ClusterBusStatus) + *out = new(ChannelStatus) **out = **in } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBus. -func (in *ClusterBus) DeepCopy() *ClusterBus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Channel. +func (in *Channel) DeepCopy() *Channel { if in == nil { return nil } - out := new(ClusterBus) + out := new(Channel) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterBus) DeepCopyObject() runtime.Object { +func (in *Channel) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -192,13 +259,13 @@ func (in *ClusterBus) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterBusList) DeepCopyInto(out *ClusterBusList) { +func (in *ChannelList) DeepCopyInto(out *ChannelList) { *out = *in out.TypeMeta = in.TypeMeta out.ListMeta = in.ListMeta if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]ClusterBus, len(*in)) + *out = make([]Channel, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -206,18 +273,18 @@ func (in *ClusterBusList) DeepCopyInto(out *ClusterBusList) { return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusList. -func (in *ClusterBusList) DeepCopy() *ClusterBusList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelList. +func (in *ChannelList) DeepCopy() *ChannelList { if in == nil { return nil } - out := new(ClusterBusList) + out := new(ChannelList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *ClusterBusList) DeepCopyObject() runtime.Object { +func (in *ChannelList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -225,101 +292,119 @@ func (in *ClusterBusList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterBusParameters) DeepCopyInto(out *ClusterBusParameters) { +func (in *ChannelSpec) DeepCopyInto(out *ChannelSpec) { *out = *in - if in.Channel != nil { - in, out := &in.Channel, &out.Channel + if in.Arguments != nil { + in, out := &in.Arguments, &out.Arguments if *in == nil { *out = nil } else { - *out = new([]Parameter) + *out = new([]Argument) if **in != nil { in, out := *in, *out - *out = make([]Parameter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } + *out = make([]Argument, len(*in)) + copy(*out, *in) } } } - if in.Subscription != nil { - in, out := &in.Subscription, &out.Subscription - if *in == nil { - *out = nil - } else { - *out = new([]Parameter) - if **in != nil { - in, out := *in, *out - *out = make([]Parameter, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelSpec. +func (in *ChannelSpec) DeepCopy() *ChannelSpec { + if in == nil { + return nil } + out := new(ChannelSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChannelStatus) DeepCopyInto(out *ChannelStatus) { + *out = *in return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusParameters. -func (in *ClusterBusParameters) DeepCopy() *ClusterBusParameters { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChannelStatus. +func (in *ChannelStatus) DeepCopy() *ChannelStatus { if in == nil { return nil } - out := new(ClusterBusParameters) + out := new(ChannelStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClusterBusSpec) DeepCopyInto(out *ClusterBusSpec) { +func (in *ClusterBus) DeepCopyInto(out *ClusterBus) { *out = *in - if in.Parameters != nil { - in, out := &in.Parameters, &out.Parameters + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + if in.Status != nil { + in, out := &in.Status, &out.Status if *in == nil { *out = nil } else { - *out = new(ClusterBusParameters) - (*in).DeepCopyInto(*out) + *out = new(ClusterBusStatus) + **out = **in } } - if in.Provisioner != nil { - in, out := &in.Provisioner, &out.Provisioner - if *in == nil { - *out = nil - } else { - *out = new(v1.Container) - (*in).DeepCopyInto(*out) - } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBus. +func (in *ClusterBus) DeepCopy() *ClusterBus { + if in == nil { + return nil } - in.Dispatcher.DeepCopyInto(&out.Dispatcher) - if in.Volumes != nil { - in, out := &in.Volumes, &out.Volumes - if *in == nil { - *out = nil - } else { - *out = new([]v1.Volume) - if **in != nil { - in, out := *in, *out - *out = make([]v1.Volume, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + out := new(ClusterBus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBus) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterBusList) DeepCopyInto(out *ClusterBusList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterBus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) } } return } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusSpec. -func (in *ClusterBusSpec) DeepCopy() *ClusterBusSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterBusList. +func (in *ClusterBusList) DeepCopy() *ClusterBusList { if in == nil { return nil } - out := new(ClusterBusSpec) + out := new(ClusterBusList) in.DeepCopyInto(out) return out } +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterBusList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterBusStatus) DeepCopyInto(out *ClusterBusStatus) { *out = *in diff --git a/pkg/buses/monitor.go b/pkg/buses/monitor.go index eb565653f8c..8e7e95dc65f 100644 --- a/pkg/buses/monitor.go +++ b/pkg/buses/monitor.go @@ -47,6 +47,7 @@ const ( Dispatcher = "dispatcher" Provisioner = "provisioner" + busKind = "Bus" clusterBusKind = "ClusterBus" channelKind = "Channel" subscriptionKind = "Subscription" @@ -60,9 +61,11 @@ const ( // Monitor utility to manage channels and subscriptions for a clusterbus type Monitor struct { - clusterBus *channelsv1alpha1.ClusterBus + bus channelsv1alpha1.GenericBus handler MonitorEventHandlerFuncs informerFactory informers.SharedInformerFactory + busesLister listers.BusLister + busesSynced cache.InformerSynced clusterBusesLister listers.ClusterBusLister clusterBusesSynced cache.InformerSynced channelsLister listers.ChannelLister @@ -89,20 +92,20 @@ type Attributes = map[string]string // MonitorEventHandlerFuncs handler functions for channel and subscription provisioning type MonitorEventHandlerFuncs struct { - ClusterBusFunc func(clusterBus *channelsv1alpha1.ClusterBus) error + BusFunc func(bus channelsv1alpha1.GenericBus) error ProvisionFunc func(channel *channelsv1alpha1.Channel, attributes Attributes) error UnprovisionFunc func(channel *channelsv1alpha1.Channel) error SubscribeFunc func(subscription *channelsv1alpha1.Subscription, attributes Attributes) error UnsubscribeFunc func(subscription *channelsv1alpha1.Subscription) error } -func (h MonitorEventHandlerFuncs) onClusterBus(clusterBus *channelsv1alpha1.ClusterBus, monitor *Monitor) error { - if h.ClusterBusFunc != nil { - err := h.ClusterBusFunc(clusterBus) +func (h MonitorEventHandlerFuncs) onBus(bus channelsv1alpha1.GenericBus, monitor *Monitor) error { + if h.BusFunc != nil { + err := h.BusFunc(bus) if err != nil { - monitor.recorder.Eventf(clusterBus, corev1.EventTypeWarning, errResourceSync, "Error syncing ClusterBus: %s", err) + monitor.recorder.Eventf(bus, corev1.EventTypeWarning, errResourceSync, "Error syncing Bus: %s", err) } else { - monitor.recorder.Event(clusterBus, corev1.EventTypeNormal, successSynced, "ClusterBus synched successfully") + monitor.recorder.Event(bus, corev1.EventTypeNormal, successSynced, "Bus synched successfully") } return err } @@ -199,6 +202,7 @@ func NewMonitor( } informerFactory := informers.NewSharedInformerFactory(client, time.Second*30) + busInformer := informerFactory.Channels().V1alpha1().Buses() clusterBusInformer := informerFactory.Channels().V1alpha1().ClusterBuses() channelInformer := informerFactory.Channels().V1alpha1().Channels() subscriptionInformer := informerFactory.Channels().V1alpha1().Subscriptions() @@ -214,10 +218,12 @@ func NewMonitor( recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: component}) monitor := &Monitor{ - clusterBus: nil, - handler: handler, + bus: nil, + handler: handler, informerFactory: informerFactory, + busesLister: busInformer.Lister(), + busesSynced: busInformer.Informer().HasSynced, clusterBusesLister: clusterBusInformer.Lister(), clusterBusesSynced: clusterBusInformer.Informer().HasSynced, channelsLister: channelInformer.Lister(), @@ -322,17 +328,18 @@ func (m *Monitor) Subscription(name string, namespace string) *channelsv1alpha1. } // Subscriptions for a channel name and namespace -func (m *Monitor) Subscriptions(channel string, namespace string) *[]channelsv1alpha1.SubscriptionSpec { - channelKey := makeChannelKeyWithNames(namespace, channel) +func (m *Monitor) Subscriptions(channelName string, namespace string) *[]channelsv1alpha1.SubscriptionSpec { + channelKey := makeChannelKeyWithNames(namespace, channelName) summary := m.getChannelSummary(channelKey) + channel := m.Channel(channelName, namespace) - if summary == nil || summary.Channel == nil { + if summary == nil || summary.Channel == nil || channel == nil { // the channel is unknown return nil } - if summary.Channel.ClusterBus != m.clusterBus.Name { - // the channel is not for this clusterbus + if !m.bus.BacksChannel(channel) { + // the channel is not for this bus return nil } @@ -347,7 +354,7 @@ func (m *Monitor) Subscriptions(channel string, namespace string) *[]channelsv1a } func (m *Monitor) channelAttributes(channel channelsv1alpha1.ChannelSpec) (Attributes, error) { - clusterBusParameters := m.clusterBus.Spec.Parameters + clusterBusParameters := m.bus.GetSpec().Parameters var parameters *[]channelsv1alpha1.Parameter if clusterBusParameters != nil { parameters = clusterBusParameters.Channel @@ -356,7 +363,7 @@ func (m *Monitor) channelAttributes(channel channelsv1alpha1.ChannelSpec) (Attri } func (m *Monitor) subscriptionAttributes(subscription channelsv1alpha1.SubscriptionSpec) (Attributes, error) { - clusterBusParameters := m.clusterBus.Spec.Parameters + clusterBusParameters := m.bus.GetSpec().Parameters var parameters *[]channelsv1alpha1.Parameter if clusterBusParameters != nil { parameters = clusterBusParameters.Subscription @@ -414,7 +421,7 @@ func (m *Monitor) RequeueSubscription(subscription *channelsv1alpha1.Subscriptio // as syncing informer caches and starting workers. It will block until stopCh // is closed, at which point it will shutdown the workqueue and wait for // workers to finish processing their current work items. -func (m *Monitor) Run(clusterBusName string, threadiness int, stopCh <-chan struct{}) error { +func (m *Monitor) Run(busName, busNamespace string, threadiness int, stopCh <-chan struct{}) error { defer runtime.HandleCrash() defer m.workqueue.ShutDown() @@ -424,15 +431,25 @@ func (m *Monitor) Run(clusterBusName string, threadiness int, stopCh <-chan stru // Wait for the caches to be synced before starting workers glog.Info("Waiting for informer caches to sync") - if ok := cache.WaitForCacheSync(stopCh, m.clusterBusesSynced, m.channelsSynced, m.subscriptionsSynced); !ok { + if ok := cache.WaitForCacheSync(stopCh, m.busesSynced, m.clusterBusesSynced, m.channelsSynced, m.subscriptionsSynced); !ok { return fmt.Errorf("failed to wait for caches to sync") } - clusterBus, err := m.clusterBusesLister.Get(clusterBusName) - if err != nil { - glog.Fatalf("Unknown clusterbus %q", clusterBusName) + if len(busNamespace) == 0 { + // monitor is for a ClusterBus + clusterBus, err := m.clusterBusesLister.Get(busName) + if err != nil { + glog.Fatalf("Unknown clusterbus %q", busName) + } + m.bus = clusterBus + } else { + // monitor is for a namespaced Bus + bus, err := m.busesLister.Buses(busNamespace).Get(busName) + if err != nil { + glog.Fatalf("Unknown bus '%s/%s'", busNamespace, busName) + } + m.bus = bus } - m.clusterBus = clusterBus glog.Info("Starting workers") // Launch two workers to process ClusterBus resources @@ -488,8 +505,7 @@ func (m *Monitor) processNextWorkItem() bool { runtime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) return nil } - // Run the syncHandler, passing it the name string of the - // ClusterBus resource to be synced. + // Run the syncHandler, passing it the name string of the resource to be synced. if err := m.syncHandler(key); err != nil { m.workqueue.AddRateLimited(obj) return fmt.Errorf("error syncing monitor '%s': %s", key, err.Error()) @@ -520,12 +536,14 @@ func (m *Monitor) syncHandler(key string) error { return nil } - if m.clusterBus == nil && kind != clusterBusKind { - // don't attempt tp sync until we have seen the clusterbus for this monitor - return fmt.Errorf("Unknown clusterbus for monitor") + if m.bus == nil && !(kind == busKind || kind == clusterBusKind) { + // don't attempt to sync until we have seen the bus for this monitor + return fmt.Errorf("Unknown bus for monitor") } switch kind { + case busKind: + err = m.syncBus(namespace, name) case clusterBusKind: err = m.syncClusterBus(name) case channelKind: @@ -544,6 +562,28 @@ func (m *Monitor) syncHandler(key string) error { return nil } +func (m *Monitor) syncBus(namespace string, name string) error { + // Get the Bus resource with this namespace/name + bus, err := m.busesLister.Buses(namespace).Get(name) + if err != nil { + // The Bus resource may no longer exist + if errors.IsNotFound(err) { + // nothing to do + return nil + } + + return err + } + + // Sync the Bus + err = m.createOrUpdateBus(bus) + if err != nil { + return err + } + + return nil +} + func (m *Monitor) syncClusterBus(name string) error { // Get the ClusterBus resource with this name clusterBus, err := m.clusterBusesLister.Get(name) @@ -635,15 +675,15 @@ func (m *Monitor) getOrCreateChannelSummary(key channelKey) *channelSummary { return summary } -func (m *Monitor) createOrUpdateClusterBus(clusterBus *channelsv1alpha1.ClusterBus) error { - if clusterBus.Name != m.clusterBus.Name { - // this is not our clusterbus +func (m *Monitor) createOrUpdateBus(bus *channelsv1alpha1.Bus) error { + if bus.Namespace == m.bus.GetObjectMeta().GetNamespace() && bus.Name != m.bus.GetObjectMeta().GetName() { + // this is not our bus return nil } - if !reflect.DeepEqual(m.clusterBus.Spec, clusterBus.Spec) { - m.clusterBus = clusterBus - err := m.handler.onClusterBus(clusterBus, m) + if !reflect.DeepEqual(m.bus.GetSpec(), bus.Spec) { + m.bus = bus + err := m.handler.onBus(bus, m) if err != nil { return err } @@ -652,8 +692,21 @@ func (m *Monitor) createOrUpdateClusterBus(clusterBus *channelsv1alpha1.ClusterB return nil } -func (m *Monitor) isChannelForBus(channel *channelsv1alpha1.Channel) bool { - return channel.Spec.ClusterBus == m.clusterBus.Name +func (m *Monitor) createOrUpdateClusterBus(clusterBus *channelsv1alpha1.ClusterBus) error { + if clusterBus.Name != m.bus.GetObjectMeta().GetName() { + // this is not our clusterbus + return nil + } + + if !reflect.DeepEqual(m.bus.GetSpec(), clusterBus.Spec) { + m.bus = clusterBus + err := m.handler.onBus(clusterBus, m) + if err != nil { + return err + } + } + + return nil } func (m *Monitor) createOrUpdateChannel(channel *channelsv1alpha1.Channel) error { @@ -666,7 +719,7 @@ func (m *Monitor) createOrUpdateChannel(channel *channelsv1alpha1.Channel) error summary.Channel = new m.mutex.Unlock() - if m.isChannelForBus(channel) && !reflect.DeepEqual(old, new) { + if m.bus.BacksChannel(channel) && !reflect.DeepEqual(old, new) { err := m.handler.onProvision(channel, m) if err != nil { return err @@ -699,24 +752,12 @@ func (m *Monitor) removeChannel(namespace string, name string) error { return nil } -func (m *Monitor) isChannelKnown(subscription *channelsv1alpha1.Subscription) bool { - channelKey := makeChannelKeyFromSubscription(subscription) - summary := m.getChannelSummary(channelKey) - return summary != nil && summary.Channel != nil -} - func (m *Monitor) isSubscriptionProvisioned(subscription *channelsv1alpha1.Subscription) bool { subscriptionKey := makeSubscriptionKeyFromSubscription(subscription) _, ok := m.provisionedSubscriptions[subscriptionKey] return ok } -func (m *Monitor) isSubscriptionForBus(subscription *channelsv1alpha1.Subscription) bool { - channelKey := makeChannelKeyFromSubscription(subscription) - summary := m.getChannelSummary(channelKey) - return summary != nil && summary.Channel != nil && summary.Channel.ClusterBus == m.clusterBus.Name -} - func (m *Monitor) createOrUpdateSubscription(subscription *channelsv1alpha1.Subscription) error { subscriptionKey := makeSubscriptionKeyFromSubscription(subscription) channelKey := makeChannelKeyFromSubscription(subscription) @@ -730,10 +771,11 @@ func (m *Monitor) createOrUpdateSubscription(subscription *channelsv1alpha1.Subs summary.Subscriptions[subscriptionKey] = new m.mutex.Unlock() - if !m.isChannelKnown(subscription) { - return fmt.Errorf("Unknown channel %q for subscription", subscription.Spec.Channel) + channel := m.Channel(subscription.Spec.Channel, subscription.Namespace) + if channel == nil { + return fmt.Errorf("unknown channel %q for subscription", subscription.Spec.Channel) } - if !m.isSubscriptionForBus(subscription) { + if !m.bus.BacksChannel(channel) { return nil } diff --git a/pkg/buses/stub/main.go b/pkg/buses/stub/main.go index d69ab7b9983..64031411905 100644 --- a/pkg/buses/stub/main.go +++ b/pkg/buses/stub/main.go @@ -70,7 +70,7 @@ func (b *StubBus) handleEvent(res http.ResponseWriter, req *http.Request) { } safeHeaders := b.safeHeaders(req.Header) - safeHeaders.Set("x-clusterbus", b.name) + safeHeaders.Set("x-bus", b.name) safeHeaders.Set("x-channel", channel) for _, subscription := range *subscriptions { subscriber := b.resolveSubscriber(subscription, namespace) @@ -149,8 +149,9 @@ func main() { // set up signals so we handle the first shutdown signal gracefully stopCh := signals.SetupSignalHandler() - clusterBusName := os.Getenv("CLUSTER_BUS_NAME") - component := fmt.Sprintf("%s-%s", clusterBusName, buses.Dispatcher) + busNamespace := os.Getenv("BUS_NAMESPACE") + busName := os.Getenv("BUS_NAME") + component := fmt.Sprintf("%s-%s", busName, buses.Dispatcher) monitor := buses.NewMonitor(component, masterURL, kubeconfig, buses.MonitorEventHandlerFuncs{ ProvisionFunc: func(channel *channelsv1alpha1.Channel, attributes buses.Attributes) error { @@ -170,10 +171,10 @@ func main() { return nil }, }) - bus := NewStubBus(clusterBusName, monitor) + bus := NewStubBus(busName, monitor) go func() { - if err := monitor.Run(clusterBusName, threadsPerMonitor, stopCh); err != nil { + if err := monitor.Run(busName, busNamespace, threadsPerMonitor, stopCh); err != nil { glog.Fatalf("Error running monitor: %s", err.Error()) } }() diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go new file mode 100644 index 00000000000..12450331d50 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/bus.go @@ -0,0 +1,157 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + scheme "github.com/knative/eventing/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// BusesGetter has a method to return a BusInterface. +// A group's client should implement this interface. +type BusesGetter interface { + Buses(namespace string) BusInterface +} + +// BusInterface has methods to work with Bus resources. +type BusInterface interface { + Create(*v1alpha1.Bus) (*v1alpha1.Bus, error) + Update(*v1alpha1.Bus) (*v1alpha1.Bus, error) + Delete(name string, options *v1.DeleteOptions) error + DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error + Get(name string, options v1.GetOptions) (*v1alpha1.Bus, error) + List(opts v1.ListOptions) (*v1alpha1.BusList, error) + Watch(opts v1.ListOptions) (watch.Interface, error) + Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) + BusExpansion +} + +// buses implements BusInterface +type buses struct { + client rest.Interface + ns string +} + +// newBuses returns a Buses +func newBuses(c *ChannelsV1alpha1Client, namespace string) *buses { + return &buses{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the bus, and returns the corresponding bus object, and an error if there is any. +func (c *buses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, err error) { + result = &v1alpha1.Bus{} + err = c.client.Get(). + Namespace(c.ns). + Resource("buses"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of Buses that match those selectors. +func (c *buses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) { + result = &v1alpha1.BusList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("buses"). + VersionedParams(&opts, scheme.ParameterCodec). + Do(). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested buses. +func (c *buses) Watch(opts v1.ListOptions) (watch.Interface, error) { + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("buses"). + VersionedParams(&opts, scheme.ParameterCodec). + Watch() +} + +// Create takes the representation of a bus and creates it. Returns the server's representation of the bus, and an error, if there is any. +func (c *buses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { + result = &v1alpha1.Bus{} + err = c.client.Post(). + Namespace(c.ns). + Resource("buses"). + Body(bus). + Do(). + Into(result) + return +} + +// Update takes the representation of a bus and updates it. Returns the server's representation of the bus, and an error, if there is any. +func (c *buses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { + result = &v1alpha1.Bus{} + err = c.client.Put(). + Namespace(c.ns). + Resource("buses"). + Name(bus.Name). + Body(bus). + Do(). + Into(result) + return +} + +// Delete takes name of the bus and deletes it. Returns an error if one occurs. +func (c *buses) Delete(name string, options *v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("buses"). + Name(name). + Body(options). + Do(). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *buses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("buses"). + VersionedParams(&listOptions, scheme.ParameterCodec). + Body(options). + Do(). + Error() +} + +// Patch applies the patch and returns the patched bus. +func (c *buses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) { + result = &v1alpha1.Bus{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("buses"). + SubResource(subresources...). + Name(name). + Body(data). + Do(). + Into(result) + return +} diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go index 280c8e88e40..d99d1390cef 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/channels_client.go @@ -27,6 +27,7 @@ import ( type ChannelsV1alpha1Interface interface { RESTClient() rest.Interface + BusesGetter ChannelsGetter ClusterBusesGetter SubscriptionsGetter @@ -37,6 +38,10 @@ type ChannelsV1alpha1Client struct { restClient rest.Interface } +func (c *ChannelsV1alpha1Client) Buses(namespace string) BusInterface { + return newBuses(c, namespace) +} + func (c *ChannelsV1alpha1Client) Channels(namespace string) ChannelInterface { return newChannels(c, namespace) } diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go new file mode 100644 index 00000000000..c49b944bf13 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_bus.go @@ -0,0 +1,128 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeBuses implements BusInterface +type FakeBuses struct { + Fake *FakeChannelsV1alpha1 + ns string +} + +var busesResource = schema.GroupVersionResource{Group: "channels.knative.dev", Version: "v1alpha1", Resource: "buses"} + +var busesKind = schema.GroupVersionKind{Group: "channels.knative.dev", Version: "v1alpha1", Kind: "Bus"} + +// Get takes name of the bus, and returns the corresponding bus object, and an error if there is any. +func (c *FakeBuses) Get(name string, options v1.GetOptions) (result *v1alpha1.Bus, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(busesResource, c.ns, name), &v1alpha1.Bus{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Bus), err +} + +// List takes label and field selectors, and returns the list of Buses that match those selectors. +func (c *FakeBuses) List(opts v1.ListOptions) (result *v1alpha1.BusList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(busesResource, busesKind, c.ns, opts), &v1alpha1.BusList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.BusList{} + for _, item := range obj.(*v1alpha1.BusList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested buses. +func (c *FakeBuses) Watch(opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(busesResource, c.ns, opts)) + +} + +// Create takes the representation of a bus and creates it. Returns the server's representation of the bus, and an error, if there is any. +func (c *FakeBuses) Create(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(busesResource, c.ns, bus), &v1alpha1.Bus{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Bus), err +} + +// Update takes the representation of a bus and updates it. Returns the server's representation of the bus, and an error, if there is any. +func (c *FakeBuses) Update(bus *v1alpha1.Bus) (result *v1alpha1.Bus, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(busesResource, c.ns, bus), &v1alpha1.Bus{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Bus), err +} + +// Delete takes name of the bus and deletes it. Returns an error if one occurs. +func (c *FakeBuses) Delete(name string, options *v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(busesResource, c.ns, name), &v1alpha1.Bus{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeBuses) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(busesResource, c.ns, listOptions) + + _, err := c.Fake.Invokes(action, &v1alpha1.BusList{}) + return err +} + +// Patch applies the patch and returns the patched bus. +func (c *FakeBuses) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.Bus, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(busesResource, c.ns, name, data, subresources...), &v1alpha1.Bus{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.Bus), err +} diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go index a345ec17a3c..3c498bd6dcb 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/fake/fake_channels_client.go @@ -28,6 +28,10 @@ type FakeChannelsV1alpha1 struct { *testing.Fake } +func (c *FakeChannelsV1alpha1) Buses(namespace string) v1alpha1.BusInterface { + return &FakeBuses{c, namespace} +} + func (c *FakeChannelsV1alpha1) Channels(namespace string) v1alpha1.ChannelInterface { return &FakeChannels{c, namespace} } diff --git a/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go index 32b96d444e4..8979577193d 100644 --- a/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/channels/v1alpha1/generated_expansion.go @@ -18,6 +18,8 @@ limitations under the License. package v1alpha1 +type BusExpansion interface{} + type ChannelExpansion interface{} type ClusterBusExpansion interface{} diff --git a/pkg/client/informers/externalversions/channels/v1alpha1/bus.go b/pkg/client/informers/externalversions/channels/v1alpha1/bus.go new file mode 100644 index 00000000000..43ee3cffb56 --- /dev/null +++ b/pkg/client/informers/externalversions/channels/v1alpha1/bus.go @@ -0,0 +1,89 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + time "time" + + channels_v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + versioned "github.com/knative/eventing/pkg/client/clientset/versioned" + internalinterfaces "github.com/knative/eventing/pkg/client/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/knative/eventing/pkg/client/listers/channels/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// BusInformer provides access to a shared informer and lister for +// Buses. +type BusInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.BusLister +} + +type busInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewBusInformer constructs a new informer for Bus type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewBusInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredBusInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredBusInformer constructs a new informer for Bus type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredBusInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ChannelsV1alpha1().Buses(namespace).List(options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.ChannelsV1alpha1().Buses(namespace).Watch(options) + }, + }, + &channels_v1alpha1.Bus{}, + resyncPeriod, + indexers, + ) +} + +func (f *busInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredBusInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *busInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&channels_v1alpha1.Bus{}, f.defaultInformer) +} + +func (f *busInformer) Lister() v1alpha1.BusLister { + return v1alpha1.NewBusLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/informers/externalversions/channels/v1alpha1/interface.go b/pkg/client/informers/externalversions/channels/v1alpha1/interface.go index 6dd9ddc97a0..0831ac85fba 100644 --- a/pkg/client/informers/externalversions/channels/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/channels/v1alpha1/interface.go @@ -24,6 +24,8 @@ import ( // Interface provides access to all the informers in this group version. type Interface interface { + // Buses returns a BusInformer. + Buses() BusInformer // Channels returns a ChannelInformer. Channels() ChannelInformer // ClusterBuses returns a ClusterBusInformer. @@ -43,6 +45,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} } +// Buses returns a BusInformer. +func (v *version) Buses() BusInformer { + return &busInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Channels returns a ChannelInformer. func (v *version) Channels() ChannelInformer { return &channelInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index dc0541981f5..5c93b4c19cb 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -55,6 +55,8 @@ func (f *genericInformer) Lister() cache.GenericLister { func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { // Group=channels.knative.dev, Version=v1alpha1 + case v1alpha1.SchemeGroupVersion.WithResource("buses"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Channels().V1alpha1().Buses().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("channels"): return &genericInformer{resource: resource.GroupResource(), informer: f.Channels().V1alpha1().Channels().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("clusterbuses"): diff --git a/pkg/client/listers/channels/v1alpha1/bus.go b/pkg/client/listers/channels/v1alpha1/bus.go new file mode 100644 index 00000000000..52d0d164e29 --- /dev/null +++ b/pkg/client/listers/channels/v1alpha1/bus.go @@ -0,0 +1,94 @@ +/* +Copyright 2018 The Knative Authors + +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// BusLister helps list Buses. +type BusLister interface { + // List lists all Buses in the indexer. + List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) + // Buses returns an object that can list and get Buses. + Buses(namespace string) BusNamespaceLister + BusListerExpansion +} + +// busLister implements the BusLister interface. +type busLister struct { + indexer cache.Indexer +} + +// NewBusLister returns a new BusLister. +func NewBusLister(indexer cache.Indexer) BusLister { + return &busLister{indexer: indexer} +} + +// List lists all Buses in the indexer. +func (s *busLister) List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.Bus)) + }) + return ret, err +} + +// Buses returns an object that can list and get Buses. +func (s *busLister) Buses(namespace string) BusNamespaceLister { + return busNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// BusNamespaceLister helps list and get Buses. +type BusNamespaceLister interface { + // List lists all Buses in the indexer for a given namespace. + List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) + // Get retrieves the Bus from the indexer for a given namespace and name. + Get(name string) (*v1alpha1.Bus, error) + BusNamespaceListerExpansion +} + +// busNamespaceLister implements the BusNamespaceLister +// interface. +type busNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all Buses in the indexer for a given namespace. +func (s busNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.Bus, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.Bus)) + }) + return ret, err +} + +// Get retrieves the Bus from the indexer for a given namespace and name. +func (s busNamespaceLister) Get(name string) (*v1alpha1.Bus, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("bus"), name) + } + return obj.(*v1alpha1.Bus), nil +} diff --git a/pkg/client/listers/channels/v1alpha1/expansion_generated.go b/pkg/client/listers/channels/v1alpha1/expansion_generated.go index bac2ac3182b..96d1fd82104 100644 --- a/pkg/client/listers/channels/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/channels/v1alpha1/expansion_generated.go @@ -18,6 +18,14 @@ limitations under the License. package v1alpha1 +// BusListerExpansion allows custom methods to be added to +// BusLister. +type BusListerExpansion interface{} + +// BusNamespaceListerExpansion allows custom methods to be added to +// BusNamespaceLister. +type BusNamespaceListerExpansion interface{} + // ChannelListerExpansion allows custom methods to be added to // ChannelLister. type ChannelListerExpansion interface{} diff --git a/pkg/controller/bus/controller.go b/pkg/controller/bus/controller.go new file mode 100644 index 00000000000..d661b9ccfc3 --- /dev/null +++ b/pkg/controller/bus/controller.go @@ -0,0 +1,793 @@ +/* +Copyright 2017 The Knative Authors + +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. +*/ + +package bus + +import ( + "fmt" + "reflect" + "time" + + "github.com/golang/glog" + "github.com/knative/eventing/pkg/controller" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + rbacv1beta1 "k8s.io/api/rbac/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/apimachinery/pkg/util/runtime" + "k8s.io/apimachinery/pkg/util/wait" + kubeinformers "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/scheme" + typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" + appslisters "k8s.io/client-go/listers/apps/v1" + corelisters "k8s.io/client-go/listers/core/v1" + rbaclisters "k8s.io/client-go/listers/rbac/v1beta1" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/tools/record" + "k8s.io/client-go/util/workqueue" + + clientset "github.com/knative/eventing/pkg/client/clientset/versioned" + channelscheme "github.com/knative/eventing/pkg/client/clientset/versioned/scheme" + informers "github.com/knative/eventing/pkg/client/informers/externalversions" + listers "github.com/knative/eventing/pkg/client/listers/channels/v1alpha1" + + servinginformers "github.com/knative/serving/pkg/client/informers/externalversions" + + channelsv1alpha1 "github.com/knative/eventing/pkg/apis/channels/v1alpha1" +) + +const controllerAgentName = "bus-controller" + +const ( + // SuccessSynced is used as part of the Event 'reason' when a Bus is synced + SuccessSynced = "Synced" + // ErrResourceExists is used as part of the Event 'reason' when a Bus fails + // to sync due to a Service of the same name already existing. + ErrResourceExists = "ErrResourceExists" + + // MessageResourceExists is the message used for Events when a resource + // fails to sync due to a Service already existing + MessageResourceExists = "Resource %q already exists and is not managed by Bus" + // MessageResourceSynced is the message used for an Event fired when a Bus + // is synced successfully + MessageResourceSynced = "Bus synced successfully" +) + +// Controller is the controller implementation for Bus resources +type Controller struct { + // kubeclientset is a standard kubernetes clientset + kubeclientset kubernetes.Interface + // busclientset is a clientset for our own API group + busclientset clientset.Interface + + deploymentsLister appslisters.DeploymentLister + deploymentsSynced cache.InformerSynced + servicesLister corelisters.ServiceLister + servicesSynced cache.InformerSynced + serviceAccountsLister corelisters.ServiceAccountLister + serviceAccountsSynced cache.InformerSynced + clusterRoleBindingsLister rbaclisters.ClusterRoleBindingLister + clusterRoleBindingsSynced cache.InformerSynced + busesLister listers.BusLister + busesSynced cache.InformerSynced + + // workqueue is a rate limited work queue. This is used to queue work to be + // processed instead of performing it as soon as a change happens. This + // means we can ensure we only process a fixed amount of resources at a + // time, and makes it easy to ensure we are never processing the same item + // simultaneously in two different workers. + workqueue workqueue.RateLimitingInterface + // recorder is an event recorder for recording Event resources to the + // Kubernetes API. + recorder record.EventRecorder +} + +// NewController returns a new bus controller +func NewController( + kubeclientset kubernetes.Interface, + busclientset clientset.Interface, + kubeInformerFactory kubeinformers.SharedInformerFactory, + busInformerFactory informers.SharedInformerFactory, + routeInformerFactory servinginformers.SharedInformerFactory) controller.Interface { + + // obtain references to shared index informers for the Bus, Deployment and Service + // types. + busInformer := busInformerFactory.Channels().V1alpha1().Buses() + deploymentInformer := kubeInformerFactory.Apps().V1().Deployments() + serviceInformer := kubeInformerFactory.Core().V1().Services() + serviceAccountInformer := kubeInformerFactory.Core().V1().ServiceAccounts() + clusterRoleBindingInformer := kubeInformerFactory.Rbac().V1beta1().ClusterRoleBindings() + + // Create event broadcaster + // Add bus-controller types to the default Kubernetes Scheme so Events can be + // logged for bus-controller types. + channelscheme.AddToScheme(scheme.Scheme) + glog.V(4).Info("Creating event broadcaster") + eventBroadcaster := record.NewBroadcaster() + eventBroadcaster.StartLogging(glog.Infof) + eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeclientset.CoreV1().Events("")}) + recorder := eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: controllerAgentName}) + + controller := &Controller{ + kubeclientset: kubeclientset, + busclientset: busclientset, + deploymentsLister: deploymentInformer.Lister(), + deploymentsSynced: deploymentInformer.Informer().HasSynced, + servicesLister: serviceInformer.Lister(), + servicesSynced: serviceInformer.Informer().HasSynced, + serviceAccountsLister: serviceAccountInformer.Lister(), + serviceAccountsSynced: serviceAccountInformer.Informer().HasSynced, + clusterRoleBindingsLister: clusterRoleBindingInformer.Lister(), + clusterRoleBindingsSynced: clusterRoleBindingInformer.Informer().HasSynced, + busesLister: busInformer.Lister(), + busesSynced: busInformer.Informer().HasSynced, + workqueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "Buses"), + recorder: recorder, + } + + glog.Info("Setting up event handlers") + // Set up an event handler for when Bus resources change + busInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.enqueueBus, + UpdateFunc: func(old, new interface{}) { + controller.enqueueBus(new) + }, + }) + // Set up an event handler for when Service resources change. This + // handler will lookup the owner of the given Service, and if it is + // owned by a Bus resource will enqueue that Bus resource for + // processing. This way, we don't need to implement custom logic for + // handling Service resources. More info on this pattern: + // https://github.com/kubernetes/community/blob/8cafef897a22026d42f5e5bb3f104febe7e29830/contributors/devel/controllers.md + serviceInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: controller.handleObject, + UpdateFunc: func(old, new interface{}) { + newService := new.(*corev1.Service) + oldService := old.(*corev1.Service) + if newService.ResourceVersion == oldService.ResourceVersion { + // Periodic resync will send update events for all known Services. + // Two different versions of the same Service will always have different RVs. + return + } + controller.handleObject(new) + }, + DeleteFunc: controller.handleObject, + }) + + return controller +} + +// Run will set up the event handlers for types we are interested in, as well +// as syncing informer caches and starting workers. It will block until stopCh +// is closed, at which point it will shutdown the workqueue and wait for +// workers to finish processing their current work items. +func (c *Controller) Run(threadiness int, stopCh <-chan struct{}) error { + defer runtime.HandleCrash() + defer c.workqueue.ShutDown() + + // Start the informer factories to begin populating the informer caches + glog.Info("Starting Bus controller") + + // Wait for the caches to be synced before starting workers + glog.Info("Waiting for informer caches to sync") + if ok := cache.WaitForCacheSync(stopCh, c.deploymentsSynced, c.servicesSynced, c.busesSynced); !ok { + return fmt.Errorf("failed to wait for caches to sync") + } + + glog.Info("Starting workers") + // Launch two workers to process Bus resources + for i := 0; i < threadiness; i++ { + go wait.Until(c.runWorker, time.Second, stopCh) + } + + glog.Info("Started workers") + <-stopCh + glog.Info("Shutting down workers") + + return nil +} + +// runWorker is a long-running function that will continually call the +// processNextWorkItem function in order to read and process a message on the +// workqueue. +func (c *Controller) runWorker() { + for c.processNextWorkItem() { + } +} + +// processNextWorkItem will read a single work item off the workqueue and +// attempt to process it, by calling the syncHandler. +func (c *Controller) processNextWorkItem() bool { + obj, shutdown := c.workqueue.Get() + + if shutdown { + return false + } + + // We wrap this block in a func so we can defer c.workqueue.Done. + err := func(obj interface{}) error { + // We call Done here so the workqueue knows we have finished + // processing this item. We also must remember to call Forget if we + // do not want this work item being re-queued. For example, we do + // not call Forget if a transient error occurs, instead the item is + // put back on the workqueue and attempted again after a back-off + // period. + defer c.workqueue.Done(obj) + var key string + var ok bool + // We expect strings to come off the workqueue. These are of the + // form namespace/name. We do this as the delayed nature of the + // workqueue means the items in the informer cache may actually be + // more up to date that when the item was initially put onto the + // workqueue. + if key, ok = obj.(string); !ok { + // As the item in the workqueue is actually invalid, we call + // Forget here else we'd go into a loop of attempting to + // process a work item that is invalid. + c.workqueue.Forget(obj) + runtime.HandleError(fmt.Errorf("expected string in workqueue but got %#v", obj)) + return nil + } + // Run the syncHandler, passing it the namespace/name string of the + // Bus resource to be synced. + if err := c.syncHandler(key); err != nil { + return fmt.Errorf("error syncing bus '%s': %s", key, err.Error()) + } + // Finally, if no error occurs we Forget this item so it does not + // get queued again until another change happens. + c.workqueue.Forget(obj) + glog.Infof("Successfully synced bus '%s'", key) + return nil + }(obj) + + if err != nil { + runtime.HandleError(err) + return true + } + + return true +} + +// syncHandler compares the actual state with the desired, and attempts to +// converge the two. It then updates the Status block of the Bus resource +// with the current status of the resource. +func (c *Controller) syncHandler(key string) error { + // Convert the namespace/name string into a distinct namespace and name + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + runtime.HandleError(fmt.Errorf("invalid resource key: %s", key)) + return nil + } + + // Get the Bus resource with this namespace/name + bus, err := c.busesLister.Buses(namespace).Get(name) + if err != nil { + // The Bus resource may no longer exist, in which case we stop + // processing. + if errors.IsNotFound(err) { + runtime.HandleError(fmt.Errorf("bus '%s' in work queue no longer exists", key)) + return nil + } + + return err + } + + // Sync ServiceAccount derived from the Bus + serviceAccount, err := c.syncBusServiceAccount(bus) + if err != nil { + return err + } + + // Sync ClusterRoleBinding derived from the Bus + clusterRoleBinding, err := c.syncBusClusterRoleBinding(bus) + if err != nil { + return err + } + + // Sync Service derived from the Bus + dispatcherService, err := c.syncBusDispatcherService(bus) + if err != nil { + return err + } + + // Sync Deployment derived from the Bus + dispatcherDeployment, err := c.syncBusDispatcherDeployment(bus) + if err != nil { + return err + } + + // Sync Deployment derived from the Bus + provisionerDeployment, err := c.syncBusProvisionerDeployment(bus) + if err != nil { + return err + } + + // Finally, we update the status block of the Bus resource to reflect the + // current state of the world + err = c.updateBusStatus(bus, dispatcherService, dispatcherDeployment, provisionerDeployment, serviceAccount, clusterRoleBinding) + if err != nil { + return err + } + + c.recorder.Event(bus, corev1.EventTypeNormal, SuccessSynced, MessageResourceSynced) + return nil +} + +func (c *Controller) syncBusDispatcherService(bus *channelsv1alpha1.Bus) (*corev1.Service, error) { + // Get the service with the specified service name + serviceName := controller.BusDispatcherServiceName(bus.ObjectMeta.Name) + service, err := c.servicesLister.Services(bus.Namespace).Get(serviceName) + // If the resource doesn't exist, we'll create it + if errors.IsNotFound(err) { + service, err = c.kubeclientset.CoreV1().Services(bus.Namespace).Create(newDispatcherService(bus)) + } + + // If an error occurs during Get/Create, we'll requeue the item so we can + // attempt processing again later. This could have been caused by a + // temporary network failure, or any other transient reason. + if err != nil { + return nil, err + } + + // If the Service is not controlled by this Bus resource, we should log + // a warning to the event recorder and return + if !metav1.IsControlledBy(service, bus) { + msg := fmt.Sprintf(MessageResourceExists, service.Name) + c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + return nil, fmt.Errorf(msg) + } + + return service, nil +} + +func (c *Controller) syncBusDispatcherDeployment(bus *channelsv1alpha1.Bus) (*appsv1.Deployment, error) { + // Get the deployment with the specified deployment name + deploymentName := controller.BusDispatcherDeploymentName(bus.ObjectMeta.Name) + deployment, err := c.deploymentsLister.Deployments(bus.Namespace).Get(deploymentName) + // If the resource doesn't exist, we'll create it + if errors.IsNotFound(err) { + deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Create(newDispatcherDeployment(bus)) + } + + // If an error occurs during Get/Create, we'll requeue the item so we can + // attempt processing again later. This could have been caused by a + // temporary network failure, or any other transient reason. + if err != nil { + return nil, err + } + + // If the Deployment is not controlled by this Bus resource, we should log + // a warning to the event recorder and return + if !metav1.IsControlledBy(deployment, bus) { + msg := fmt.Sprintf(MessageResourceExists, deployment.Name) + c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + return nil, fmt.Errorf(msg) + } + + // If the Deployment does not match the Bus's proposed Deployment we should update + // the Deployment resource. + proposedDeployment := newDispatcherDeployment(bus) + if !reflect.DeepEqual(proposedDeployment.Spec, deployment.Spec) { + glog.V(4).Infof("Bus %s dispatcher spec updated", bus.Name) + deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Update(proposedDeployment) + + if err != nil { + return nil, err + } + } + + return deployment, nil +} + +func (c *Controller) syncBusServiceAccount(bus *channelsv1alpha1.Bus) (*corev1.ServiceAccount, error) { + // Get the serviceAccount with the specified serviceAccount name + serviceAccountName := controller.BusServiceAccountName(bus.ObjectMeta.Name) + serviceAccount, err := c.serviceAccountsLister.ServiceAccounts(bus.Namespace).Get(serviceAccountName) + // If the resource doesn't exist, we'll create it + if errors.IsNotFound(err) { + serviceAccount, err = c.kubeclientset.CoreV1().ServiceAccounts(bus.Namespace).Create(newServiceAccount(bus)) + } + + // If an error occurs during Get/Create, we'll requeue the item so we can + // attempt processing again later. This could have been caused by a + // temporary network failure, or any other transient reason. + if err != nil { + return nil, err + } + + // If the ServiceAccount is not controlled by this Bus resource, we should log + // a warning to the event recorder and return + if !metav1.IsControlledBy(serviceAccount, bus) { + msg := fmt.Sprintf(MessageResourceExists, serviceAccount.Name) + c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + return nil, fmt.Errorf(msg) + } + + return serviceAccount, nil +} + +func (c *Controller) syncBusClusterRoleBinding(bus *channelsv1alpha1.Bus) (*rbacv1beta1.ClusterRoleBinding, error) { + // Get the clusterRoleBinding with the specified clusterRoleBinding name + clusterRoleBindingName := controller.BusClusterRoleBindingName(bus.ObjectMeta.Name) + clusterRoleBinding, err := c.clusterRoleBindingsLister.Get(clusterRoleBindingName) + // If the resource doesn't exist, we'll create it + if errors.IsNotFound(err) { + clusterRoleBinding, err = c.kubeclientset.RbacV1beta1().ClusterRoleBindings().Create(newClusterRoleBinding(bus)) + } + + // If an error occurs during Get/Create, we'll requeue the item so we can + // attempt processing again later. This could have been caused by a + // temporary network failure, or any other transient reason. + if err != nil { + return nil, err + } + + // If the ClusterRoleBinding is not controlled by this Bus resource, we should log + // a warning to the event recorder and return + if !metav1.IsControlledBy(clusterRoleBinding, bus) { + msg := fmt.Sprintf(MessageResourceExists, clusterRoleBinding.Name) + c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + return nil, fmt.Errorf(msg) + } + + // If the ClusterRoleBinding does not match the Bus's proposed ClusterRoleBinding we + // should update the ClusterRoleBinding resource. + proposedClusterRoleBinding := newClusterRoleBinding(bus) + if !reflect.DeepEqual(proposedClusterRoleBinding.Subjects, clusterRoleBinding.Subjects) && + !reflect.DeepEqual(proposedClusterRoleBinding.RoleRef, clusterRoleBinding.RoleRef) { + glog.V(4).Infof("Bus %s provisioner spec updated", bus.Name) + clusterRoleBinding, err = c.kubeclientset.RbacV1beta1().ClusterRoleBindings().Update(proposedClusterRoleBinding) + + if err != nil { + return nil, err + } + } + + return clusterRoleBinding, nil +} + +func (c *Controller) syncBusProvisionerDeployment(bus *channelsv1alpha1.Bus) (*appsv1.Deployment, error) { + provisioner := bus.Spec.Provisioner + + // Get the deployment with the specified deployment name + deploymentName := controller.BusProvisionerDeploymentName(bus.ObjectMeta.Name) + deployment, err := c.deploymentsLister.Deployments(bus.Namespace).Get(deploymentName) + + // If the resource shouldn't exists + if provisioner == nil { + // If the resource exists, we'll delete it + if deployment != nil { + err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Delete(deploymentName, nil) + } + if errors.IsNotFound(err) { + return nil, nil + } + return nil, err + } + + // If the resource doesn't exist, we'll create it + if errors.IsNotFound(err) { + deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Create(newProvisionerDeployment(bus)) + } + + // If an error occurs during Get/Create, we'll requeue the item so we can + // attempt processing again later. This could have been caused by a + // temporary network failure, or any other transient reason. + if err != nil { + return nil, err + } + + // If the Deployment is not controlled by this Bus resource, we should log + // a warning to the event recorder and return + if !metav1.IsControlledBy(deployment, bus) { + msg := fmt.Sprintf(MessageResourceExists, deployment.Name) + c.recorder.Event(bus, corev1.EventTypeWarning, ErrResourceExists, msg) + return nil, fmt.Errorf(msg) + } + + // If the Deployment does not match the Bus's proposed Deployment we should update + // the Deployment resource. + proposedDeployment := newProvisionerDeployment(bus) + if !reflect.DeepEqual(proposedDeployment.Spec, deployment.Spec) { + glog.V(4).Infof("Bus %s provisioner spec updated", bus.Name) + deployment, err = c.kubeclientset.AppsV1().Deployments(bus.Namespace).Update(proposedDeployment) + + if err != nil { + return nil, err + } + } + + return deployment, nil +} + +func (c *Controller) updateBusStatus( + bus *channelsv1alpha1.Bus, + dispatcherService *corev1.Service, + dispatcherDeployment *appsv1.Deployment, + provisionerDeployment *appsv1.Deployment, + serviceAccount *corev1.ServiceAccount, + clusterRoleBinding *rbacv1beta1.ClusterRoleBinding, +) error { + // NEVER modify objects from the store. It's a read-only, local cache. + // You can use DeepCopy() to make a deep copy of original object and modify this copy + // Or create a copy manually for better performance + busCopy := bus.DeepCopy() + // If the CustomResourceSubresources feature gate is not enabled, + // we must use Update instead of UpdateStatus to update the Status block of the Bus resource. + // UpdateStatus will not allow changes to the Spec of the resource, + // which is ideal for ensuring nothing other than resource status has been updated. + _, err := c.busclientset.ChannelsV1alpha1().Buses(bus.Namespace).Update(busCopy) + return err +} + +// enqueueBus takes a Bus resource and converts it into a namespace/name +// string which is then put onto the work queue. This method should *not* be +// passed resources of any type other than Bus. +func (c *Controller) enqueueBus(obj interface{}) { + var key string + var err error + if key, err = cache.MetaNamespaceKeyFunc(obj); err != nil { + runtime.HandleError(err) + return + } + c.workqueue.AddRateLimited(key) +} + +// handleObject will take any resource implementing metav1.Object and attempt +// to find the Bus resource that 'owns' it. It does this by looking at the +// objects metadata.ownerReferences field for an appropriate OwnerReference. +// It then enqueues that Bus resource to be processed. If the object does not +// have an appropriate OwnerReference, it will simply be skipped. +func (c *Controller) handleObject(obj interface{}) { + var object metav1.Object + var ok bool + if object, ok = obj.(metav1.Object); !ok { + tombstone, ok := obj.(cache.DeletedFinalStateUnknown) + if !ok { + runtime.HandleError(fmt.Errorf("error decoding object, invalid type")) + return + } + object, ok = tombstone.Obj.(metav1.Object) + if !ok { + runtime.HandleError(fmt.Errorf("error decoding object tombstone, invalid type")) + return + } + glog.V(4).Infof("Recovered deleted object '%s' from tombstone", object.GetName()) + } + glog.V(4).Infof("Processing object: %s", object.GetName()) + if ownerRef := metav1.GetControllerOf(object); ownerRef != nil { + // If this object is not owned by a Bus, we should not do anything more + // with it. + if ownerRef.Kind != "Bus" { + return + } + + bus, err := c.busesLister.Buses(object.GetNamespace()).Get(ownerRef.Name) + if err != nil { + glog.V(4).Infof("ignoring orphaned object '%s' of bus '%s'", object.GetSelfLink(), ownerRef.Name) + return + } + + c.enqueueBus(bus) + return + } +} + +// newDispatcherService creates a new Service for a Bus resource. It also sets +// the appropriate OwnerReferences on the resource so handleObject can discover +// the Bus resource that 'owns' it. +func newDispatcherService(bus *channelsv1alpha1.Bus) *corev1.Service { + labels := map[string]string{ + "bus": bus.Name, + "role": "dispatcher", + } + return &corev1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: controller.BusDispatcherServiceName(bus.ObjectMeta.Name), + Namespace: bus.Namespace, + Labels: labels, + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + Group: channelsv1alpha1.SchemeGroupVersion.Group, + Version: channelsv1alpha1.SchemeGroupVersion.Version, + Kind: "Bus", + }), + }, + }, + Spec: corev1.ServiceSpec{ + Selector: labels, + Ports: []corev1.ServicePort{ + { + Name: "http", + Port: 80, + TargetPort: intstr.FromInt(8080), + }, + }, + }, + } +} + +// newDispatcherDeployment creates a new Deployment for a Bus resource. It also sets +// the appropriate OwnerReferences on the resource so handleObject can discover +// the Bus resource that 'owns' it. +func newDispatcherDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { + labels := map[string]string{ + "bus": bus.Name, + "role": "dispatcher", + } + one := int32(1) + container := bus.Spec.Dispatcher.DeepCopy() + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "PORT", + Value: "8080", + }, + corev1.EnvVar{ + Name: "BUS_NAMESPACE", + Value: bus.Namespace, + }, + corev1.EnvVar{ + Name: "BUS_NAME", + Value: bus.Name, + }, + ) + volumes := []corev1.Volume{} + if bus.Spec.Volumes != nil { + volumes = *bus.Spec.Volumes + } + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: controller.BusDispatcherDeploymentName(bus.ObjectMeta.Name), + Namespace: bus.Namespace, + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + Group: channelsv1alpha1.SchemeGroupVersion.Group, + Version: channelsv1alpha1.SchemeGroupVersion.Version, + Kind: "Bus", + }), + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &one, + Selector: &metav1.LabelSelector{ + MatchLabels: labels, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: labels, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: controller.BusServiceAccountName(bus.Name), + Containers: []corev1.Container{ + *container, + }, + Volumes: volumes, + }, + }, + }, + } +} + +// newServiceAccount creates a new ServiceAccount for a Bus resource. It also sets +// the appropriate OwnerReferences on the resource so handleObject can discover +// the Bus resource that 'owns' it. +func newServiceAccount(bus *channelsv1alpha1.Bus) *corev1.ServiceAccount { + return &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: controller.BusServiceAccountName(bus.ObjectMeta.Name), + Namespace: bus.Namespace, + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + Group: channelsv1alpha1.SchemeGroupVersion.Group, + Version: channelsv1alpha1.SchemeGroupVersion.Version, + Kind: "Bus", + }), + }, + }, + } +} + +// newClusterRoleBinding creates a new ClusterRoleBinding for a Bus resource. It also sets +// the appropriate OwnerReferences on the resource so handleObject can discover +// the Bus resource that 'owns' it. +func newClusterRoleBinding(bus *channelsv1alpha1.Bus) *rbacv1beta1.ClusterRoleBinding { + return &rbacv1beta1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: controller.BusClusterRoleBindingName(bus.ObjectMeta.Name), + Namespace: bus.Namespace, + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + Group: channelsv1alpha1.SchemeGroupVersion.Group, + Version: channelsv1alpha1.SchemeGroupVersion.Version, + Kind: "Bus", + }), + }, + }, + Subjects: []rbacv1beta1.Subject{ + { + Kind: "ServiceAccount", + Name: controller.BusServiceAccountName(bus.ObjectMeta.Name), + Namespace: bus.Namespace, + }, + }, + RoleRef: rbacv1beta1.RoleRef{ + Kind: "ClusterRole", + Name: "knative-channels-bus", + APIGroup: "rbac.authorization.k8s.io", + }, + } +} + +// newProvisionerDeployment creates a new Deployment for a Bus resource. It also sets +// the appropriate OwnerReferences on the resource so handleObject can discover +// the Bus resource that 'owns' it. +func newProvisionerDeployment(bus *channelsv1alpha1.Bus) *appsv1.Deployment { + labels := map[string]string{ + "bus": bus.Name, + "role": "provisioner", + } + one := int32(1) + container := bus.Spec.Provisioner.DeepCopy() + container.Env = append(container.Env, + corev1.EnvVar{ + Name: "BUS_NAMESPACE", + Value: bus.Namespace, + }, + corev1.EnvVar{ + Name: "BUS_NAME", + Value: bus.Name, + }, + ) + volumes := []corev1.Volume{} + if bus.Spec.Volumes != nil { + volumes = *bus.Spec.Volumes + } + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: controller.BusProvisionerDeploymentName(bus.ObjectMeta.Name), + Namespace: bus.Namespace, + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(bus, schema.GroupVersionKind{ + Group: channelsv1alpha1.SchemeGroupVersion.Group, + Version: channelsv1alpha1.SchemeGroupVersion.Version, + Kind: "Bus", + }), + }, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: &one, + Selector: &metav1.LabelSelector{ + MatchLabels: labels, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: labels, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: controller.BusServiceAccountName(bus.Name), + Containers: []corev1.Container{ + *container, + }, + Volumes: volumes, + }, + }, + }, + } +} diff --git a/pkg/controller/channel/controller.go b/pkg/controller/channel/controller.go index 750606928fd..ef521804901 100644 --- a/pkg/controller/channel/controller.go +++ b/pkg/controller/channel/controller.go @@ -456,8 +456,16 @@ func newService(channel *channelsv1alpha1.Channel) *corev1.Service { // the Channel resource that 'owns' it. func newVirtualService(channel *channelsv1alpha1.Channel) *istiov1alpha3.VirtualService { labels := map[string]string{ - "clusterBus": channel.Spec.ClusterBus, - "channel": channel.Name, + "channel": channel.Name, + } + var destinationHost string + if len(channel.Spec.Bus) != 0 { + labels["bus"] = channel.Spec.Bus + destinationHost = controller.ServiceHostName(controller.BusDispatcherServiceName(channel.Spec.Bus), channel.Namespace) + } + if len(channel.Spec.ClusterBus) != 0 { + labels["clusterBus"] = channel.Spec.ClusterBus + destinationHost = controller.ServiceHostName(controller.ClusterBusDispatcherServiceName(channel.Spec.ClusterBus), pkg.GetEventingSystemNamespace()) } return &istiov1alpha3.VirtualService{ ObjectMeta: metav1.ObjectMeta{ @@ -485,7 +493,7 @@ func newVirtualService(channel *channelsv1alpha1.Channel) *istiov1alpha3.Virtual Route: []istiov1alpha3.DestinationWeight{ { Destination: istiov1alpha3.Destination{ - Host: controller.ServiceHostName(controller.ClusterBusDispatcherServiceName(channel.Spec.ClusterBus), pkg.GetEventingSystemNamespace()), + Host: destinationHost, }, }, }, diff --git a/pkg/controller/clusterbus/controller.go b/pkg/controller/clusterbus/controller.go index 9419c725c56..643ab659ec5 100644 --- a/pkg/controller/clusterbus/controller.go +++ b/pkg/controller/clusterbus/controller.go @@ -551,7 +551,7 @@ func newDispatcherDeployment(clusterBus *channelsv1alpha1.ClusterBus) *appsv1.De Value: "8080", }, corev1.EnvVar{ - Name: "CLUSTER_BUS_NAME", + Name: "BUS_NAME", Value: clusterBus.Name, }, ) @@ -604,7 +604,7 @@ func newProvisionerDeployment(clusterBus *channelsv1alpha1.ClusterBus) *appsv1.D container := clusterBus.Spec.Provisioner.DeepCopy() container.Env = append(container.Env, corev1.EnvVar{ - Name: "CLUSTER_BUS_NAME", + Name: "BUS_NAME", Value: clusterBus.Name, }, ) diff --git a/pkg/controller/names.go b/pkg/controller/names.go index a92450f2c14..e8deb1a68a9 100644 --- a/pkg/controller/names.go +++ b/pkg/controller/names.go @@ -18,6 +18,26 @@ package controller import "fmt" +func BusProvisionerDeploymentName(busName string) string { + return fmt.Sprintf("%s-bus-provisioner", busName) +} + +func BusDispatcherDeploymentName(busName string) string { + return fmt.Sprintf("%s-bus", busName) +} + +func BusServiceAccountName(busName string) string { + return fmt.Sprintf("%s-bus", busName) +} + +func BusClusterRoleBindingName(busName string) string { + return fmt.Sprintf("%s-bus", busName) +} + +func BusDispatcherServiceName(busName string) string { + return fmt.Sprintf("%s-bus", busName) +} + func ClusterBusProvisionerDeploymentName(clusterBusName string) string { return fmt.Sprintf("%s-clusterbus-provisioner", clusterBusName) } diff --git a/pkg/webhook/channel.go b/pkg/webhook/channel.go index 19f6422267d..c7137a831aa 100644 --- a/pkg/webhook/channel.go +++ b/pkg/webhook/channel.go @@ -26,7 +26,8 @@ import ( var ( errInvalidChannelInput = errors.New("failed to convert input into Channel") - errInvalidChannelClusterBusMissing = errors.New("the Channel must reference a ClusterBus") + errInvalidChannelBusMissing = errors.New("the Channel must reference a Bus or ClusterBus") + errInvalidChannelBusMutation = errors.New("the Channel's ClusterBus may not change") errInvalidChannelClusterBusMutation = errors.New("the Channel's ClusterBus may not change") ) @@ -43,11 +44,16 @@ func ValidateChannel(ctx context.Context) ResourceCallback { } func validateChannel(old, new *v1alpha1.Channel) error { - if len(new.Spec.ClusterBus) == 0 { - return errInvalidChannelClusterBusMissing + if len(new.Spec.Bus) == 0 && len(new.Spec.ClusterBus) == 0 { + return errInvalidChannelBusMissing } - if old != nil && old.Spec.ClusterBus != new.Spec.ClusterBus { - return errInvalidChannelClusterBusMutation + if old != nil { + if old.Spec.Bus != new.Spec.Bus { + return errInvalidChannelBusMutation + } + if old.Spec.ClusterBus != new.Spec.ClusterBus { + return errInvalidChannelClusterBusMutation + } } return nil } diff --git a/pkg/webhook/channel_test.go b/pkg/webhook/channel_test.go index 328cf3743d9..829ffa7c413 100644 --- a/pkg/webhook/channel_test.go +++ b/pkg/webhook/channel_test.go @@ -19,34 +19,53 @@ import ( "testing" ) -func TestNewChannel(t *testing.T) { - c := createChannel(testChannelName, testClusterBusName) +func TestNewChannelNSBus(t *testing.T) { + c := createChannel(testChannelName, testBusName, "") + if err := ValidateChannel(testCtx)(nil, nil, &c); err != nil { + t.Errorf("Expected success, but failed with: %s", err) + } +} + +func TestNewChannelClusterBus(t *testing.T) { + c := createChannel(testChannelName, "", testClusterBusName) if err := ValidateChannel(testCtx)(nil, nil, &c); err != nil { t.Errorf("Expected success, but failed with: %s", err) } } func TestNewEmptyChannel(t *testing.T) { - c := createChannel(testChannelName, "") + c := createChannel(testChannelName, "", "") err := ValidateChannel(testCtx)(nil, nil, &c) if err == nil { t.Errorf("Expected failure, but succeeded with: %+v", c) } - if e, a := errInvalidChannelClusterBusMissing, err; e != a { + if e, a := errInvalidChannelBusMissing, err; e != a { t.Errorf("Expected %s got %s", e, a) } } -func TestChannelMutation(t *testing.T) { - c := createChannel(testChannelName, testClusterBusName) +func TestChannelNoopMutation(t *testing.T) { + c := createChannel(testChannelName, testBusName, "") if err := ValidateChannel(testCtx)(nil, &c, &c); err != nil { t.Errorf("Expected success, but failed with: %s", err) } } +func TestChannelNSBusMutation(t *testing.T) { + old := createChannel(testChannelName, "stub", "") + new := createChannel(testChannelName, "pubsub", "") + err := ValidateChannel(testCtx)(nil, &old, &new) + if err == nil { + t.Errorf("Expected failure, but succeeded with: %+v %+v", old, new) + } + if e, a := errInvalidChannelBusMutation, err; e != a { + t.Errorf("Expected %s got %s", e, a) + } +} + func TestChannelClusterBusMutation(t *testing.T) { - old := createChannel(testChannelName, "stub") - new := createChannel(testChannelName, "pubsub") + old := createChannel(testChannelName, "", "stub") + new := createChannel(testChannelName, "", "pubsub") err := ValidateChannel(testCtx)(nil, &old, &new) if err == nil { t.Errorf("Expected failure, but succeeded with: %+v %+v", old, new) diff --git a/pkg/webhook/webhook_test.go b/pkg/webhook/webhook_test.go index 59aa60268da..5a4c073ecb5 100644 --- a/pkg/webhook/webhook_test.go +++ b/pkg/webhook/webhook_test.go @@ -46,6 +46,7 @@ func newDefaultOptions() ControllerOptions { const ( testNamespace = "test-namespace" + testBusName = "test-bus" testClusterBusName = "test-clusterbus" testChannelName = "test-channel" testSubscriptionName = "test-subscription" @@ -133,7 +134,7 @@ func TestInvalidNewChannelNameFails(t *testing.T) { Kind: metav1.GroupVersionKind{Kind: "Channel"}, } invalidName := "channel.example" - channel := createChannel(invalidName, testClusterBusName) + channel := createChannel(invalidName, testBusName, "") marshaled, err := json.Marshal(channel) if err != nil { t.Fatalf("Failed to marshal channel: %s", err) @@ -142,7 +143,7 @@ func TestInvalidNewChannelNameFails(t *testing.T) { expectFailsWith(t, ac.admit(testCtx, req), "Invalid resource name") invalidName = strings.Repeat("a", 64) - channel = createChannel(invalidName, testClusterBusName) + channel = createChannel(invalidName, testBusName, "") marshaled, err = json.Marshal(channel) if err != nil { t.Fatalf("Failed to marshal channel: %s", err) @@ -158,10 +159,19 @@ func TestValidNewChannelObject(t *testing.T) { expectPatches(t, resp.Patch, []jsonpatch.JsonPatchOperation{}) } -func TestValidChannelNoChanges(t *testing.T) { +func TestValidChannelNSBusNoChanges(t *testing.T) { _, ac := newNonRunningTestAdmissionController(t, newDefaultOptions()) - old := createChannel(testChannelName, testClusterBusName) - new := createChannel(testChannelName, testClusterBusName) + old := createChannel(testChannelName, testBusName, "") + new := createChannel(testChannelName, testBusName, "") + resp := ac.admit(testCtx, createUpdateChannel(&old, &new)) + expectAllowed(t, resp) + expectPatches(t, resp.Patch, []jsonpatch.JsonPatchOperation{}) +} + +func TestValidChannelClusterBusNoChanges(t *testing.T) { + _, ac := newNonRunningTestAdmissionController(t, newDefaultOptions()) + old := createChannel(testChannelName, "", testClusterBusName) + new := createChannel(testChannelName, "", testClusterBusName) resp := ac.admit(testCtx, createUpdateChannel(&old, &new)) expectAllowed(t, resp) expectPatches(t, resp.Patch, []jsonpatch.JsonPatchOperation{}) @@ -345,16 +355,17 @@ func createCreateChannel(channel v1alpha1.Channel) *admissionv1beta1.AdmissionRe } func createValidCreateChannel() *admissionv1beta1.AdmissionRequest { - return createCreateChannel(createChannel(testChannelName, testClusterBusName)) + return createCreateChannel(createChannel(testChannelName, testBusName, "")) } -func createChannel(channelName string, clusterBusName string) v1alpha1.Channel { +func createChannel(channelName string, busName, clusterBusName string) v1alpha1.Channel { return v1alpha1.Channel{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, Name: channelName, }, Spec: v1alpha1.ChannelSpec{ + Bus: busName, ClusterBus: clusterBusName, }, } From 0aa0ad443f66dfc7871ca37d251bb030446aea73 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Wed, 27 Jun 2018 09:57:22 -0400 Subject: [PATCH 4/7] doc polish --- pkg/apis/channels/v1alpha1/bus_types.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pkg/apis/channels/v1alpha1/bus_types.go b/pkg/apis/channels/v1alpha1/bus_types.go index 51aa76e68c8..9db3683fbba 100644 --- a/pkg/apis/channels/v1alpha1/bus_types.go +++ b/pkg/apis/channels/v1alpha1/bus_types.go @@ -29,7 +29,7 @@ import ( // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:defaulter-gen=true -// Bus represents the clusterbuses.channels.knative.dev CRD +// Bus represents the buses.channels.knative.dev CRD type Bus struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ObjectMeta `json:"metadata"` @@ -37,33 +37,33 @@ type Bus struct { Status *BusStatus `json:"status,omitempty"` } -// BusSpec (what the user wants) for a clusterbus +// BusSpec (what the user wants) for a bus type BusSpec struct { - // Parameters exposed by the clusterbus for channels and subscriptions + // Parameters exposed by the bus for channels and subscriptions Parameters *BusParameters `json:"parameters,omitempty"` - // Provisioner container definition to manage channels on the clusterbus. + // Provisioner container definition to manage channels on the bus. Provisioner *kapi.Container `json:"provisioner,omitempty"` - // Dispatcher container definition to use for the clusterbus data plane. + // Dispatcher container definition to use for the bus data plane. Dispatcher kapi.Container `json:"dispatcher"` // Volumes to be mounted inside the provisioner or dispatcher containers Volumes *[]kapi.Volume `json:"volumes,omitempty"` } -// BusParameters parameters exposed by the clusterbus +// BusParameters parameters exposed by the bus type BusParameters struct { - // Channel configuration params for channels on the clusterbus + // Channel configuration params for channels on the bus Channel *[]Parameter `json:"channel,omitempty"` - // Subscription configuration params for subscriptions on the clusterbus + // Subscription configuration params for subscriptions on the bus Subscription *[]Parameter `json:"subscription,omitempty"` } -// BusStatus (computed) for a clusterbus +// BusStatus (computed) for a bus type BusStatus struct { } From 6195673e3abcca3e9dc27da1360b88750f2623a4 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Wed, 27 Jun 2018 11:36:53 -0400 Subject: [PATCH 5/7] Enforce Bus and ClusterBus are not both used in a Channel --- pkg/webhook/channel.go | 7 ++++++- pkg/webhook/channel_test.go | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/webhook/channel.go b/pkg/webhook/channel.go index c7137a831aa..c2cb027efb0 100644 --- a/pkg/webhook/channel.go +++ b/pkg/webhook/channel.go @@ -27,6 +27,7 @@ import ( var ( errInvalidChannelInput = errors.New("failed to convert input into Channel") errInvalidChannelBusMissing = errors.New("the Channel must reference a Bus or ClusterBus") + errInvalidChannelBusExclusivity = errors.New("the Channel must reference either a Bus or ClusterBus, not both") errInvalidChannelBusMutation = errors.New("the Channel's ClusterBus may not change") errInvalidChannelClusterBusMutation = errors.New("the Channel's ClusterBus may not change") ) @@ -44,8 +45,12 @@ func ValidateChannel(ctx context.Context) ResourceCallback { } func validateChannel(old, new *v1alpha1.Channel) error { - if len(new.Spec.Bus) == 0 && len(new.Spec.ClusterBus) == 0 { + refsBus := len(new.Spec.Bus) != 0 + refsClusterBus := len(new.Spec.ClusterBus) != 0 + if !refsBus && !refsClusterBus { return errInvalidChannelBusMissing + } else if refsBus && refsClusterBus { + return errInvalidChannelBusExclusivity } if old != nil { if old.Spec.Bus != new.Spec.Bus { diff --git a/pkg/webhook/channel_test.go b/pkg/webhook/channel_test.go index 829ffa7c413..11c2ec12ecb 100644 --- a/pkg/webhook/channel_test.go +++ b/pkg/webhook/channel_test.go @@ -44,6 +44,17 @@ func TestNewEmptyChannel(t *testing.T) { } } +func TestNewExclusiveChannel(t *testing.T) { + c := createChannel(testChannelName, testBusName, testClusterBusName) + err := ValidateChannel(testCtx)(nil, nil, &c) + if err == nil { + t.Errorf("Expected failure, but succeeded with: %+v", c) + } + if e, a := errInvalidChannelBusExclusivity, err; e != a { + t.Errorf("Expected %s got %s", e, a) + } +} + func TestChannelNoopMutation(t *testing.T) { c := createChannel(testChannelName, testBusName, "") if err := ValidateChannel(testCtx)(nil, &c, &c); err != nil { From 105b7648c44cb1b2d119b703a4251d0c72d96e23 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Wed, 27 Jun 2018 14:04:33 -0400 Subject: [PATCH 6/7] review feedback --- pkg/buses/monitor.go | 53 +++++++++++++++++++++++---------- pkg/buses/stub/main.go | 4 +-- pkg/webhook/channel.go | 2 +- sample/hello/hello-channel.yaml | 2 +- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/pkg/buses/monitor.go b/pkg/buses/monitor.go index 8e7e95dc65f..db5ada947ab 100644 --- a/pkg/buses/monitor.go +++ b/pkg/buses/monitor.go @@ -59,7 +59,7 @@ const ( errResourceSync = "ErrResourceSync" ) -// Monitor utility to manage channels and subscriptions for a clusterbus +// Monitor utility to manage channels and subscriptions for a GenericBus type Monitor struct { bus channelsv1alpha1.GenericBus handler MonitorEventHandlerFuncs @@ -181,7 +181,7 @@ type subscriptionSummary struct { Subscription channelsv1alpha1.SubscriptionSpec } -// NewMonitor creates a monitor for a clusterbus +// NewMonitor creates a monitor for a GenericBus func NewMonitor( component, masterURL, kubeconfig string, handler MonitorEventHandlerFuncs, @@ -208,8 +208,7 @@ func NewMonitor( subscriptionInformer := informerFactory.Channels().V1alpha1().Subscriptions() // Create event broadcaster - // Add clusterbus-controller types to the default Kubernetes Scheme so Events can be - // logged for clusterbus-controller types. + // Add types to the default Kubernetes Scheme so Events can be logged for the component. channelscheme.AddToScheme(scheme.Scheme) glog.V(4).Info("Creating event broadcaster") eventBroadcaster := record.NewBroadcaster() @@ -240,6 +239,25 @@ func NewMonitor( } glog.Info("Setting up event handlers") + // Set up an event handler for when Bus resources change + busInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { + bus := obj.(*channelsv1alpha1.Bus) + monitor.workqueue.AddRateLimited(makeWorkqueueKeyForBus(bus)) + }, + UpdateFunc: func(old, new interface{}) { + oldBus := old.(*channelsv1alpha1.Bus) + newBus := new.(*channelsv1alpha1.Bus) + + if oldBus.ResourceVersion == newBus.ResourceVersion { + // Periodic resync will send update events for all known Buses. + // Two different versions of the same Bus will always have different RVs. + return + } + + monitor.workqueue.AddRateLimited(makeWorkqueueKeyForBus(newBus)) + }, + }) // Set up an event handler for when ClusterBus resources change clusterBusInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { @@ -354,19 +372,19 @@ func (m *Monitor) Subscriptions(channelName string, namespace string) *[]channel } func (m *Monitor) channelAttributes(channel channelsv1alpha1.ChannelSpec) (Attributes, error) { - clusterBusParameters := m.bus.GetSpec().Parameters + genericBusParameters := m.bus.GetSpec().Parameters var parameters *[]channelsv1alpha1.Parameter - if clusterBusParameters != nil { - parameters = clusterBusParameters.Channel + if genericBusParameters != nil { + parameters = genericBusParameters.Channel } return m.resolveAttributes(parameters, channel.Arguments) } func (m *Monitor) subscriptionAttributes(subscription channelsv1alpha1.SubscriptionSpec) (Attributes, error) { - clusterBusParameters := m.bus.GetSpec().Parameters + genericBusParameters := m.bus.GetSpec().Parameters var parameters *[]channelsv1alpha1.Parameter - if clusterBusParameters != nil { - parameters = clusterBusParameters.Subscription + if genericBusParameters != nil { + parameters = genericBusParameters.Subscription } return m.resolveAttributes(parameters, subscription.Arguments) } @@ -421,7 +439,7 @@ func (m *Monitor) RequeueSubscription(subscription *channelsv1alpha1.Subscriptio // as syncing informer caches and starting workers. It will block until stopCh // is closed, at which point it will shutdown the workqueue and wait for // workers to finish processing their current work items. -func (m *Monitor) Run(busName, busNamespace string, threadiness int, stopCh <-chan struct{}) error { +func (m *Monitor) Run(busNamespace, busName string, threadiness int, stopCh <-chan struct{}) error { defer runtime.HandleCrash() defer m.workqueue.ShutDown() @@ -452,7 +470,7 @@ func (m *Monitor) Run(busName, busNamespace string, threadiness int, stopCh <-ch } glog.Info("Starting workers") - // Launch two workers to process ClusterBus resources + // Launch workers to process resources for i := 0; i < threadiness; i++ { go wait.Until(m.runWorker, time.Second, stopCh) } @@ -526,8 +544,8 @@ func (m *Monitor) processNextWorkItem() bool { } // syncHandler compares the actual state with the desired, and attempts to -// converge the two. It then updates the Status block of the ClusterBus resource -// with the current status of the resource. +// converge the two. It then updates the Status block of the resource with the +// current status. func (m *Monitor) syncHandler(key string) error { // Convert the namespace/name string into a distinct namespace and name kind, namespace, name, err := splitWorkqueueKey(key) @@ -676,7 +694,8 @@ func (m *Monitor) getOrCreateChannelSummary(key channelKey) *channelSummary { } func (m *Monitor) createOrUpdateBus(bus *channelsv1alpha1.Bus) error { - if bus.Namespace == m.bus.GetObjectMeta().GetNamespace() && bus.Name != m.bus.GetObjectMeta().GetName() { + if bus.Namespace != m.bus.GetObjectMeta().GetNamespace() || + bus.Name != m.bus.GetObjectMeta().GetName() { // this is not our bus return nil } @@ -849,6 +868,10 @@ func makeSubscriptionKeyWithNames(namespace string, name string) subscriptionKey } } +func makeWorkqueueKeyForBus(bus *channelsv1alpha1.Bus) string { + return makeWorkqueueKey(busKind, bus.Namespace, bus.Name) +} + func makeWorkqueueKeyForClusterBus(clusterBus *channelsv1alpha1.ClusterBus) string { return makeWorkqueueKey(clusterBusKind, "", clusterBus.Name) } diff --git a/pkg/buses/stub/main.go b/pkg/buses/stub/main.go index 64031411905..019290a9daa 100644 --- a/pkg/buses/stub/main.go +++ b/pkg/buses/stub/main.go @@ -99,7 +99,7 @@ func (b *StubBus) dispatchEvent(subscriber string, body []byte, headers http.Hea func (b *StubBus) resolveSubscriber(subscription channelsv1alpha1.SubscriptionSpec, namespace string) string { subscriber := subscription.Subscriber if strings.Index(subscriber, ".") == -1 { - subscriber = fmt.Sprintf("%s.%s.svc.cluster.local", subscriber, namespace) + subscriber = fmt.Sprintf("%s.%s", subscriber, namespace) } return subscriber } @@ -174,7 +174,7 @@ func main() { bus := NewStubBus(busName, monitor) go func() { - if err := monitor.Run(busName, busNamespace, threadsPerMonitor, stopCh); err != nil { + if err := monitor.Run(busNamespace, busName, threadsPerMonitor, stopCh); err != nil { glog.Fatalf("Error running monitor: %s", err.Error()) } }() diff --git a/pkg/webhook/channel.go b/pkg/webhook/channel.go index c2cb027efb0..8b16604289f 100644 --- a/pkg/webhook/channel.go +++ b/pkg/webhook/channel.go @@ -28,7 +28,7 @@ var ( errInvalidChannelInput = errors.New("failed to convert input into Channel") errInvalidChannelBusMissing = errors.New("the Channel must reference a Bus or ClusterBus") errInvalidChannelBusExclusivity = errors.New("the Channel must reference either a Bus or ClusterBus, not both") - errInvalidChannelBusMutation = errors.New("the Channel's ClusterBus may not change") + errInvalidChannelBusMutation = errors.New("the Channel's Bus may not change") errInvalidChannelClusterBusMutation = errors.New("the Channel's ClusterBus may not change") ) diff --git a/sample/hello/hello-channel.yaml b/sample/hello/hello-channel.yaml index 849d1ccfc88..b7d8c7dbc49 100644 --- a/sample/hello/hello-channel.yaml +++ b/sample/hello/hello-channel.yaml @@ -3,4 +3,4 @@ kind: Channel metadata: name: aloha spec: - clusterBus: stub + bus: stub From 3c1be8389e954d0a15f450a378ab74ba3e291633 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Wed, 27 Jun 2018 14:07:41 -0400 Subject: [PATCH 7/7] Channel CRD Status properties are no longer pointers --- Gopkg.lock | 2 +- pkg/apis/channels/v1alpha1/bus_types.go | 4 +- pkg/apis/channels/v1alpha1/channel_types.go | 4 +- .../channels/v1alpha1/clusterbus_types.go | 4 +- .../channels/v1alpha1/subscription_types.go | 4 +- .../v1alpha1/zz_generated.deepcopy.go | 40 ++----------------- 6 files changed, 13 insertions(+), 45 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 59fbf3f80c5..16b73bda01d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -897,6 +897,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "dfe6a86a6b4b2e5617ee80431b66faa49acd84654f854782313924cfc14bc79f" + inputs-digest = "001aef2bcc7b7a7f3d307748cd9b0615acff2999d22ff7b3fcfc76a807420e69" solver-name = "gps-cdcl" solver-version = 1 diff --git a/pkg/apis/channels/v1alpha1/bus_types.go b/pkg/apis/channels/v1alpha1/bus_types.go index 9db3683fbba..96bc509247b 100644 --- a/pkg/apis/channels/v1alpha1/bus_types.go +++ b/pkg/apis/channels/v1alpha1/bus_types.go @@ -33,8 +33,8 @@ import ( type Bus struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ObjectMeta `json:"metadata"` - Spec BusSpec `json:"spec"` - Status *BusStatus `json:"status,omitempty"` + Spec BusSpec `json:"spec"` + Status BusStatus `json:"status,omitempty"` } // BusSpec (what the user wants) for a bus diff --git a/pkg/apis/channels/v1alpha1/channel_types.go b/pkg/apis/channels/v1alpha1/channel_types.go index 72064ed74b6..18f53102d2f 100644 --- a/pkg/apis/channels/v1alpha1/channel_types.go +++ b/pkg/apis/channels/v1alpha1/channel_types.go @@ -31,8 +31,8 @@ import ( type Channel struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ObjectMeta `json:"metadata"` - Spec ChannelSpec `json:"spec"` - Status *ChannelStatus `json:"status,omitempty"` + Spec ChannelSpec `json:"spec"` + Status ChannelStatus `json:"status,omitempty"` } // ChannelSpec (what the user wants) for a channel diff --git a/pkg/apis/channels/v1alpha1/clusterbus_types.go b/pkg/apis/channels/v1alpha1/clusterbus_types.go index ce74f791268..6b726e1fe15 100644 --- a/pkg/apis/channels/v1alpha1/clusterbus_types.go +++ b/pkg/apis/channels/v1alpha1/clusterbus_types.go @@ -32,8 +32,8 @@ import ( type ClusterBus struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ObjectMeta `json:"metadata"` - Spec ClusterBusSpec `json:"spec"` - Status *ClusterBusStatus `json:"status,omitempty"` + Spec ClusterBusSpec `json:"spec"` + Status ClusterBusStatus `json:"status,omitempty"` } // ClusterBusSpec (what the user wants) for a clusterbus diff --git a/pkg/apis/channels/v1alpha1/subscription_types.go b/pkg/apis/channels/v1alpha1/subscription_types.go index 942202bb666..e3efb5de4f4 100644 --- a/pkg/apis/channels/v1alpha1/subscription_types.go +++ b/pkg/apis/channels/v1alpha1/subscription_types.go @@ -31,8 +31,8 @@ import ( type Subscription struct { meta_v1.TypeMeta `json:",inline"` meta_v1.ObjectMeta `json:"metadata"` - Spec SubscriptionSpec `json:"spec"` - Status *SubscriptionStatus `json:"status,omitempty"` + Spec SubscriptionSpec `json:"spec"` + Status SubscriptionStatus `json:"status,omitempty"` } // SubscriptionSpec (what the user wants) for a subscription diff --git a/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go index 0adb2a6cb19..14bc4b7b849 100644 --- a/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/channels/v1alpha1/zz_generated.deepcopy.go @@ -47,15 +47,7 @@ func (in *Bus) DeepCopyInto(out *Bus) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - if *in == nil { - *out = nil - } else { - *out = new(BusStatus) - **out = **in - } - } + out.Status = in.Status return } @@ -228,15 +220,7 @@ func (in *Channel) DeepCopyInto(out *Channel) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - if *in == nil { - *out = nil - } else { - *out = new(ChannelStatus) - **out = **in - } - } + out.Status = in.Status return } @@ -342,15 +326,7 @@ func (in *ClusterBus) DeepCopyInto(out *ClusterBus) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - if *in == nil { - *out = nil - } else { - *out = new(ClusterBusStatus) - **out = **in - } - } + out.Status = in.Status return } @@ -452,15 +428,7 @@ func (in *Subscription) DeepCopyInto(out *Subscription) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - if *in == nil { - *out = nil - } else { - *out = new(SubscriptionStatus) - **out = **in - } - } + out.Status = in.Status return }