Skip to content

Commit e7f0e3b

Browse files
committed
DBAAS-831: update DBaaSConnection status to conform to the Provisioned Service ducktype defined in the Service Binding Specification for Kubernetes
1 parent 0980243 commit e7f0e3b

File tree

9 files changed

+1312
-126
lines changed

9 files changed

+1312
-126
lines changed

bundle/manifests/dbaas.redhat.com_rdsconnections.yaml

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ spec:
5757
status:
5858
description: DBaaSConnectionStatus defines the observed state of DBaaSConnection
5959
properties:
60+
binding:
61+
description: 'Binding exposes a secret containing the binding information
62+
for the instance. It implements the service binding Provisioned
63+
Service duck type. See: https://github.com/servicebinding/spec#provisioned-service'
64+
properties:
65+
name:
66+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
67+
TODO: Add other useful fields. apiVersion, kind, uid?'
68+
type: string
69+
type: object
6070
conditions:
6171
items:
6272
description: "Condition contains details for one aspect of the current
@@ -125,24 +135,6 @@ spec:
125135
- type
126136
type: object
127137
type: array
128-
connectionInfoRef:
129-
description: A ConfigMap holding non-sensitive information needed
130-
for connecting to the DB instance
131-
properties:
132-
name:
133-
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
134-
TODO: Add other useful fields. apiVersion, kind, uid?'
135-
type: string
136-
type: object
137-
credentialsRef:
138-
description: Secret holding the credentials needed for accessing the
139-
DB instance
140-
properties:
141-
name:
142-
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
143-
TODO: Add other useful fields. apiVersion, kind, uid?'
144-
type: string
145-
type: object
146138
type: object
147139
type: object
148140
served: true

config/crd/bases/dbaas.redhat.com_rdsconnections.yaml

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ spec:
5858
status:
5959
description: DBaaSConnectionStatus defines the observed state of DBaaSConnection
6060
properties:
61+
binding:
62+
description: 'Binding exposes a secret containing the binding information
63+
for the instance. It implements the service binding Provisioned
64+
Service duck type. See: https://github.com/servicebinding/spec#provisioned-service'
65+
properties:
66+
name:
67+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
68+
TODO: Add other useful fields. apiVersion, kind, uid?'
69+
type: string
70+
type: object
6171
conditions:
6272
items:
6373
description: "Condition contains details for one aspect of the current
@@ -126,24 +136,6 @@ spec:
126136
- type
127137
type: object
128138
type: array
129-
connectionInfoRef:
130-
description: A ConfigMap holding non-sensitive information needed
131-
for connecting to the DB instance
132-
properties:
133-
name:
134-
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
135-
TODO: Add other useful fields. apiVersion, kind, uid?'
136-
type: string
137-
type: object
138-
credentialsRef:
139-
description: Secret holding the credentials needed for accessing the
140-
DB instance
141-
properties:
142-
name:
143-
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
144-
TODO: Add other useful fields. apiVersion, kind, uid?'
145-
type: string
146-
type: object
147139
type: object
148140
type: object
149141
served: true

controllers/rdsconnection_controller.go

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import (
4343
const (
4444
instanceIDKey = ".spec.instanceID"
4545

46-
databaseProvider = "Red Hat DBaaS / Amazon Relational Database Service (RDS)"
46+
databaseProvider = "rhoda/amazon rds"
4747

4848
connectionConditionReady = "ReadyForBinding"
4949

@@ -57,7 +57,6 @@ const (
5757
connectionStatusMessageUpdateError = "Failed to update Connection"
5858
connectionStatusMessageUpdating = "Updating Connection"
5959
connectionStatusMessageSecretError = "Failed to create or update secret"
60-
connectionStatusMessageConfigMapError = "Failed to create or update configmap"
6160
connectionStatusMessageInstanceNotFound = "Instance not found"
6261
connectionStatusMessageInstanceNotReady = "Instance not ready"
6362
connectionStatusMessageGetInstanceError = "Failed to get Instance"
@@ -221,15 +220,7 @@ func (r *RDSConnectionReconciler) Reconcile(ctx context.Context, req ctrl.Reques
221220
return true
222221
}
223222

224-
dbConfigMap, e := r.createOrUpdateConfigMap(ctx, &connection, &dbInstance)
225-
if e != nil {
226-
logger.Error(e, "Failed to create or update configmap for Connection")
227-
returnError(e, connectionStatusReasonBackendError, connectionStatusMessageConfigMapError)
228-
return true
229-
}
230-
231-
connection.Status.CredentialsRef = &v1.LocalObjectReference{Name: userSecret.Name}
232-
connection.Status.ConnectionInfoRef = &v1.LocalObjectReference{Name: dbConfigMap.Name}
223+
connection.Status.Binding = &v1.LocalObjectReference{Name: userSecret.Name}
233224
if e := r.Status().Update(ctx, &connection); e != nil {
234225
if errors.IsConflict(e) {
235226
logger.Info("Connection modified, retry reconciling")
@@ -290,7 +281,7 @@ func (r *RDSConnectionReconciler) Reconcile(ctx context.Context, req ctrl.Reques
290281

291282
func (r *RDSConnectionReconciler) createOrUpdateSecret(ctx context.Context, connection *rdsdbaasv1alpha1.RDSConnection,
292283
dbSecret *v1.Secret, dbInstance *rdsv1alpha1.DBInstance) (*v1.Secret, error) {
293-
secretName := fmt.Sprintf("%s-credentials", connection.Name)
284+
secretName := fmt.Sprintf("%s-connection-credentials", connection.Name)
294285
secret := &v1.Secret{
295286
ObjectMeta: metav1.ObjectMeta{
296287
Name: secretName,
@@ -303,6 +294,7 @@ func (r *RDSConnectionReconciler) createOrUpdateSecret(ctx context.Context, conn
303294
if err := ctrl.SetControllerReference(connection, secret, r.Scheme); err != nil {
304295
return err
305296
}
297+
secret.Type = v1.SecretType(fmt.Sprintf("servicebinding.io/%s", generateBindingType(*dbInstance.Spec.Engine)))
306298
setSecret(secret, dbSecret, dbInstance)
307299
return nil
308300
})
@@ -316,7 +308,42 @@ func setSecret(secret *v1.Secret, dbSecret *v1.Secret, dbInstance *rdsv1alpha1.D
316308
data := map[string][]byte{
317309
"username": []byte(*dbInstance.Spec.MasterUsername),
318310
"password": dbSecret.Data[dbInstance.Spec.MasterUserPassword.Key],
311+
"type": []byte(generateBindingType(*dbInstance.Spec.Engine)),
312+
"provider": []byte(databaseProvider),
313+
"host": []byte(*dbInstance.Status.Endpoint.Address),
314+
"port": []byte(strconv.FormatInt(*dbInstance.Status.Endpoint.Port, 10)),
315+
}
316+
317+
if dbInstance.Spec.DBName != nil {
318+
data["database"] = []byte(*dbInstance.Spec.DBName)
319+
} else if dbInstance.Spec.Engine != nil {
320+
if dbName := getDefaultDBName(*dbInstance.Spec.Engine); dbName != nil {
321+
data["database"] = []byte(*dbName)
322+
}
323+
}
324+
325+
if dbInstance.Spec.Engine != nil {
326+
host := data["host"]
327+
port := data["port"]
328+
db, dbOk := data["database"]
329+
330+
switch *dbInstance.Spec.Engine {
331+
case oracleSe2, oracleSe2Cdb, oracleEe, oracleEeCdb, customOracleEe:
332+
if dbOk {
333+
data["jdbc-url"] = []byte(fmt.Sprintf("jdbc:oracle:thin:@%s:%s/%s", host, port, db))
334+
} else {
335+
data["jdbc-url"] = []byte(fmt.Sprintf("jdbc:oracle:thin:@%s:%s", host, port))
336+
}
337+
case sqlserverEe, sqlserverSe, sqlserverEx, sqlserverWeb, customSqlserverEe, customSqlserverSe, customSqlserverWeb:
338+
if dbOk {
339+
data["jdbc-url"] = []byte(fmt.Sprintf("jdbc:sqlserver://%s:%s;databaseName=%s", host, port, db))
340+
} else {
341+
data["jdbc-url"] = []byte(fmt.Sprintf("jdbc:sqlserver://%s:%s", host, port))
342+
}
343+
default:
344+
}
319345
}
346+
320347
secret.Data = data
321348
}
322349

controllers/rdsconnection_controller_test.go

Lines changed: 60 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -511,17 +511,15 @@ var _ = Describe("RDSConnectionController", func() {
511511
if condition == nil || condition.Status != metav1.ConditionTrue || condition.Reason != "Ready" {
512512
return false
513513
}
514-
Expect(conn.Status.CredentialsRef).ShouldNot(BeNil())
515-
Expect(conn.Status.CredentialsRef.Name).Should(Equal(fmt.Sprintf("%s-credentials", conn.Name)))
516-
Expect(conn.Status.ConnectionInfoRef).ShouldNot(BeNil())
517-
Expect(conn.Status.ConnectionInfoRef.Name).Should(Equal(fmt.Sprintf("%s-configs", conn.Name)))
514+
Expect(conn.Status.Binding).ShouldNot(BeNil())
515+
Expect(conn.Status.Binding.Name).Should(Equal(fmt.Sprintf("%s-connection-credentials", conn.Name)))
518516
return true
519517
}, timeout).Should(BeTrue())
520518

521519
By("checking the Secret of the Connection")
522520
secret := &v1.Secret{
523521
ObjectMeta: metav1.ObjectMeta{
524-
Name: conn.Status.CredentialsRef.Name,
522+
Name: conn.Status.Binding.Name,
525523
Namespace: testNamespace,
526524
},
527525
}
@@ -535,45 +533,28 @@ var _ = Describe("RDSConnectionController", func() {
535533
Expect(*secretOwner.Controller).Should(BeTrue())
536534
Expect(secretOwner.BlockOwnerDeletion).ShouldNot(BeNil())
537535
Expect(*secretOwner.BlockOwnerDeletion).Should(BeTrue())
536+
Expect(string(secret.Type)).Should(Equal(fmt.Sprintf("servicebinding.io/%s", "postgresql")))
538537
user, userOk := secret.Data["username"]
539538
Expect(userOk).Should(BeTrue())
540539
Expect(string(user)).Should(Equal("user-connection-controller"))
541540
password, passwordOk := secret.Data["password"]
542541
Expect(passwordOk).Should(BeTrue())
543542
Expect(string(password)).Should(Equal("testpassword"))
544-
545-
By("checking the ConfigMap of the Connection")
546-
configmap := &v1.ConfigMap{
547-
ObjectMeta: metav1.ObjectMeta{
548-
Name: conn.Status.ConnectionInfoRef.Name,
549-
Namespace: testNamespace,
550-
},
551-
}
552-
err = k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), configmap)
553-
Expect(err).ShouldNot(HaveOccurred())
554-
configmapOwner := metav1.GetControllerOf(configmap)
555-
Expect(configmapOwner).ShouldNot(BeNil())
556-
Expect(configmapOwner.Kind).Should(Equal("RDSConnection"))
557-
Expect(configmapOwner.Name).Should(Equal(conn.Name))
558-
Expect(configmapOwner.Controller).ShouldNot(BeNil())
559-
Expect(*configmapOwner.Controller).Should(BeTrue())
560-
Expect(configmapOwner.BlockOwnerDeletion).ShouldNot(BeNil())
561-
Expect(*configmapOwner.BlockOwnerDeletion).Should(BeTrue())
562-
t, typeOk := configmap.Data["type"]
543+
t, typeOk := secret.Data["type"]
563544
Expect(typeOk).Should(BeTrue())
564-
Expect(t).Should(Equal("postgresql"))
565-
provider, providerOk := configmap.Data["provider"]
545+
Expect(string(t)).Should(Equal("postgresql"))
546+
provider, providerOk := secret.Data["provider"]
566547
Expect(providerOk).Should(BeTrue())
567-
Expect(provider).Should(Equal("Red Hat DBaaS / Amazon Relational Database Service (RDS)"))
568-
host, hostOk := configmap.Data["host"]
548+
Expect(string(provider)).Should(Equal("rhoda/amazon rds"))
549+
host, hostOk := secret.Data["host"]
569550
Expect(hostOk).Should(BeTrue())
570-
Expect(host).Should(Equal("address-connection-controller"))
571-
port, portOk := configmap.Data["port"]
551+
Expect(string(host)).Should(Equal("address-connection-controller"))
552+
port, portOk := secret.Data["port"]
572553
Expect(portOk).Should(BeTrue())
573-
Expect(port).Should(Equal("9000"))
574-
db, dbOk := configmap.Data["database"]
554+
Expect(string(port)).Should(Equal("9000"))
555+
db, dbOk := secret.Data["database"]
575556
Expect(dbOk).Should(BeTrue())
576-
Expect(db).Should(Equal("postgres"))
557+
Expect(string(db)).Should(Equal("postgres"))
577558
})
578559
})
579560
})
@@ -683,40 +664,44 @@ var _ = Describe("RDSConnectionController", func() {
683664
if condition == nil || condition.Status != metav1.ConditionTrue || condition.Reason != "Ready" {
684665
return false
685666
}
686-
Expect(conn.Status.CredentialsRef).ShouldNot(BeNil())
687-
Expect(conn.Status.CredentialsRef.Name).Should(Equal(fmt.Sprintf("%s-credentials", conn.Name)))
688-
Expect(conn.Status.ConnectionInfoRef).ShouldNot(BeNil())
689-
Expect(conn.Status.ConnectionInfoRef.Name).Should(Equal(fmt.Sprintf("%s-configs", conn.Name)))
667+
Expect(conn.Status.Binding).ShouldNot(BeNil())
668+
Expect(conn.Status.Binding.Name).Should(Equal(fmt.Sprintf("%s-connection-credentials", conn.Name)))
690669
return true
691670
}, timeout).Should(BeTrue())
692671

693672
By("checking the ConfigMap of the Connection")
694-
configmap := &v1.ConfigMap{
673+
secret := &v1.Secret{
695674
ObjectMeta: metav1.ObjectMeta{
696-
Name: conn.Status.ConnectionInfoRef.Name,
675+
Name: conn.Status.Binding.Name,
697676
Namespace: testNamespace,
698677
},
699678
}
700-
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), configmap)
679+
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(secret), secret)
701680
Expect(err).ShouldNot(HaveOccurred())
702-
ju, juOk := configmap.Data["jdbc-url"]
681+
user, userOk := secret.Data["username"]
682+
Expect(userOk).Should(BeTrue())
683+
Expect(string(user)).Should(Equal("user-oracle-connection-controller"))
684+
password, passwordOk := secret.Data["password"]
685+
Expect(passwordOk).Should(BeTrue())
686+
Expect(string(password)).Should(Equal("testpassword"))
687+
ju, juOk := secret.Data["jdbc-url"]
703688
Expect(juOk).Should(BeTrue())
704-
Expect(ju).Should(Equal("jdbc:oracle:thin:@address-oracle-connection-controller:9000/ORCL"))
705-
t, typeOk := configmap.Data["type"]
689+
Expect(string(ju)).Should(Equal("jdbc:oracle:thin:@address-oracle-connection-controller:9000/ORCL"))
690+
t, typeOk := secret.Data["type"]
706691
Expect(typeOk).Should(BeTrue())
707-
Expect(t).Should(Equal("oracle"))
708-
provider, providerOk := configmap.Data["provider"]
692+
Expect(string(t)).Should(Equal("oracle"))
693+
provider, providerOk := secret.Data["provider"]
709694
Expect(providerOk).Should(BeTrue())
710-
Expect(provider).Should(Equal("Red Hat DBaaS / Amazon Relational Database Service (RDS)"))
711-
host, hostOk := configmap.Data["host"]
695+
Expect(string(provider)).Should(Equal("rhoda/amazon rds"))
696+
host, hostOk := secret.Data["host"]
712697
Expect(hostOk).Should(BeTrue())
713-
Expect(host).Should(Equal("address-oracle-connection-controller"))
714-
port, portOk := configmap.Data["port"]
698+
Expect(string(host)).Should(Equal("address-oracle-connection-controller"))
699+
port, portOk := secret.Data["port"]
715700
Expect(portOk).Should(BeTrue())
716-
Expect(port).Should(Equal("9000"))
717-
db, dbOk := configmap.Data["database"]
701+
Expect(string(port)).Should(Equal("9000"))
702+
db, dbOk := secret.Data["database"]
718703
Expect(dbOk).Should(BeTrue())
719-
Expect(db).Should(Equal("ORCL"))
704+
Expect(string(db)).Should(Equal("ORCL"))
720705
})
721706
})
722707

@@ -769,40 +754,44 @@ var _ = Describe("RDSConnectionController", func() {
769754
if condition == nil || condition.Status != metav1.ConditionTrue || condition.Reason != "Ready" {
770755
return false
771756
}
772-
Expect(conn.Status.CredentialsRef).ShouldNot(BeNil())
773-
Expect(conn.Status.CredentialsRef.Name).Should(Equal(fmt.Sprintf("%s-credentials", conn.Name)))
774-
Expect(conn.Status.ConnectionInfoRef).ShouldNot(BeNil())
775-
Expect(conn.Status.ConnectionInfoRef.Name).Should(Equal(fmt.Sprintf("%s-configs", conn.Name)))
757+
Expect(conn.Status.Binding).ShouldNot(BeNil())
758+
Expect(conn.Status.Binding.Name).Should(Equal(fmt.Sprintf("%s-connection-credentials", conn.Name)))
776759
return true
777760
}, timeout).Should(BeTrue())
778761

779762
By("checking the ConfigMap of the Connection")
780-
configmap := &v1.ConfigMap{
763+
secret := &v1.Secret{
781764
ObjectMeta: metav1.ObjectMeta{
782-
Name: conn.Status.ConnectionInfoRef.Name,
765+
Name: conn.Status.Binding.Name,
783766
Namespace: testNamespace,
784767
},
785768
}
786-
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(configmap), configmap)
769+
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(secret), secret)
787770
Expect(err).ShouldNot(HaveOccurred())
788-
ju, juOk := configmap.Data["jdbc-url"]
771+
user, userOk := secret.Data["username"]
772+
Expect(userOk).Should(BeTrue())
773+
Expect(string(user)).Should(Equal("user-sqlserver-connection-controller"))
774+
password, passwordOk := secret.Data["password"]
775+
Expect(passwordOk).Should(BeTrue())
776+
Expect(string(password)).Should(Equal("testpassword"))
777+
ju, juOk := secret.Data["jdbc-url"]
789778
Expect(juOk).Should(BeTrue())
790-
Expect(ju).Should(Equal("jdbc:sqlserver://address-sqlserver-connection-controller:9000;databaseName=master"))
791-
t, typeOk := configmap.Data["type"]
779+
Expect(string(ju)).Should(Equal("jdbc:sqlserver://address-sqlserver-connection-controller:9000;databaseName=master"))
780+
t, typeOk := secret.Data["type"]
792781
Expect(typeOk).Should(BeTrue())
793-
Expect(t).Should(Equal("sqlserver"))
794-
provider, providerOk := configmap.Data["provider"]
782+
Expect(string(t)).Should(Equal("sqlserver"))
783+
provider, providerOk := secret.Data["provider"]
795784
Expect(providerOk).Should(BeTrue())
796-
Expect(provider).Should(Equal("Red Hat DBaaS / Amazon Relational Database Service (RDS)"))
797-
host, hostOk := configmap.Data["host"]
785+
Expect(string(provider)).Should(Equal("rhoda/amazon rds"))
786+
host, hostOk := secret.Data["host"]
798787
Expect(hostOk).Should(BeTrue())
799-
Expect(host).Should(Equal("address-sqlserver-connection-controller"))
800-
port, portOk := configmap.Data["port"]
788+
Expect(string(host)).Should(Equal("address-sqlserver-connection-controller"))
789+
port, portOk := secret.Data["port"]
801790
Expect(portOk).Should(BeTrue())
802-
Expect(port).Should(Equal("9000"))
803-
db, dbOk := configmap.Data["database"]
791+
Expect(string(port)).Should(Equal("9000"))
792+
db, dbOk := secret.Data["database"]
804793
Expect(dbOk).Should(BeTrue())
805-
Expect(db).Should(Equal("master"))
794+
Expect(string(db)).Should(Equal("master"))
806795
})
807796
})
808797
})

controllers/rdsinstance_controller.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ func setCredentials(ctx context.Context, cli client.Client, scheme *runtime.Sche
510510
namespace string, owner metav1.Object, kind string) (*v1.Secret, error) {
511511
logger := log.FromContext(ctx)
512512

513-
secretName := fmt.Sprintf("%s-credentials", dbInstance.GetName())
513+
secretName := fmt.Sprintf("%s-instance-credentials", dbInstance.GetName())
514514
secret := &v1.Secret{}
515515
if e := cli.Get(ctx, client.ObjectKey{Namespace: namespace, Name: secretName}, secret); e != nil {
516516
if errors.IsNotFound(e) {

0 commit comments

Comments
 (0)