diff --git a/docs/resources/dli_template_flink.md b/docs/resources/dli_template_flink.md new file mode 100644 index 00000000..8dc819a4 --- /dev/null +++ b/docs/resources/dli_template_flink.md @@ -0,0 +1,81 @@ +--- +subcategory: "Data Lake Insight (DLI)" +--- + +# flexibleengine_dli_template_flink + +Manages a DLI Flink template resource within FlexibleEngineCloud. + +## Example Usage + +```hcl +variable "sql" {} + +resource "flexibleengine_dli_template_flink" "test" { + name = "demo" + type = "flink_sql_job" + sql = var.sql + description = "This is a demo" + + tags = { + foo = "bar" + key = "value" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `region` - (Optional, String, ForceNew) Specifies the region in which to create the resource. + If omitted, the provider-level region will be used. Changing this parameter will create a new resource. + +* `name` - (Required, String) The name of the flink template. + +* `sql` - (Optional, String) The statement of the flink template. + +* `description` - (Optional, String) The description of the flink template. + +* `type` - (Optional, String, ForceNew) The type of the flink template. + Valid values are **flink_sql_job** and **flink_opensource_sql_job**. + Defaults to **flink_sql_job**. + + Changing this parameter will create a new resource. + +* `tags` - (Optional, Map, ForceNew) The key/value pairs to associate with the flink template. + + Changing this parameter will create a new resource. + +## Attribute Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - The resource ID. + +## Import + +The flink template can be imported using the `id`, e.g. + +```bash +$ terraform import flexibleengine_dli_template_flink.test 1231 +``` + +Note that the imported state may not be identical to your resource definition, due to some attributes missing from the +API response, security or some other reason. The missing attributes include: +`tags`. +It is generally recommended running `terraform plan` after importing a resource. +You can then decide if changes should be applied to the resource, or the resource definition should be updated to align +with the resource. Also, you can ignore changes as below. + +```bash +resource "flexibleengine_dli_template_flink" "test" { + ... + + lifecycle { + ignore_changes = [ + tags + ] + } +} +``` diff --git a/flexibleengine/acceptance/resource_flexibleengine_dli_template_flink_test.go b/flexibleengine/acceptance/resource_flexibleengine_dli_template_flink_test.go new file mode 100644 index 00000000..ee91f670 --- /dev/null +++ b/flexibleengine/acceptance/resource_flexibleengine_dli_template_flink_test.go @@ -0,0 +1,142 @@ +package acceptance + +import ( + "fmt" + "strings" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + + "github.com/chnsz/golangsdk" + + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/config" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/services/acceptance" + "github.com/huaweicloud/terraform-provider-huaweicloud/huaweicloud/utils" +) + +func getFlinkTemplateResourceFunc(cfg *config.Config, state *terraform.ResourceState) (interface{}, error) { + region := OS_REGION_NAME + // getFlinkTemplate: Query the Flink template. + var ( + getFlinkTemplateHttpUrl = "v1.0/{project_id}/streaming/job-templates" + getFlinkTemplateProduct = "dli" + ) + getFlinkTemplateClient, err := cfg.NewServiceClient(getFlinkTemplateProduct, region) + if err != nil { + return nil, fmt.Errorf("error creating DLI Client: %s", err) + } + + getFlinkTemplatePath := getFlinkTemplateClient.Endpoint + getFlinkTemplateHttpUrl + getFlinkTemplatePath = strings.ReplaceAll(getFlinkTemplatePath, "{project_id}", getFlinkTemplateClient.ProjectID) + + if v, ok := state.Primary.Attributes["name"]; ok { + getFlinkTemplatePath += fmt.Sprintf("?limit=100&name=%s", v) + } + + getFlinkTemplateOpt := golangsdk.RequestOpts{ + KeepResponseBody: true, + OkCodes: []int{ + 200, + }, + } + getFlinkTemplateResp, err := getFlinkTemplateClient.Request("GET", getFlinkTemplatePath, &getFlinkTemplateOpt) + if err != nil { + return nil, fmt.Errorf("error retrieving FlinkTemplate: %s", err) + } + + getFlinkTemplateRespBody, err := utils.FlattenResponse(getFlinkTemplateResp) + if err != nil { + return nil, fmt.Errorf("error retrieving Flink template: %s", err) + } + + jsonPath := fmt.Sprintf("template_list.templates[?template_id==`%s`]|[0]", state.Primary.ID) + template := utils.PathSearch(jsonPath, getFlinkTemplateRespBody, nil) + if template == nil { + return nil, fmt.Errorf("no data found") + } + return template, nil +} + +func TestAccFlinkTemplate_basic(t *testing.T) { + var obj interface{} + + name := acceptance.RandomAccResourceName() + rName := "flexibleengine_dli_template_flink.test" + + rc := acceptance.InitResourceCheck( + rName, + &obj, + getFlinkTemplateResourceFunc, + ) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProviderFactories: TestAccProviderFactories, + CheckDestroy: rc.CheckResourceDestroy(), + Steps: []resource.TestStep{ + { + Config: testFlinkTemplate_basic(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name), + resource.TestCheckResourceAttr(rName, "sql", "select * from source_table"), + resource.TestCheckResourceAttr(rName, "description", "This is a demo"), + resource.TestCheckResourceAttr(rName, "type", "flink_sql_job"), + resource.TestCheckResourceAttr(rName, "tags.foo", "bar"), + resource.TestCheckResourceAttr(rName, "tags.key", "value"), + ), + }, + { + Config: testFlinkTemplate_basic_update(name), + Check: resource.ComposeTestCheckFunc( + rc.CheckResourceExists(), + resource.TestCheckResourceAttr(rName, "name", name), + resource.TestCheckResourceAttr(rName, "sql", "select * from source_table2"), + resource.TestCheckResourceAttr(rName, "description", "This is a demo2"), + resource.TestCheckResourceAttr(rName, "type", "flink_sql_job"), + resource.TestCheckResourceAttr(rName, "tags.foo", "bar"), + resource.TestCheckResourceAttr(rName, "tags.key", "value2"), + ), + }, + { + ResourceName: rName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"tags"}, + }, + }, + }) +} + +func testFlinkTemplate_basic(name string) string { + return fmt.Sprintf(` +resource "flexibleengine_dli_template_flink" "test" { + name = "%s" + type = "flink_sql_job" + sql = "select * from source_table" + description = "This is a demo" + + tags = { + foo = "bar" + key = "value" + } +} +`, name) +} + +func testFlinkTemplate_basic_update(name string) string { + return fmt.Sprintf(` +resource "flexibleengine_dli_template_flink" "test" { + name = "%s" + type = "flink_sql_job" + sql = "select * from source_table2" + description = "This is a demo2" + + tags = { + foo = "bar" + key = "value2" + } +} +`, name) +} diff --git a/flexibleengine/provider.go b/flexibleengine/provider.go index 989b7a00..70a50530 100644 --- a/flexibleengine/provider.go +++ b/flexibleengine/provider.go @@ -490,15 +490,16 @@ func Provider() *schema.Provider { "flexibleengine_dms_rocketmq_topic": dms.ResourceDmsRocketMQTopic(), "flexibleengine_dms_rocketmq_user": dms.ResourceDmsRocketMQUser(), - "flexibleengine_dli_database": dli.ResourceDliSqlDatabaseV1(), - "flexibleengine_dli_package": dli.ResourceDliPackageV2(), - "flexibleengine_dli_spark_job": dli.ResourceDliSparkJobV2(), - "flexibleengine_dli_table": dli.ResourceDliTable(), - "flexibleengine_dli_flinksql_job": dli.ResourceFlinkSqlJob(), - "flexibleengine_drs_job": drs.ResourceDrsJob(), - "flexibleengine_fgs_dependency": fgs.ResourceFgsDependency(), - "flexibleengine_fgs_function": fgs.ResourceFgsFunctionV2(), - "flexibleengine_fgs_trigger": fgs.ResourceFunctionGraphTrigger(), + "flexibleengine_dli_database": dli.ResourceDliSqlDatabaseV1(), + "flexibleengine_dli_package": dli.ResourceDliPackageV2(), + "flexibleengine_dli_spark_job": dli.ResourceDliSparkJobV2(), + "flexibleengine_dli_table": dli.ResourceDliTable(), + "flexibleengine_dli_flinksql_job": dli.ResourceFlinkSqlJob(), + "flexibleengine_dli_template_flink": dli.ResourceFlinkTemplate(), + "flexibleengine_drs_job": drs.ResourceDrsJob(), + "flexibleengine_fgs_dependency": fgs.ResourceFgsDependency(), + "flexibleengine_fgs_function": fgs.ResourceFgsFunctionV2(), + "flexibleengine_fgs_trigger": fgs.ResourceFunctionGraphTrigger(), "flexibleengine_gaussdb_cassandra_instance": gaussdb.ResourceGeminiDBInstanceV3(), "flexibleengine_gaussdb_influx_instance": gaussdb.ResourceGaussDBInfluxInstanceV3(),