Skip to content

Commit 68dd969

Browse files
committed
use system MariaDBAccount for the galera server's root pw
This commit ties together the previous ones to create a new MariaDBAccount when a Galera instance is created, and then to use the password from that account/secret in the mariadb bootstrap/maintenance scripts. Galera gets bootstrapped with this secret, then the mariadbaccount controller, who is waiting for galera to be available to set up this new "root" account, wakes up when galera is running, and changes the root password to itself, establishing the initial job hash for the mariadbaccount.
1 parent b602d50 commit 68dd969

File tree

9 files changed

+196
-64
lines changed

9 files changed

+196
-64
lines changed

api/bases/mariadb.openstack.org_galeras.yaml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,16 @@ spec:
7878
maximum: 3
7979
minimum: 0
8080
type: integer
81+
rootDatabaseAccount:
82+
default: mariadbroot
83+
description: |-
84+
RootDatabaseAccount - name of MariaDBAccount which will be used to
85+
generate root account / password.
86+
type: string
8187
secret:
82-
description: Name of the secret to look for password keys
88+
description: |-
89+
Deprecated; no longer used; see the "root" MariaDBAccount
90+
secret
8391
type: string
8492
storageClass:
8593
description: Storage class to host the mariadb databases
@@ -118,7 +126,6 @@ spec:
118126
required:
119127
- containerImage
120128
- replicas
121-
- secret
122129
- storageClass
123130
- storageRequest
124131
type: object

api/v1beta1/galera_types.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ limitations under the License.
1717
package v1beta1
1818

1919
import (
20+
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
2021
condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2122
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
2223
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
23-
topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1"
24-
"k8s.io/apimachinery/pkg/util/validation/field"
2524
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
"k8s.io/apimachinery/pkg/util/validation/field"
2626
)
2727

2828
const (
@@ -50,9 +50,17 @@ type GaleraSpec struct {
5050

5151
// GaleraSpec defines the desired state of Galera
5252
type GaleraSpecCore struct {
53-
// Name of the secret to look for password keys
54-
// +kubebuilder:validation:Required
53+
// Deprecated; no longer used; see the "root" MariaDBAccount
54+
// secret
55+
// +kubebuilder:validation:Optional
5556
Secret string `json:"secret"`
57+
58+
// +kubebuilder:validation:Optional
59+
// +kubebuilder:default=mariadbroot
60+
// RootDatabaseAccount - name of MariaDBAccount which will be used to
61+
// generate root account / password.
62+
RootDatabaseAccount string `json:"rootDatabaseAccount"`
63+
5664
// Storage class to host the mariadb databases
5765
// +kubebuilder:validation:Required
5866
StorageClass string `json:"storageClass"`

api/v1beta1/mariadbaccount_types.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ const (
2828
// AccountDeleteHash hash
2929
AccountDeleteHash = "accountdelete"
3030

31-
// DbRootPassword selector for galera root account
32-
DbRootPasswordSelector = "DbRootPassword"
33-
3431
// DatabasePassword selector for MariaDBAccount->Secret
3532
DatabasePasswordSelector = "DatabasePassword"
3633
)

api/v1beta1/mariadbdatabase_funcs.go

Lines changed: 87 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,47 @@ func DeleteDatabaseAndAccountFinalizers(
541541
namespace string,
542542
) error {
543543

544+
err := DeleteAccountFinalizers(
545+
ctx,
546+
h,
547+
accountName,
548+
namespace,
549+
)
550+
if err != nil {
551+
return err
552+
}
553+
554+
// also do a delete for "unused" MariaDBAccounts, associated with
555+
// this MariaDBDatabase.
556+
err = DeleteUnusedMariaDBAccountFinalizers(
557+
ctx, h, name, accountName, namespace,
558+
)
559+
if err != nil && !k8s_errors.IsNotFound(err) {
560+
return err
561+
}
562+
563+
mariaDBDatabase, err := GetDatabase(ctx, h, name, namespace)
564+
if err != nil && !k8s_errors.IsNotFound(err) {
565+
return err
566+
} else if err == nil && controllerutil.RemoveFinalizer(mariaDBDatabase, h.GetFinalizer()) {
567+
err := h.GetClient().Update(ctx, mariaDBDatabase)
568+
if err != nil && !k8s_errors.IsNotFound(err) {
569+
return err
570+
}
571+
util.LogForObject(h, fmt.Sprintf("Removed finalizer %s from MariaDBDatabase %s", h.GetFinalizer(), mariaDBDatabase.Spec.Name), mariaDBDatabase)
572+
}
573+
574+
return nil
575+
}
576+
577+
// DeleteAccountFinalizers performs just the primary account + secret finalizer
578+
// removal part of DeleteDatabaseAndAccountFinalizers
579+
func DeleteAccountFinalizers(
580+
ctx context.Context,
581+
h *helper.Helper,
582+
accountName string,
583+
namespace string,
584+
) error {
544585
databaseAccount, err := GetAccount(ctx, h, accountName, namespace)
545586
if err != nil && !k8s_errors.IsNotFound(err) {
546587
return err
@@ -572,26 +613,6 @@ func DeleteDatabaseAndAccountFinalizers(
572613
}
573614
}
574615

575-
// also do a delete for "unused" MariaDBAccounts, associated with
576-
// this MariaDBDatabase.
577-
err = DeleteUnusedMariaDBAccountFinalizers(
578-
ctx, h, name, accountName, namespace,
579-
)
580-
if err != nil && !k8s_errors.IsNotFound(err) {
581-
return err
582-
}
583-
584-
mariaDBDatabase, err := GetDatabase(ctx, h, name, namespace)
585-
if err != nil && !k8s_errors.IsNotFound(err) {
586-
return err
587-
} else if err == nil && controllerutil.RemoveFinalizer(mariaDBDatabase, h.GetFinalizer()) {
588-
err := h.GetClient().Update(ctx, mariaDBDatabase)
589-
if err != nil && !k8s_errors.IsNotFound(err) {
590-
return err
591-
}
592-
util.LogForObject(h, fmt.Sprintf("Removed finalizer %s from MariaDBDatabase %s", h.GetFinalizer(), mariaDBDatabase.Spec.Name), mariaDBDatabase)
593-
}
594-
595616
return nil
596617
}
597618

@@ -811,6 +832,32 @@ func EnsureMariaDBAccount(ctx context.Context,
811832
userNamePrefix string,
812833
) (*MariaDBAccount, *corev1.Secret, error) {
813834

835+
return ensureMariaDBAccount(
836+
ctx, helper, accountName, namespace, requireTLS,
837+
userNamePrefix, "", map[string]string{})
838+
839+
}
840+
841+
// EnsureMariaDBSystemAccount ensures a MariaDBAccount has been created for a given
842+
// operator calling the function, and returns the MariaDBAccount and its
843+
// Secret for use in consumption into a configuration.
844+
// Unlike EnsureMariaDBAccount, the function accepts an exact username that
845+
// expected to remain constant, supporting in-place password changes for the
846+
// account.
847+
func EnsureMariaDBSystemAccount(ctx context.Context,
848+
helper *helper.Helper,
849+
accountName string, galeraInstanceName string, namespace string, requireTLS bool,
850+
exactUserName string) (*MariaDBAccount, *corev1.Secret, error) {
851+
return ensureMariaDBAccount(
852+
ctx, helper, accountName, namespace, requireTLS,
853+
"", exactUserName, map[string]string{"dbName": galeraInstanceName})
854+
}
855+
856+
func ensureMariaDBAccount(ctx context.Context,
857+
helper *helper.Helper,
858+
accountName string, namespace string, requireTLS bool,
859+
userNamePrefix string, exactUserName string, labels map[string]string,
860+
) (*MariaDBAccount, *corev1.Secret, error) {
814861
if accountName == "" {
815862
return nil, nil, fmt.Errorf("accountName is empty")
816863
}
@@ -822,9 +869,20 @@ func EnsureMariaDBAccount(ctx context.Context,
822869
return nil, nil, err
823870
}
824871

825-
username, err := generateUniqueUsername(userNamePrefix)
826-
if err != nil {
827-
return nil, nil, err
872+
var username string
873+
var accountType AccountType
874+
875+
if exactUserName == "" {
876+
accountType = "User"
877+
username, err = generateUniqueUsername(userNamePrefix)
878+
if err != nil {
879+
return nil, nil, err
880+
}
881+
} else if userNamePrefix != "" {
882+
return nil, nil, fmt.Errorf("userNamePrefix and exactUserName are mutually exclusive")
883+
} else {
884+
accountType = "System"
885+
username = exactUserName
828886
}
829887

830888
account = &MariaDBAccount{
@@ -837,9 +895,10 @@ func EnsureMariaDBAccount(ctx context.Context,
837895
// MariaDBAccount once this is filled in
838896
},
839897
Spec: MariaDBAccountSpec{
840-
UserName: username,
841-
Secret: fmt.Sprintf("%s-db-secret", accountName),
842-
RequireTLS: requireTLS,
898+
UserName: username,
899+
Secret: fmt.Sprintf("%s-db-secret", accountName),
900+
RequireTLS: requireTLS,
901+
AccountType: accountType,
843902
},
844903
}
845904

@@ -874,7 +933,7 @@ func EnsureMariaDBAccount(ctx context.Context,
874933
}
875934
}
876935

877-
_, err = createOrPatchAccountAndSecret(ctx, helper, account, dbSecret, map[string]string{})
936+
_, err = createOrPatchAccountAndSecret(ctx, helper, account, dbSecret, labels)
878937
if err != nil {
879938
return nil, nil, err
880939
}
@@ -890,6 +949,7 @@ func EnsureMariaDBAccount(ctx context.Context,
890949
)
891950

892951
return account, dbSecret, nil
952+
893953
}
894954

895955
// generateUniqueUsername creates a MySQL-compliant database username based on

config/crd/bases/mariadb.openstack.org_galeras.yaml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,16 @@ spec:
7878
maximum: 3
7979
minimum: 0
8080
type: integer
81+
rootDatabaseAccount:
82+
default: mariadbroot
83+
description: |-
84+
RootDatabaseAccount - name of MariaDBAccount which will be used to
85+
generate root account / password.
86+
type: string
8187
secret:
82-
description: Name of the secret to look for password keys
88+
description: |-
89+
Deprecated; no longer used; see the "root" MariaDBAccount
90+
secret
8391
type: string
8492
storageClass:
8593
description: Storage class to host the mariadb databases
@@ -118,7 +126,6 @@ spec:
118126
required:
119127
- containerImage
120128
- replicas
121-
- secret
122129
- storageClass
123130
- storageRequest
124131
type: object

controllers/galera_controller.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper"
3434
"github.com/openstack-k8s-operators/lib-common/modules/common/labels"
3535
common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac"
36-
secret "github.com/openstack-k8s-operators/lib-common/modules/common/secret"
3736
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
3837
commonstatefulset "github.com/openstack-k8s-operators/lib-common/modules/common/statefulset"
3938
"github.com/openstack-k8s-operators/lib-common/modules/common/tls"
@@ -489,7 +488,7 @@ func (r *GaleraReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
489488
{
490489
APIGroups: []string{"mariadb.openstack.org"},
491490
Resources: []string{"mariadbaccounts"},
492-
Verbs: []string{"get"},
491+
Verbs: []string{"get", "list"},
493492
},
494493
{
495494
APIGroups: []string{""},
@@ -567,34 +566,28 @@ func (r *GaleraReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
567566
clusterPropertiesEnv := make(map[string]env.Setter)
568567

569568
// Check and hash inputs
570-
// NOTE do not hash the db root password, as its change requires
571-
// more orchestration than a simple rolling restart
572-
_, res, err := secret.VerifySecret(
573-
ctx,
574-
types.NamespacedName{Namespace: instance.Namespace, Name: instance.Spec.Secret},
575-
[]string{
576-
"DbRootPassword",
577-
},
578-
helper.GetClient(),
579-
time.Duration(5)*time.Second)
569+
570+
_, _, err = mariadbv1.EnsureMariaDBSystemAccount(
571+
ctx, helper, instance.Spec.RootDatabaseAccount,
572+
instance.Name, instance.Namespace, false, "root")
573+
580574
if err != nil {
581-
if k8s_errors.IsNotFound(err) {
582-
instance.Status.Conditions.Set(condition.FalseCondition(
583-
condition.InputReadyCondition,
584-
condition.RequestedReason,
585-
condition.SeverityInfo,
586-
condition.InputReadyWaitingMessage))
587-
return res, fmt.Errorf("OpenStack secret %s not found", instance.Spec.Secret)
588-
}
589575
instance.Status.Conditions.Set(condition.FalseCondition(
590-
condition.InputReadyCondition,
576+
mariadbv1.MariaDBAccountReadyCondition,
591577
condition.ErrorReason,
592578
condition.SeverityWarning,
593-
condition.InputReadyErrorMessage,
579+
mariadbv1.MariaDBAccountNotReadyMessage,
594580
err.Error()))
581+
595582
return ctrl.Result{}, err
596583
}
597-
instance.Status.Conditions.MarkTrue(condition.InputReadyCondition, condition.InputReadyMessage)
584+
instance.Status.Conditions.MarkTrue(
585+
mariadbv1.MariaDBAccountReadyCondition,
586+
mariadbv1.MariaDBAccountReadyMessage)
587+
588+
instance.Status.Conditions.MarkTrue(
589+
condition.InputReadyCondition,
590+
condition.InputReadyMessage)
598591

599592
//
600593
// TLS input validation
@@ -1127,6 +1120,13 @@ func (r *GaleraReconciler) reconcileDelete(ctx context.Context, instance *databa
11271120
return ctrlResult, err
11281121
}
11291122

1123+
// remove finalizer from the system mariadbaccount and associated secret
1124+
err = mariadbv1.DeleteAccountFinalizers(
1125+
ctx, helper, instance.Spec.RootDatabaseAccount, instance.Namespace)
1126+
if err != nil {
1127+
return ctrl.Result{}, err
1128+
}
1129+
11301130
// Service is deleted so remove the finalizer.
11311131
controllerutil.RemoveFinalizer(instance, helper.GetFinalizer())
11321132
helper.GetLogger().Info("Reconciled Service delete successfully")

controllers/mariadbaccount_controller.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ func (r *MariaDBAccountReconciler) reconcileDelete(
327327
// implemented in the database either, so remove all finalizers and
328328
// exit
329329
if k8s_errors.IsNotFound(err) {
330+
log.Info("Galera instance not found, so we will remove finalizers and exit")
330331
if instance.IsUserAccount() {
331332
// remove finalizer from the MariaDBDatabase instance
332333
if controllerutil.RemoveFinalizer(mariadbDatabase, fmt.Sprintf("%s-%s", helper.GetFinalizer(), instance.Name)) {
@@ -572,7 +573,11 @@ func (r *MariaDBAccountReconciler) getGaleraForCreateOrDelete(
572573
dbGalera, err = GetDatabaseObject(ctx, r.Client, dbName, instance.Namespace)
573574

574575
if err != nil {
575-
log.Error(err, "Error retrieving Galera instance")
576+
if k8s_errors.IsNotFound(err) {
577+
log.Info(fmt.Sprintf("Galera instance '%s' does not exist", dbName))
578+
} else {
579+
log.Error(err, "Error retrieving Galera instance")
580+
}
576581

577582
instance.Status.Conditions.Set(condition.FalseCondition(
578583
databasev1beta1.MariaDBServerReadyCondition,
@@ -687,6 +692,7 @@ func (r *MariaDBAccountReconciler) ensureAccountSecret(
687692
// as current primary secret
688693
func (r *MariaDBAccountReconciler) removeAccountAndSecretFinalizer(ctx context.Context,
689694
helper *helper.Helper, instance *databasev1beta1.MariaDBAccount) error {
695+
690696
controllerutil.RemoveFinalizer(instance, helper.GetFinalizer())
691697

692698
return r.removeSecretFinalizer(

0 commit comments

Comments
 (0)