Skip to content
This repository was archived by the owner on May 6, 2022. It is now read-only.

Commit 18d78ee

Browse files
Thulio Ferraz Assismook-as
andauthored
refactor: improve Provider logic (#99)
* refactor: improve Provider logic This refactor improves the Provider.Bind logic by being clearer on what parameters are used for finding the expected keys and by introducing new types wrapping map[string]interface{} for dealing with repetitive actions. Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: apply review comments 1 Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: license headers Signed-off-by: Thulio Ferraz Assis <[email protected]> * feat: add extra Object helper methods Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: use DigStringAlt for postgresql password Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: DigStringAlt comment Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: use if instead of switch Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: silly nesting Co-authored-by: Mark Yen <[email protected]> * fix: use ifs instead of switches on providers Signed-off-by: Thulio Ferraz Assis <[email protected]> * fix: handle empty keys and key parts on Dig Signed-off-by: Thulio Ferraz Assis <[email protected]> Co-authored-by: Mark Yen <[email protected]>
1 parent 3783f46 commit 18d78ee

File tree

13 files changed

+684
-326
lines changed

13 files changed

+684
-326
lines changed

pkg/broker/broker.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ func (d *ProvisioningSettings) ForService(service string) (*ServiceProvisioningS
7777
type MinibrokerClient interface {
7878
Init(repoURL string) error
7979
ListServices() ([]osb.Service, error)
80-
Provision(instanceID, serviceID, planID, namespace string, acceptsIncomplete bool, provisionParams map[string]interface{}) (string, error)
81-
Bind(instanceID, serviceID, bindingID string, acceptsIncomplete bool, bindParams map[string]interface{}) (string, error)
80+
Provision(instanceID, serviceID, planID, namespace string, acceptsIncomplete bool, provisionParams *minibroker.ProvisionParams) (string, error)
81+
Bind(instanceID, serviceID, bindingID string, acceptsIncomplete bool, bindParams *minibroker.BindParams) (string, error)
8282
Unbind(instanceID, bindingID string) error
8383
GetBinding(instanceID, bindingID string) (*osb.GetBindingResponse, error)
8484
Deprovision(instanceID string, acceptsIncomplete bool) (string, error)
@@ -182,7 +182,14 @@ func (b *Broker) Provision(request *osb.ProvisionRequest, _ *broker.RequestConte
182182
params = request.Parameters
183183
}
184184

185-
operationName, err := b.client.Provision(request.InstanceID, request.ServiceID, request.PlanID, namespace, request.AcceptsIncomplete, params)
185+
operationName, err := b.client.Provision(
186+
request.InstanceID,
187+
request.ServiceID,
188+
request.PlanID,
189+
namespace,
190+
request.AcceptsIncomplete,
191+
minibroker.NewProvisionParams(params),
192+
)
186193
if err != nil {
187194
klog.V(4).Infof("broker: failed to provision request %q: %v", request.InstanceID, err)
188195
return nil, err
@@ -247,7 +254,13 @@ func (b *Broker) Bind(request *osb.BindRequest, _ *broker.RequestContext) (*brok
247254
b.Lock()
248255
defer b.Unlock()
249256

250-
operationName, err := b.client.Bind(request.InstanceID, request.ServiceID, request.BindingID, request.AcceptsIncomplete, request.Parameters)
257+
operationName, err := b.client.Bind(
258+
request.InstanceID,
259+
request.ServiceID,
260+
request.BindingID,
261+
request.AcceptsIncomplete,
262+
minibroker.NewBindParams(request.Parameters),
263+
)
251264
if err != nil {
252265
klog.V(4).Infof("broker: failed to bind %q: %v", request.InstanceID, err)
253266
return nil, err

pkg/broker/broker_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727

2828
"github.com/kubernetes-sigs/minibroker/pkg/broker"
2929
"github.com/kubernetes-sigs/minibroker/pkg/broker/mocks"
30+
"github.com/kubernetes-sigs/minibroker/pkg/minibroker"
3031
)
3132

3233
//go:generate mockgen -destination=./mocks/mock_broker.go -package=mocks github.com/kubernetes-sigs/minibroker/pkg/broker MinibrokerClient
@@ -80,12 +81,12 @@ var _ = Describe("Broker", func() {
8081

8182
Describe("Provision", func() {
8283
var (
83-
provisionParams = map[string]interface{}{
84+
provisionParams = minibroker.NewProvisionParams(map[string]interface{}{
8485
"key": "value",
85-
}
86+
})
8687
provisionRequest = &osb.ProvisionRequest{
8788
ServiceID: "redis",
88-
Parameters: provisionParams,
89+
Parameters: provisionParams.Object,
8990
}
9091
requestContext = &osbbroker.RequestContext{}
9192
)
@@ -113,7 +114,7 @@ var _ = Describe("Broker", func() {
113114
provisionRequest.ServiceID = service
114115
provisioningSettings, found := provisioningSettings.ForService(service)
115116
Expect(found).To(BeTrue())
116-
params := provisioningSettings.OverrideParams
117+
params := minibroker.NewProvisionParams(provisioningSettings.OverrideParams)
117118

118119
mbclient.EXPECT().
119120
Provision(gomock.Any(), gomock.Eq(service), gomock.Any(), gomock.Eq(namespace), gomock.Any(), gomock.Eq(params))

pkg/broker/mocks/mock_broker.go

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/minibroker/mariadb.go

Lines changed: 42 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019 The Kubernetes Authors.
2+
Copyright 2020 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -17,15 +17,26 @@ limitations under the License.
1717
package minibroker
1818

1919
import (
20+
"fmt"
21+
"net/url"
22+
2023
"github.com/pkg/errors"
2124
corev1 "k8s.io/api/core/v1"
2225
)
2326

24-
const mariadbProtocolName = "mysql"
27+
const (
28+
mariadbProtocolName = "mysql"
29+
rootMariadbUsername = "root"
30+
)
2531

2632
type MariadbProvider struct{}
2733

28-
func (p MariadbProvider) Bind(services []corev1.Service, params map[string]interface{}, chartSecrets map[string]interface{}) (*Credentials, error) {
34+
func (p MariadbProvider) Bind(
35+
services []corev1.Service,
36+
_ *BindParams,
37+
provisionParams *ProvisionParams,
38+
chartSecrets Object,
39+
) (Object, error) {
2940
service := services[0]
3041
if len(service.Spec.Ports) == 0 {
3142
return nil, errors.Errorf("no ports found")
@@ -34,58 +45,40 @@ func (p MariadbProvider) Bind(services []corev1.Service, params map[string]inter
3445

3546
host := buildHostFromService(service)
3647

37-
dbParams, ok := params["db"].(map[string]interface{})
38-
if !ok {
39-
dbParams = make(map[string]interface{})
48+
database, err := provisionParams.DigStringOr("db.name", "")
49+
if err != nil {
50+
return nil, fmt.Errorf("failed to get database name: %w", err)
4051
}
41-
42-
database := ""
43-
dbVal, ok := dbParams["name"]
44-
if ok {
45-
database, ok = dbVal.(string)
46-
if !ok {
47-
return nil, errors.Errorf("db.name not a string")
48-
}
52+
user, err := provisionParams.DigStringOr("db.user", rootMariadbUsername)
53+
if err != nil {
54+
return nil, fmt.Errorf("failed to get username: %w", err)
4955
}
5056

51-
var user, password string
52-
userVal, ok := dbParams["user"]
53-
if ok {
54-
user, ok = userVal.(string)
55-
if !ok {
56-
return nil, errors.Errorf("db.user not a string")
57-
}
58-
59-
passwordVal, ok := chartSecrets["mariadb-password"]
60-
if !ok {
61-
return nil, errors.Errorf("mariadb-password not found in secret keys")
62-
}
63-
password, ok = passwordVal.(string)
64-
if !ok {
65-
return nil, errors.Errorf("password not a string")
66-
}
57+
var passwordKey string
58+
if user == rootMariadbUsername {
59+
passwordKey = "mariadb-root-password"
6760
} else {
68-
user = "root"
69-
70-
rootPassword, ok := chartSecrets["mariadb-root-password"]
71-
if !ok {
72-
return nil, errors.Errorf("mariadb-root-password not found in secret keys")
73-
}
74-
password, ok = rootPassword.(string)
75-
if !ok {
76-
return nil, errors.Errorf("password not a string")
77-
}
61+
passwordKey = "mariadb-password"
62+
}
63+
password, err := chartSecrets.DigString(passwordKey)
64+
if err != nil {
65+
return nil, fmt.Errorf("failed to get password: %w", err)
7866
}
7967

80-
creds := Credentials{
81-
Protocol: mariadbProtocolName,
82-
Port: svcPort.Port,
83-
Host: host,
84-
Username: user,
85-
Password: password,
86-
Database: database,
68+
creds := Object{
69+
"protocol": mariadbProtocolName,
70+
"port": svcPort.Port,
71+
"host": host,
72+
"username": user,
73+
"password": password,
74+
"database": database,
75+
"uri": (&url.URL{
76+
Scheme: mariadbProtocolName,
77+
User: url.UserPassword(user, password),
78+
Host: fmt.Sprintf("%s:%d", host, svcPort.Port),
79+
Path: database,
80+
}).String(),
8781
}
88-
creds.URI = buildURI(creds)
8982

90-
return &creds, nil
83+
return creds, nil
9184
}

pkg/minibroker/minibroker.go

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019 The Kubernetes Authors.
2+
Copyright 2020 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -284,7 +284,7 @@ func (c *Client) ListServices() ([]osb.Service, error) {
284284

285285
// Provision a new service instance. Returns the async operation key (if
286286
// acceptsIncomplete is set).
287-
func (c *Client) Provision(instanceID, serviceID, planID, namespace string, acceptsIncomplete bool, provisionParams map[string]interface{}) (string, error) {
287+
func (c *Client) Provision(instanceID, serviceID, planID, namespace string, acceptsIncomplete bool, provisionParams *ProvisionParams) (string, error) {
288288
klog.V(3).Infof("minibroker: provisioning intance %q, service %q, namespace %q, params %v", instanceID, serviceID, namespace, provisionParams)
289289
ctx := context.TODO()
290290

@@ -369,15 +369,15 @@ func (c *Client) Provision(instanceID, serviceID, planID, namespace string, acce
369369
}
370370

371371
// provisionSynchronously will provision the service instance synchronously.
372-
func (c *Client) provisionSynchronously(instanceID, namespace, serviceID, planID, chartName, chartVersion string, provisionParams map[string]interface{}) error {
372+
func (c *Client) provisionSynchronously(instanceID, namespace, serviceID, planID, chartName, chartVersion string, provisionParams *ProvisionParams) error {
373373
klog.V(3).Infof("minibroker: provisioning %s/%s using helm chart %s@%s", serviceID, planID, chartName, chartVersion)
374374

375375
chartDef, err := c.helm.GetChart(chartName, chartVersion)
376376
if err != nil {
377377
return err
378378
}
379379

380-
release, err := c.helm.ChartClient().Install(chartDef, namespace, provisionParams)
380+
release, err := c.helm.ChartClient().Install(chartDef, namespace, provisionParams.Object)
381381
if err != nil {
382382
return err
383383
}
@@ -394,7 +394,7 @@ func (c *Client) provisionSynchronously(instanceID, namespace, serviceID, planID
394394
return err
395395
}
396396
for _, service := range services.Items {
397-
err := c.labelService(service, instanceID, provisionParams)
397+
err := c.labelService(service, instanceID)
398398
if err != nil {
399399
return err
400400
}
@@ -424,7 +424,7 @@ func (c *Client) provisionSynchronously(instanceID, namespace, serviceID, planID
424424
return nil
425425
}
426426

427-
func (c *Client) labelService(service corev1.Service, instanceID string, params map[string]interface{}) error {
427+
func (c *Client) labelService(service corev1.Service, instanceID string) error {
428428
ctx := context.TODO()
429429

430430
labeledService := service.DeepCopy()
@@ -484,7 +484,7 @@ func (c *Client) labelSecret(secret corev1.Secret, instanceID string) error {
484484

485485
// Bind the given service instance (of the given service) asynchronously; the
486486
// binding operation key is returned.
487-
func (c *Client) Bind(instanceID, serviceID, bindingID string, acceptsIncomplete bool, bindParams map[string]interface{}) (string, error) {
487+
func (c *Client) Bind(instanceID, serviceID, bindingID string, acceptsIncomplete bool, bindParams *BindParams) (string, error) {
488488
klog.V(3).Infof("minibroker: binding instance %q, service %q, binding %q, binding params %v", instanceID, serviceID, bindingID, bindParams)
489489
config, err := c.getConfigMap(instanceID)
490490
if err != nil {
@@ -501,7 +501,7 @@ func (c *Client) Bind(instanceID, serviceID, bindingID string, acceptsIncomplete
501501
rawProvisionParams := config.Data[ProvisionParamsKey]
502502
operationName := generateOperationName(OperationPrefixBind)
503503

504-
var provisionParams map[string]interface{}
504+
var provisionParams *ProvisionParams
505505
err = json.Unmarshal([]byte(rawProvisionParams), &provisionParams)
506506
if err != nil {
507507
return "", errors.Wrapf(err, "could not unmarshall provision parameters for instance %q", instanceID)
@@ -510,14 +510,28 @@ func (c *Client) Bind(instanceID, serviceID, bindingID string, acceptsIncomplete
510510
if acceptsIncomplete {
511511
klog.V(3).Infof("minibroker: initializing asynchronous binding %q", bindingID)
512512
go func() {
513-
_ = c.bindSynchronously(instanceID, serviceID, bindingID, releaseNamespace, bindParams, provisionParams)
513+
_ = c.bindSynchronously(
514+
instanceID,
515+
serviceID,
516+
bindingID,
517+
releaseNamespace,
518+
bindParams,
519+
provisionParams,
520+
)
514521
klog.V(3).Infof("minibroker: asynchronously bound instance %q, service %q, binding %q", instanceID, serviceID, bindingID)
515522
}()
516523
return operationName, nil
517524
}
518525

519526
klog.V(3).Infof("minibroker: initializing synchronous binding %q", bindingID)
520-
if err = c.bindSynchronously(instanceID, serviceID, bindingID, releaseNamespace, bindParams, provisionParams); err != nil {
527+
if err := c.bindSynchronously(
528+
instanceID,
529+
serviceID,
530+
bindingID,
531+
releaseNamespace,
532+
bindParams,
533+
provisionParams,
534+
); err != nil {
521535
return "", err
522536
}
523537

@@ -529,20 +543,18 @@ func (c *Client) Bind(instanceID, serviceID, bindingID string, acceptsIncomplete
529543
// bindSynchronously creates a new binding for the given service instance. All
530544
// results are only reported via the service instance configmap (under the
531545
// appropriate key for the binding) for lookup by LastBindingOperationState().
532-
func (c *Client) bindSynchronously(instanceID, serviceID, bindingID, releaseNamespace string, bindParams, provisionParams map[string]interface{}) error {
546+
func (c *Client) bindSynchronously(
547+
instanceID,
548+
serviceID,
549+
bindingID,
550+
releaseNamespace string,
551+
bindParams *BindParams,
552+
provisionParams *ProvisionParams,
553+
) error {
533554
ctx := context.TODO()
534555

535556
// Wrap most of the code in an inner function to simplify error handling
536557
err := func() error {
537-
// Smoosh all the params together
538-
params := make(map[string]interface{}, len(bindParams)+len(provisionParams))
539-
for k, v := range provisionParams {
540-
params[k] = v
541-
}
542-
for k, v := range bindParams {
543-
params[k] = v
544-
}
545-
546558
filterByInstance := metav1.ListOptions{
547559
LabelSelector: labels.SelectorFromSet(map[string]string{
548560
InstanceLabel: instanceID,
@@ -569,7 +581,7 @@ func (c *Client) bindSynchronously(instanceID, serviceID, bindingID, releaseName
569581
return osb.HTTPStatusCodeError{StatusCode: http.StatusNotFound}
570582
}
571583

572-
data := make(map[string]interface{})
584+
data := make(Object)
573585
for _, secret := range secrets.Items {
574586
for key, value := range secret.Data {
575587
data[key] = string(value)
@@ -579,19 +591,24 @@ func (c *Client) bindSynchronously(instanceID, serviceID, bindingID, releaseName
579591
// Apply additional provisioning logic for Service Catalog Enabled services
580592
provider, ok := c.providers[serviceID]
581593
if ok {
582-
creds, err := provider.Bind(services.Items, params, data)
594+
creds, err := provider.Bind(
595+
services.Items,
596+
bindParams,
597+
provisionParams,
598+
data,
599+
)
583600
if err != nil {
584601
return errors.Wrapf(err, "unable to bind instance %s", instanceID)
585602
}
586-
for k, v := range creds.ToMap() {
603+
for k, v := range creds {
587604
data[k] = v
588605
}
589606
}
590607

591608
// Record the result for later fetching
592609
bindingResponse := osb.GetBindingResponse{
593610
Credentials: data,
594-
Parameters: bindParams,
611+
Parameters: bindParams.Object,
595612
}
596613
bindingResponseJSON, err := json.Marshal(bindingResponse)
597614
if err != nil {

pkg/minibroker/minibroker_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright 2019 The Kubernetes Authors.
2+
Copyright 2020 The Kubernetes Authors.
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.

0 commit comments

Comments
 (0)