Skip to content

Commit

Permalink
Merge pull request #1199 in CLOUD/terraform-provider-yandex-mirror fr…
Browse files Browse the repository at this point in the history
…om feature/opensearch/host-list to master

Squashed commit of the following:

commit e8359cb1c6cd9fc5b53a80a9697d147f429d7ede
Author: Aleksandr Tuliakov <tulyakov@yandex-team.ru>
Date:   Fri Apr 5 15:52:17 2024 +0200

    add compute field "hosts" for resource and data_source
  • Loading branch information
Aleksandr Tuliakov committed Apr 24, 2024
1 parent b496f7a commit 029e1e8
Show file tree
Hide file tree
Showing 8 changed files with 271 additions and 39 deletions.
3 changes: 3 additions & 0 deletions .changes/unreleased/ENHANCEMENTS-20240418-211916.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: ENHANCEMENTS
body: 'opensearch: add `hosts` computed attribute'
time: 2024-04-18T21:19:16.797354+02:00
17 changes: 17 additions & 0 deletions website/docs/d/datasource_mdb_opensearch_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ exported:
* `health` - Aggregated health of the cluster.
* `status` - Status of the cluster.
* `config` - Configuration of the OpenSearch cluster. The structure is documented below.
* `hosts` - A hosts of the OpenSearch cluster. The structure is documented below.
* `security_group_ids` - A set of ids of security groups assigned to hosts of the cluster.
* `service_account_id` - ID of the service account authorized for this cluster.

Expand Down Expand Up @@ -102,6 +103,22 @@ The `resources` block supports:
* `disk_size` - Volume of the storage available to a OpenSearch host, in gigabytes.
* `disk_type_id` - Type of the storage of OpenSearch hosts.

The `hosts` block supports:

* `fqdn` - The fully qualified domain name of the host.

* `zone` - The availability zone where the OpenSearch host was created.
For more information see [the official documentation](https://cloud.yandex.com/docs/overview/concepts/geo-scope).

* `type` - The type of the deployed host. Can be either `OPENSEARCH` or `DASHBOARDS`.

* `roles` - The roles of the deployed host. Can contain `DATA` and/or `MANAGER` roles. Will be empty for `DASHBOARDS` type.

* `subnet_id` - The ID of the subnet, to which the host belongs. The subnet must
be a part of the network to which the cluster belongs.

* `assign_public_ip` - Sets whether the host should get a public IP address. Can be either `true` or `false`.

The `maintenance_window` block supports:

* `type` - Type of a maintenance window. Can be either `ANYTIME` or `WEEKLY`. A day and hour need to be specified with the weekly window.
Expand Down
18 changes: 18 additions & 0 deletions website/docs/r/mdb_opensearch_cluster.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,24 @@ In addition to the arguments listed above, the following computed attributes are
* `status` - Status of the cluster. Can be either `CREATING`, `STARTING`, `RUNNING`, `UPDATING`, `STOPPING`, `STOPPED`, `ERROR` or `STATUS_UNKNOWN`.
For more information see `status` field of JSON representation in [the official documentation](https://cloud.yandex.com/docs/managed-opensearch/api-ref/Cluster/).

* `hosts` - A hosts of the OpenSearch cluster. The structure is documented below.

The `hosts` block supports:

* `fqdn` - The fully qualified domain name of the host.

* `zone` - The availability zone where the OpenSearch host will be created.
For more information see [the official documentation](https://cloud.yandex.com/docs/overview/concepts/geo-scope).

* `type` - The type of the deployed host. Can be either `OPENSEARCH` or `DASHBOARDS`.

* `roles` - The roles of the deployed host. Can contain `DATA` and/or `MANAGER` roles. Will be empty for `DASHBOARDS` type.

* `subnet_id` - The ID of the subnet, to which the host belongs. The subnet must
be a part of the network to which the cluster belongs.

* `assign_public_ip` - Sets whether the host should get a public IP address. Can be either `true` or `false`.

## Import

A cluster can be imported using the `id` of the resource, e.g.
Expand Down
41 changes: 40 additions & 1 deletion yandex/data_source_yandex_mdb_opensearch_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ package yandex
import (
"context"
"fmt"
"github.com/yandex-cloud/go-genproto/yandex/cloud/mdb/opensearch/v1"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/yandex-cloud/go-genproto/yandex/cloud/mdb/opensearch/v1"

"github.com/yandex-cloud/go-sdk/sdkresolvers"
)

Expand Down Expand Up @@ -211,6 +212,44 @@ func dataSourceYandexMDBOpenSearchCluster() *schema.Resource {
},
},

"hosts": {
Type: schema.TypeSet,
Computed: true,
Set: opensearchHostFQDNHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"fqdn": {
Type: schema.TypeString,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"roles": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"assign_public_ip": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"subnet_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
},
},

"network_id": {
Type: schema.TypeString,
Computed: true,
Expand Down
5 changes: 4 additions & 1 deletion yandex/data_source_yandex_mdb_opensearch_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func testAccDataSourceMDBOpenSearchClusterAttributesCheck(datasourceName string,
"description",
"labels",
"environment",
"host",
"hosts",
"config",
"security_group_ids",
"service_account_id",
Expand Down Expand Up @@ -120,6 +120,9 @@ func testAccDataSourceMDBOpenSearchClusterCheck(datasourceName string, resourceN
resource.TestCheckResourceAttr(datasourceName, "config.#", "1"),
resource.TestCheckResourceAttrSet(datasourceName, "service_account_id"),
resource.TestCheckResourceAttr(datasourceName, "deletion_protection", "false"),
resource.TestCheckResourceAttr(openSearchResource, "hosts.#", "2"),
resource.TestCheckResourceAttrSet(openSearchResource, "hosts.0.fqdn"),
resource.TestCheckResourceAttrSet(openSearchResource, "hosts.1.fqdn"),
testAccCheckCreatedAtAttr(datasourceName),
resource.TestCheckResourceAttr(datasourceName, "maintenance_window.0.type", "WEEKLY"),
resource.TestCheckResourceAttr(datasourceName, "maintenance_window.0.day", "FRI"),
Expand Down
76 changes: 43 additions & 33 deletions yandex/mdb_opensearch_structures.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package yandex

import (
"context"
"fmt"
"reflect"
"strings"
Expand Down Expand Up @@ -633,27 +632,6 @@ func copyDashboardsNodeGroupsData(oldGroups []*opensearch.DashboardsCreateSpec_N
return modified
}

func opensearchNodeGroupsDiffCustomize(ctx context.Context, rdiff *schema.ResourceDiff, _ interface{}) error {
oc, nc := rdiff.GetChange("config")
if oc == nil {
if nc == nil {
return fmt.Errorf("Missing required option: config")
}
}

var (
oldConfig = expandOpenSearchConfigCreateSpec(oc)
newConfig = expandOpenSearchConfigCreateSpec(nc)
)

if modifyConfig(oldConfig, newConfig) {
flattened := flattenOpenSearchConfigCreateSpec(newConfig)
return rdiff.SetNew("config", flattened)
}

return nil
}

func modifyConfig(oldConfig, newConfig *opensearch.ConfigCreateSpec) bool {
var modified bool

Expand All @@ -664,19 +642,51 @@ func modifyConfig(oldConfig, newConfig *opensearch.ConfigCreateSpec) bool {
return false
}

if oldConfig != nil {
if copyOpenSearchNodeGroupsData(oldConfig.GetOpensearchSpec().GetNodeGroups(), newConfig.GetOpensearchSpec().GetNodeGroups()) {
modified = true
}
if copyDashboardsNodeGroupsData(oldConfig.GetDashboardsSpec().GetNodeGroups(), newConfig.GetDashboardsSpec().GetNodeGroups()) {
modified = true
}
if copyOpenSearchNodeGroupsData(oldConfig.GetOpensearchSpec().GetNodeGroups(), newConfig.GetOpensearchSpec().GetNodeGroups()) {
modified = true
}
if copyDashboardsNodeGroupsData(oldConfig.GetDashboardsSpec().GetNodeGroups(), newConfig.GetDashboardsSpec().GetNodeGroups()) {
modified = true
}

if newConfig.GetOpensearchSpec().GetPlugins() == nil || len(oldConfig.GetOpensearchSpec().GetPlugins()) == 0 {
newConfig.OpensearchSpec.Plugins = oldConfig.GetOpensearchSpec().Plugins
modified = true
}
if newConfig.GetOpensearchSpec().GetPlugins() == nil || len(oldConfig.GetOpensearchSpec().GetPlugins()) == 0 {
newConfig.OpensearchSpec.Plugins = oldConfig.GetOpensearchSpec().Plugins
modified = true
}

return modified
}

func opensearchHostFQDNHash(v interface{}) int {
m := v.(map[string]interface{})

if n, ok := m["fqdn"]; ok {
return hashcode.String(n.(string))
}
return 0
}

func flattenOpensearchHosts(hosts []*opensearch.Host) []interface{} {
res := []interface{}{}

for _, h := range hosts {
res = append(res, map[string]interface{}{
"type": h.Type.String(),
"roles": mapRoles(h.Roles),
"zone": h.ZoneId,
"subnet_id": h.SubnetId,
"assign_public_ip": h.AssignPublicIp,
"fqdn": h.Name,
})
}

return res
}

func mapRoles(roles []opensearch.OpenSearch_GroupRole) []string {
res := make([]string, 0, len(roles))
for _, role := range roles {
res = append(res, role.String())
}
return res
}
135 changes: 133 additions & 2 deletions yandex/resource_yandex_mdb_opensearch_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ package yandex
import (
"context"
"fmt"
"log"
"reflect"
"time"

"github.com/yandex-cloud/go-genproto/yandex/cloud/mdb/opensearch/v1"
"github.com/yandex-cloud/go-genproto/yandex/cloud/operation"
sdkoperation "github.com/yandex-cloud/go-sdk/operation"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"log"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand Down Expand Up @@ -271,6 +273,45 @@ func resourceYandexMDBOpenSearchCluster() *schema.Resource {
Computed: true,
},

// Current nodes in the cluster
"hosts": {
Type: schema.TypeSet,
Computed: true,
Set: opensearchHostFQDNHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"fqdn": {
Type: schema.TypeString,
Computed: true,
},
"zone": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"roles": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"assign_public_ip": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"subnet_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
},
},

// User security groups
"security_group_ids": {
Type: schema.TypeSet,
Expand Down Expand Up @@ -387,6 +428,17 @@ func resourceYandexMDBOpenSearchClusterReadEx(d *schema.ResourceData, meta inter
return err
}

actualHosts, err := listOpensearchHosts(ctx, config, d.Id())
if err != nil {
return err
}

result := flattenOpensearchHosts(actualHosts)

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

d.Set("service_account_id", cluster.GetServiceAccountId())

d.Set("deletion_protection", cluster.GetDeletionProtection())
Expand Down Expand Up @@ -949,3 +1001,82 @@ func makeDeleteDashboardsNodeGroupRequest(req *opensearch.DeleteDashboardsNodeGr
}
return nil
}

func listOpensearchHosts(ctx context.Context, config *Config, clusterID string) ([]*opensearch.Host, error) {
hosts := []*opensearch.Host{}
pageToken := ""
for {
resp, err := config.sdk.MDB().OpenSearch().Cluster().ListHosts(ctx, &opensearch.ListClusterHostsRequest{
ClusterId: clusterID,
PageSize: defaultMDBPageSize,
PageToken: pageToken,
})
if err != nil {
return nil, fmt.Errorf("error while getting list of hosts for '%s': %s", clusterID, err)
}
hosts = append(hosts, resp.Hosts...)
if resp.NextPageToken == "" || resp.NextPageToken == "0" {
break
}
pageToken = resp.NextPageToken
}
return hosts, nil
}

func opensearchNodeGroupsDiffCustomize(ctx context.Context, rdiff *schema.ResourceDiff, meta interface{}) error {
oc, nc := rdiff.GetChange("config")
if oc == nil {
if nc == nil {
return fmt.Errorf("Missing required option: config")
}
}

var (
oldConfig = expandOpenSearchConfigCreateSpec(oc)
newConfig = expandOpenSearchConfigCreateSpec(nc)
)

if isNodeGroupsChanged(oldConfig, newConfig) {
err := rdiff.SetNewComputed("hosts")
if err != nil {
return err
}
}

if modifyConfig(oldConfig, newConfig) {
flattened := flattenOpenSearchConfigCreateSpec(newConfig)
err := rdiff.SetNew("config", flattened)
if err != nil {
return err
}
}

return nil
}

func isNodeGroupsChanged(oldConfig, newConfig *opensearch.ConfigCreateSpec) bool {
if (oldConfig == nil || newConfig == nil) ||
(oldConfig.OpensearchSpec == nil || newConfig.OpensearchSpec == nil) ||
(oldConfig.DashboardsSpec == nil || newConfig.DashboardsSpec == nil) {

return false
}

if len(oldConfig.OpensearchSpec.NodeGroups) != len(newConfig.OpensearchSpec.NodeGroups) {
return true
}

if len(oldConfig.DashboardsSpec.NodeGroups) != len(newConfig.DashboardsSpec.NodeGroups) {
return true
}

if !reflect.DeepEqual(oldConfig.OpensearchSpec.NodeGroups, newConfig.OpensearchSpec.NodeGroups) {
return true
}

if !reflect.DeepEqual(oldConfig.DashboardsSpec.NodeGroups, newConfig.DashboardsSpec.NodeGroups) {
return true
}

return false
}
Loading

0 comments on commit 029e1e8

Please sign in to comment.