diff --git a/charts/service-broker-proxy-k8s/templates/deployment.yaml b/charts/service-broker-proxy-k8s/templates/deployment.yaml index c5adeff2..6defefae 100644 --- a/charts/service-broker-proxy-k8s/templates/deployment.yaml +++ b/charts/service-broker-proxy-k8s/templates/deployment.yaml @@ -45,6 +45,8 @@ spec: value: {{ template "service-broker-proxy.fullname" . }}-regsecret - name: K8S_SECRET_NAMESPACE value: {{ .Release.Namespace }} + - name: K8S_TARGET_NAMESPACE + value: {{ .Values.targetNamespace }} - name: SM_USER valueFrom: secretKeyRef: diff --git a/charts/service-broker-proxy-k8s/templates/rbac.yaml b/charts/service-broker-proxy-k8s/templates/rbac.yaml index 8f9fd692..9987d6e2 100644 --- a/charts/service-broker-proxy-k8s/templates/rbac.yaml +++ b/charts/service-broker-proxy-k8s/templates/rbac.yaml @@ -10,7 +10,11 @@ metadata: rules: - apiGroups: ["servicecatalog.k8s.io"] resources: + {{- if .Values.targetNamespace }} + - servicebrokers + {{- else}} - clusterservicebrokers + {{- end}} verbs: - "*" @@ -71,3 +75,47 @@ subjects: - kind: ServiceAccount name: {{ template "service-broker-proxy.fullname" . }} namespace: {{ .Release.Namespace }} + +{{- if .Values.targetNamespace }} +{{- if ne .Values.targetNamespace .Release.Namespace }} + +--- + +kind: Role +apiVersion: rbac.authorization.k8s.io/v1beta1 +metadata: + namespace: {{ .Values.targetNamespace }} + name: {{ template "service-broker-proxy.fullname" . }}-regsecretviewer + labels: + app: {{ template "service-broker-proxy.name" . }} + chart: {{ template "service-broker-proxy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create", "delete", "update", "patch"] + +--- + +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "service-broker-proxy.fullname" . }} + namespace: {{ .Values.targetNamespace }} + labels: + app: {{ template "service-broker-proxy.name" . }} + chart: {{ template "service-broker-proxy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + kind: Role + name: {{ template "service-broker-proxy.fullname" . }}-regsecretviewer + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ template "service-broker-proxy.fullname" . }} + namespace: {{ .Release.Namespace }} + +{{- end}} +{{- end}} \ No newline at end of file diff --git a/charts/service-broker-proxy-k8s/values.yaml b/charts/service-broker-proxy-k8s/values.yaml index a737ebe7..e4799c25 100644 --- a/charts/service-broker-proxy-k8s/values.yaml +++ b/charts/service-broker-proxy-k8s/values.yaml @@ -23,6 +23,9 @@ sm: user: admin password: admin +# targetNamespace is the namespace in which service brokers will be registered, if not set service brokers will be registered in cluster scope +targetNamespace: + ## # Security context securityContext: {} diff --git a/pkg/k8s/api/api.go b/pkg/k8s/api/api.go index c515551c..e6cc68f2 100644 --- a/pkg/k8s/api/api.go +++ b/pkg/k8s/api/api.go @@ -21,8 +21,22 @@ type KubernetesAPI interface { UpdateClusterServiceBroker(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) // SyncClusterServiceBroker synchronize a cluster-wide visible service broker SyncClusterServiceBroker(name string, retries int) error - // UpdateClusterServiceBrokerCredentials updates broker's credentials secret - UpdateClusterServiceBrokerCredentials(secret *v1core.Secret) (*v1core.Secret, error) + + // CreateNamespaceServiceBroker creates namespace service broker + CreateNamespaceServiceBroker(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) + // DeleteNamespaceServiceBroker deletes a service broker in a namespace + DeleteNamespaceServiceBroker(name string, namespace string, options *v1.DeleteOptions) error + // RetrieveNamespaceServiceBrokers gets all service brokers in a namespace + RetrieveNamespaceServiceBrokers(namespace string) (*v1beta1.ServiceBrokerList, error) + // RetrieveNamespaceServiceBrokerByName gets a service broker in a namespace + RetrieveNamespaceServiceBrokerByName(name, namespace string) (*v1beta1.ServiceBroker, error) + // UpdateNamespaceServiceBroker updates a service broker in a namespace + UpdateNamespaceServiceBroker(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) + // SyncNamespaceServiceBroker synchronize a service broker in a namespace + SyncNamespaceServiceBroker(name, namespace string, retries int) error + + // UpdateServiceBrokerCredentials updates broker's credentials secret + UpdateServiceBrokerCredentials(secret *v1core.Secret) (*v1core.Secret, error) // CreateSecret creates a secret for broker's credentials CreateSecret(secret *v1core.Secret) (*v1core.Secret, error) // DeleteSecret deletes broker credentials secret diff --git a/pkg/k8s/api/apifakes/fake_kubernetes_api.go b/pkg/k8s/api/apifakes/fake_kubernetes_api.go index 4b651bc6..72ebcc3d 100644 --- a/pkg/k8s/api/apifakes/fake_kubernetes_api.go +++ b/pkg/k8s/api/apifakes/fake_kubernetes_api.go @@ -24,6 +24,20 @@ type FakeKubernetesAPI struct { result1 *v1beta1.ClusterServiceBroker result2 error } + CreateNamespaceServiceBrokerStub func(*v1beta1.ServiceBroker, string) (*v1beta1.ServiceBroker, error) + createNamespaceServiceBrokerMutex sync.RWMutex + createNamespaceServiceBrokerArgsForCall []struct { + arg1 *v1beta1.ServiceBroker + arg2 string + } + createNamespaceServiceBrokerReturns struct { + result1 *v1beta1.ServiceBroker + result2 error + } + createNamespaceServiceBrokerReturnsOnCall map[int]struct { + result1 *v1beta1.ServiceBroker + result2 error + } CreateSecretStub func(*v1.Secret) (*v1.Secret, error) createSecretMutex sync.RWMutex createSecretArgsForCall []struct { @@ -49,6 +63,19 @@ type FakeKubernetesAPI struct { deleteClusterServiceBrokerReturnsOnCall map[int]struct { result1 error } + DeleteNamespaceServiceBrokerStub func(string, string, *v1a.DeleteOptions) error + deleteNamespaceServiceBrokerMutex sync.RWMutex + deleteNamespaceServiceBrokerArgsForCall []struct { + arg1 string + arg2 string + arg3 *v1a.DeleteOptions + } + deleteNamespaceServiceBrokerReturns struct { + result1 error + } + deleteNamespaceServiceBrokerReturnsOnCall map[int]struct { + result1 error + } DeleteSecretStub func(string, string) error deleteSecretMutex sync.RWMutex deleteSecretArgsForCall []struct { @@ -86,6 +113,33 @@ type FakeKubernetesAPI struct { result1 *v1beta1.ClusterServiceBrokerList result2 error } + RetrieveNamespaceServiceBrokerByNameStub func(string, string) (*v1beta1.ServiceBroker, error) + retrieveNamespaceServiceBrokerByNameMutex sync.RWMutex + retrieveNamespaceServiceBrokerByNameArgsForCall []struct { + arg1 string + arg2 string + } + retrieveNamespaceServiceBrokerByNameReturns struct { + result1 *v1beta1.ServiceBroker + result2 error + } + retrieveNamespaceServiceBrokerByNameReturnsOnCall map[int]struct { + result1 *v1beta1.ServiceBroker + result2 error + } + RetrieveNamespaceServiceBrokersStub func(string) (*v1beta1.ServiceBrokerList, error) + retrieveNamespaceServiceBrokersMutex sync.RWMutex + retrieveNamespaceServiceBrokersArgsForCall []struct { + arg1 string + } + retrieveNamespaceServiceBrokersReturns struct { + result1 *v1beta1.ServiceBrokerList + result2 error + } + retrieveNamespaceServiceBrokersReturnsOnCall map[int]struct { + result1 *v1beta1.ServiceBrokerList + result2 error + } SyncClusterServiceBrokerStub func(string, int) error syncClusterServiceBrokerMutex sync.RWMutex syncClusterServiceBrokerArgsForCall []struct { @@ -98,6 +152,19 @@ type FakeKubernetesAPI struct { syncClusterServiceBrokerReturnsOnCall map[int]struct { result1 error } + SyncNamespaceServiceBrokerStub func(string, string, int) error + syncNamespaceServiceBrokerMutex sync.RWMutex + syncNamespaceServiceBrokerArgsForCall []struct { + arg1 string + arg2 string + arg3 int + } + syncNamespaceServiceBrokerReturns struct { + result1 error + } + syncNamespaceServiceBrokerReturnsOnCall map[int]struct { + result1 error + } UpdateClusterServiceBrokerStub func(*v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) updateClusterServiceBrokerMutex sync.RWMutex updateClusterServiceBrokerArgsForCall []struct { @@ -111,16 +178,30 @@ type FakeKubernetesAPI struct { result1 *v1beta1.ClusterServiceBroker result2 error } - UpdateClusterServiceBrokerCredentialsStub func(*v1.Secret) (*v1.Secret, error) - updateClusterServiceBrokerCredentialsMutex sync.RWMutex - updateClusterServiceBrokerCredentialsArgsForCall []struct { + UpdateNamespaceServiceBrokerStub func(*v1beta1.ServiceBroker, string) (*v1beta1.ServiceBroker, error) + updateNamespaceServiceBrokerMutex sync.RWMutex + updateNamespaceServiceBrokerArgsForCall []struct { + arg1 *v1beta1.ServiceBroker + arg2 string + } + updateNamespaceServiceBrokerReturns struct { + result1 *v1beta1.ServiceBroker + result2 error + } + updateNamespaceServiceBrokerReturnsOnCall map[int]struct { + result1 *v1beta1.ServiceBroker + result2 error + } + UpdateServiceBrokerCredentialsStub func(*v1.Secret) (*v1.Secret, error) + updateServiceBrokerCredentialsMutex sync.RWMutex + updateServiceBrokerCredentialsArgsForCall []struct { arg1 *v1.Secret } - updateClusterServiceBrokerCredentialsReturns struct { + updateServiceBrokerCredentialsReturns struct { result1 *v1.Secret result2 error } - updateClusterServiceBrokerCredentialsReturnsOnCall map[int]struct { + updateServiceBrokerCredentialsReturnsOnCall map[int]struct { result1 *v1.Secret result2 error } @@ -191,6 +272,70 @@ func (fake *FakeKubernetesAPI) CreateClusterServiceBrokerReturnsOnCall(i int, re }{result1, result2} } +func (fake *FakeKubernetesAPI) CreateNamespaceServiceBroker(arg1 *v1beta1.ServiceBroker, arg2 string) (*v1beta1.ServiceBroker, error) { + fake.createNamespaceServiceBrokerMutex.Lock() + ret, specificReturn := fake.createNamespaceServiceBrokerReturnsOnCall[len(fake.createNamespaceServiceBrokerArgsForCall)] + fake.createNamespaceServiceBrokerArgsForCall = append(fake.createNamespaceServiceBrokerArgsForCall, struct { + arg1 *v1beta1.ServiceBroker + arg2 string + }{arg1, arg2}) + fake.recordInvocation("CreateNamespaceServiceBroker", []interface{}{arg1, arg2}) + fake.createNamespaceServiceBrokerMutex.Unlock() + if fake.CreateNamespaceServiceBrokerStub != nil { + return fake.CreateNamespaceServiceBrokerStub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.createNamespaceServiceBrokerReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeKubernetesAPI) CreateNamespaceServiceBrokerCallCount() int { + fake.createNamespaceServiceBrokerMutex.RLock() + defer fake.createNamespaceServiceBrokerMutex.RUnlock() + return len(fake.createNamespaceServiceBrokerArgsForCall) +} + +func (fake *FakeKubernetesAPI) CreateNamespaceServiceBrokerCalls(stub func(*v1beta1.ServiceBroker, string) (*v1beta1.ServiceBroker, error)) { + fake.createNamespaceServiceBrokerMutex.Lock() + defer fake.createNamespaceServiceBrokerMutex.Unlock() + fake.CreateNamespaceServiceBrokerStub = stub +} + +func (fake *FakeKubernetesAPI) CreateNamespaceServiceBrokerArgsForCall(i int) (*v1beta1.ServiceBroker, string) { + fake.createNamespaceServiceBrokerMutex.RLock() + defer fake.createNamespaceServiceBrokerMutex.RUnlock() + argsForCall := fake.createNamespaceServiceBrokerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeKubernetesAPI) CreateNamespaceServiceBrokerReturns(result1 *v1beta1.ServiceBroker, result2 error) { + fake.createNamespaceServiceBrokerMutex.Lock() + defer fake.createNamespaceServiceBrokerMutex.Unlock() + fake.CreateNamespaceServiceBrokerStub = nil + fake.createNamespaceServiceBrokerReturns = struct { + result1 *v1beta1.ServiceBroker + result2 error + }{result1, result2} +} + +func (fake *FakeKubernetesAPI) CreateNamespaceServiceBrokerReturnsOnCall(i int, result1 *v1beta1.ServiceBroker, result2 error) { + fake.createNamespaceServiceBrokerMutex.Lock() + defer fake.createNamespaceServiceBrokerMutex.Unlock() + fake.CreateNamespaceServiceBrokerStub = nil + if fake.createNamespaceServiceBrokerReturnsOnCall == nil { + fake.createNamespaceServiceBrokerReturnsOnCall = make(map[int]struct { + result1 *v1beta1.ServiceBroker + result2 error + }) + } + fake.createNamespaceServiceBrokerReturnsOnCall[i] = struct { + result1 *v1beta1.ServiceBroker + result2 error + }{result1, result2} +} + func (fake *FakeKubernetesAPI) CreateSecret(arg1 *v1.Secret) (*v1.Secret, error) { fake.createSecretMutex.Lock() ret, specificReturn := fake.createSecretReturnsOnCall[len(fake.createSecretArgsForCall)] @@ -315,6 +460,68 @@ func (fake *FakeKubernetesAPI) DeleteClusterServiceBrokerReturnsOnCall(i int, re }{result1} } +func (fake *FakeKubernetesAPI) DeleteNamespaceServiceBroker(arg1 string, arg2 string, arg3 *v1a.DeleteOptions) error { + fake.deleteNamespaceServiceBrokerMutex.Lock() + ret, specificReturn := fake.deleteNamespaceServiceBrokerReturnsOnCall[len(fake.deleteNamespaceServiceBrokerArgsForCall)] + fake.deleteNamespaceServiceBrokerArgsForCall = append(fake.deleteNamespaceServiceBrokerArgsForCall, struct { + arg1 string + arg2 string + arg3 *v1a.DeleteOptions + }{arg1, arg2, arg3}) + fake.recordInvocation("DeleteNamespaceServiceBroker", []interface{}{arg1, arg2, arg3}) + fake.deleteNamespaceServiceBrokerMutex.Unlock() + if fake.DeleteNamespaceServiceBrokerStub != nil { + return fake.DeleteNamespaceServiceBrokerStub(arg1, arg2, arg3) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.deleteNamespaceServiceBrokerReturns + return fakeReturns.result1 +} + +func (fake *FakeKubernetesAPI) DeleteNamespaceServiceBrokerCallCount() int { + fake.deleteNamespaceServiceBrokerMutex.RLock() + defer fake.deleteNamespaceServiceBrokerMutex.RUnlock() + return len(fake.deleteNamespaceServiceBrokerArgsForCall) +} + +func (fake *FakeKubernetesAPI) DeleteNamespaceServiceBrokerCalls(stub func(string, string, *v1a.DeleteOptions) error) { + fake.deleteNamespaceServiceBrokerMutex.Lock() + defer fake.deleteNamespaceServiceBrokerMutex.Unlock() + fake.DeleteNamespaceServiceBrokerStub = stub +} + +func (fake *FakeKubernetesAPI) DeleteNamespaceServiceBrokerArgsForCall(i int) (string, string, *v1a.DeleteOptions) { + fake.deleteNamespaceServiceBrokerMutex.RLock() + defer fake.deleteNamespaceServiceBrokerMutex.RUnlock() + argsForCall := fake.deleteNamespaceServiceBrokerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeKubernetesAPI) DeleteNamespaceServiceBrokerReturns(result1 error) { + fake.deleteNamespaceServiceBrokerMutex.Lock() + defer fake.deleteNamespaceServiceBrokerMutex.Unlock() + fake.DeleteNamespaceServiceBrokerStub = nil + fake.deleteNamespaceServiceBrokerReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeKubernetesAPI) DeleteNamespaceServiceBrokerReturnsOnCall(i int, result1 error) { + fake.deleteNamespaceServiceBrokerMutex.Lock() + defer fake.deleteNamespaceServiceBrokerMutex.Unlock() + fake.DeleteNamespaceServiceBrokerStub = nil + if fake.deleteNamespaceServiceBrokerReturnsOnCall == nil { + fake.deleteNamespaceServiceBrokerReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.deleteNamespaceServiceBrokerReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakeKubernetesAPI) DeleteSecret(arg1 string, arg2 string) error { fake.deleteSecretMutex.Lock() ret, specificReturn := fake.deleteSecretReturnsOnCall[len(fake.deleteSecretArgsForCall)] @@ -494,6 +701,133 @@ func (fake *FakeKubernetesAPI) RetrieveClusterServiceBrokersReturnsOnCall(i int, }{result1, result2} } +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokerByName(arg1 string, arg2 string) (*v1beta1.ServiceBroker, error) { + fake.retrieveNamespaceServiceBrokerByNameMutex.Lock() + ret, specificReturn := fake.retrieveNamespaceServiceBrokerByNameReturnsOnCall[len(fake.retrieveNamespaceServiceBrokerByNameArgsForCall)] + fake.retrieveNamespaceServiceBrokerByNameArgsForCall = append(fake.retrieveNamespaceServiceBrokerByNameArgsForCall, struct { + arg1 string + arg2 string + }{arg1, arg2}) + fake.recordInvocation("RetrieveNamespaceServiceBrokerByName", []interface{}{arg1, arg2}) + fake.retrieveNamespaceServiceBrokerByNameMutex.Unlock() + if fake.RetrieveNamespaceServiceBrokerByNameStub != nil { + return fake.RetrieveNamespaceServiceBrokerByNameStub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.retrieveNamespaceServiceBrokerByNameReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokerByNameCallCount() int { + fake.retrieveNamespaceServiceBrokerByNameMutex.RLock() + defer fake.retrieveNamespaceServiceBrokerByNameMutex.RUnlock() + return len(fake.retrieveNamespaceServiceBrokerByNameArgsForCall) +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokerByNameCalls(stub func(string, string) (*v1beta1.ServiceBroker, error)) { + fake.retrieveNamespaceServiceBrokerByNameMutex.Lock() + defer fake.retrieveNamespaceServiceBrokerByNameMutex.Unlock() + fake.RetrieveNamespaceServiceBrokerByNameStub = stub +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokerByNameArgsForCall(i int) (string, string) { + fake.retrieveNamespaceServiceBrokerByNameMutex.RLock() + defer fake.retrieveNamespaceServiceBrokerByNameMutex.RUnlock() + argsForCall := fake.retrieveNamespaceServiceBrokerByNameArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokerByNameReturns(result1 *v1beta1.ServiceBroker, result2 error) { + fake.retrieveNamespaceServiceBrokerByNameMutex.Lock() + defer fake.retrieveNamespaceServiceBrokerByNameMutex.Unlock() + fake.RetrieveNamespaceServiceBrokerByNameStub = nil + fake.retrieveNamespaceServiceBrokerByNameReturns = struct { + result1 *v1beta1.ServiceBroker + result2 error + }{result1, result2} +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokerByNameReturnsOnCall(i int, result1 *v1beta1.ServiceBroker, result2 error) { + fake.retrieveNamespaceServiceBrokerByNameMutex.Lock() + defer fake.retrieveNamespaceServiceBrokerByNameMutex.Unlock() + fake.RetrieveNamespaceServiceBrokerByNameStub = nil + if fake.retrieveNamespaceServiceBrokerByNameReturnsOnCall == nil { + fake.retrieveNamespaceServiceBrokerByNameReturnsOnCall = make(map[int]struct { + result1 *v1beta1.ServiceBroker + result2 error + }) + } + fake.retrieveNamespaceServiceBrokerByNameReturnsOnCall[i] = struct { + result1 *v1beta1.ServiceBroker + result2 error + }{result1, result2} +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokers(arg1 string) (*v1beta1.ServiceBrokerList, error) { + fake.retrieveNamespaceServiceBrokersMutex.Lock() + ret, specificReturn := fake.retrieveNamespaceServiceBrokersReturnsOnCall[len(fake.retrieveNamespaceServiceBrokersArgsForCall)] + fake.retrieveNamespaceServiceBrokersArgsForCall = append(fake.retrieveNamespaceServiceBrokersArgsForCall, struct { + arg1 string + }{arg1}) + fake.recordInvocation("RetrieveNamespaceServiceBrokers", []interface{}{arg1}) + fake.retrieveNamespaceServiceBrokersMutex.Unlock() + if fake.RetrieveNamespaceServiceBrokersStub != nil { + return fake.RetrieveNamespaceServiceBrokersStub(arg1) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.retrieveNamespaceServiceBrokersReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokersCallCount() int { + fake.retrieveNamespaceServiceBrokersMutex.RLock() + defer fake.retrieveNamespaceServiceBrokersMutex.RUnlock() + return len(fake.retrieveNamespaceServiceBrokersArgsForCall) +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokersCalls(stub func(string) (*v1beta1.ServiceBrokerList, error)) { + fake.retrieveNamespaceServiceBrokersMutex.Lock() + defer fake.retrieveNamespaceServiceBrokersMutex.Unlock() + fake.RetrieveNamespaceServiceBrokersStub = stub +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokersArgsForCall(i int) string { + fake.retrieveNamespaceServiceBrokersMutex.RLock() + defer fake.retrieveNamespaceServiceBrokersMutex.RUnlock() + argsForCall := fake.retrieveNamespaceServiceBrokersArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokersReturns(result1 *v1beta1.ServiceBrokerList, result2 error) { + fake.retrieveNamespaceServiceBrokersMutex.Lock() + defer fake.retrieveNamespaceServiceBrokersMutex.Unlock() + fake.RetrieveNamespaceServiceBrokersStub = nil + fake.retrieveNamespaceServiceBrokersReturns = struct { + result1 *v1beta1.ServiceBrokerList + result2 error + }{result1, result2} +} + +func (fake *FakeKubernetesAPI) RetrieveNamespaceServiceBrokersReturnsOnCall(i int, result1 *v1beta1.ServiceBrokerList, result2 error) { + fake.retrieveNamespaceServiceBrokersMutex.Lock() + defer fake.retrieveNamespaceServiceBrokersMutex.Unlock() + fake.RetrieveNamespaceServiceBrokersStub = nil + if fake.retrieveNamespaceServiceBrokersReturnsOnCall == nil { + fake.retrieveNamespaceServiceBrokersReturnsOnCall = make(map[int]struct { + result1 *v1beta1.ServiceBrokerList + result2 error + }) + } + fake.retrieveNamespaceServiceBrokersReturnsOnCall[i] = struct { + result1 *v1beta1.ServiceBrokerList + result2 error + }{result1, result2} +} + func (fake *FakeKubernetesAPI) SyncClusterServiceBroker(arg1 string, arg2 int) error { fake.syncClusterServiceBrokerMutex.Lock() ret, specificReturn := fake.syncClusterServiceBrokerReturnsOnCall[len(fake.syncClusterServiceBrokerArgsForCall)] @@ -555,6 +889,68 @@ func (fake *FakeKubernetesAPI) SyncClusterServiceBrokerReturnsOnCall(i int, resu }{result1} } +func (fake *FakeKubernetesAPI) SyncNamespaceServiceBroker(arg1 string, arg2 string, arg3 int) error { + fake.syncNamespaceServiceBrokerMutex.Lock() + ret, specificReturn := fake.syncNamespaceServiceBrokerReturnsOnCall[len(fake.syncNamespaceServiceBrokerArgsForCall)] + fake.syncNamespaceServiceBrokerArgsForCall = append(fake.syncNamespaceServiceBrokerArgsForCall, struct { + arg1 string + arg2 string + arg3 int + }{arg1, arg2, arg3}) + fake.recordInvocation("SyncNamespaceServiceBroker", []interface{}{arg1, arg2, arg3}) + fake.syncNamespaceServiceBrokerMutex.Unlock() + if fake.SyncNamespaceServiceBrokerStub != nil { + return fake.SyncNamespaceServiceBrokerStub(arg1, arg2, arg3) + } + if specificReturn { + return ret.result1 + } + fakeReturns := fake.syncNamespaceServiceBrokerReturns + return fakeReturns.result1 +} + +func (fake *FakeKubernetesAPI) SyncNamespaceServiceBrokerCallCount() int { + fake.syncNamespaceServiceBrokerMutex.RLock() + defer fake.syncNamespaceServiceBrokerMutex.RUnlock() + return len(fake.syncNamespaceServiceBrokerArgsForCall) +} + +func (fake *FakeKubernetesAPI) SyncNamespaceServiceBrokerCalls(stub func(string, string, int) error) { + fake.syncNamespaceServiceBrokerMutex.Lock() + defer fake.syncNamespaceServiceBrokerMutex.Unlock() + fake.SyncNamespaceServiceBrokerStub = stub +} + +func (fake *FakeKubernetesAPI) SyncNamespaceServiceBrokerArgsForCall(i int) (string, string, int) { + fake.syncNamespaceServiceBrokerMutex.RLock() + defer fake.syncNamespaceServiceBrokerMutex.RUnlock() + argsForCall := fake.syncNamespaceServiceBrokerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 +} + +func (fake *FakeKubernetesAPI) SyncNamespaceServiceBrokerReturns(result1 error) { + fake.syncNamespaceServiceBrokerMutex.Lock() + defer fake.syncNamespaceServiceBrokerMutex.Unlock() + fake.SyncNamespaceServiceBrokerStub = nil + fake.syncNamespaceServiceBrokerReturns = struct { + result1 error + }{result1} +} + +func (fake *FakeKubernetesAPI) SyncNamespaceServiceBrokerReturnsOnCall(i int, result1 error) { + fake.syncNamespaceServiceBrokerMutex.Lock() + defer fake.syncNamespaceServiceBrokerMutex.Unlock() + fake.SyncNamespaceServiceBrokerStub = nil + if fake.syncNamespaceServiceBrokerReturnsOnCall == nil { + fake.syncNamespaceServiceBrokerReturnsOnCall = make(map[int]struct { + result1 error + }) + } + fake.syncNamespaceServiceBrokerReturnsOnCall[i] = struct { + result1 error + }{result1} +} + func (fake *FakeKubernetesAPI) UpdateClusterServiceBroker(arg1 *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { fake.updateClusterServiceBrokerMutex.Lock() ret, specificReturn := fake.updateClusterServiceBrokerReturnsOnCall[len(fake.updateClusterServiceBrokerArgsForCall)] @@ -618,64 +1014,128 @@ func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerReturnsOnCall(i int, re }{result1, result2} } -func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerCredentials(arg1 *v1.Secret) (*v1.Secret, error) { - fake.updateClusterServiceBrokerCredentialsMutex.Lock() - ret, specificReturn := fake.updateClusterServiceBrokerCredentialsReturnsOnCall[len(fake.updateClusterServiceBrokerCredentialsArgsForCall)] - fake.updateClusterServiceBrokerCredentialsArgsForCall = append(fake.updateClusterServiceBrokerCredentialsArgsForCall, struct { +func (fake *FakeKubernetesAPI) UpdateNamespaceServiceBroker(arg1 *v1beta1.ServiceBroker, arg2 string) (*v1beta1.ServiceBroker, error) { + fake.updateNamespaceServiceBrokerMutex.Lock() + ret, specificReturn := fake.updateNamespaceServiceBrokerReturnsOnCall[len(fake.updateNamespaceServiceBrokerArgsForCall)] + fake.updateNamespaceServiceBrokerArgsForCall = append(fake.updateNamespaceServiceBrokerArgsForCall, struct { + arg1 *v1beta1.ServiceBroker + arg2 string + }{arg1, arg2}) + fake.recordInvocation("UpdateNamespaceServiceBroker", []interface{}{arg1, arg2}) + fake.updateNamespaceServiceBrokerMutex.Unlock() + if fake.UpdateNamespaceServiceBrokerStub != nil { + return fake.UpdateNamespaceServiceBrokerStub(arg1, arg2) + } + if specificReturn { + return ret.result1, ret.result2 + } + fakeReturns := fake.updateNamespaceServiceBrokerReturns + return fakeReturns.result1, fakeReturns.result2 +} + +func (fake *FakeKubernetesAPI) UpdateNamespaceServiceBrokerCallCount() int { + fake.updateNamespaceServiceBrokerMutex.RLock() + defer fake.updateNamespaceServiceBrokerMutex.RUnlock() + return len(fake.updateNamespaceServiceBrokerArgsForCall) +} + +func (fake *FakeKubernetesAPI) UpdateNamespaceServiceBrokerCalls(stub func(*v1beta1.ServiceBroker, string) (*v1beta1.ServiceBroker, error)) { + fake.updateNamespaceServiceBrokerMutex.Lock() + defer fake.updateNamespaceServiceBrokerMutex.Unlock() + fake.UpdateNamespaceServiceBrokerStub = stub +} + +func (fake *FakeKubernetesAPI) UpdateNamespaceServiceBrokerArgsForCall(i int) (*v1beta1.ServiceBroker, string) { + fake.updateNamespaceServiceBrokerMutex.RLock() + defer fake.updateNamespaceServiceBrokerMutex.RUnlock() + argsForCall := fake.updateNamespaceServiceBrokerArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeKubernetesAPI) UpdateNamespaceServiceBrokerReturns(result1 *v1beta1.ServiceBroker, result2 error) { + fake.updateNamespaceServiceBrokerMutex.Lock() + defer fake.updateNamespaceServiceBrokerMutex.Unlock() + fake.UpdateNamespaceServiceBrokerStub = nil + fake.updateNamespaceServiceBrokerReturns = struct { + result1 *v1beta1.ServiceBroker + result2 error + }{result1, result2} +} + +func (fake *FakeKubernetesAPI) UpdateNamespaceServiceBrokerReturnsOnCall(i int, result1 *v1beta1.ServiceBroker, result2 error) { + fake.updateNamespaceServiceBrokerMutex.Lock() + defer fake.updateNamespaceServiceBrokerMutex.Unlock() + fake.UpdateNamespaceServiceBrokerStub = nil + if fake.updateNamespaceServiceBrokerReturnsOnCall == nil { + fake.updateNamespaceServiceBrokerReturnsOnCall = make(map[int]struct { + result1 *v1beta1.ServiceBroker + result2 error + }) + } + fake.updateNamespaceServiceBrokerReturnsOnCall[i] = struct { + result1 *v1beta1.ServiceBroker + result2 error + }{result1, result2} +} + +func (fake *FakeKubernetesAPI) UpdateServiceBrokerCredentials(arg1 *v1.Secret) (*v1.Secret, error) { + fake.updateServiceBrokerCredentialsMutex.Lock() + ret, specificReturn := fake.updateServiceBrokerCredentialsReturnsOnCall[len(fake.updateServiceBrokerCredentialsArgsForCall)] + fake.updateServiceBrokerCredentialsArgsForCall = append(fake.updateServiceBrokerCredentialsArgsForCall, struct { arg1 *v1.Secret }{arg1}) - fake.recordInvocation("UpdateClusterServiceBrokerCredentials", []interface{}{arg1}) - fake.updateClusterServiceBrokerCredentialsMutex.Unlock() - if fake.UpdateClusterServiceBrokerCredentialsStub != nil { - return fake.UpdateClusterServiceBrokerCredentialsStub(arg1) + fake.recordInvocation("UpdateServiceBrokerCredentials", []interface{}{arg1}) + fake.updateServiceBrokerCredentialsMutex.Unlock() + if fake.UpdateServiceBrokerCredentialsStub != nil { + return fake.UpdateServiceBrokerCredentialsStub(arg1) } if specificReturn { return ret.result1, ret.result2 } - fakeReturns := fake.updateClusterServiceBrokerCredentialsReturns + fakeReturns := fake.updateServiceBrokerCredentialsReturns return fakeReturns.result1, fakeReturns.result2 } -func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerCredentialsCallCount() int { - fake.updateClusterServiceBrokerCredentialsMutex.RLock() - defer fake.updateClusterServiceBrokerCredentialsMutex.RUnlock() - return len(fake.updateClusterServiceBrokerCredentialsArgsForCall) +func (fake *FakeKubernetesAPI) UpdateServiceBrokerCredentialsCallCount() int { + fake.updateServiceBrokerCredentialsMutex.RLock() + defer fake.updateServiceBrokerCredentialsMutex.RUnlock() + return len(fake.updateServiceBrokerCredentialsArgsForCall) } -func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerCredentialsCalls(stub func(*v1.Secret) (*v1.Secret, error)) { - fake.updateClusterServiceBrokerCredentialsMutex.Lock() - defer fake.updateClusterServiceBrokerCredentialsMutex.Unlock() - fake.UpdateClusterServiceBrokerCredentialsStub = stub +func (fake *FakeKubernetesAPI) UpdateServiceBrokerCredentialsCalls(stub func(*v1.Secret) (*v1.Secret, error)) { + fake.updateServiceBrokerCredentialsMutex.Lock() + defer fake.updateServiceBrokerCredentialsMutex.Unlock() + fake.UpdateServiceBrokerCredentialsStub = stub } -func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerCredentialsArgsForCall(i int) *v1.Secret { - fake.updateClusterServiceBrokerCredentialsMutex.RLock() - defer fake.updateClusterServiceBrokerCredentialsMutex.RUnlock() - argsForCall := fake.updateClusterServiceBrokerCredentialsArgsForCall[i] +func (fake *FakeKubernetesAPI) UpdateServiceBrokerCredentialsArgsForCall(i int) *v1.Secret { + fake.updateServiceBrokerCredentialsMutex.RLock() + defer fake.updateServiceBrokerCredentialsMutex.RUnlock() + argsForCall := fake.updateServiceBrokerCredentialsArgsForCall[i] return argsForCall.arg1 } -func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerCredentialsReturns(result1 *v1.Secret, result2 error) { - fake.updateClusterServiceBrokerCredentialsMutex.Lock() - defer fake.updateClusterServiceBrokerCredentialsMutex.Unlock() - fake.UpdateClusterServiceBrokerCredentialsStub = nil - fake.updateClusterServiceBrokerCredentialsReturns = struct { +func (fake *FakeKubernetesAPI) UpdateServiceBrokerCredentialsReturns(result1 *v1.Secret, result2 error) { + fake.updateServiceBrokerCredentialsMutex.Lock() + defer fake.updateServiceBrokerCredentialsMutex.Unlock() + fake.UpdateServiceBrokerCredentialsStub = nil + fake.updateServiceBrokerCredentialsReturns = struct { result1 *v1.Secret result2 error }{result1, result2} } -func (fake *FakeKubernetesAPI) UpdateClusterServiceBrokerCredentialsReturnsOnCall(i int, result1 *v1.Secret, result2 error) { - fake.updateClusterServiceBrokerCredentialsMutex.Lock() - defer fake.updateClusterServiceBrokerCredentialsMutex.Unlock() - fake.UpdateClusterServiceBrokerCredentialsStub = nil - if fake.updateClusterServiceBrokerCredentialsReturnsOnCall == nil { - fake.updateClusterServiceBrokerCredentialsReturnsOnCall = make(map[int]struct { +func (fake *FakeKubernetesAPI) UpdateServiceBrokerCredentialsReturnsOnCall(i int, result1 *v1.Secret, result2 error) { + fake.updateServiceBrokerCredentialsMutex.Lock() + defer fake.updateServiceBrokerCredentialsMutex.Unlock() + fake.UpdateServiceBrokerCredentialsStub = nil + if fake.updateServiceBrokerCredentialsReturnsOnCall == nil { + fake.updateServiceBrokerCredentialsReturnsOnCall = make(map[int]struct { result1 *v1.Secret result2 error }) } - fake.updateClusterServiceBrokerCredentialsReturnsOnCall[i] = struct { + fake.updateServiceBrokerCredentialsReturnsOnCall[i] = struct { result1 *v1.Secret result2 error }{result1, result2} @@ -686,22 +1146,34 @@ func (fake *FakeKubernetesAPI) Invocations() map[string][][]interface{} { defer fake.invocationsMutex.RUnlock() fake.createClusterServiceBrokerMutex.RLock() defer fake.createClusterServiceBrokerMutex.RUnlock() + fake.createNamespaceServiceBrokerMutex.RLock() + defer fake.createNamespaceServiceBrokerMutex.RUnlock() fake.createSecretMutex.RLock() defer fake.createSecretMutex.RUnlock() fake.deleteClusterServiceBrokerMutex.RLock() defer fake.deleteClusterServiceBrokerMutex.RUnlock() + fake.deleteNamespaceServiceBrokerMutex.RLock() + defer fake.deleteNamespaceServiceBrokerMutex.RUnlock() fake.deleteSecretMutex.RLock() defer fake.deleteSecretMutex.RUnlock() fake.retrieveClusterServiceBrokerByNameMutex.RLock() defer fake.retrieveClusterServiceBrokerByNameMutex.RUnlock() fake.retrieveClusterServiceBrokersMutex.RLock() defer fake.retrieveClusterServiceBrokersMutex.RUnlock() + fake.retrieveNamespaceServiceBrokerByNameMutex.RLock() + defer fake.retrieveNamespaceServiceBrokerByNameMutex.RUnlock() + fake.retrieveNamespaceServiceBrokersMutex.RLock() + defer fake.retrieveNamespaceServiceBrokersMutex.RUnlock() fake.syncClusterServiceBrokerMutex.RLock() defer fake.syncClusterServiceBrokerMutex.RUnlock() + fake.syncNamespaceServiceBrokerMutex.RLock() + defer fake.syncNamespaceServiceBrokerMutex.RUnlock() fake.updateClusterServiceBrokerMutex.RLock() defer fake.updateClusterServiceBrokerMutex.RUnlock() - fake.updateClusterServiceBrokerCredentialsMutex.RLock() - defer fake.updateClusterServiceBrokerCredentialsMutex.RUnlock() + fake.updateNamespaceServiceBrokerMutex.RLock() + defer fake.updateNamespaceServiceBrokerMutex.RUnlock() + fake.updateServiceBrokerCredentialsMutex.RLock() + defer fake.updateServiceBrokerCredentialsMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/pkg/k8s/client/client.go b/pkg/k8s/client/client.go index 02a9bc46..07286d10 100644 --- a/pkg/k8s/client/client.go +++ b/pkg/k8s/client/client.go @@ -7,6 +7,7 @@ import ( "github.com/Peripli/service-broker-proxy-k8s/pkg/k8s/config" servicecatalog "github.com/kubernetes-sigs/service-catalog/pkg/svcat/service-catalog" "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" "sync" "github.com/Peripli/service-broker-proxy/pkg/platform" @@ -20,9 +21,9 @@ const resyncBrokerRetryCount = 3 // NewDefaultKubernetesAPI returns default kubernetes api interface func NewDefaultKubernetesAPI(cli *servicecatalog.SDK) *ServiceCatalogAPI { return &ServiceCatalogAPI{ - SDK:cli, + SDK: cli, brokersInProgress: make(map[string]bool), - lock: &sync.Mutex{}, + lock: &sync.Mutex{}, } } @@ -30,7 +31,12 @@ func NewDefaultKubernetesAPI(cli *servicecatalog.SDK) *ServiceCatalogAPI { type ServiceCatalogAPI struct { *servicecatalog.SDK brokersInProgress map[string]bool - lock *sync.Mutex + lock *sync.Mutex +} + +// CreateNamespaceServiceBroker creates namespace service broker +func (sca *ServiceCatalogAPI) CreateNamespaceServiceBroker(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) { + return sca.ServiceCatalog().ServiceBrokers(namespace).Create(broker) } // CreateClusterServiceBroker creates a cluster service broker @@ -38,26 +44,59 @@ func (sca *ServiceCatalogAPI) CreateClusterServiceBroker(broker *v1beta1.Cluster return sca.ServiceCatalog().ClusterServiceBrokers().Create(broker) } +// DeleteNamespaceServiceBroker deletes a service broker in a namespace +func (sca *ServiceCatalogAPI) DeleteNamespaceServiceBroker(name string, namespace string, options *v1.DeleteOptions) error { + return sca.ServiceCatalog().ServiceBrokers(namespace).Delete(name, options) +} + // DeleteClusterServiceBroker deletes a cluster service broker func (sca *ServiceCatalogAPI) DeleteClusterServiceBroker(name string, options *v1.DeleteOptions) error { return sca.ServiceCatalog().ClusterServiceBrokers().Delete(name, options) } +// RetrieveNamespaceServiceBrokers gets all service brokers in a namespace +func (sca *ServiceCatalogAPI) RetrieveNamespaceServiceBrokers(namespace string) (*v1beta1.ServiceBrokerList, error) { + return sca.ServiceCatalog().ServiceBrokers(namespace).List(v1.ListOptions{}) +} + // RetrieveClusterServiceBrokers returns all cluster service brokers func (sca *ServiceCatalogAPI) RetrieveClusterServiceBrokers() (*v1beta1.ClusterServiceBrokerList, error) { return sca.ServiceCatalog().ClusterServiceBrokers().List(v1.ListOptions{}) } +// RetrieveNamespaceServiceBrokerByName gets a service broker in a namespace +func (sca *ServiceCatalogAPI) RetrieveNamespaceServiceBrokerByName(name, namespace string) (*v1beta1.ServiceBroker, error) { + return sca.ServiceCatalog().ServiceBrokers(namespace).Get(name, v1.GetOptions{}) +} + // RetrieveClusterServiceBrokerByName returns a cluster service broker by name func (sca *ServiceCatalogAPI) RetrieveClusterServiceBrokerByName(name string) (*v1beta1.ClusterServiceBroker, error) { return sca.ServiceCatalog().ClusterServiceBrokers().Get(name, v1.GetOptions{}) } +// UpdateNamespaceServiceBroker updates a service broker in a namespace +func (sca *ServiceCatalogAPI) UpdateNamespaceServiceBroker(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) { + return sca.ServiceCatalog().ServiceBrokers(namespace).Update(broker) +} + // UpdateClusterServiceBroker updates a cluster service broker func (sca *ServiceCatalogAPI) UpdateClusterServiceBroker(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { return sca.ServiceCatalog().ClusterServiceBrokers().Update(broker) } +// SyncNamespaceServiceBroker synchronize a service broker in a namespace +func (sca *ServiceCatalogAPI) SyncNamespaceServiceBroker(name, namespace string, retries int) error { + if sca.setBrokerInProgress(name) { + defer sca.unsetBrokerInProgress(name) + err := sca.Sync(name, servicecatalog.ScopeOptions{ + Scope: servicecatalog.NamespaceScope, + Namespace: namespace, + }, retries) + return err + } + return nil +} + // SyncClusterServiceBroker synchronizes a cluster service broker including its catalog func (sca *ServiceCatalogAPI) SyncClusterServiceBroker(name string, retries int) error { if sca.setBrokerInProgress(name) { @@ -70,8 +109,8 @@ func (sca *ServiceCatalogAPI) SyncClusterServiceBroker(name string, retries int) return nil } -// UpdateClusterServiceBrokerCredentials updates broker's credentials secret -func (sca *ServiceCatalogAPI) UpdateClusterServiceBrokerCredentials(secret *v1core.Secret) (*v1core.Secret, error) { +// UpdateServiceBrokerCredentials updates broker's credentials secret +func (sca *ServiceCatalogAPI) UpdateServiceBrokerCredentials(secret *v1core.Secret) (*v1core.Secret, error) { _, err := sca.K8sClient.CoreV1().Secrets(secret.Namespace).Get(secret.Name, v1.GetOptions{}) if err != nil { if errors.IsNotFound(err) { @@ -92,7 +131,6 @@ func (sca *ServiceCatalogAPI) DeleteSecret(namespace, name string) error { return sca.K8sClient.CoreV1().Secrets(namespace).Delete(name, &v1.DeleteOptions{}) } - func (sca *ServiceCatalogAPI) setBrokerInProgress(name string) bool { sca.lock.Lock() defer sca.lock.Unlock() @@ -100,7 +138,7 @@ func (sca *ServiceCatalogAPI) setBrokerInProgress(name string) bool { sca.brokersInProgress[name] = true return true } - return false; + return false } func (sca *ServiceCatalogAPI) unsetBrokerInProgress(name string) { @@ -111,8 +149,11 @@ func (sca *ServiceCatalogAPI) unsetBrokerInProgress(name string) { type PlatformClient struct { platformAPI api.KubernetesAPI secretNamespace string + targetNamespace string } +type brokersByUID map[types.UID]servicecatalog.Broker + var _ platform.Client = &PlatformClient{} // NewClient create a client to communicate with the kubernetes service-catalog. @@ -127,6 +168,7 @@ func NewClient(settings *config.Settings) (*PlatformClient, error) { return &PlatformClient{ platformAPI: NewDefaultKubernetesAPI(svcatSDK), secretNamespace: settings.K8S.Secret.Namespace, + targetNamespace: settings.K8S.TargetNamespace, }, nil } @@ -147,33 +189,62 @@ func (pc *PlatformClient) Visibility() platform.VisibilityClient { // GetBrokers returns all service-brokers currently registered in kubernetes service-catalog. func (pc *PlatformClient) GetBrokers(ctx context.Context) ([]*platform.ServiceBroker, error) { - brokers, err := pc.platformAPI.RetrieveClusterServiceBrokers() - if err != nil { - return nil, fmt.Errorf("unable to list cluster-scoped brokers (%s)", err) - } var clientBrokers = make([]*platform.ServiceBroker, 0) - for _, broker := range brokers.Items { + var brokers brokersByUID + + if pc.isClusterScoped() { + clusterBrokers, err := pc.platformAPI.RetrieveClusterServiceBrokers() + if err != nil { + return nil, fmt.Errorf("unable to list cluster-scoped brokers (%s)", err) + } + + brokers = clusterBrokersToBrokers(clusterBrokers) + } else { + namespaceBrokers, err := pc.platformAPI.RetrieveNamespaceServiceBrokers(pc.targetNamespace) + if err != nil { + return nil, fmt.Errorf("unable to list namespace-scoped brokers (%s)", err) + } + + brokers = namespaceBrokersToBrokers(namespaceBrokers) + } + + for uid, broker := range brokers { serviceBroker := &platform.ServiceBroker{ - GUID: string(broker.ObjectMeta.UID), - Name: broker.Name, - BrokerURL: broker.Spec.URL, + GUID: string(uid), + Name: broker.GetName(), + BrokerURL: broker.GetURL(), } clientBrokers = append(clientBrokers, serviceBroker) } + return clientBrokers, nil } // GetBrokerByName returns the service-broker with the specified name currently registered in kubernetes service-catalog with. func (pc *PlatformClient) GetBrokerByName(ctx context.Context, name string) (*platform.ServiceBroker, error) { - broker, err := pc.platformAPI.RetrieveClusterServiceBrokerByName(name) - if err != nil { - return nil, fmt.Errorf("unable to get cluster-scoped broker (%s)", err) + var broker servicecatalog.Broker + var brokerUID types.UID + + if pc.isClusterScoped() { + clusterBroker, err := pc.platformAPI.RetrieveClusterServiceBrokerByName(name) + if err != nil { + return nil, fmt.Errorf("unable to get cluster-scoped broker (%s)", err) + } + + broker, brokerUID = clusterBroker, clusterBroker.GetUID() + } else { + namespaceBroker, err := pc.platformAPI.RetrieveNamespaceServiceBrokerByName(name, pc.targetNamespace) + if err != nil { + return nil, fmt.Errorf("unable to get namespace-scoped broker (%s)", err) + } + + broker, brokerUID = namespaceBroker, namespaceBroker.GetUID() } return &platform.ServiceBroker{ - GUID: string(broker.ObjectMeta.UID), - Name: broker.Name, - BrokerURL: broker.Spec.URL, + GUID: string(brokerUID), + Name: broker.GetName(), + BrokerURL: broker.GetURL(), }, nil } @@ -182,30 +253,56 @@ func (pc *PlatformClient) CreateBroker(ctx context.Context, r *platform.CreateSe if err := pc.updateBrokerPlatformSecret(r.ID, r.Username, r.Password); err != nil { return nil, err } + var brokerUID types.UID - broker := newServiceBroker(r.Name, r.BrokerURL, &v1beta1.ObjectReference{ - Name: r.ID, - Namespace: pc.secretNamespace, - }) - broker.Spec.CommonServiceBrokerSpec.RelistBehavior = "Manual" + if pc.isClusterScoped() { + broker := newClusterServiceBroker(r.Name, r.BrokerURL, &v1beta1.ObjectReference{ + Name: r.ID, + Namespace: pc.secretNamespace, + }) - csb, err := pc.platformAPI.CreateClusterServiceBroker(broker) - if err != nil { - return nil, err + broker.Spec.CommonServiceBrokerSpec.RelistBehavior = "Manual" + + csb, err := pc.platformAPI.CreateClusterServiceBroker(broker) + if err != nil { + return nil, err + } + brokerUID = csb.GetUID() + } else { + broker := newNamespaceServiceBroker(r.Name, r.BrokerURL, &v1beta1.LocalObjectReference{ + Name: r.ID, + }) + broker.Spec.CommonServiceBrokerSpec.RelistBehavior = "Manual" + + csb, err := pc.platformAPI.CreateNamespaceServiceBroker(broker, pc.targetNamespace) + if err != nil { + return nil, err + } + brokerUID = csb.GetUID() } + return &platform.ServiceBroker{ - GUID: string(csb.UID), + GUID: string(brokerUID), Name: r.Name, BrokerURL: r.BrokerURL, }, nil + } // DeleteBroker deletes an existing broker in from kubernetes service-catalog. func (pc *PlatformClient) DeleteBroker(ctx context.Context, r *platform.DeleteServiceBrokerRequest) error { - if err := pc.platformAPI.DeleteSecret(pc.secretNamespace, r.ID); err != nil { - return fmt.Errorf("error deleting broker credentials secret: %v", err) + if pc.isClusterScoped() { + if err := pc.platformAPI.DeleteSecret(pc.secretNamespace, r.ID); err != nil { + return fmt.Errorf("error deleting broker credentials secret: %v", err) + } + return pc.platformAPI.DeleteClusterServiceBroker(r.Name, &v1.DeleteOptions{}) } - return pc.platformAPI.DeleteClusterServiceBroker(r.Name, &v1.DeleteOptions{}) + + if err := pc.platformAPI.DeleteSecret(pc.targetNamespace, r.ID); err != nil { + return fmt.Errorf("error deleting broker credentials secret in namespace %s: %v", pc.targetNamespace, err) + } + return pc.platformAPI.DeleteNamespaceServiceBroker(r.Name, pc.targetNamespace, &v1.DeleteOptions{}) + } // UpdateBroker updates a service broker in the kubernetes service-catalog. @@ -216,20 +313,40 @@ func (pc *PlatformClient) UpdateBroker(ctx context.Context, r *platform.UpdateSe } } - // Only broker url and secret-references are updateable - broker := newServiceBroker(r.Name, r.BrokerURL, &v1beta1.ObjectReference{ - Name: r.ID, - Namespace: pc.secretNamespace, - }) + var updatedBrokerUID types.UID + var updatedBroker servicecatalog.Broker - updatedBroker, err := pc.platformAPI.UpdateClusterServiceBroker(broker) - if err != nil { - return nil, err + if pc.isClusterScoped() { + // Only broker url and secret-references are updateable + broker := newClusterServiceBroker(r.Name, r.BrokerURL, &v1beta1.ObjectReference{ + Name: r.ID, + Namespace: pc.secretNamespace, + }) + + updatedClusterBroker, err := pc.platformAPI.UpdateClusterServiceBroker(broker) + if err != nil { + return nil, err + } + + updatedBroker, updatedBrokerUID = updatedClusterBroker, updatedClusterBroker.GetUID() + } else { + // Only broker url and secret-references are updateable + broker := newNamespaceServiceBroker(r.Name, r.BrokerURL, &v1beta1.LocalObjectReference{ + Name: r.ID, + }) + + updatedNamespaceBroker, err := pc.platformAPI.UpdateNamespaceServiceBroker(broker, pc.targetNamespace) + if err != nil { + return nil, err + } + + updatedBroker, updatedBrokerUID = updatedNamespaceBroker, updatedNamespaceBroker.GetUID() } + return &platform.ServiceBroker{ - GUID: string(updatedBroker.ObjectMeta.UID), - Name: updatedBroker.Name, - BrokerURL: updatedBroker.Spec.URL, + GUID: string(updatedBrokerUID), + Name: updatedBroker.GetName(), + BrokerURL: updatedBroker.GetURL(), }, nil } @@ -241,20 +358,52 @@ func (pc *PlatformClient) Fetch(ctx context.Context, r *platform.UpdateServiceBr return err } } - return pc.platformAPI.SyncClusterServiceBroker(r.Name, resyncBrokerRetryCount) + + if pc.isClusterScoped() { + return pc.platformAPI.SyncClusterServiceBroker(r.Name, resyncBrokerRetryCount) + } + + return pc.platformAPI.SyncNamespaceServiceBroker(r.Name, pc.targetNamespace, resyncBrokerRetryCount) } func (pc *PlatformClient) updateBrokerPlatformSecret(name, username, password string) error { - secret := newServiceBrokerCredentialsSecret(pc.secretNamespace, name, username, password) - _, err := pc.platformAPI.UpdateClusterServiceBrokerCredentials(secret) + var secretNamespace string + if pc.isClusterScoped() { + secretNamespace = pc.secretNamespace + } else { + secretNamespace = pc.targetNamespace + } + + secret := newServiceBrokerCredentialsSecret(secretNamespace, name, username, password) + _, err := pc.platformAPI.UpdateServiceBrokerCredentials(secret) if err != nil { - return fmt.Errorf("error updating broker credentials secret %v", err) + return fmt.Errorf("error updating broker credentials secret in namespace %s: %v", secretNamespace, err) } return nil } -func newServiceBroker(name string, url string, secret *v1beta1.ObjectReference) *v1beta1.ClusterServiceBroker { +func clusterBrokersToBrokers(clusterBrokers *v1beta1.ClusterServiceBrokerList) brokersByUID { + brokers := make(brokersByUID, len(clusterBrokers.Items)) + + for _, clusterBroker := range clusterBrokers.Items { + brokers[clusterBroker.ObjectMeta.UID] = &clusterBroker + } + + return brokers +} + +func namespaceBrokersToBrokers(namespaceBrokers *v1beta1.ServiceBrokerList) brokersByUID { + brokers := make(brokersByUID, len(namespaceBrokers.Items)) + + for _, clusterBroker := range namespaceBrokers.Items { + brokers[clusterBroker.ObjectMeta.UID] = &clusterBroker + } + + return brokers +} + +func newClusterServiceBroker(name string, url string, secret *v1beta1.ObjectReference) *v1beta1.ClusterServiceBroker { return &v1beta1.ClusterServiceBroker{ ObjectMeta: v1.ObjectMeta{ Name: name, @@ -272,6 +421,24 @@ func newServiceBroker(name string, url string, secret *v1beta1.ObjectReference) } } +func newNamespaceServiceBroker(name string, url string, secret *v1beta1.LocalObjectReference) *v1beta1.ServiceBroker { + return &v1beta1.ServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + Name: name, + }, + Spec: v1beta1.ServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: url, + }, + AuthInfo: &v1beta1.ServiceBrokerAuthInfo{ + Basic: &v1beta1.BasicAuthConfig{ + SecretRef: secret, + }, + }, + }, + } +} + func newServiceBrokerCredentialsSecret(namespace, name, username, password string) *v1core.Secret { return &v1core.Secret{ ObjectMeta: v1.ObjectMeta{ @@ -285,6 +452,10 @@ func newServiceBrokerCredentialsSecret(namespace, name, username, password strin } } +func (pc *PlatformClient) isClusterScoped() bool { + return len(pc.targetNamespace) == 0 +} + // GetVisibilitiesByBrokers get currently available visibilities in the platform for specific broker names func (pc *PlatformClient) GetVisibilitiesByBrokers(ctx context.Context, brokers []string) ([]*platform.Visibility, error) { // This will cause all brokers to re-fetch their catalogs @@ -298,10 +469,18 @@ func (pc *PlatformClient) VisibilityScopeLabelKey() string { // EnableAccessForPlan enables the access for the specified plan func (pc *PlatformClient) EnableAccessForPlan(ctx context.Context, request *platform.ModifyPlanAccessRequest) error { - return pc.platformAPI.SyncClusterServiceBroker(request.BrokerName, resyncBrokerRetryCount) + if pc.isClusterScoped() { + return pc.platformAPI.SyncClusterServiceBroker(request.BrokerName, resyncBrokerRetryCount) + } + + return pc.platformAPI.SyncNamespaceServiceBroker(request.BrokerName, pc.targetNamespace, resyncBrokerRetryCount) } // DisableAccessForPlan disables the access for the specified plan func (pc *PlatformClient) DisableAccessForPlan(ctx context.Context, request *platform.ModifyPlanAccessRequest) error { - return pc.platformAPI.SyncClusterServiceBroker(request.BrokerName, resyncBrokerRetryCount) + if pc.isClusterScoped() { + return pc.platformAPI.SyncClusterServiceBroker(request.BrokerName, resyncBrokerRetryCount) + } + + return pc.platformAPI.SyncNamespaceServiceBroker(request.BrokerName, pc.targetNamespace, resyncBrokerRetryCount) } diff --git a/pkg/k8s/client/client_test.go b/pkg/k8s/client/client_test.go index 3ce3c91b..944940b3 100644 --- a/pkg/k8s/client/client_test.go +++ b/pkg/k8s/client/client_test.go @@ -115,334 +115,741 @@ var _ = Describe("Kubernetes Broker Proxy", func() { }) }) - Describe("Create a service broker", func() { - - Context("with no error", func() { - It("returns broker", func() { - platformClient := newDefaultPlatformClient() - - k8sApi.CreateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { - return &v1beta1.ClusterServiceBroker{ - ObjectMeta: v1.ObjectMeta{ - UID: "1234", - Name: broker.Name, - }, - Spec: v1beta1.ClusterServiceBrokerSpec{ - CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ - URL: broker.Spec.URL, + Describe("Cluster service broker", func() { + Describe("Create a service broker", func() { + + Context("with no error", func() { + It("returns broker", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.CreateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { + return &v1beta1.ClusterServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + UID: "1234", + Name: broker.Name, }, - }, - }, nil - } + Spec: v1beta1.ClusterServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: broker.Spec.URL, + }, + }, + }, nil + } + + requestBroker := &platform.CreateServiceBrokerRequest{ + ID: "id-in-sm", + Name: "fake-broker", + BrokerURL: "http://fake.broker.url", + Username: "admin", + Password: "admin", + } + + k8sApi.CreateSecretStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + Expect(secret2.Name).To(Equal(requestBroker.ID)) + Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) + Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) + return secret2, nil + } + createdBroker, err := platformClient.CreateBroker(ctx, requestBroker) + + Expect(err).To(BeNil()) + Expect(createdBroker.GUID).To(Equal("1234")) + Expect(createdBroker.Name).To(Equal("fake-broker")) + Expect(createdBroker.BrokerURL).To(Equal("http://fake.broker.url")) + }) + }) - requestBroker := &platform.CreateServiceBrokerRequest{ - ID: "id-in-sm", - Name: "fake-broker", - BrokerURL: "http://fake.broker.url", - Username: "admin", - Password: "admin", - } + Context("with an error", func() { + It("returns error", func() { + platformClient := newDefaultPlatformClient() - k8sApi.CreateSecretStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { - Expect(secret2.Name).To(Equal(requestBroker.ID)) - Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) - Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) - return secret2, nil - } - createdBroker, err := platformClient.CreateBroker(ctx, requestBroker) + k8sApi.CreateSecretStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + return secret2, nil + } + k8sApi.CreateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { + return nil, errors.New("error from service-catalog") + } + + requestBroker := &platform.CreateServiceBrokerRequest{} + createdBroker, err := platformClient.CreateBroker(ctx, requestBroker) - Expect(err).To(BeNil()) - Expect(createdBroker.GUID).To(Equal("1234")) - Expect(createdBroker.Name).To(Equal("fake-broker")) - Expect(createdBroker.BrokerURL).To(Equal("http://fake.broker.url")) + Expect(createdBroker).To(BeNil()) + Expect(err).To(Equal(errors.New("error from service-catalog"))) + }) }) }) - Context("with an error", func() { - It("returns error", func() { - platformClient := newDefaultPlatformClient() + Describe("Delete a service broker", func() { + Context("with no error", func() { + It("returns no error", func() { + platformClient := newDefaultPlatformClient() - k8sApi.CreateSecretStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { - return secret2, nil - } - k8sApi.CreateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { - return nil, errors.New("error from service-catalog") - } + k8sApi.DeleteClusterServiceBrokerStub = func(name string, options *v1.DeleteOptions) error { + return nil + } - requestBroker := &platform.CreateServiceBrokerRequest{} - createdBroker, err := platformClient.CreateBroker(ctx, requestBroker) + requestBroker := &platform.DeleteServiceBrokerRequest{ + ID: "id-in-sm", + GUID: "1234", + Name: "fake-broker", + } - Expect(createdBroker).To(BeNil()) - Expect(err).To(Equal(errors.New("error from service-catalog"))) + err := platformClient.DeleteBroker(ctx, requestBroker) + + Expect(err).To(BeNil()) + }) }) - }) - }) - Describe("Delete a service broker", func() { - Context("with no error", func() { - It("returns no error", func() { - platformClient := newDefaultPlatformClient() + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() - k8sApi.DeleteClusterServiceBrokerStub = func(name string, options *v1.DeleteOptions) error { - return nil - } + k8sApi.DeleteClusterServiceBrokerStub = func(name string, options *v1.DeleteOptions) error { + return errors.New("error deleting clusterservicebroker") + } - requestBroker := &platform.DeleteServiceBrokerRequest{ - ID: "id-in-sm", - GUID: "1234", - Name: "fake-broker", - } + requestBroker := &platform.DeleteServiceBrokerRequest{} - err := platformClient.DeleteBroker(ctx, requestBroker) + err := platformClient.DeleteBroker(ctx, requestBroker) - Expect(err).To(BeNil()) + Expect(err).To(Equal(errors.New("error deleting clusterservicebroker"))) + }) }) }) - Context("with an error", func() { - It("returns the error", func() { - platformClient := newDefaultPlatformClient() + Describe("Get all service brokers", func() { + Context("with no error", func() { + It("returns brokers", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.RetrieveClusterServiceBrokersStub = func() (*v1beta1.ClusterServiceBrokerList, error) { + brokers := make([]v1beta1.ClusterServiceBroker, 0) + brokers = append(brokers, v1beta1.ClusterServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + UID: "1234", + Name: "fake-broker", + }, + Spec: v1beta1.ClusterServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: "http://fake.broker.url", + }, + }, + }) + return &v1beta1.ClusterServiceBrokerList{ + Items: brokers, + }, nil + } + + brokers, err := platformClient.GetBrokers(ctx) + + Expect(err).To(BeNil()) + Expect(brokers).ToNot(BeNil()) + Expect(len(brokers)).To(Equal(1)) + Expect(brokers[0].GUID).To(Equal("1234")) + Expect(brokers[0].Name).To(Equal("fake-broker")) + Expect(brokers[0].BrokerURL).To(Equal("http://fake.broker.url")) + }) + }) - k8sApi.DeleteClusterServiceBrokerStub = func(name string, options *v1.DeleteOptions) error { - return errors.New("error deleting clusterservicebroker") - } + Context("when no service brokers are registered", func() { + It("returns empty array", func() { + platformClient := newDefaultPlatformClient() - requestBroker := &platform.DeleteServiceBrokerRequest{} + k8sApi.RetrieveClusterServiceBrokersStub = func() (*v1beta1.ClusterServiceBrokerList, error) { + brokers := make([]v1beta1.ClusterServiceBroker, 0) + return &v1beta1.ClusterServiceBrokerList{ + Items: brokers, + }, nil + } - err := platformClient.DeleteBroker(ctx, requestBroker) + brokers, err := platformClient.GetBrokers(ctx) - Expect(err).To(Equal(errors.New("error deleting clusterservicebroker"))) + Expect(err).To(BeNil()) + Expect(brokers).ToNot(BeNil()) + Expect(len(brokers)).To(Equal(0)) + }) + }) + + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.RetrieveClusterServiceBrokersStub = func() (*v1beta1.ClusterServiceBrokerList, error) { + return nil, errors.New("error getting clusterservicebrokers") + } + + brokers, err := platformClient.GetBrokers(ctx) + + Expect(brokers).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error getting clusterservicebrokers")) + }) }) }) - }) - Describe("Get all service brokers", func() { - Context("with no error", func() { - It("returns brokers", func() { - platformClient := newDefaultPlatformClient() + Describe("Get service broker by name", func() { + Context("with no error", func() { + It("returns the service broker", func() { + platformClient := newDefaultPlatformClient() + brokerName := "brokerName" + + k8sApi.RetrieveClusterServiceBrokerByNameStub = func(name string) (*v1beta1.ClusterServiceBroker, error) { + return &v1beta1.ClusterServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + UID: "1234", + Name: brokerName, + }, + Spec: v1beta1.ClusterServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: "http://fake.broker.url", + }, + }, + }, nil + } + + broker, err := platformClient.GetBrokerByName(ctx, brokerName) + + Expect(err).To(BeNil()) + Expect(broker).ToNot(BeNil()) + Expect(broker.Name).To(Equal(brokerName)) + }) + }) - k8sApi.RetrieveClusterServiceBrokersStub = func() (*v1beta1.ClusterServiceBrokerList, error) { - brokers := make([]v1beta1.ClusterServiceBroker, 0) - brokers = append(brokers, v1beta1.ClusterServiceBroker{ - ObjectMeta: v1.ObjectMeta{ - UID: "1234", - Name: "fake-broker", - }, - Spec: v1beta1.ClusterServiceBrokerSpec{ - CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ - URL: "http://fake.broker.url", + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.RetrieveClusterServiceBrokerByNameStub = func(name string) (*v1beta1.ClusterServiceBroker, error) { + return nil, errors.New("error getting clusterservicebroker") + } + + broker, err := platformClient.GetBrokerByName(ctx, "brokerName") + + Expect(broker).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error getting clusterservicebroker")) + }) + }) + }) + + Describe("Update a service broker", func() { + Context("with no errors", func() { + It("returns updated broker", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.UpdateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { + // Return a new fake clusterservicebroker with the three attributes relevant for the OSBAPI guid, name and broker url. + // UID and name cannot be modified, url can be modified + return &v1beta1.ClusterServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + Name: broker.Name + "-updated", + UID: "1234", }, - }, - }) - return &v1beta1.ClusterServiceBrokerList{ - Items: brokers, - }, nil - } + Spec: v1beta1.ClusterServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: broker.Spec.CommonServiceBrokerSpec.URL + "-updated", + }, + }, + }, nil + } + + requestBroker := &platform.UpdateServiceBrokerRequest{ + ID: "id-in-sm", + GUID: "1234", + Name: "fake-broker", + BrokerURL: "http://fake.broker.url", + Username: "admin", + Password: "admin", + } + + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + Expect(secret2.Name).To(Equal(requestBroker.ID)) + Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) + Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) + return secret2, nil + } + + broker, err := platformClient.UpdateBroker(ctx, requestBroker) + + Expect(err).To(BeNil()) + Expect(broker.GUID).To(Equal("1234")) + Expect(broker.Name).To(Equal("fake-broker-updated")) + Expect(broker.BrokerURL).To(Equal("http://fake.broker.url-updated")) + }) + }) - brokers, err := platformClient.GetBrokers(ctx) + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() - Expect(err).To(BeNil()) - Expect(brokers).ToNot(BeNil()) - Expect(len(brokers)).To(Equal(1)) - Expect(brokers[0].GUID).To(Equal("1234")) - Expect(brokers[0].Name).To(Equal("fake-broker")) - Expect(brokers[0].BrokerURL).To(Equal("http://fake.broker.url")) + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + return secret2, nil + } + k8sApi.UpdateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { + return nil, errors.New("error updating clusterservicebroker") + } + + requestBroker := &platform.UpdateServiceBrokerRequest{} + + broker, err := platformClient.UpdateBroker(ctx, requestBroker) + + Expect(broker).To(BeNil()) + Expect(err).To(Equal(errors.New("error updating clusterservicebroker"))) + }) }) }) - Context("when no service brokers are registered", func() { - It("returns empty array", func() { - platformClient := newDefaultPlatformClient() + Describe("Fetch the catalog information of a service broker", func() { + Context("with no errors", func() { + It("returns nil", func() { + platformClient := newDefaultPlatformClient() + + requestBroker := &platform.UpdateServiceBrokerRequest{ + ID: "id-in-sm", + GUID: "1234", + Name: "fake-broker", + BrokerURL: "http://fake.broker.url", + Username: "admin", + Password: "admin", + } + + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + Expect(secret2.Name).To(Equal(requestBroker.ID)) + Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) + Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) + return secret2, nil + } + k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { + return nil + } + + err := platformClient.Fetch(ctx, requestBroker) + + Expect(err).To(BeNil()) + }) + }) - k8sApi.RetrieveClusterServiceBrokersStub = func() (*v1beta1.ClusterServiceBrokerList, error) { - brokers := make([]v1beta1.ClusterServiceBroker, 0) - return &v1beta1.ClusterServiceBrokerList{ - Items: brokers, - }, nil - } + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() + + requestBroker := &platform.UpdateServiceBrokerRequest{} + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + return secret2, nil + } + k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { + return errors.New("error syncing service broker") + } - brokers, err := platformClient.GetBrokers(ctx) + err := platformClient.Fetch(ctx, requestBroker) - Expect(err).To(BeNil()) - Expect(brokers).ToNot(BeNil()) - Expect(len(brokers)).To(Equal(0)) + Expect(err).To(Equal(errors.New("error syncing service broker"))) + }) }) }) - Context("with an error", func() { - It("returns the error", func() { + Describe("EnableAccessForPlan", func() { + It("should call Fetch", func() { platformClient := newDefaultPlatformClient() - - k8sApi.RetrieveClusterServiceBrokersStub = func() (*v1beta1.ClusterServiceBrokerList, error) { - return nil, errors.New("error getting clusterservicebrokers") + k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { + return expectedError } + Expect(platformClient.EnableAccessForPlan(ctx, &platform.ModifyPlanAccessRequest{})).To(Equal(expectedError)) + }) + }) - brokers, err := platformClient.GetBrokers(ctx) + Describe("DisableAccessForPlan", func() { - Expect(brokers).To(BeNil()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("error getting clusterservicebrokers")) + It("should call Fetch", func() { + platformClient := newDefaultPlatformClient() + k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { + return expectedError + } + Expect(platformClient.DisableAccessForPlan(ctx, &platform.ModifyPlanAccessRequest{})).To(Equal(expectedError)) + }) + }) + + Describe("Concurrent Modification", func() { + It("visibility for the same broker", func() { + NewClient(settings) + platformClient, err := NewClient(settings) + Expect(err).ToNot(HaveOccurred()) + scat := platformClient.platformAPI.(*ServiceCatalogAPI) + scat.setBrokerInProgress("test") + expectedError := platformClient.platformAPI.SyncClusterServiceBroker("test", 1) + Expect(expectedError).NotTo(HaveOccurred()) + scat.unsetBrokerInProgress("test") }) }) }) - Describe("Get service broker by name", func() { - Context("with no error", func() { - It("returns the service broker", func() { - platformClient := newDefaultPlatformClient() - brokerName := "brokerName" - - k8sApi.RetrieveClusterServiceBrokerByNameStub = func(name string) (*v1beta1.ClusterServiceBroker, error) { - return &v1beta1.ClusterServiceBroker{ - ObjectMeta: v1.ObjectMeta{ - UID: "1234", - Name: brokerName, - }, - Spec: v1beta1.ClusterServiceBrokerSpec{ - CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ - URL: "http://fake.broker.url", + Describe("Namespace service broker", func() { + BeforeEach(func() { + settings.K8S.TargetNamespace = "test-namespace" + }) + Describe("Create a service broker", func() { + + Context("with no error", func() { + It("returns broker", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.CreateNamespaceServiceBrokerStub = func(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) { + return &v1beta1.ServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + UID: "1234", + Name: broker.Name, }, - }, - }, nil - } + Spec: v1beta1.ServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: broker.Spec.URL, + }, + }, + }, nil + } + + requestBroker := &platform.CreateServiceBrokerRequest{ + ID: "id-in-sm", + Name: "fake-broker", + BrokerURL: "http://fake.broker.url", + Username: "admin", + Password: "admin", + } + + k8sApi.CreateSecretStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + Expect(secret2.Name).To(Equal(requestBroker.ID)) + Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) + Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) + return secret2, nil + } + createdBroker, err := platformClient.CreateBroker(ctx, requestBroker) + + Expect(err).To(BeNil()) + Expect(createdBroker.GUID).To(Equal("1234")) + Expect(createdBroker.Name).To(Equal("fake-broker")) + Expect(createdBroker.BrokerURL).To(Equal("http://fake.broker.url")) + }) + }) + + Context("with an error", func() { + It("returns error", func() { + platformClient := newDefaultPlatformClient() - broker, err := platformClient.GetBrokerByName(ctx, brokerName) + k8sApi.CreateSecretStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + return secret2, nil + } + k8sApi.CreateNamespaceServiceBrokerStub = func(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) { + return nil, errors.New("error from service-catalog") + } - Expect(err).To(BeNil()) - Expect(broker).ToNot(BeNil()) - Expect(broker.Name).To(Equal(brokerName)) + requestBroker := &platform.CreateServiceBrokerRequest{} + createdBroker, err := platformClient.CreateBroker(ctx, requestBroker) + + Expect(createdBroker).To(BeNil()) + Expect(err).To(Equal(errors.New("error from service-catalog"))) + }) }) }) - Context("with an error", func() { - It("returns the error", func() { - platformClient := newDefaultPlatformClient() + Describe("Delete a service broker", func() { + Context("with no error", func() { + It("returns no error", func() { + platformClient := newDefaultPlatformClient() - k8sApi.RetrieveClusterServiceBrokerByNameStub = func(name string) (*v1beta1.ClusterServiceBroker, error) { - return nil, errors.New("error getting clusterservicebroker") - } + k8sApi.DeleteNamespaceServiceBrokerStub = func(name, namespace string, options *v1.DeleteOptions) error { + return nil + } - broker, err := platformClient.GetBrokerByName(ctx, "brokerName") + requestBroker := &platform.DeleteServiceBrokerRequest{ + ID: "id-in-sm", + GUID: "1234", + Name: "fake-broker", + } - Expect(broker).To(BeNil()) - Expect(err).To(HaveOccurred()) - Expect(err.Error()).To(ContainSubstring("error getting clusterservicebroker")) + err := platformClient.DeleteBroker(ctx, requestBroker) + + Expect(err).To(BeNil()) + }) + }) + + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.DeleteNamespaceServiceBrokerStub = func(name, namespace string, options *v1.DeleteOptions) error { + return errors.New("error deleting servicebroker") + } + + requestBroker := &platform.DeleteServiceBrokerRequest{} + + err := platformClient.DeleteBroker(ctx, requestBroker) + + Expect(err).To(Equal(errors.New("error deleting servicebroker"))) + }) }) }) - }) - Describe("Update a service broker", func() { - Context("with no errors", func() { - It("returns updated broker", func() { - platformClient := newDefaultPlatformClient() + Describe("Get all service brokers", func() { + Context("with no error", func() { + It("returns brokers", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.RetrieveNamespaceServiceBrokersStub = func(namespace string) (*v1beta1.ServiceBrokerList, error) { + brokers := make([]v1beta1.ServiceBroker, 0) + brokers = append(brokers, v1beta1.ServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + UID: "1234", + Name: "fake-broker", + }, + Spec: v1beta1.ServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: "http://fake.broker.url", + }, + }, + }) + return &v1beta1.ServiceBrokerList{ + Items: brokers, + }, nil + } + + brokers, err := platformClient.GetBrokers(ctx) + + Expect(err).To(BeNil()) + Expect(brokers).ToNot(BeNil()) + Expect(len(brokers)).To(Equal(1)) + Expect(brokers[0].GUID).To(Equal("1234")) + Expect(brokers[0].Name).To(Equal("fake-broker")) + Expect(brokers[0].BrokerURL).To(Equal("http://fake.broker.url")) + }) + }) + + Context("when no service brokers are registered", func() { + It("returns empty array", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.RetrieveNamespaceServiceBrokersStub = func(namespace string) (*v1beta1.ServiceBrokerList, error) { + brokers := make([]v1beta1.ServiceBroker, 0) + return &v1beta1.ServiceBrokerList{ + Items: brokers, + }, nil + } - k8sApi.UpdateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { - // Return a new fake clusterservicebroker with the three attributes relevant for the OSBAPI guid, name and broker url. - // UID and name cannot be modified, url can be modified - return &v1beta1.ClusterServiceBroker{ - ObjectMeta: v1.ObjectMeta{ - Name: broker.Name + "-updated", - UID: "1234", - }, - Spec: v1beta1.ClusterServiceBrokerSpec{ - CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ - URL: broker.Spec.CommonServiceBrokerSpec.URL + "-updated", + brokers, err := platformClient.GetBrokers(ctx) + + Expect(err).To(BeNil()) + Expect(brokers).ToNot(BeNil()) + Expect(len(brokers)).To(Equal(0)) + }) + }) + + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.RetrieveNamespaceServiceBrokersStub = func(namespace string) (*v1beta1.ServiceBrokerList, error) { + return nil, errors.New("error getting servicebrokers") + } + + brokers, err := platformClient.GetBrokers(ctx) + + Expect(brokers).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error getting servicebrokers")) + }) + }) + }) + + Describe("Get service broker by name", func() { + Context("with no error", func() { + It("returns the service broker", func() { + platformClient := newDefaultPlatformClient() + brokerName := "brokerName" + + k8sApi.RetrieveNamespaceServiceBrokerByNameStub = func(name, namespace string) (*v1beta1.ServiceBroker, error) { + return &v1beta1.ServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + UID: "1234", + Name: brokerName, }, - }, - }, nil - } + Spec: v1beta1.ServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: "http://fake.broker.url", + }, + }, + }, nil + } - requestBroker := &platform.UpdateServiceBrokerRequest{ - ID: "id-in-sm", - GUID: "1234", - Name: "fake-broker", - BrokerURL: "http://fake.broker.url", - Username: "admin", - Password: "admin", - } + broker, err := platformClient.GetBrokerByName(ctx, brokerName) - k8sApi.UpdateClusterServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { - Expect(secret2.Name).To(Equal(requestBroker.ID)) - Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) - Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) - return secret2, nil - } + Expect(err).To(BeNil()) + Expect(broker).ToNot(BeNil()) + Expect(broker.Name).To(Equal(brokerName)) + }) + }) + + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() - broker, err := platformClient.UpdateBroker(ctx, requestBroker) + k8sApi.RetrieveNamespaceServiceBrokerByNameStub = func(name, namespace string) (*v1beta1.ServiceBroker, error) { + return nil, errors.New("error getting servicebroker") + } - Expect(err).To(BeNil()) - Expect(broker.GUID).To(Equal("1234")) - Expect(broker.Name).To(Equal("fake-broker-updated")) - Expect(broker.BrokerURL).To(Equal("http://fake.broker.url-updated")) + broker, err := platformClient.GetBrokerByName(ctx, "brokerName") + + Expect(broker).To(BeNil()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error getting servicebroker")) + }) }) }) - Context("with an error", func() { - It("returns the error", func() { - platformClient := newDefaultPlatformClient() + Describe("Update a service broker", func() { + Context("with no errors", func() { + It("returns updated broker", func() { + platformClient := newDefaultPlatformClient() + + k8sApi.UpdateNamespaceServiceBrokerStub = func(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) { + // Return a new fake clusterservicebroker with the three attributes relevant for the OSBAPI guid, name and broker url. + // UID and name cannot be modified, url can be modified + return &v1beta1.ServiceBroker{ + ObjectMeta: v1.ObjectMeta{ + Name: broker.Name + "-updated", + UID: "1234", + }, + Spec: v1beta1.ServiceBrokerSpec{ + CommonServiceBrokerSpec: v1beta1.CommonServiceBrokerSpec{ + URL: broker.Spec.CommonServiceBrokerSpec.URL + "-updated", + }, + }, + }, nil + } + + requestBroker := &platform.UpdateServiceBrokerRequest{ + ID: "id-in-sm", + GUID: "1234", + Name: "fake-broker", + BrokerURL: "http://fake.broker.url", + Username: "admin", + Password: "admin", + } + + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + Expect(secret2.Name).To(Equal(requestBroker.ID)) + Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) + Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) + return secret2, nil + } + + broker, err := platformClient.UpdateBroker(ctx, requestBroker) + + Expect(err).To(BeNil()) + Expect(broker.GUID).To(Equal("1234")) + Expect(broker.Name).To(Equal("fake-broker-updated")) + Expect(broker.BrokerURL).To(Equal("http://fake.broker.url-updated")) + }) + }) - k8sApi.UpdateClusterServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { - return secret2, nil - } - k8sApi.UpdateClusterServiceBrokerStub = func(broker *v1beta1.ClusterServiceBroker) (*v1beta1.ClusterServiceBroker, error) { - return nil, errors.New("error updating clusterservicebroker") - } + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() - requestBroker := &platform.UpdateServiceBrokerRequest{} + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + return secret2, nil + } + k8sApi.UpdateNamespaceServiceBrokerStub = func(broker *v1beta1.ServiceBroker, namespace string) (*v1beta1.ServiceBroker, error) { + return nil, errors.New("error updating servicebroker") + } - broker, err := platformClient.UpdateBroker(ctx, requestBroker) + requestBroker := &platform.UpdateServiceBrokerRequest{} - Expect(broker).To(BeNil()) - Expect(err).To(Equal(errors.New("error updating clusterservicebroker"))) + broker, err := platformClient.UpdateBroker(ctx, requestBroker) + + Expect(broker).To(BeNil()) + Expect(err).To(Equal(errors.New("error updating servicebroker"))) + }) }) }) - }) - Describe("Fetch the catalog information of a service broker", func() { - Context("with no errors", func() { - It("returns nil", func() { - platformClient := newDefaultPlatformClient() + Describe("Fetch the catalog information of a service broker", func() { + Context("with no errors", func() { + It("returns nil", func() { + platformClient := newDefaultPlatformClient() + + requestBroker := &platform.UpdateServiceBrokerRequest{ + ID: "id-in-sm", + GUID: "1234", + Name: "fake-broker", + BrokerURL: "http://fake.broker.url", + Username: "admin", + Password: "admin", + } + + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + Expect(secret2.Name).To(Equal(requestBroker.ID)) + Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) + Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) + return secret2, nil + } + k8sApi.SyncNamespaceServiceBrokerStub = func(name, namespace string, retries int) error { + return nil + } + + err := platformClient.Fetch(ctx, requestBroker) + + Expect(err).To(BeNil()) + }) + }) - requestBroker := &platform.UpdateServiceBrokerRequest{ - ID: "id-in-sm", - GUID: "1234", - Name: "fake-broker", - BrokerURL: "http://fake.broker.url", - Username: "admin", - Password: "admin", - } + Context("with an error", func() { + It("returns the error", func() { + platformClient := newDefaultPlatformClient() - k8sApi.UpdateClusterServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { - Expect(secret2.Name).To(Equal(requestBroker.ID)) - Expect(string(secret2.Data["username"])).To(Equal(requestBroker.Username)) - Expect(string(secret2.Data["password"])).To(Equal(requestBroker.Password)) - return secret2, nil - } - k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { - return nil - } + requestBroker := &platform.UpdateServiceBrokerRequest{} + k8sApi.UpdateServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { + return secret2, nil + } + k8sApi.SyncNamespaceServiceBrokerStub = func(name, namespace string, retries int) error { + return errors.New("error syncing service broker") + } - err := platformClient.Fetch(ctx, requestBroker) + err := platformClient.Fetch(ctx, requestBroker) - Expect(err).To(BeNil()) + Expect(err).To(Equal(errors.New("error syncing service broker"))) + }) }) }) - Context("with an error", func() { - It("returns the error", func() { + Describe("EnableAccessForPlan", func() { + It("should call Fetch", func() { platformClient := newDefaultPlatformClient() - - requestBroker := &platform.UpdateServiceBrokerRequest{} - k8sApi.UpdateClusterServiceBrokerCredentialsStub = func(secret2 *v1core.Secret) (secret *v1core.Secret, err error) { - return secret2, nil - } - k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { - return errors.New("error syncing service broker") + k8sApi.SyncNamespaceServiceBrokerStub = func(name, namespace string, retries int) error { + return expectedError } + Expect(platformClient.EnableAccessForPlan(ctx, &platform.ModifyPlanAccessRequest{})).To(Equal(expectedError)) + }) + }) - err := platformClient.Fetch(ctx, requestBroker) + Describe("DisableAccessForPlan", func() { - Expect(err).To(Equal(errors.New("error syncing service broker"))) + It("should call Fetch", func() { + platformClient := newDefaultPlatformClient() + k8sApi.SyncNamespaceServiceBrokerStub = func(name, namespace string, retries int) error { + return expectedError + } + Expect(platformClient.DisableAccessForPlan(ctx, &platform.ModifyPlanAccessRequest{})).To(Equal(expectedError)) + }) + }) + + Describe("Concurrent Modification", func() { + It("visibility for the same broker", func() { + NewClient(settings) + platformClient, err := NewClient(settings) + Expect(err).ToNot(HaveOccurred()) + scat := platformClient.platformAPI.(*ServiceCatalogAPI) + scat.setBrokerInProgress("test") + expectedError := platformClient.platformAPI.SyncNamespaceServiceBroker("test", "test-namespace", 1) + Expect(expectedError).NotTo(HaveOccurred()) + scat.unsetBrokerInProgress("test") }) }) }) @@ -462,37 +869,4 @@ var _ = Describe("Kubernetes Broker Proxy", func() { }) }) - Describe("EnableAccessForPlan", func() { - It("should call Fetch", func() { - platformClient := newDefaultPlatformClient() - k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { - return expectedError - } - Expect(platformClient.EnableAccessForPlan(ctx, &platform.ModifyPlanAccessRequest{})).To(Equal(expectedError)) - }) - }) - - Describe("DisableAccessForPlan", func() { - - It("should call Fetch", func() { - platformClient := newDefaultPlatformClient() - k8sApi.SyncClusterServiceBrokerStub = func(name string, retries int) error { - return expectedError - } - Expect(platformClient.DisableAccessForPlan(ctx, &platform.ModifyPlanAccessRequest{})).To(Equal(expectedError)) - }) - }) - - Describe("Concurrent Modification", func() { - It("visibility for the same broker", func() { - NewClient(settings) - platformClient, err := NewClient(settings) - Expect(err).ToNot(HaveOccurred()) - scat := platformClient.platformAPI.(*ServiceCatalogAPI) - scat.setBrokerInProgress("test") - expectedError := platformClient.platformAPI.SyncClusterServiceBroker("test", 1) - Expect(expectedError).NotTo(HaveOccurred()) - scat.unsetBrokerInProgress("test") - }) - }) }) diff --git a/pkg/k8s/config/config.go b/pkg/k8s/config/config.go index b6d28a34..a46c6da6 100644 --- a/pkg/k8s/config/config.go +++ b/pkg/k8s/config/config.go @@ -45,6 +45,7 @@ type ClientConfiguration struct { ClientSettings *LibraryConfig `mapstructure:"client"` Secret *SecretRef `mapstructure:"secret"` K8sClientCreateFunc func(*LibraryConfig) (*servicecatalog.SDK, error) `mapstructure:"-"` + TargetNamespace string `mapstructure:"target_namespace"` } // Validate validates the configuration and returns appropriate errors in case it is invalid diff --git a/pkg/k8s/config/config_test.go b/pkg/k8s/config/config_test.go index a844b5ce..7dfa6a56 100644 --- a/pkg/k8s/config/config_test.go +++ b/pkg/k8s/config/config_test.go @@ -63,6 +63,7 @@ var _ = Describe("Kubernetes Broker Proxy", func() { BeforeEach(func() { config = DefaultClientConfiguration() + config.TargetNamespace = "some-namespace" config.Secret.Namespace = "abc" }) @@ -73,6 +74,14 @@ var _ = Describe("Kubernetes Broker Proxy", func() { }) }) + Context("when TargetNamespace is missing", func() { + It("should return nil", func() { + config.TargetNamespace = "" + err := config.Validate() + Expect(err).ToNot(HaveOccurred()) + }) + }) + Context("when ClientCreateFunc is missing", func() { It("should fail", func() { config.K8sClientCreateFunc = nil