Skip to content

Commit

Permalink
Add database connection details to sub level secret
Browse files Browse the repository at this point in the history
Add the database connection details to the secret creted by the watcher
controller to pass to the sub CRs, so we don't need to access the
database object from the subCRs.
  • Loading branch information
cescgina authored and openshift-merge-bot[bot] committed Jan 10, 2025
1 parent e607848 commit ab9d7d1
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 109 deletions.
11 changes: 0 additions & 11 deletions api/bases/watcher.openstack.org_watcherapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,6 @@ spec:
description: The service specific Container Image URL (will be set
to environmental default if empty)
type: string
databaseAccount:
default: watcher
description: DatabaseAccount - MariaDBAccount CR name used for watcher
DB, defaults to watcher
type: string
databaseInstance:
description: |-
MariaDB instance name
Required to use the mariadb-operator instance to create the DB and user
type: string
memcachedInstance:
default: memcached
description: MemcachedInstance is the name of the Memcached CR that
Expand Down Expand Up @@ -84,7 +74,6 @@ spec:
to register in keystone
type: string
required:
- databaseInstance
- secret
type: object
status:
Expand Down
20 changes: 10 additions & 10 deletions api/v1beta1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@ type WatcherCommon struct {
// PasswordSelectors - Selectors to identify the ServiceUser password from the Secret
PasswordSelectors PasswordSelector `json:"passwordSelectors"`

// +kubebuilder:validation:Required
// MariaDB instance name
// Required to use the mariadb-operator instance to create the DB and user
DatabaseInstance string `json:"databaseInstance"`

// +kubebuilder:validation:Optional
// +kubebuilder:default=watcher
// DatabaseAccount - MariaDBAccount CR name used for watcher DB, defaults to watcher
DatabaseAccount string `json:"databaseAccount"`

// +kubebuilder:validation:Optional
// +kubebuilder:default=memcached
// MemcachedInstance is the name of the Memcached CR that all watcher service will use.
Expand Down Expand Up @@ -75,6 +65,16 @@ type WatcherTemplate struct {
// +kubebuilder:default=osp-secret
// Secret containing all passwords / keys needed
Secret string `json:"secret"`

// +kubebuilder:validation:Required
// MariaDB instance name
// Required to use the mariadb-operator instance to create the DB and user
DatabaseInstance string `json:"databaseInstance"`

// +kubebuilder:validation:Optional
// +kubebuilder:default=watcher
// DatabaseAccount - MariaDBAccount CR name used for watcher DB, defaults to watcher
DatabaseAccount string `json:"databaseAccount"`
}

// PasswordSelector to identify the DB and AdminUser password from the Secret
Expand Down
11 changes: 0 additions & 11 deletions config/crd/bases/watcher.openstack.org_watcherapis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,6 @@ spec:
description: The service specific Container Image URL (will be set
to environmental default if empty)
type: string
databaseAccount:
default: watcher
description: DatabaseAccount - MariaDBAccount CR name used for watcher
DB, defaults to watcher
type: string
databaseInstance:
description: |-
MariaDB instance name
Required to use the mariadb-operator instance to create the DB and user
type: string
memcachedInstance:
default: memcached
description: MemcachedInstance is the name of the Memcached CR that
Expand Down Expand Up @@ -84,7 +74,6 @@ spec:
to register in keystone
type: string
required:
- databaseInstance
- secret
type: object
status:
Expand Down
3 changes: 1 addition & 2 deletions config/samples/watcher_v1beta1_watcherapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ metadata:
app.kubernetes.io/managed-by: kustomize
name: watcherapi-sample
spec:
databaseInstance: "openstack"
secret: "osp-secret"
secret: "watcher"
7 changes: 7 additions & 0 deletions controllers/watcher_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ var (
const (
// TransportURLSelector is the name of key in the secret created by TransportURL
TransportURLSelector = "transport_url"
// DatabaseUsername is the name of key in the secret for the user name used to login to the database
DatabaseUsername = "database_username"
// DatabaseUsername is the name of key in the secret for the password used to login to the database
DatabasePassword = "database_password"
// DatabaseUsername is the name of key in the secret for the database
// hostname
DatabaseHostname = "database_hostname"
)

// GetLogger returns a logger object with a prefix of "controller.name" and additional controller context fields
Expand Down
11 changes: 9 additions & 2 deletions controllers/watcher_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,6 @@ func (r *WatcherReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re
} else if (result != ctrl.Result{}) {
return result, nil
}
_ = db
// create service DB - end

//
Expand Down Expand Up @@ -245,7 +244,7 @@ func (r *WatcherReconciler) Reconcile(ctx context.Context, req ctrl.Request) (re
return ctrl.Result{}, errors.New("error retrieving required data from transporturl secret")
}

subLevelSecretName, err := r.createSubLevelSecret(ctx, helper, instance, transporturlSecret, inputSecret)
subLevelSecretName, err := r.createSubLevelSecret(ctx, helper, instance, transporturlSecret, inputSecret, db)
if err != nil {
return ctrl.Result{}, nil
}
Expand Down Expand Up @@ -698,10 +697,18 @@ func (r *WatcherReconciler) createSubLevelSecret(
instance *watcherv1beta1.Watcher,
transportURLSecret corev1.Secret,
inputSecret corev1.Secret,
db *mariadbv1.Database,
) (string, error) {
Log := r.GetLogger(ctx)
Log.Info(fmt.Sprintf("Creating SubCr Level Secret for '%s'", instance.Name))
databaseAccount := db.GetAccount()
databaseSecret := db.GetSecret()
data := map[string]string{
instance.Spec.PasswordSelectors.Service: string(inputSecret.Data[instance.Spec.PasswordSelectors.Service]),
TransportURLSelector: string(transportURLSecret.Data[TransportURLSelector]),
DatabaseUsername: databaseAccount.Spec.UserName,
DatabasePassword: string(databaseSecret.Data[mariadbv1.DatabasePasswordSelector]),
DatabaseHostname: db.GetDatabaseHostname(),
}
secretName := instance.Name

Expand Down
27 changes: 8 additions & 19 deletions controllers/watcherapi_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ import (
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
"github.com/openstack-k8s-operators/lib-common/modules/common/labels"
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1"

watcherv1beta1 "github.com/openstack-k8s-operators/watcher-operator/api/v1beta1"
"github.com/openstack-k8s-operators/watcher-operator/pkg/watcher"
Expand Down Expand Up @@ -160,17 +159,6 @@ func (r *WatcherAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request)

configVars[instance.Spec.Secret] = env.SetValue(secretHash)

db, err := mariadbv1.GetDatabaseByNameAndAccount(ctx, helper, watcher.DatabaseCRName, instance.Spec.DatabaseAccount, instance.Namespace)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.InputReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.InputReadyErrorMessage,
fmt.Sprintf("couldn't get database %s and account %s", watcher.DatabaseCRName, instance.Spec.DatabaseAccount)))
return ctrl.Result{}, err
}

// all our input checks out so report InputReady
instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage)

Expand All @@ -193,7 +181,7 @@ func (r *WatcherAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request)
}
}

err = r.generateServiceConfigs(ctx, instance, secret, db, memcached, helper, &configVars)
err = r.generateServiceConfigs(ctx, instance, secret, memcached, helper, &configVars)
if err != nil {
return ctrl.Result{}, err
}
Expand All @@ -213,7 +201,7 @@ func (r *WatcherAPIReconciler) Reconcile(ctx context.Context, req ctrl.Request)
// generateServiceConfigs - create Secret which holds the service configuration
func (r *WatcherAPIReconciler) generateServiceConfigs(
ctx context.Context, instance *watcherv1beta1.WatcherAPI,
secret corev1.Secret, db *mariadbv1.Database,
secret corev1.Secret,
memcachedInstance *memcachedv1.Memcached,
helper *helper.Helper, envVars *map[string]env.Setter,
) error {
Expand Down Expand Up @@ -243,13 +231,14 @@ func (r *WatcherAPIReconciler) generateServiceConfigs(
// implement CustomServiceConfig later
customData := map[string]string{}

databaseAccount := db.GetAccount()
databaseSecret := db.GetSecret()
databaseUsername := string(secret.Data[DatabaseUsername])
databaseHostname := string(secret.Data[DatabaseHostname])
databasePassword := string(secret.Data[DatabasePassword])
templateParameters := map[string]interface{}{
"DatabaseConnection": fmt.Sprintf("mysql+pymysql://%s:%s@%s/%s?charset=utf8",
databaseAccount.Spec.UserName,
string(databaseSecret.Data[mariadbv1.DatabasePasswordSelector]),
db.GetDatabaseHostname(),
databaseUsername,
databasePassword,
databaseHostname,
watcher.DatabaseName,
),
"KeystoneAuthURL": keystoneInternalURL,
Expand Down
61 changes: 10 additions & 51 deletions tests/functional/watcherapi_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,13 @@ import (
. "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers"
mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1"
watcherv1beta1 "github.com/openstack-k8s-operators/watcher-operator/api/v1beta1"
"github.com/openstack-k8s-operators/watcher-operator/pkg/watcher"
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"
)

var (
MinimalWatcherAPISpec = map[string]interface{}{
"secret": "osp-secret",
"databaseInstance": "openstack",
"memcachedInstance": "memcached",
}
)
Expand All @@ -33,8 +31,6 @@ var _ = Describe("WatcherAPI controller with minimal spec values", func() {

It("should have the Spec fields defaulted", func() {
WatcherAPI := GetWatcherAPI(watcherTest.WatcherAPI)
Expect(WatcherAPI.Spec.DatabaseInstance).Should(Equal("openstack"))
Expect(WatcherAPI.Spec.DatabaseAccount).Should(Equal("watcher"))
Expect(WatcherAPI.Spec.Secret).Should(Equal("osp-secret"))
Expect(WatcherAPI.Spec.MemcachedInstance).Should(Equal("memcached"))
Expect(WatcherAPI.Spec.PasswordSelectors).Should(Equal(watcherv1beta1.PasswordSelector{Service: "WatcherPassword"}))
Expand Down Expand Up @@ -64,8 +60,6 @@ var _ = Describe("WatcherAPI controller", func() {

It("should have the Spec fields defaulted", func() {
WatcherAPI := GetWatcherAPI(watcherTest.WatcherAPI)
Expect(WatcherAPI.Spec.DatabaseInstance).Should(Equal("openstack"))
Expect(WatcherAPI.Spec.DatabaseAccount).Should(Equal("watcher"))
Expect(WatcherAPI.Spec.Secret).Should(Equal("test-osp-secret"))
Expect(WatcherAPI.Spec.MemcachedInstance).Should(Equal("memcached"))
})
Expand Down Expand Up @@ -218,54 +212,16 @@ var _ = Describe("WatcherAPI controller", func() {
)
})
})
When("A WatcherAPI instance without a database but with a secret is created", func() {
BeforeEach(func() {
secret := th.CreateSecret(
watcherTest.InternalTopLevelSecretName,
map[string][]byte{
"WatcherPassword": []byte("service-password"),
"transport_url": []byte("url"),
},
)
DeferCleanup(k8sClient.Delete, ctx, secret)
DeferCleanup(th.DeleteInstance, CreateWatcherAPI(watcherTest.WatcherAPI, GetDefaultWatcherAPISpec()))
})
It("should have input not ready", func() {
WatcherAPI := GetWatcherAPI(watcherTest.WatcherAPI)
customErrorString := fmt.Sprintf(
"couldn't get database %s and account %s",
watcher.DatabaseCRName,
WatcherAPI.Spec.DatabaseAccount,
)
errorString := fmt.Sprintf(
condition.InputReadyErrorMessage,
customErrorString,
)
th.ExpectConditionWithDetails(
watcherTest.WatcherAPI,
ConditionGetterFunc(WatcherAPIConditionGetter),
condition.InputReadyCondition,
corev1.ConditionFalse,
condition.ErrorReason,
errorString,
)
})
It("should have config service unknown", func() {
th.ExpectCondition(
watcherTest.WatcherAPI,
ConditionGetterFunc(WatcherAPIConditionGetter),
condition.ServiceConfigReadyCondition,
corev1.ConditionUnknown,
)
})
})
When("secret and db are created, but there is no memcached", func() {
BeforeEach(func() {
secret := th.CreateSecret(
watcherTest.InternalTopLevelSecretName,
map[string][]byte{
"WatcherPassword": []byte("service-password"),
"transport_url": []byte("url"),
"WatcherPassword": []byte("service-password"),
"transport_url": []byte("url"),
"database_username": []byte("username"),
"database_password": []byte("password"),
"database_hostname": []byte("hostname"),
},
)
DeferCleanup(k8sClient.Delete, ctx, secret)
Expand Down Expand Up @@ -303,8 +259,11 @@ var _ = Describe("WatcherAPI controller", func() {
secret := th.CreateSecret(
watcherTest.InternalTopLevelSecretName,
map[string][]byte{
"WatcherPassword": []byte("service-password"),
"transport_url": []byte("url"),
"WatcherPassword": []byte("service-password"),
"transport_url": []byte("url"),
"database_username": []byte("username"),
"database_password": []byte("password"),
"database_hostname": []byte("hostname"),
},
)
DeferCleanup(k8sClient.Delete, ctx, secret)
Expand Down
2 changes: 0 additions & 2 deletions tests/kuttl/test-suites/default/watcher-api/03-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ metadata:
- openstack.org/watcherapi
name: watcherapi-kuttl
spec:
databaseAccount: watcher
databaseInstance: openstack
passwordSelectors:
service: WatcherPassword
secret: watcher-kuttl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@ kind: WatcherAPI
metadata:
name: watcherapi-kuttl
spec:
databaseInstance: openstack
secret: watcher-kuttl
memcachedInstance: "memcached"

0 comments on commit ab9d7d1

Please sign in to comment.