diff --git a/cmd/controller-manager/app/controller_manager.go b/cmd/controller-manager/app/controller_manager.go index bf929b4936a..eea82f8d4a5 100644 --- a/cmd/controller-manager/app/controller_manager.go +++ b/cmd/controller-manager/app/controller_manager.go @@ -292,6 +292,7 @@ func StartControllers(s *options.ControllerManagerServer, serviceCatalogSharedInformers.Instances(), serviceCatalogSharedInformers.Bindings(), openservicebroker.NewClient, + s.OSBAPIContextProfile, ) if err != nil { return err diff --git a/cmd/controller-manager/app/options/options.go b/cmd/controller-manager/app/options/options.go index c671b3b2159..aa7889dfa60 100644 --- a/cmd/controller-manager/app/options/options.go +++ b/cmd/controller-manager/app/options/options.go @@ -41,6 +41,7 @@ const defaultBindAddress = "0.0.0.0" const defaultPort = 10000 const defaultK8sKubeconfigPath = "./kubeconfig" const defaultServiceCatalogKubeconfigPath = "./service-catalog-kubeconfig" +const defaultOSBAPIContextProfile = true // NewControllerManagerServer creates a new ControllerManagerServer with a // default config. @@ -53,6 +54,7 @@ func NewControllerManagerServer() *ControllerManagerServer { K8sKubeconfigPath: defaultK8sKubeconfigPath, ServiceCatalogKubeconfigPath: defaultServiceCatalogKubeconfigPath, ResyncInterval: defaultResyncInterval, + OSBAPIContextProfile: defaultOSBAPIContextProfile, }, } } @@ -67,4 +69,5 @@ func (s *ControllerManagerServer) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&s.ServiceCatalogAPIServerURL, "service-catalog-api-server-url", "", "The URL for the service-catalog API server") fs.StringVar(&s.ServiceCatalogKubeconfigPath, "service-catalog-kubeconfig", s.ServiceCatalogKubeconfigPath, "Path to service-catalog kubeconfig") fs.DurationVar(&s.ResyncInterval, "resync-interval", s.ResyncInterval, "The interval on which the controller will resync its informers") + fs.BoolVar(&s.OSBAPIContextProfile, "enable-osb-api-context-profile", s.OSBAPIContextProfile, "Whether or not to send the proposed optional OpenServiceBroker API Context Profile field") } diff --git a/pkg/apis/componentconfig/types.go b/pkg/apis/componentconfig/types.go index d6de8824966..bf32dc737b6 100644 --- a/pkg/apis/componentconfig/types.go +++ b/pkg/apis/componentconfig/types.go @@ -56,4 +56,8 @@ type ControllerManagerConfiguration struct { // ResyncInterval is the interval on which the controller should re-sync // all informers. ResyncInterval time.Duration + + // Whether or not to send the proposed optional + // OpenServiceBroker API Context Profile field + OSBAPIContextProfile bool } diff --git a/pkg/brokerapi/fake/fake.go b/pkg/brokerapi/fake/fake.go index cfdc94e13cf..87030b15af9 100644 --- a/pkg/brokerapi/fake/fake.go +++ b/pkg/brokerapi/fake/fake.go @@ -17,6 +17,7 @@ limitations under the License. package fake import ( + "errors" "fmt" "github.com/kubernetes-incubator/service-catalog/pkg/brokerapi" @@ -91,6 +92,13 @@ func (i *InstanceClient) CreateServiceInstance( if i.exists(id) { return nil, ErrInstanceAlreadyExists } + // context profile and contents should always (optionally) exist. + if req.ContextProfile.Platform != brokerapi.ContextProfilePlatformKubernetes { + return nil, errors.New("OSB context profile not set to " + brokerapi.ContextProfilePlatformKubernetes) + } + if req.ContextProfile.Namespace == "" { + return nil, errors.New("missing valid OSB context profile namespace") + } i.Instances[id] = convertInstanceRequest(req) return &brokerapi.CreateServiceInstanceResponse{}, nil diff --git a/pkg/brokerapi/service_instance.go b/pkg/brokerapi/service_instance.go index 70372f3ee66..2475559b80e 100644 --- a/pkg/brokerapi/service_instance.go +++ b/pkg/brokerapi/service_instance.go @@ -40,6 +40,20 @@ type CreateServiceInstanceRequest struct { SpaceID string `json:"space_guid,omitempty"` Parameters map[string]interface{} `json:"parameters,omitempty"` AcceptsIncomplete bool `json:"accepts_incomplete,omitempty"` + ContextProfile ContextProfile `json:"context,omitempty"` +} + +// ContextProfilePlatformKubernetes is a constant to send when the +// client is representing a kubernetes style ecosystem. +const ContextProfilePlatformKubernetes string = "kubernetes" + +// ContextProfile implements the optional OSB field +// https://github.com/duglin/servicebroker/blob/CFisms/context-profiles.md#kubernetes +type ContextProfile struct { + // Platform is always `kubernetes` + Platform string `json:"platform,omitempty"` + // Namespace is the Kubernetes namespace in which the service instance will be visible. + Namespace string `json:"namespace,omitempty"` } // CreateServiceInstanceResponse represents the response from a broker after a diff --git a/pkg/controller/controller.go b/pkg/controller/controller.go index 5207d8e7287..d50e7c9631d 100644 --- a/pkg/controller/controller.go +++ b/pkg/controller/controller.go @@ -52,6 +52,7 @@ func NewController( instanceInformer informers.InstanceInformer, bindingInformer informers.BindingInformer, brokerClientCreateFunc brokerapi.CreateFunc, + osbAPIContextProfile bool, ) (Controller, error) { var ( @@ -60,12 +61,13 @@ func NewController( instanceLister = instanceInformer.Lister() controller = &controller{ - kubeClient: kubeClient, - serviceCatalogClient: serviceCatalogClient, - brokerClientCreateFunc: brokerClientCreateFunc, - brokerLister: brokerLister, - serviceClassLister: serviceClassLister, - instanceLister: instanceLister, + kubeClient: kubeClient, + serviceCatalogClient: serviceCatalogClient, + brokerClientCreateFunc: brokerClientCreateFunc, + brokerLister: brokerLister, + serviceClassLister: serviceClassLister, + instanceLister: instanceLister, + enableOSBAPIContextProfle: osbAPIContextProfile, } ) @@ -105,12 +107,13 @@ type Controller interface { // controller is a concrete Controller. type controller struct { - kubeClient kubernetes.Interface - serviceCatalogClient servicecatalogclientset.ServicecatalogV1alpha1Interface - brokerClientCreateFunc brokerapi.CreateFunc - brokerLister listers.BrokerLister - serviceClassLister listers.ServiceClassLister - instanceLister listers.InstanceLister + kubeClient kubernetes.Interface + serviceCatalogClient servicecatalogclientset.ServicecatalogV1alpha1Interface + brokerClientCreateFunc brokerapi.CreateFunc + brokerLister listers.BrokerLister + serviceClassLister listers.ServiceClassLister + instanceLister listers.InstanceLister + enableOSBAPIContextProfle bool } // Run runs the controller until the given stop channel can be read from. @@ -548,6 +551,12 @@ func (c *controller) reconcileInstance(instance *v1alpha1.Instance) { SpaceID: string(ns.UID), AcceptsIncomplete: true, } + if c.enableOSBAPIContextProfle { + request.ContextProfile = brokerapi.ContextProfile{ + Platform: brokerapi.ContextProfilePlatformKubernetes, + Namespace: instance.Namespace, + } + } // TODO: handle async provisioning diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 2d066add168..8bafaedbf19 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -1866,6 +1866,7 @@ func newTestController(t *testing.T) ( serviceCatalogSharedInformers.Instances(), serviceCatalogSharedInformers.Bindings(), brokerClFunc, + true, ) if err != nil { t.Fatal(err) diff --git a/test/integration/controller_test.go b/test/integration/controller_test.go index d5d62ce070c..38aa7815606 100644 --- a/test/integration/controller_test.go +++ b/test/integration/controller_test.go @@ -275,6 +275,7 @@ func newTestController(t *testing.T) ( serviceCatalogSharedInformers.Instances(), serviceCatalogSharedInformers.Bindings(), brokerClFunc, + true, ) t.Log("controller start") if err != nil {