diff --git a/apis/mysql/v1alpha1/user_types.go b/apis/mysql/v1alpha1/user_types.go index 89fe9d98..b42b21cf 100644 --- a/apis/mysql/v1alpha1/user_types.go +++ b/apis/mysql/v1alpha1/user_types.go @@ -49,6 +49,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" default:"true"` + + // AuthPlugin defines the MySQL auth plugin (ie. AWSAuthenticationPlugin for AWS IAM authentication when using AWS RDS ) + // See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html + // +optional + AuthPlugin string `json:"authPlugin,omitempty" default:"mysql_native_password"` } // ResourceOptions define the account specific resource limits. diff --git a/package/crds/mysql.sql.crossplane.io_users.yaml b/package/crds/mysql.sql.crossplane.io_users.yaml index 6a481dd2..ed15b63b 100644 --- a/package/crds/mysql.sql.crossplane.io_users.yaml +++ b/package/crds/mysql.sql.crossplane.io_users.yaml @@ -71,6 +71,11 @@ spec: description: UserParameters define the desired state of a MySQL user instance. properties: + authPlugin: + description: |- + AuthPlugin defines the MySQL auth plugin (ie. AWSAuthenticationPlugin for AWS IAM authentication when using AWS RDS ) + See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.DBAccounts.html + type: string binlog: description: BinLog defines whether the create, delete, update operations of this user are propagated to replicas. Defaults diff --git a/pkg/controller/mysql/user/reconciler.go b/pkg/controller/mysql/user/reconciler.go index 92e7e0fe..07e2bf57 100644 --- a/pkg/controller/mysql/user/reconciler.go +++ b/pkg/controller/mysql/user/reconciler.go @@ -54,6 +54,7 @@ const ( errUpdateUser = "cannot update user" errGetPasswordSecretFailed = "cannot get password secret" errCompareResourceOptions = "cannot compare desired and observed resource options" + errAuthPluginNotSupported = "auth plugin not supported" maxConcurrency = 5 ) @@ -238,20 +239,39 @@ func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext cr.SetConditions(xpv1.Creating()) username, host := mysql.SplitUserHost(meta.GetExternalName(cr)) - pw, _, err := c.getPassword(ctx, cr) - if err != nil { - return managed.ExternalCreation{}, err + + var auth string + + var authplugin string + + if cr.Spec.ForProvider.AuthPlugin != "" { + authplugin = cr.Spec.ForProvider.AuthPlugin } + var pw string - if pw == "" { - pw, err = password.Generate() + switch authplugin { + case "": + var err error + pw, _, err = c.getPassword(ctx, cr) if err != nil { return managed.ExternalCreation{}, err } + + if pw == "" { + pw, err = password.Generate() + if err != nil { + return managed.ExternalCreation{}, err + } + } + auth = fmt.Sprintf("BY %s", mysql.QuoteValue(pw)) + case "AWSAuthenticationPlugin": + auth = fmt.Sprintf("WITH %s AS %s", authplugin, mysql.QuoteValue("RDS")) + default: + return managed.ExternalCreation{}, errors.New(errAuthPluginNotSupported) } ro := resourceOptionsToClauses(cr.Spec.ForProvider.ResourceOptions) - if err := c.executeCreateUserQuery(ctx, username, host, ro, pw); err != nil { + if err := c.executeCreateUserQuery(ctx, username, host, ro, auth); err != nil { return managed.ExternalCreation{}, err } @@ -264,17 +284,17 @@ func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext }, nil } -func (c *external) executeCreateUserQuery(ctx context.Context, username string, host string, resourceOptionsClauses []string, pw string) error { +func (c *external) executeCreateUserQuery(ctx context.Context, username string, host string, resourceOptionsClauses []string, auth string) error { resourceOptions := "" if len(resourceOptionsClauses) != 0 { resourceOptions = fmt.Sprintf(" WITH %s", strings.Join(resourceOptionsClauses, " ")) } query := fmt.Sprintf( - "CREATE USER %s@%s IDENTIFIED BY %s%s", + "CREATE USER %s@%s IDENTIFIED %s%s", mysql.QuoteValue(username), mysql.QuoteValue(host), - mysql.QuoteValue(pw), + auth, resourceOptions, )