Skip to content
41 changes: 41 additions & 0 deletions apis/cluster/mysql/v1alpha1/user_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,31 @@ type UserStatus struct {
}

// UserParameters define the desired state of a MySQL user instance.
// +kubebuilder:validation:XValidation:rule="!(has(self.authenticationPlugin) && has(self.passwordSecretRef))",message="authenticationPlugin and passwordSecretRef are mutually exclusive"
type UserParameters struct {
// PasswordSecretRef references the secret that contains the password used
// for this user. If no reference is given, a password will be auto-generated.
// Cannot be set together with AuthenticationPlugin.
// +optional
PasswordSecretRef *xpv1.SecretKeySelector `json:"passwordSecretRef,omitempty"`

// AuthenticationPlugin selects a non-default MySQL authentication plugin
// for the user. When set, the user is created with
// CREATE USER ... IDENTIFIED WITH <plugin> [AS '<authString>'] and no
// password is generated or required.
//
// Most commonly used for AWS RDS IAM authentication, where the DB user
// has no static password and clients authenticate via short-lived IAM
// auth tokens. Example:
// authenticationPlugin:
// name: AWSAuthenticationPlugin
// authString: RDS
//
// When AuthenticationPlugin is set, PasswordSecretRef must not be set
// and the connection secret will not contain a password.
// +optional
AuthenticationPlugin *AuthenticationPlugin `json:"authenticationPlugin,omitempty"`

// ResourceOptions sets account specific resource limits.
// See https://dev.mysql.com/doc/refman/8.0/en/user-resources.html
// +optional
Expand All @@ -51,6 +70,20 @@ type UserParameters struct {
BinLog *bool `json:"binlog,omitempty"`
}

// AuthenticationPlugin selects the auth plugin used when creating the user.
type AuthenticationPlugin struct {
// Name is the auth plugin name. Examples: "AWSAuthenticationPlugin",
// "mysql_native_password", "caching_sha2_password", "auth_socket".
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`

// AuthString is the optional auth string passed to the plugin via the
// AS clause. For AWSAuthenticationPlugin set this to "RDS". For native
// password plugins, leave empty and use PasswordSecretRef instead.
// +optional
AuthString *string `json:"authString,omitempty"`
}

// ResourceOptions define the account specific resource limits.
type ResourceOptions struct {
// MaxQueriesPerHour sets the number of queries an account can issue per hour
Expand All @@ -74,6 +107,14 @@ type ResourceOptions struct {
type UserObservation struct {
// ResourceOptionsAsClauses represents the applied resource options
ResourceOptionsAsClauses []string `json:"resourceOptionsAsClauses,omitempty"`

// AuthenticationPlugin reflects the user's actual authentication plugin
// as read from mysql.user. Populated only when the observed plugin is a
// non-default-password plugin (e.g., AWSAuthenticationPlugin). Used by
// the reconciler to detect drift between the desired
// spec.forProvider.authenticationPlugin and what's actually configured
// on the DB so plugin changes are not silently ignored.
AuthenticationPlugin *AuthenticationPlugin `json:"authenticationPlugin,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
30 changes: 30 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.

41 changes: 41 additions & 0 deletions apis/namespaced/mysql/v1alpha1/user_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,31 @@ type UserStatus struct {
}

// UserParameters define the desired state of a MySQL user instance.
// +kubebuilder:validation:XValidation:rule="!(has(self.authenticationPlugin) && has(self.passwordSecretRef))",message="authenticationPlugin and passwordSecretRef are mutually exclusive"
type UserParameters struct {
// PasswordSecretRef references the secret that contains the password used
// for this user. If no reference is given, a password will be auto-generated.
// Cannot be set together with AuthenticationPlugin.
// +optional
PasswordSecretRef *xpv1.LocalSecretKeySelector `json:"passwordSecretRef,omitempty"`

// AuthenticationPlugin selects a non-default MySQL authentication plugin
// for the user. When set, the user is created with
// CREATE USER ... IDENTIFIED WITH <plugin> [AS '<authString>'] and no
// password is generated or required.
//
// Most commonly used for AWS RDS IAM authentication, where the DB user
// has no static password and clients authenticate via short-lived IAM
// auth tokens. Example:
// authenticationPlugin:
// name: AWSAuthenticationPlugin
// authString: RDS
//
// When AuthenticationPlugin is set, PasswordSecretRef must not be set
// and the connection secret will not contain a password.
// +optional
AuthenticationPlugin *AuthenticationPlugin `json:"authenticationPlugin,omitempty"`

// ResourceOptions sets account specific resource limits.
// See https://dev.mysql.com/doc/refman/8.0/en/user-resources.html
// +optional
Expand All @@ -52,6 +71,20 @@ type UserParameters struct {
BinLog *bool `json:"binlog,omitempty"`
}

// AuthenticationPlugin selects the auth plugin used when creating the user.
type AuthenticationPlugin struct {
// Name is the auth plugin name. Examples: "AWSAuthenticationPlugin",
// "mysql_native_password", "caching_sha2_password", "auth_socket".
// +kubebuilder:validation:MinLength=1
Name string `json:"name"`

// AuthString is the optional auth string passed to the plugin via the
// AS clause. For AWSAuthenticationPlugin set this to "RDS". For native
// password plugins, leave empty and use PasswordSecretRef instead.
// +optional
AuthString *string `json:"authString,omitempty"`
}

// ResourceOptions define the account specific resource limits.
type ResourceOptions struct {
// MaxQueriesPerHour sets the number of queries an account can issue per hour
Expand All @@ -75,6 +108,14 @@ type ResourceOptions struct {
type UserObservation struct {
// ResourceOptionsAsClauses represents the applied resource options
ResourceOptionsAsClauses []string `json:"resourceOptionsAsClauses,omitempty"`

// AuthenticationPlugin reflects the user's actual authentication plugin
// as read from mysql.user. Populated only when the observed plugin is a
// non-default-password plugin (e.g., AWSAuthenticationPlugin). Used by
// the reconciler to detect drift between the desired
// spec.forProvider.authenticationPlugin and what's actually configured
// on the DB so plugin changes are not silently ignored.
AuthenticationPlugin *AuthenticationPlugin `json:"authenticationPlugin,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
30 changes: 30 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.

22 changes: 22 additions & 0 deletions examples/cluster/mysql/user_iam_auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
# AWS RDS IAM authentication: the DB user has no static password and the
# application authenticates with a short-lived auth token generated from its
# IAM role (see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).
#
# Crossplane runs:
# CREATE USER 'example-iam-user'@'%' IDENTIFIED WITH `AWSAuthenticationPlugin` AS 'RDS'
#
# The connection secret will not contain a password (only username, endpoint,
# port). Clients fetch a temporary auth token from AWS RDS at connect time.
apiVersion: mysql.sql.crossplane.io/v1alpha1
kind: User
metadata:
name: example-iam-user
spec:
forProvider:
authenticationPlugin:
name: AWSAuthenticationPlugin
authString: RDS
writeConnectionSecretToRef:
name: example-iam-user-connection
namespace: default
22 changes: 22 additions & 0 deletions examples/namespaced/mysql/user_iam_auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
# AWS RDS IAM authentication: the DB user has no static password and the
# application authenticates with a short-lived auth token generated from its
# IAM role (see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html).
#
# Crossplane runs:
# CREATE USER 'example-iam-user'@'%' IDENTIFIED WITH `AWSAuthenticationPlugin` AS 'RDS'
#
# The connection secret will not contain a password (only username, endpoint,
# port). Clients fetch a temporary auth token from AWS RDS at connect time.
apiVersion: mysql.sql.m.crossplane.io/v1alpha1
kind: User
metadata:
name: example-iam-user
namespace: default
spec:
forProvider:
authenticationPlugin:
name: AWSAuthenticationPlugin
authString: RDS
writeConnectionSecretToRef:
name: example-iam-user-connection
61 changes: 61 additions & 0 deletions package/crds/mysql.sql.crossplane.io_users.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,38 @@ spec:
description: UserParameters define the desired state of a MySQL user
instance.
properties:
authenticationPlugin:
description: |-
AuthenticationPlugin selects a non-default MySQL authentication plugin
for the user. When set, the user is created with
CREATE USER ... IDENTIFIED WITH <plugin> [AS '<authString>'] and no
password is generated or required.

Most commonly used for AWS RDS IAM authentication, where the DB user
has no static password and clients authenticate via short-lived IAM
auth tokens. Example:
authenticationPlugin:
name: AWSAuthenticationPlugin
authString: RDS

When AuthenticationPlugin is set, PasswordSecretRef must not be set
and the connection secret will not contain a password.
properties:
authString:
description: |-
AuthString is the optional auth string passed to the plugin via the
AS clause. For AWSAuthenticationPlugin set this to "RDS". For native
password plugins, leave empty and use PasswordSecretRef instead.
type: string
name:
description: |-
Name is the auth plugin name. Examples: "AWSAuthenticationPlugin",
"mysql_native_password", "caching_sha2_password", "auth_socket".
minLength: 1
type: string
required:
- name
type: object
binlog:
description: BinLog defines whether the create, delete, update
operations of this user are propagated to replicas. Defaults
Expand All @@ -80,6 +112,7 @@ spec:
description: |-
PasswordSecretRef references the secret that contains the password used
for this user. If no reference is given, a password will be auto-generated.
Cannot be set together with AuthenticationPlugin.
properties:
key:
description: The key to select.
Expand Down Expand Up @@ -118,6 +151,10 @@ spec:
type: integer
type: object
type: object
x-kubernetes-validations:
- message: authenticationPlugin and passwordSecretRef are mutually
exclusive
rule: '!(has(self.authenticationPlugin) && has(self.passwordSecretRef))'
managementPolicies:
default:
- '*'
Expand Down Expand Up @@ -211,6 +248,30 @@ spec:
description: A UserObservation represents the observed state of a
MySQL user.
properties:
authenticationPlugin:
description: |-
AuthenticationPlugin reflects the user's actual authentication plugin
as read from mysql.user. Populated only when the observed plugin is a
non-default-password plugin (e.g., AWSAuthenticationPlugin). Used by
the reconciler to detect drift between the desired
spec.forProvider.authenticationPlugin and what's actually configured
on the DB so plugin changes are not silently ignored.
properties:
authString:
description: |-
AuthString is the optional auth string passed to the plugin via the
AS clause. For AWSAuthenticationPlugin set this to "RDS". For native
password plugins, leave empty and use PasswordSecretRef instead.
type: string
name:
description: |-
Name is the auth plugin name. Examples: "AWSAuthenticationPlugin",
"mysql_native_password", "caching_sha2_password", "auth_socket".
minLength: 1
type: string
required:
- name
type: object
resourceOptionsAsClauses:
description: ResourceOptionsAsClauses represents the applied resource
options
Expand Down
Loading
Loading