Skip to content

Commit

Permalink
feat(alloydbomni_database): add resource and datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
byashimov committed Dec 6, 2024
1 parent f0af692 commit f117259
Show file tree
Hide file tree
Showing 9 changed files with 431 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ nav_order: 1

- Add `alloydbomni` BETA resource and datasource
- Add `aiven_alloydbomni_user` BETA resource and datasource
- Add `aiven_alloydbomni_database` BETA resource and datasource

## [4.30.0] - 2024-12-05

Expand Down
33 changes: 33 additions & 0 deletions docs/data-sources/alloydbomni_database.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "aiven_alloydbomni_database Data Source - terraform-provider-aiven"
subcategory: ""
description: |-
Gets information about a database in an Aiven for AlloyDB Omni service.
This resource is in the beta stage and may change without notice. Set
the PROVIDER_AIVEN_ENABLE_BETA environment variable to use the resource.
---

# aiven_alloydbomni_database (Data Source)

Gets information about a database in an Aiven for AlloyDB Omni service.

**This resource is in the beta stage and may change without notice.** Set
the `PROVIDER_AIVEN_ENABLE_BETA` environment variable to use the resource.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `database_name` (String) The name of the service database. Changing this property forces recreation of the resource.
- `project` (String) The name of the project this resource belongs to. To set up proper dependencies please refer to this variable as a reference. Changing this property forces recreation of the resource.
- `service_name` (String) The name of the service that this resource belongs to. To set up proper dependencies please refer to this variable as a reference. Changing this property forces recreation of the resource.

### Read-Only

- `id` (String) The ID of this resource.
- `lc_collate` (String) Default string sort order (`LC_COLLATE`) of the database. The default value is `en_US.UTF-8`. Changing this property forces recreation of the resource.
- `lc_ctype` (String) Default character classification (`LC_CTYPE`) of the database. The default value is `en_US.UTF-8`. Changing this property forces recreation of the resource.
48 changes: 48 additions & 0 deletions docs/resources/alloydbomni_database.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "aiven_alloydbomni_database Resource - terraform-provider-aiven"
subcategory: ""
description: |-
Creates and manages a database in an Aiven for AlloyDB Omni service.
This resource is in the beta stage and may change without notice. Set
the PROVIDER_AIVEN_ENABLE_BETA environment variable to use the resource.
---

# aiven_alloydbomni_database (Resource)

Creates and manages a database in an Aiven for AlloyDB Omni service.

**This resource is in the beta stage and may change without notice.** Set
the `PROVIDER_AIVEN_ENABLE_BETA` environment variable to use the resource.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `database_name` (String) The name of the service database. Changing this property forces recreation of the resource.
- `project` (String) The name of the project this resource belongs to. To set up proper dependencies please refer to this variable as a reference. Changing this property forces recreation of the resource.
- `service_name` (String) The name of the service that this resource belongs to. To set up proper dependencies please refer to this variable as a reference. Changing this property forces recreation of the resource.

### Optional

- `lc_collate` (String) Default string sort order (`LC_COLLATE`) of the database. The default value is `en_US.UTF-8`. Changing this property forces recreation of the resource.
- `lc_ctype` (String) Default character classification (`LC_CTYPE`) of the database. The default value is `en_US.UTF-8`. Changing this property forces recreation of the resource.
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))

### Read-Only

- `id` (String) The ID of this resource.

<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`

Optional:

- `create` (String)
- `default` (String)
- `delete` (String)
- `read` (String)
- `update` (String)
15 changes: 15 additions & 0 deletions internal/schemautil/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -957,10 +958,24 @@ func setProp[T comparable](m map[string]any, k string, v *T) {
}
}

// NewNotFound creates a new not found error
// There are lots of endpoints that return a list of objects which might not contain the object we are looking for.
// In this case, we should still return 404.
func NewNotFound(msg string, args ...any) error {
return aiven.Error{Status: http.StatusNotFound, Message: fmt.Sprintf(msg, args...)}
}

func IsNotFound(err error) bool {
return aiven.IsNotFound(err) || avngen.IsNotFound(err)
}

func OmitNotFound(err error) error {
if IsNotFound(err) {
return nil
}
return err
}

// IsUnknownRole checks if the database returned an error because of an unknown role
// to make deletions idempotent
func IsUnknownRole(err error) bool {
Expand Down
13 changes: 13 additions & 0 deletions internal/schemautil/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
avngen "github.com/aiven/go-client-codegen"
"github.com/aiven/go-client-codegen/handler/service"
"github.com/aiven/go-client-codegen/handler/staticip"
retryGo "github.com/avast/retry-go"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

Expand Down Expand Up @@ -357,3 +358,15 @@ L:
func staticIpsForServiceFromSchema(d *schema.ResourceData) []string {
return FlattenToString(d.Get("static_ips").(*schema.Set).List())
}

// WaitUntilNotFound retries the given retryableFunc until it returns 404
// To stop the retrying, the function should return retryGo.Unrecoverable
func WaitUntilNotFound(ctx context.Context, retryableFunc retryGo.RetryableFunc) error {
return retryGo.Do(
func() error {
return OmitNotFound(retryableFunc())
},
retryGo.Context(ctx),
retryGo.Delay(common.DefaultStateChangeDelay),
)
}
12 changes: 8 additions & 4 deletions internal/sdkprovider/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ func Provider(version string) (*schema.Provider, error) {
"aiven_pg_database": pg.DatasourcePGDatabase(),

// alloydbomni
"aiven_alloydbomni": alloydbomni.DatasourceAlloyDBOmni(),
"aiven_alloydbomni_user": alloydbomni.DatasourceAlloyDBOmniUser(),
"aiven_alloydbomni": alloydbomni.DatasourceAlloyDBOmni(),
"aiven_alloydbomni_user": alloydbomni.DatasourceAlloyDBOmniUser(),
"aiven_alloydbomni_database": alloydbomni.DatasourceAlloyDBOmniDatabase(),

// cassandra
"aiven_cassandra": cassandra.DatasourceCassandra(),
Expand Down Expand Up @@ -192,8 +193,9 @@ func Provider(version string) (*schema.Provider, error) {
"aiven_pg_database": pg.ResourcePGDatabase(),

// alloydbomni
"aiven_alloydbomni": alloydbomni.ResourceAlloyDBOmni(),
"aiven_alloydbomni_user": alloydbomni.ResourceAlloyDBOmniUser(),
"aiven_alloydbomni": alloydbomni.ResourceAlloyDBOmni(),
"aiven_alloydbomni_user": alloydbomni.ResourceAlloyDBOmniUser(),
"aiven_alloydbomni_database": alloydbomni.ResourceAlloyDBOmniDatabase(),

// cassandra
"aiven_cassandra": cassandra.ResourceCassandra(),
Expand Down Expand Up @@ -290,11 +292,13 @@ func Provider(version string) (*schema.Provider, error) {
betaResources := []string{
"aiven_alloydbomni",
"aiven_alloydbomni_user",
"aiven_alloydbomni_database",
}

betaDataSources := []string{
"aiven_alloydbomni",
"aiven_alloydbomni_user",
"aiven_alloydbomni_database",
"aiven_organization_user_list",
}

Expand Down
128 changes: 128 additions & 0 deletions internal/sdkprovider/service/alloydbomni/alloydbomni_database.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package alloydbomni

import (
"context"

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"
)

const defaultLC = "en_US.UTF-8"

var aivenAlloyDBOmniDatabaseSchema = map[string]*schema.Schema{
"project": schemautil.CommonSchemaProjectReference,
"service_name": schemautil.CommonSchemaServiceNameReference,
"database_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: userconfig.Desc("The name of the service database.").ForceNew().Build(),
},
"lc_ctype": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: defaultLC,
Description: userconfig.Desc("Default character classification (`LC_CTYPE`) of the database.").DefaultValue(defaultLC).ForceNew().Build(),
},
"lc_collate": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Default: defaultLC,
Description: userconfig.Desc("Default string sort order (`LC_COLLATE`) of the database.").DefaultValue(defaultLC).ForceNew().Build(),
},
}

func ResourceAlloyDBOmniDatabase() *schema.Resource {
return &schema.Resource{
Description: "Creates and manages a database in an Aiven for AlloyDB Omni service.",
CreateContext: common.WithGenClient(resourceAlloyDBOmniDatabaseCreate),
ReadContext: common.WithGenClient(resourceAlloyDBOmniDatabaseRead),
DeleteContext: common.WithGenClient(resourceAlloyDBOmniDatabaseDelete),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: schemautil.DefaultResourceTimeouts(),
Schema: aivenAlloyDBOmniDatabaseSchema,
}
}

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

req := new(service.ServiceDatabaseCreateIn)
err := schemautil.ResourceDataGet(d, req, schemautil.RenameAlias("database_name", "database"))
if err != nil {
return err
}

err = client.ServiceDatabaseCreate(ctx, projectName, serviceName, req)
if err != nil {
return err
}

d.SetId(schemautil.BuildResourceID(projectName, serviceName, req.Database))
return resourceAlloyDBOmniDatabaseRead(ctx, d, client)
}

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

db, err := getDatabase(ctx, client, projectName, serviceName, dbName)
if err != nil {
return err
}

if err := d.Set("project", projectName); err != nil {
return err
}

if err := d.Set("service_name", serviceName); err != nil {
return err
}

return schemautil.ResourceDataSet(aivenAlloyDBOmniDatabaseSchema, d, db)
}

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

err = client.ServiceDatabaseDelete(ctx, projectName, serviceName, dbName)
if err != nil {
return err
}

// Waits until database is deleted
return schemautil.WaitUntilNotFound(ctx, func() error {
_, err = getDatabase(ctx, client, projectName, serviceName, dbName)
return err
})
}

func getDatabase(ctx context.Context, client avngen.Client, projectName, serviceName, dbName string) (*service.DatabaseOut, error) {
list, err := client.ServiceDatabaseList(ctx, projectName, serviceName)
if err != nil {
return nil, err
}

for _, db := range list {
if db.DatabaseName == dbName {
return &db, nil
}
}

return nil, schemautil.NewNotFound("service database %q not found", dbName)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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"
)

func DatasourceAlloyDBOmniDatabase() *schema.Resource {
return &schema.Resource{
ReadContext: common.WithGenClient(datasourceDatabaseRead),
Description: "Gets information about a database in an Aiven for AlloyDB Omni service.",
Schema: schemautil.ResourceSchemaAsDatasourceSchema(aivenAlloyDBOmniDatabaseSchema,
"project", "service_name", "database_name"),
}
}

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

d.SetId(schemautil.BuildResourceID(projectName, serviceName, databaseName))
return resourceAlloyDBOmniDatabaseRead(ctx, d, client)
}
Loading

0 comments on commit f117259

Please sign in to comment.