Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apis/cluster/mysql/v1alpha1/user_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ type UserParameters struct {
// BinLog defines whether the create, delete, update operations of this user are propagated to replicas. Defaults to true
// +optional
BinLog *bool `json:"binlog,omitempty"`

// PasswordRotationTrigger triggers rotation of the auto-generated password when set to
// a time after the current LastPasswordChange. Has no effect when passwordSecretRef is set.
// +optional
PasswordRotationTrigger *metav1.Time `json:"passwordRotationTrigger,omitempty"`
}

// AuthenticationPlugin selects the auth plugin used when creating the user.
Expand Down Expand Up @@ -115,6 +120,9 @@ type UserObservation struct {
// spec.forProvider.authenticationPlugin and what's actually configured
// on the DB so plugin changes are not silently ignored.
AuthenticationPlugin *AuthenticationPlugin `json:"authenticationPlugin,omitempty"`

// LastPasswordChange records when the provider last set the user's password.
LastPasswordChange *metav1.Time `json:"lastPasswordChange,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
8 changes: 8 additions & 0 deletions apis/cluster/mysql/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions apis/namespaced/mysql/v1alpha1/user_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ type UserParameters struct {
// BinLog defines whether the create, delete, update operations of this user are propagated to replicas. Defaults to true
// +optional
BinLog *bool `json:"binlog,omitempty"`

// PasswordRotationTrigger triggers rotation of the auto-generated password when set to
// a time after the current LastPasswordChange. Has no effect when passwordSecretRef is set.
// +optional
PasswordRotationTrigger *metav1.Time `json:"passwordRotationTrigger,omitempty"`
}

// AuthenticationPlugin selects the auth plugin used when creating the user.
Expand Down Expand Up @@ -116,6 +121,9 @@ type UserObservation struct {
// spec.forProvider.authenticationPlugin and what's actually configured
// on the DB so plugin changes are not silently ignored.
AuthenticationPlugin *AuthenticationPlugin `json:"authenticationPlugin,omitempty"`

// LastPasswordChange records when the provider last set the user's password.
LastPasswordChange *metav1.Time `json:"lastPasswordChange,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
8 changes: 8 additions & 0 deletions apis/namespaced/mysql/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions package/crds/mysql.sql.crossplane.io_users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ spec:
operations of this user are propagated to replicas. Defaults
to true
type: boolean
passwordRotationTrigger:
description: |-
PasswordRotationTrigger triggers rotation of the auto-generated password when set to
a time after the current LastPasswordChange. Has no effect when passwordSecretRef is set.
format: date-time
type: string
passwordSecretRef:
description: |-
PasswordSecretRef references the secret that contains the password used
Expand Down Expand Up @@ -272,6 +278,11 @@ spec:
required:
- name
type: object
lastPasswordChange:
description: LastPasswordChange records when the provider last
set the user's password.
format: date-time
type: string
resourceOptionsAsClauses:
description: ResourceOptionsAsClauses represents the applied resource
options
Expand Down
11 changes: 11 additions & 0 deletions package/crds/mysql.sql.m.crossplane.io_users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ spec:
operations of this user are propagated to replicas. Defaults
to true
type: boolean
passwordRotationTrigger:
description: |-
PasswordRotationTrigger triggers rotation of the auto-generated password when set to
a time after the current LastPasswordChange. Has no effect when passwordSecretRef is set.
format: date-time
type: string
passwordSecretRef:
description: |-
PasswordSecretRef references the secret that contains the password used
Expand Down Expand Up @@ -225,6 +231,11 @@ spec:
required:
- name
type: object
lastPasswordChange:
description: LastPasswordChange records when the provider last
set the user's password.
format: date-time
type: string
resourceOptionsAsClauses:
description: ResourceOptionsAsClauses represents the applied resource
options
Expand Down
22 changes: 16 additions & 6 deletions pkg/controller/cluster/mysql/user/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/crossplane/crossplane-runtime/v2/pkg/statemetrics"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -51,12 +52,13 @@ const (
errGetSecret = "cannot get credentials Secret"
errTLSConfig = "cannot load TLS config"

errSelectUser = "cannot select user"
errCreateUser = "cannot create user"
errDropUser = "cannot drop user"
errUpdateUser = "cannot update user"
errGetPasswordSecretFailed = "cannot get password secret"
errCompareResourceOptions = "cannot compare desired and observed resource options"
errSelectUser = "cannot select user"
errCreateUser = "cannot create user"
errDropUser = "cannot drop user"
errUpdateUser = "cannot update user"
errGetPasswordSecretFailed = "cannot get password secret"
errGetConnectionSecretFailed = "cannot get connection secret"
errCompareResourceOptions = "cannot compare desired and observed resource options"

maxConcurrency = 5
)
Expand Down Expand Up @@ -525,10 +527,18 @@ func (c *external) UpdatePassword(ctx context.Context, cr *v1alpha1.User, userna
}

if pwchanged {
if pw == "" {
pw, err = password.Generate()
if err != nil {
return managed.ConnectionDetails{}, err
}
}
query := fmt.Sprintf("ALTER USER %s@%s IDENTIFIED BY %s", mysql.QuoteValue(username), mysql.QuoteValue(host), mysql.QuoteValue(pw))
if err := mysql.ExecWrapper(ctx, c.db, mysql.ExecQuery{Query: query, ErrorValue: errUpdateUser}); err != nil {
return managed.ConnectionDetails{}, err
}
now := metav1.Now()
cr.Status.AtProvider.LastPasswordChange = &now

return c.db.GetConnectionDetails(username, pw), nil
}
Expand Down
Loading