Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(alloydbomni_user): use pg_user handlers and schema #1985

Merged
merged 1 commit into from
Jan 10, 2025
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ nav_order: 1
- Replaced `aiven-go-client/v2` with `aiven/go-client-codegen` in `account_team_project` resource/data source
- Replaced `aiven-go-client/v2` with `aiven/go-client-codegen` in `aiven_pg_user` resource/data source
- Fix `aiven_pg_user` creating in bulk occasionally results in a 404 error
- Use `aiven_pg_user` handlers and schema in `aiven_alloydbomni_user` resource

## [4.31.1] - 2024-12-23

Expand Down
19 changes: 17 additions & 2 deletions internal/common/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/aiven/aiven-go-client/v2"
avngen "github.com/aiven/go-client-codegen"
"github.com/avast/retry-go"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
Expand Down Expand Up @@ -62,10 +63,10 @@ func GenClient() (avngen.Client, error) {
return genClientCache, nil
}

type crudHandler func(context.Context, *schema.ResourceData, avngen.Client) error
type CrudHandler func(context.Context, *schema.ResourceData, avngen.Client) error

// WithGenClient wraps CRUD handlers and runs with avngen.Client
func WithGenClient(handler crudHandler) func(context.Context, *schema.ResourceData, any) diag.Diagnostics {
func WithGenClient(handler CrudHandler) func(context.Context, *schema.ResourceData, any) diag.Diagnostics {
return func(ctx context.Context, d *schema.ResourceData, _ any) diag.Diagnostics {
return diag.FromErr(handler(ctx, d, genClientCache))
}
Expand Down Expand Up @@ -119,3 +120,17 @@ func TokenOpt(v string) ClientOpt {
o.token = v
}
}

// RetryCrudNotFound retries the handler if the error is NotFound
// This happens when GET called right after CREATE, and the resource is not yet available
func RetryCrudNotFound(f CrudHandler) CrudHandler {
return func(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
return retry.Do(
func() error {
return f(ctx, d, client)
},
retry.Context(ctx),
retry.RetryIf(avngen.IsNotFound),
)
}
}
2 changes: 1 addition & 1 deletion internal/schemautil/service_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func ResourceServiceUserRead(ctx context.Context, d *schema.ResourceData, m inte
return nil
}

func DeleteResourceServiceUser(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
func ResourceServiceUserDelete(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
projectName, serviceName, username, err := SplitResourceID3(d.Id())
if err != nil {
return err
Expand Down
187 changes: 6 additions & 181 deletions internal/sdkprovider/service/alloydbomni/alloydbomni_user.go
Original file line number Diff line number Diff line change
@@ -1,199 +1,24 @@
package alloydbomni

import (
"context"
"fmt"

avngen "github.com/aiven/go-client-codegen"
"github.com/aiven/go-client-codegen/handler/service"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/aiven/terraform-provider-aiven/internal/common"
"github.com/aiven/terraform-provider-aiven/internal/schemautil"
"github.com/aiven/terraform-provider-aiven/internal/schemautil/userconfig"
"github.com/aiven/terraform-provider-aiven/internal/sdkprovider/service/pg"
)

var aivenAlloyDBOmniUserSchema = map[string]*schema.Schema{
"project": schemautil.CommonSchemaProjectReference,
"service_name": schemautil.CommonSchemaServiceNameReference,
"username": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: schemautil.GetServiceUserValidateFunc(),
Description: userconfig.Desc("The name of the service user for this service.").ForceNew().Referenced().Build(),
},
"password": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
Computed: true,
DiffSuppressFunc: schemautil.EmptyObjectDiffSuppressFunc,
Description: "The password of the service user.",
},
"pg_allow_replication": {
Type: schema.TypeBool,
Optional: true,
Description: "Allows replication. For the default avnadmin user this attribute is required and is always `true`.",
},

// computed fields
"type": {
Type: schema.TypeString,
Computed: true,
Description: "The service user account type, either primary or regular.",
},
"access_cert": {
Type: schema.TypeString,
Sensitive: true,
Computed: true,
Description: "The access certificate for the servie user.",
},
"access_key": {
Type: schema.TypeString,
Sensitive: true,
Computed: true,
Description: "The access certificate key for the service user.",
},
}

func ResourceAlloyDBOmniUser() *schema.Resource {
return &schema.Resource{
Description: "Creates and manages an Aiven for AlloyDB Omni service user.",
CreateContext: common.WithGenClient(resourceAlloyDBOmniUserCreate),
UpdateContext: common.WithGenClient(resourceAlloyDBOmniUserUpdate),
ReadContext: common.WithGenClient(resourceAlloyDBOmniUserRead),
DeleteContext: common.WithGenClient(resourceServiceUserDelete),
CreateContext: common.WithGenClient(pg.ResourcePGUserCreate),
UpdateContext: common.WithGenClient(pg.ResourcePGUserUpdate),
ReadContext: common.WithGenClient(pg.ResourcePGUserRead),
DeleteContext: common.WithGenClient(schemautil.ResourceServiceUserDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: schemautil.DefaultResourceTimeouts(),

Schema: aivenAlloyDBOmniUserSchema,
}
}

func resourceAlloyDBOmniUserCreate(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
projectName := d.Get("project").(string)
serviceName := d.Get("service_name").(string)

// Validates that the service is an AlloyDBOmni service
alloydb, err := client.ServiceGet(ctx, projectName, serviceName)
if err != nil {
return err
}

if alloydb.ServiceType != schemautil.ServiceTypeAlloyDBOmni {
return fmt.Errorf("expected service type %q, got %q", schemautil.ServiceTypeAlloyDBOmni, alloydb.ServiceType)
Schema: pg.ResourcePGUserSchema,
}

username := d.Get("username").(string)
allowReplication := d.Get("pg_allow_replication").(bool)
_, err = client.ServiceUserCreate(
ctx,
projectName,
serviceName,
&service.ServiceUserCreateIn{
Username: username,
AccessControl: &service.AccessControlIn{
PgAllowReplication: &allowReplication,
},
},
)
if err != nil {
return err
}

if _, ok := d.GetOk("password"); ok {
_, err = client.ServiceUserCredentialsModify(
ctx, projectName, serviceName, username,
&service.ServiceUserCredentialsModifyIn{
Operation: service.ServiceUserCredentialsModifyOperationTypeResetCredentials,
NewPassword: schemautil.OptionalStringPointer(d, "password"),
},
)
if err != nil {
return err
}
}

d.SetId(schemautil.BuildResourceID(projectName, serviceName, username))
return resourceAlloyDBOmniUserRead(ctx, d, client)
}

func resourceAlloyDBOmniUserUpdate(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
projectName, serviceName, username, err := schemautil.SplitResourceID3(d.Id())
if err != nil {
return err
}

_, err = client.ServiceUserCredentialsModify(
ctx, projectName, serviceName, username,
&service.ServiceUserCredentialsModifyIn{
Operation: service.ServiceUserCredentialsModifyOperationTypeResetCredentials,
NewPassword: schemautil.OptionalStringPointer(d, "password"),
},
)

if err != nil {
return err
}

if d.HasChange("pg_allow_replication") {
allowReplication := d.Get("pg_allow_replication").(bool)
_, err = client.ServiceUserCredentialsModify(
ctx, projectName, serviceName, username,
&service.ServiceUserCredentialsModifyIn{
Operation: service.ServiceUserCredentialsModifyOperationTypeSetAccessControl,
AccessControl: &service.AccessControlIn{
PgAllowReplication: &allowReplication,
},
},
)
if err != nil {
return err
}
}

return resourceAlloyDBOmniUserRead(ctx, d, client)
}

func resourceAlloyDBOmniUserRead(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
projectName, serviceName, username, err := schemautil.SplitResourceID3(d.Id())
if err != nil {
return err
}

user, err := client.ServiceUserGet(ctx, projectName, serviceName, username)
if err != nil {
return schemautil.ResourceReadHandleNotFound(err, d)
}

err = schemautil.ResourceDataSet(aivenAlloyDBOmniUserSchema, d, user)
if err != nil {
return err
}

if user.AccessControl != nil && user.AccessControl.PgAllowReplication != nil {
err = d.Set("pg_allow_replication", *user.AccessControl.PgAllowReplication)
if err != nil {
return err
}
}

return nil
}

func resourceServiceUserDelete(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
projectName, serviceName, username, err := schemautil.SplitResourceID3(d.Id())
if err != nil {
return err
}

err = client.ServiceUserDelete(ctx, projectName, serviceName, username)
if common.IsCritical(err) {
return err
}

return nil
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
package alloydbomni

import (
"context"

avngen "github.com/aiven/go-client-codegen"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/aiven/terraform-provider-aiven/internal/common"
"github.com/aiven/terraform-provider-aiven/internal/schemautil"
"github.com/aiven/terraform-provider-aiven/internal/sdkprovider/service/pg"
)

func DatasourceAlloyDBOmniUser() *schema.Resource {
return &schema.Resource{
ReadContext: common.WithGenClient(datasourceAlloyDBOmniUserRead),
Description: "Gets information about an Aiven for AlloyDB Omni service user.",
Schema: schemautil.ResourceSchemaAsDatasourceSchema(aivenAlloyDBOmniUserSchema,
"project", "service_name", "username"),
ReadContext: common.WithGenClient(pg.DatasourcePGUserRead),
Schema: pg.DatasourcePGUserSchema(),
}
}

func datasourceAlloyDBOmniUserRead(ctx context.Context, d *schema.ResourceData, client avngen.Client) error {
projectName := d.Get("project").(string)
serviceName := d.Get("service_name").(string)
userName := d.Get("username").(string)

d.SetId(schemautil.BuildResourceID(projectName, serviceName, userName))
return resourceAlloyDBOmniUserRead(ctx, d, client)
}
2 changes: 1 addition & 1 deletion internal/sdkprovider/service/cassandra/cassandra_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func ResourceCassandraUser() *schema.Resource {
CreateContext: schemautil.ResourceServiceUserCreate,
UpdateContext: schemautil.ResourceServiceUserUpdate,
ReadContext: schemautil.ResourceServiceUserRead,
DeleteContext: common.WithGenClient(schemautil.DeleteResourceServiceUser),
DeleteContext: common.WithGenClient(schemautil.ResourceServiceUserDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
2 changes: 1 addition & 1 deletion internal/sdkprovider/service/influxdb/influxdb_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func ResourceInfluxDBUser() *schema.Resource {
CreateContext: schemautil.ResourceServiceUserCreate,
UpdateContext: schemautil.ResourceServiceUserUpdate,
ReadContext: schemautil.ResourceServiceUserRead,
DeleteContext: common.WithGenClient(schemautil.DeleteResourceServiceUser),
DeleteContext: common.WithGenClient(schemautil.ResourceServiceUserDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
2 changes: 1 addition & 1 deletion internal/sdkprovider/service/kafka/kafka_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func ResourceKafkaUser() *schema.Resource {
CreateContext: schemautil.ResourceServiceUserCreate,
UpdateContext: schemautil.ResourceServiceUserUpdate,
ReadContext: schemautil.ResourceServiceUserRead,
DeleteContext: common.WithGenClient(schemautil.DeleteResourceServiceUser),
DeleteContext: common.WithGenClient(schemautil.ResourceServiceUserDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
2 changes: 1 addition & 1 deletion internal/sdkprovider/service/m3db/m3db_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func ResourceM3DBUser() *schema.Resource {
CreateContext: schemautil.ResourceServiceUserCreate,
UpdateContext: schemautil.ResourceServiceUserUpdate,
ReadContext: schemautil.ResourceServiceUserRead,
DeleteContext: common.WithGenClient(schemautil.DeleteResourceServiceUser),
DeleteContext: common.WithGenClient(schemautil.ResourceServiceUserDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
2 changes: 1 addition & 1 deletion internal/sdkprovider/service/mysql/mysql_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func ResourceMySQLUser() *schema.Resource {
CreateContext: resourceMySQLUserCreate,
UpdateContext: resourceMySQLUserUpdate,
ReadContext: schemautil.ResourceServiceUserRead,
DeleteContext: common.WithGenClient(schemautil.DeleteResourceServiceUser),
DeleteContext: common.WithGenClient(schemautil.ResourceServiceUserDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down
Loading
Loading