Skip to content

Commit

Permalink
feat(GaussDB): gaussdb opengauss instance support tags
Browse files Browse the repository at this point in the history
  • Loading branch information
houpeng80 committed Dec 16, 2024
1 parent bbb9702 commit c6c69fc
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
2 changes: 2 additions & 0 deletions docs/resources/gaussdb_opengauss_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ The following arguments are supported:

Changing this parameter will create a new resource.

* `tags` - (Optional, Map) Specifies the key/value pairs to associate with the GaussDB OpenGauss instance.

* `force_import` - (Optional, Bool) Specifies whether to import the instance with the given configuration instead of
creation. If specified, try to import the instance instead of creation if the instance already existed.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ func TestAccOpenGaussInstance_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "volume.0.size", "40"),
resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.start_time", "20:00-21:00"),
resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.keep_days", "6"),
resource.TestCheckResourceAttr(resourceName, "tags.foo", "bar"),
resource.TestCheckResourceAttr(resourceName, "tags.key", "value"),
),
},
{
Expand All @@ -114,6 +116,8 @@ func TestAccOpenGaussInstance_basic(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "volume.0.size", "80"),
resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.start_time", "08:00-09:00"),
resource.TestCheckResourceAttr(resourceName, "backup_strategy.0.keep_days", "8"),
resource.TestCheckResourceAttr(resourceName, "tags.foo_update", "bar"),
resource.TestCheckResourceAttr(resourceName, "tags.key", "value_update"),
),
},
},
Expand Down Expand Up @@ -295,6 +299,11 @@ resource "huaweicloud_gaussdb_opengauss_instance" "test" {
start_time = "20:00-21:00"
keep_days = 6
}
tags = {
foo = "bar"
key = "value"
}
}
`, testAccOpenGaussInstance_base(rName), rName, password, replicaNum, acceptance.HW_ENTERPRISE_PROJECT_ID_TEST)
}
Expand Down Expand Up @@ -346,6 +355,11 @@ resource "huaweicloud_gaussdb_opengauss_instance" "test" {
start_time = "08:00-09:00"
keep_days = 8
}
tags = {
foo_update = "bar"
key = "value_update"
}
}
`, testAccOpenGaussInstance_base(rName), rName, password, replicaNum, acceptance.HW_ENTERPRISE_MIGRATE_PROJECT_ID_TEST)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ const (
// @API GaussDB GET /v3/{project_id}/instances
// @API GaussDB POST /v3/{project_id}/instances
// @API GaussDB GET /v3/{project_id}/jobs
// @API GaussDB POST /v3/{project_id}/instances/{instance_id}/tags
// @API GaussDB PUT /v3/{project_id}/instances/{instance_id}/name
// @API GaussDB POST /v3/{project_id}/instances/{instance_id}/password
// @API GaussDB POST /v3/{project_id}/instances/{instance_id}/action
// @API GaussDB PUT /v3/{project_id}/instances/{instance_id}/backups/policy
// @API GaussDB PUT /v3/{project_id}/instance/{instance_id}/flavor
// @API GaussDB DELETE /v3/{project_id}/instances/{instance_id}/tag
// @API GaussDB DELETE /v3/{project_id}/instances/{instance_id}
// @API BSS GET /v2/orders/customer-orders/details/{order_id}
// @API BSS POST /v2/orders/suscriptions/resources/query
Expand Down Expand Up @@ -246,6 +248,7 @@ func ResourceOpenGaussInstance() *schema.Resource {
},
},
},
"tags": common.TagsSchema(),
"force_import": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -423,6 +426,15 @@ func resourceOpenGaussInstanceCreate(ctx context.Context, d *schema.ResourceData
return diag.Errorf("error waiting for instance (%s) to become ready: %s", d.Id(), err)
}

// set tags
tagRaw := d.Get("tags").(map[string]interface{})
if len(tagRaw) > 0 {
err = addInstanceTags(d, client, d.Get("tags").(map[string]interface{}))
if err != nil {
return diag.Errorf("error setting tags for GaussDB OpenGauss instance %s: %s", d.Id(), err)
}
}

// This is a workaround to avoid db connection issue
time.Sleep(360 * time.Second) // lintignore:R018

Expand Down Expand Up @@ -600,6 +612,7 @@ func resourceOpenGaussInstanceRead(_ context.Context, d *schema.ResourceData, me
d.Set("security_group_id", utils.PathSearch("security_group_id", instance, nil)),
d.Set("db_user_name", utils.PathSearch("db_user_name", instance, nil)),
d.Set("time_zone", utils.PathSearch("time_zone", instance, nil)),
d.Set("enterprise_project_id", utils.PathSearch("enterprise_project_id", instance, nil)),
d.Set("flavor", utils.PathSearch("flavor_ref", instance, nil)),
d.Set("port", strconv.Itoa(int(utils.PathSearch("port", instance, float64(0)).(float64)))),
d.Set("switch_strategy", utils.PathSearch("switch_strategy", instance, nil)),
Expand All @@ -612,6 +625,7 @@ func resourceOpenGaussInstanceRead(_ context.Context, d *schema.ResourceData, me
setOpenGaussNodesAndRelatedNumbers(d, instance, &dnNum),
d.Set("volume", flattenGaussDBOpenGaussResponseBodyVolume(instance, dnNum)),
setOpenGaussPrivateIpsAndEndpoints(d, instance),
d.Set("tags", flattenGaussDBOpenGaussInstanceTags(instance)),
)

return diag.FromErr(mErr.ErrorOrNil())
Expand Down Expand Up @@ -726,6 +740,22 @@ func setOpenGaussPrivateIpsAndEndpoints(d *schema.ResourceData, instance interfa
return mErr
}

func flattenGaussDBOpenGaussInstanceTags(resp interface{}) map[string]interface{} {
if resp == nil {
return nil
}

curJson := utils.PathSearch("tags", resp, make([]interface{}, 0))
curArray := curJson.([]interface{})
rst := make(map[string]interface{})
for _, v := range curArray {
key := utils.PathSearch("key", v, "").(string)
value := utils.PathSearch("value", v, "").(string)
rst[key] = value
}
return rst
}

func resourceOpenGaussInstanceUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
region := cfg.GetRegion(d)
Expand Down Expand Up @@ -800,6 +830,13 @@ func resourceOpenGaussInstanceUpdate(ctx context.Context, d *schema.ResourceData
}
}

if d.HasChange("tags") {
err = updateInstanceTags(d, client)
if err != nil {
return diag.Errorf("error updating tags of GaussDB OpenGauss instance %q: %s", d.Id(), err)
}
}

return resourceOpenGaussInstanceRead(ctx, d, meta)
}

Expand Down Expand Up @@ -1136,6 +1173,96 @@ func buildUpdateInstanceFlavorBodyParams(d *schema.ResourceData) map[string]inte
return bodyParams
}

func addInstanceTags(d *schema.ResourceData, client *golangsdk.ServiceClient, addTags map[string]interface{}) error {
var (
httpUrl = "v3/{project_id}/instances/{instance_id}/tags"
)

addPath := client.Endpoint + httpUrl
addPath = strings.ReplaceAll(addPath, "{project_id}", client.ProjectID)
addPath = strings.ReplaceAll(addPath, "{instance_id}", d.Id())

addOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}
addOpt.JSONBody = utils.RemoveNil(buildAddInstanceTagsBodyParams(addTags))

_, err := client.Request("POST", addPath, &addOpt)
if err != nil {
return fmt.Errorf("error adding tags to GaussDB OpenGauss instance (%s): %s", d.Id(), err)
}

return nil
}

func buildAddInstanceTagsBodyParams(addTags map[string]interface{}) map[string]interface{} {
tags := make([]interface{}, 0, len(addTags))
for key, value := range addTags {
tags = append(tags, map[string]interface{}{
"key": key,
"value": value,
})
}
bodyParams := map[string]interface{}{
"tags": tags,
}
return bodyParams
}

func deleteInstanceTags(d *schema.ResourceData, client *golangsdk.ServiceClient, deleteTagKeys []string) error {
var (
httpUrl = "v3/{project_id}/instances/{instance_id}/tag"
)

deleteBasePath := client.Endpoint + httpUrl
deleteBasePath = strings.ReplaceAll(deleteBasePath, "{project_id}", client.ProjectID)
deleteBasePath = strings.ReplaceAll(deleteBasePath, "{instance_id}", d.Id())

deleteOpt := golangsdk.RequestOpts{
KeepResponseBody: true,
}

for _, deleteTagKey := range deleteTagKeys {
deletePath := deleteBasePath + buildDeleteInstanceTagParamBodyParams(deleteTagKey)
_, err := client.Request("DELETE", deletePath, &deleteOpt)
if err != nil {
return fmt.Errorf("error deleting tag(%s) from GaussDB OpenGauss instance (%s): %s", d.Id(), deleteTagKey, err)
}
}

return nil
}

func buildDeleteInstanceTagParamBodyParams(key string) string {
return fmt.Sprintf("?key=%s", key)
}

func updateInstanceTags(d *schema.ResourceData, client *golangsdk.ServiceClient) error {
oRaw, nRaw := d.GetChange("tags")
oMap := oRaw.(map[string]interface{})
nMap := nRaw.(map[string]interface{})

if len(oMap) > 0 {
keys := make([]string, 0, len(oMap))
for key := range oMap {
keys = append(keys, key)
}
err := deleteInstanceTags(d, client, keys)
if err != nil {
return err
}
}

if len(nMap) > 0 {
err := addInstanceTags(d, client, nMap)
if err != nil {
return err
}
}

return nil
}

func resourceOpenGaussInstanceDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
cfg := meta.(*config.Config)
region := cfg.GetRegion(d)
Expand Down

0 comments on commit c6c69fc

Please sign in to comment.