diff --git a/docs/resources/css_configuration_v1.md b/docs/resources/css_configuration_v1.md new file mode 100644 index 000000000..732ca6fa0 --- /dev/null +++ b/docs/resources/css_configuration_v1.md @@ -0,0 +1,93 @@ +--- +subcategory: "Cloud Search Service (CSS)" +layout: "opentelekomcloud" +page_title: "OpenTelekomCloud: opentelekomcloud_css_configuration_v1" +sidebar_current: "docs-opentelekomcloud-resource-css-configuration-v1" +description: |- + Manage CSS cluster configurations in OpenTelekomCloud. +--- + +Up-to-date reference for API arguments and details can be found at the [documentation portal](https://docs.otc.t-systems.com/cloud-search-service/api-ref/parameter_configuration/index.html). + +# opentelekomcloud_css_configuration_v1 + +Manage the configuration settings of a CSS cluster in OpenTelekomCloud. + +## Example Usage + +```hcl +resource "opentelekomcloud_css_configuration_v1" "example" { + cluster_id = "your-cluster-id" + http_cors_allow_credentials = "true" + http_cors_allow_origin = "122.122.122.122:9200" + indices_queries_cache_size = "50" + auto_create_index = "true" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `cluster_id` - (Required, String, ForceNew) The CSS cluster ID. + + Changing this parameter will create a new resource. + +* `http_cors_allow_credetials` - (Optional, String) Whether to return the Access-Control-Allow-Credentials of + the header during cross-domain access. + The value can be `true` or `false`. Default value: `false`. + +* `http_cors_allow_origin` - (Optional, String) Origin IP address allowed for cross-domain access, for example, `122.122.122.122:9200`. + +* `http_cors_max_age` - (Optional, String) Cache duration of the browser. The cache is automatically cleared + after the time range you specify. + Unit: s, Default value: `1,728,000`. + +* `http_cors_allow_headers` - (Optional, String) Headers allowed for cross-domain access. + Including `X-Requested-With`, `Content-Type`, and `Content-Length`. + Use commas (,) and spaces to separate headers. + +* `http_cors_enabled` - (Optional, String) Whether to allow cross-domain access. + The value can be `true` or `false`. Default value: `false`. + +* `http_cors_allow_methods` - (Optional, String) Methods allowed for cross-domain access. + Including `OPTIONS`, `HEAD`, `GET`, `POST`, `PUT`, and `DELETE`. + Use commas (,) and spaces to separate methods. + +* `reindex_remote_whitelist` - (Optional, String) Configured for migrating data from the current cluster to + the target cluster through the reindex API. + The example value is `122.122.122.122:9200`. + +* `indices_queries_cache_size` - (Optional, String) Cache size in the query phase. Value range: `1%` to `100%`. + Unit: %, Default value: `10%`. + +* `thread_pool_force_merge_size` - (Optional, String) Queue size in the force merge thread pool. + Default value: `1`. + +* `auto_create_index` - (Optional, String) Whether to auto-create an index. + The value can be `true` or `false`. + + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The resource ID which equals the `cluster_id`. + +* `region` - The region where the CSS cluster is deployed. + + +## Timeouts + +This resource provides the following timeouts configuration options: + +* `create` - Default is 20 minutes. +* `delete` - Default is 20 minutes. + +## Import + +The CSS configuration can be imported using the `id` which equals the `cluster_id`, e.g. + +```bash +$ terraform import opentelekomcloud_css_configuration_v1.test +``` diff --git a/go.mod b/go.mod index 5b74b7085..f96fcbb18 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 github.com/mitchellh/go-homedir v1.1.0 - github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20250115161007-a7fae3c659fc + github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20250117142924-89e7b723fcc7 github.com/unknwon/com v1.0.1 golang.org/x/crypto v0.31.0 golang.org/x/sync v0.10.0 diff --git a/go.sum b/go.sum index 0bcc22f62..4af816c21 100644 --- a/go.sum +++ b/go.sum @@ -158,6 +158,8 @@ github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20250115161007-a7fae3c659fc h1:JDr/sgKTh98agnyd5aEZp7EiYKTjwHAG5FW+bGFboig= github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20250115161007-a7fae3c659fc/go.mod h1:la8cQVYopRoEbNe2L7HlGTdLxUQOwIqHp1VHtjE/5qA= +github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20250117142924-89e7b723fcc7 h1:MGGtjRYekil3cch//l2gQBZWv32d/4ztF9GlO6FfCBI= +github.com/opentelekomcloud/gophertelekomcloud v0.9.4-0.20250117142924-89e7b723fcc7/go.mod h1:la8cQVYopRoEbNe2L7HlGTdLxUQOwIqHp1VHtjE/5qA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/opentelekomcloud/acceptance/css/resource_opentelekomcloud_css_configuration_v1_test.go b/opentelekomcloud/acceptance/css/resource_opentelekomcloud_css_configuration_v1_test.go new file mode 100644 index 000000000..d8d0578ab --- /dev/null +++ b/opentelekomcloud/acceptance/css/resource_opentelekomcloud_css_configuration_v1_test.go @@ -0,0 +1,100 @@ +package acceptance + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + pc "github.com/opentelekomcloud/gophertelekomcloud/openstack/css/v1/parameter-configuration" + "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/common" + + "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/acceptance/env" + "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/common/cfg" +) + +func getCssConfigurationV1ResourceFunc(cfg *cfg.Config, state *terraform.ResourceState) (interface{}, error) { + c, err := cfg.CssV1Client(env.OS_REGION_NAME) + if err != nil { + return nil, fmt.Errorf("error creating APIG v2 client: %s", err) + } + configurations, err := pc.List(c, state.Primary.ID) + if err != nil { + return nil, fmt.Errorf("error retrieving OpenTelekomCloud CSS configuration: %s", err) + } + for _, template := range configurations.Templates { + if template.Value != template.DefaultValue { + return configurations, nil + } + } + return nil, golangsdk.ErrDefault404{} +} + +func TestAccCssConfiguration_basic(t *testing.T) { + clusterID := os.Getenv("OS_CSS_CLUSTER_ID") + if clusterID == "" { + t.Skip("OS_CSS_CLUSTER_ID env var is not set") + } + + var obj pc.Configurations + rName := "opentelekomcloud_css_configuration_v1.config" + rc := common.InitResourceCheck( + rName, + &obj, + getCssConfigurationV1ResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { common.TestAccPreCheck(t) }, + ProviderFactories: common.TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testCssConfigurationV1_basic(clusterID), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "thread_pool_force_merge_size", "3"), + resource.TestCheckResourceAttr(rName, "http_cors_allow_credentials", "true"), + ), + }, + { + Config: testCssConfigurationV1_update(clusterID), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "thread_pool_force_merge_size", "4"), + resource.TestCheckResourceAttr(rName, "http_cors_allow_credentials", "true"), + resource.TestCheckResourceAttr(rName, "http_cors_allow_headers", "X-Requested-With, Content-Type"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testCssConfigurationV1_basic(clusterID string) string { + return fmt.Sprintf(` +resource "opentelekomcloud_css_configuration_v1" "config" { + cluster_id = "%s" + thread_pool_force_merge_size = "3" + http_cors_allow_credentials = true +} +`, clusterID) +} + +func testCssConfigurationV1_update(clusterID string) string { + return fmt.Sprintf(` +resource "opentelekomcloud_css_configuration_v1" "config" { + cluster_id = "%s" + thread_pool_force_merge_size = "4" + http_cors_allow_credentials = true + http_cors_allow_headers = "X-Requested-With, Content-Type" + auto_create_index = true +} +`, clusterID) +} diff --git a/opentelekomcloud/common/errors.go b/opentelekomcloud/common/errors.go new file mode 100644 index 000000000..6518478e1 --- /dev/null +++ b/opentelekomcloud/common/errors.go @@ -0,0 +1,58 @@ +package common + +import ( + "encoding/json" + "errors" + "fmt" + "log" + "reflect" + + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" +) + +// ConvertExpected403ErrInto404Err is a method used to parsing 403 error and try to convert it to 404 error according +// to the right error code. +// Arguments: +// + err: The error response obtained through HTTP/HTTPS request. +// + errCodeKey: The key name of the error code in the error response body, e.g. 'error_code', 'err_code'. +// + specErrCodes: One or more error codes that you wish to match against the current error, e.g. 'APIGW.0001'. +// Notes: If you missing specErrCodes input, this function will convert all 403 errors into 404 errors. +// How to use it: +// + For the general cases, their error code key is 'error_code', and we should call as follows: +// - utils.ConvertExpected403ErrInto404Err(err, "error_code") +// - utils.ConvertExpected403ErrInto404Err(err, "error_code", "DWS.0001") +// - utils.ConvertExpected403ErrInto404Err(err, "error_code", []string{"DWS.0001", "DLM.3028"}...) +func ConvertExpected403ErrInto404Err(err error, errCodeKey string, specErrCodes ...string) error { + var err403 golangsdk.ErrDefault403 + if !errors.As(err, &err403) { + log.Printf("[WARN] Unable to recognize expected error type, want 'golangsdk.ErrDefault403', but got '%s'", + reflect.TypeOf(err).String()) + return err + } + var apiError interface{} + if jsonErr := json.Unmarshal(err403.Body, &apiError); jsonErr != nil { + return err + } + + errCode := PathSearch(errCodeKey, apiError, nil) + if errCode == nil { + // 4xx means the client parsing was failed. + return golangsdk.ErrDefault400{ + ErrUnexpectedResponseCode: golangsdk.ErrUnexpectedResponseCode{ + Body: []byte(fmt.Sprintf("Unable to find the error code from the error body using given error code key (%s), the error is: %#v", + errCodeKey, apiError)), + }, + } + } + + if len(specErrCodes) < 1 { + log.Printf("[INFO] Identified 403 error parsed it as 404 error (without the error code control)") + return golangsdk.ErrDefault404{} + } + if StrSliceContains(specErrCodes, fmt.Sprint(errCode)) { + log.Printf("[INFO] Identified 403 error with code '%v' and parsed it as 404 error", errCode) + return golangsdk.ErrDefault404{} + } + log.Printf("[WARN] Unable to recognize expected error code (%v), want %v", errCode, specErrCodes) + return err +} diff --git a/opentelekomcloud/common/utils.go b/opentelekomcloud/common/utils.go index c9b22ac91..3f4f5a0ef 100644 --- a/opentelekomcloud/common/utils.go +++ b/opentelekomcloud/common/utils.go @@ -513,6 +513,13 @@ func ValueIgnoreEmpty(v interface{}) interface{} { return v } +// SetIfNotEmpty to set key if value is not empty +func SetIfNotEmpty(target map[string]interface{}, key string, value interface{}) { + if value != nil && value != "" { + target[key] = value + } +} + // PathSearch evaluates a JMESPath expression against input data and returns the result. func PathSearch(expression string, obj interface{}, defaultValue interface{}) interface{} { v, err := jmespath.Search(expression, obj) diff --git a/opentelekomcloud/provider.go b/opentelekomcloud/provider.go index 1cfd19f05..7852ec38d 100644 --- a/opentelekomcloud/provider.go +++ b/opentelekomcloud/provider.go @@ -425,6 +425,7 @@ func Provider() *schema.Provider { "opentelekomcloud_cts_tracker_v1": cts.ResourceCTSTrackerV1(), "opentelekomcloud_cts_tracker_v3": cts.ResourceCTSTrackerV3(), "opentelekomcloud_css_cluster_v1": css.ResourceCssClusterV1(), + "opentelekomcloud_css_configuration_v1": css.ResourceCssConfigurationV1(), "opentelekomcloud_css_snapshot_configuration_v1": css.ResourceCssSnapshotConfigurationV1(), "opentelekomcloud_direct_connect_v2": dcaas.ResourceDirectConnectV2(), "opentelekomcloud_dc_endpoint_group_v2": dcaas.ResourceDCEndpointGroupV2(), diff --git a/opentelekomcloud/services/css/resource_opentelekomcloud_css_configuration_v1.go b/opentelekomcloud/services/css/resource_opentelekomcloud_css_configuration_v1.go new file mode 100644 index 000000000..8e6681887 --- /dev/null +++ b/opentelekomcloud/services/css/resource_opentelekomcloud_css_configuration_v1.go @@ -0,0 +1,282 @@ +package css + +import ( + "context" + "time" + + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + golangsdk "github.com/opentelekomcloud/gophertelekomcloud" + pc "github.com/opentelekomcloud/gophertelekomcloud/openstack/css/v1/parameter-configuration" + "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/common" + "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/common/cfg" + "github.com/opentelekomcloud/terraform-provider-opentelekomcloud/opentelekomcloud/common/fmterr" +) + +func ResourceCssConfigurationV1() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceCssConfigurationV1Update, + UpdateContext: resourceCssConfigurationV1Update, + ReadContext: resourceCssConfigurationV1Read, + DeleteContext: resourceCssConfigurationV1Delete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(20 * time.Minute), + Delete: schema.DefaultTimeout(20 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "cluster_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: `The CSS cluster ID.`, + }, + "http_cors_allow_credentials": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Whether to return the Access-Control-Allow-Credentials of the header during cross-domain access.`, + }, + "http_cors_allow_origin": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Origin IP address allowed for cross-domain access, for example, **122.122.122.122:9200**.`, + }, + "http_cors_max_age": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Cache duration of the browser. The cache is automatically cleared after the time range you specify.`, + }, + "http_cors_allow_headers": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Headers allowed for cross-domain access.`, + }, + "http_cors_enabled": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Whether to allow cross-domain access.`, + }, + "http_cors_allow_methods": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Methods allowed for cross-domain access.`, + }, + "reindex_remote_whitelist": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Configured for migrating data from the current cluster to the target cluster through the reindex API.`, + }, + "indices_queries_cache_size": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Cache size in the query phase. Value range: **1** to **100**.`, + }, + "thread_pool_force_merge_size": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Queue size in the force merge thread pool.`, + }, + "auto_create_index": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: `Whether to auto-create index.`, + }, + "region": { + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func resourceCssConfigurationV1Update(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*cfg.Config) + client, err := common.ClientFromCtx(ctx, keyClientV1, func() (*golangsdk.ServiceClient, error) { + return config.CssV1Client(config.GetRegion(d)) + }) + if err != nil { + return fmterr.Errorf(clientError, err) + } + + _, err = pc.Modify(client, buildUpdateConfigurationBodyParams(d), d.Get("cluster_id").(string)) + if err != nil { + return diag.Errorf("error creating OpenTelekomCloud CSS configuration: %s", err) + } + + d.SetId(d.Get("cluster_id").(string)) + + err = configurationWaitingForStateCompleted(ctx, d, meta, d.Timeout(schema.TimeoutCreate)) + if err != nil { + return diag.Errorf("error waiting for the OpenTelekomCloud CSS configuration (%s) update to complete: %s", d.Id(), err) + } + + clientCtx := common.CtxWithClient(ctx, client, keyClientV1) + return resourceCssConfigurationV1Read(clientCtx, d, meta) +} + +func buildUpdateConfigurationBodyParams(d *schema.ResourceData) pc.ModifyOpts { + elasticsearchYml := make(map[string]interface{}) + + common.SetIfNotEmpty(elasticsearchYml, "http.cors.allow-credentials", d.Get("http_cors_allow_credentials")) + common.SetIfNotEmpty(elasticsearchYml, "http.cors.allow-origin", d.Get("http_cors_allow_origin")) + common.SetIfNotEmpty(elasticsearchYml, "http.cors.max-age", d.Get("http_cors_max_age")) + common.SetIfNotEmpty(elasticsearchYml, "http.cors.allow-headers", d.Get("http_cors_allow_headers")) + common.SetIfNotEmpty(elasticsearchYml, "http.cors.enabled", d.Get("http_cors_enabled")) + common.SetIfNotEmpty(elasticsearchYml, "http.cors.allow-methods", d.Get("http_cors_allow_methods")) + common.SetIfNotEmpty(elasticsearchYml, "reindex.remote.whitelist", d.Get("reindex_remote_whitelist")) + common.SetIfNotEmpty(elasticsearchYml, "indices.queries.cache.size", d.Get("indices_queries_cache_size")) + common.SetIfNotEmpty(elasticsearchYml, "thread_pool.force_merge.size", d.Get("thread_pool_force_merge_size")) + common.SetIfNotEmpty(elasticsearchYml, "action.auto_create_index", d.Get("auto_create_index")) + + opts := pc.ModifyOpts{ + Edit: map[string]interface{}{ + "modify": map[string]interface{}{ + "elasticsearch.yml": elasticsearchYml, + }, + }, + } + return opts +} + +func resourceCssConfigurationV1Read(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*cfg.Config) + client, err := common.ClientFromCtx(ctx, keyClientV1, func() (*golangsdk.ServiceClient, error) { + return config.CssV1Client(config.GetRegion(d)) + }) + if err != nil { + return fmterr.Errorf(clientError, err) + } + + configurations, err := pc.List(client, d.Id()) + if err != nil { + return common.CheckDeletedDiag(d, err, "error getting OpenTelekomCloud CSS configurations") + } + + mErr := multierror.Append( + nil, + d.Set("region", config.GetRegion(d)), + d.Set("cluster_id", d.Id()), + ) + + keyMappings := map[string]string{ + "http.cors.allow-credentials": "http_cors_allow_credentials", + "http.cors.cors.allow-origin": "http_cors_allow_origin", + "http.cors.max-age": "http_cors_max_age", + "http.cors.allow-headers": "http_cors_allow_headers", + "http.cors.enabled": "http_cors_enabled", + "http.cors.allow-methods": "http_cors_allow_methods", + "reindex.remote.whitelist": "reindex_remote_whitelist", + "indices.queries.cache.size": "indices_queries_cache_size", + "thread_pool.force_merge.size": "thread_pool_force_merge_size", + "action.auto_create_index": "auto_create_index", + } + for key, c := range configurations.Templates { + if mappedKey, exists := keyMappings[key]; exists { + mErr = multierror.Append(mErr, d.Set(mappedKey, c.Value)) + } + } + + return diag.FromErr(mErr.ErrorOrNil()) +} + +func resourceCssConfigurationV1Delete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + config := meta.(*cfg.Config) + client, err := common.ClientFromCtx(ctx, keyClientV1, func() (*golangsdk.ServiceClient, error) { + return config.CssV1Client(config.GetRegion(d)) + }) + if err != nil { + return fmterr.Errorf(clientError, err) + } + delMsg := "error deleting OpenTelekomCloud CSS configuration" + _, err = pc.Modify(client, buildResetConfigurationBodyParams(), d.Id()) + if err != nil { + // The cluster does not exist, http code is 403, key/value of error code is errCode/CSS.0015 + return common.CheckDeletedDiag(d, + common.ConvertExpected403ErrInto404Err(err, "errCode", "CSS.0015"), delMsg) + } + + err = configurationWaitingForStateCompleted(ctx, d, meta, d.Timeout(schema.TimeoutDelete)) + if err != nil { + return diag.Errorf("error waiting for the OpenTelekomCloud CSS configuration (%s) deletion to complete: %s", d.Id(), err) + } + return nil +} + +// Reset to default value. +func buildResetConfigurationBodyParams() pc.ModifyOpts { + opts := pc.ModifyOpts{ + Edit: map[string]interface{}{ + "reset": map[string]interface{}{ + "elasticsearch.yml": map[string]interface{}{ + "http.cors.allow-credentials": "", + "http.cors.allow-origin": "", + "http.cors.max-age": "", + "http.cors.allow-headers": "", + "http.cors.enabled": "", + "http.cors.allow-methods": "", + "reindex.remote.whitelist": "", + "indices.queries.cache.size": "", + "thread_pool.force_merge.size": "", + }, + }, + "delete": map[string]interface{}{ + "elasticsearch.yml": map[string]interface{}{ + "action.auto_create_index": "", + }, + }, + }, + } + return opts +} + +func configurationWaitingForStateCompleted(ctx context.Context, d *schema.ResourceData, meta interface{}, t time.Duration) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"PENDING"}, + Target: []string{"COMPLETED"}, + Refresh: func() (interface{}, string, error) { + config := meta.(*cfg.Config) + client, err := common.ClientFromCtx(ctx, keyClientV1, func() (*golangsdk.ServiceClient, error) { + return config.CssV1Client(config.GetRegion(d)) + }) + if err != nil { + return nil, "ERROR", err + } + + cfgList, err := pc.ListTask(client, d.Id()) + if err != nil { + if _, ok := err.(golangsdk.ErrDefault404); ok { + return cfgList, "COMPLETED", nil + } + + return nil, "ERROR", err + } + + for _, task := range cfgList { + if task.Status == "running" { + return cfgList, "PENDING", nil + } + } + return cfgList, "COMPLETED", nil + }, + Timeout: t, + Delay: 30 * time.Second, + PollInterval: 10 * time.Second, + } + _, err := stateConf.WaitForStateContext(ctx) + return err +} diff --git a/opentelekomcloud/services/css/utils.go b/opentelekomcloud/services/css/utils.go index a5548b10c..768c5fafc 100644 --- a/opentelekomcloud/services/css/utils.go +++ b/opentelekomcloud/services/css/utils.go @@ -2,7 +2,10 @@ package css import "github.com/opentelekomcloud/gophertelekomcloud/openstack/css/v1/clusters" -const clientError = `error creating CSSv1 client: %w` +const ( + clientError = `error creating CSSv1 client: %w` + keyClientV1 = "css-v1-client" +) var defaultDatastore = clusters.Datastore{ Version: "7.6.2", diff --git a/releasenotes/notes/css-configuration-e67a9f30b1e1704b.yaml b/releasenotes/notes/css-configuration-e67a9f30b1e1704b.yaml new file mode 100644 index 000000000..beb37144b --- /dev/null +++ b/releasenotes/notes/css-configuration-e67a9f30b1e1704b.yaml @@ -0,0 +1,4 @@ +--- +enhancements: + - | + **[DCS]** New resource ``resource/opentelekomcloud_css_configuration_v1`` (`#2792 `_)