From 7f83aab420b48a9deb038024c8432865d10dff91 Mon Sep 17 00:00:00 2001 From: "maoshuai.17" Date: Tue, 20 Jun 2023 20:09:58 +0800 Subject: [PATCH 1/7] feat: support cloud assistant --- example/dataEcsCommands/main.tf | 3 + example/dataEcsInvocations/main.tf | 3 + example/ecsCommand/main.tf | 8 + example/ecsInvocation/main.tf | 14 + .../data_source_volcengine_ecs_commands.go | 135 ++++++++ .../resource_volcengine_ecs_command.go | 127 +++++++ .../service_volcengine_ecs_command.go | 248 ++++++++++++++ .../data_source_volcengine_ecs_invocations.go | 202 +++++++++++ .../resource_volcengine_ecs_invocation.go | 180 ++++++++++ .../service_volcengine_ecs_invocation.go | 316 ++++++++++++++++++ volcengine/provider.go | 6 + 11 files changed, 1242 insertions(+) create mode 100644 example/dataEcsCommands/main.tf create mode 100644 example/dataEcsInvocations/main.tf create mode 100644 example/ecsCommand/main.tf create mode 100644 example/ecsInvocation/main.tf create mode 100644 volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go create mode 100644 volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go create mode 100644 volcengine/ecs/ecs_command/service_volcengine_ecs_command.go create mode 100644 volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go create mode 100644 volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go create mode 100644 volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go diff --git a/example/dataEcsCommands/main.tf b/example/dataEcsCommands/main.tf new file mode 100644 index 00000000..6cf7c573 --- /dev/null +++ b/example/dataEcsCommands/main.tf @@ -0,0 +1,3 @@ +data "volcengine_ecs_commands" "default" { + command_id = "cmd-ychkepkhtim0tr3b****" +} \ No newline at end of file diff --git a/example/dataEcsInvocations/main.tf b/example/dataEcsInvocations/main.tf new file mode 100644 index 00000000..295eb905 --- /dev/null +++ b/example/dataEcsInvocations/main.tf @@ -0,0 +1,3 @@ +data "volcengine_ecs_invocations" "default" { + invocation_id = "ivk-ych9y4vujvl8j01c****" +} \ No newline at end of file diff --git a/example/ecsCommand/main.tf b/example/ecsCommand/main.tf new file mode 100644 index 00000000..6d8756ed --- /dev/null +++ b/example/ecsCommand/main.tf @@ -0,0 +1,8 @@ +resource "volcengine_ecs_command" "foo" { + name = "tf-test" + description = "tf" + working_dir = "/home" + username = "root" + timeout = 100 + command_content = "IyEvYmluL2Jhc2gKCgplY2hvICJvcGVyYXRpb24gc3VjY2VzcyEi" +} \ No newline at end of file diff --git a/example/ecsInvocation/main.tf b/example/ecsInvocation/main.tf new file mode 100644 index 00000000..3ce3f4e9 --- /dev/null +++ b/example/ecsInvocation/main.tf @@ -0,0 +1,14 @@ +resource "volcengine_ecs_invocation" "foo" { + command_id = "cmd-ychkepkhtim0tr3b****" + instance_ids = ["i-ychmz92487l8j00o****"] + invocation_name = "tf-test" + invocation_description = "tf" + username = "root" + timeout = 90 + working_dir = "/home" + repeat_mode = "Rate" +# frequency = "2023-06-20T08:28:00Z" + frequency = "5m" + launch_time = "2023-06-20T09:48:00Z" + recurrence_end_time = "2023-06-20T09:59:00Z" +} \ No newline at end of file diff --git a/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go b/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go new file mode 100644 index 00000000..d46fd228 --- /dev/null +++ b/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go @@ -0,0 +1,135 @@ +package ecs_command + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcengineEcsCommands() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcengineEcsCommandsRead, + Schema: map[string]*schema.Schema{ + "command_provider": { + Type: schema.TypeString, + Optional: true, + Description: "The provider of public command. When this field is not specified, query for custom commands.", + }, + "command_id": { + Type: schema.TypeString, + Optional: true, + Description: "The id of ecs command.", + }, + "name": { + Type: schema.TypeString, + Optional: true, + Description: "The name of ecs command. This field support fuzzy query.", + }, + "type": { + Type: schema.TypeString, + Optional: true, + Description: "The type of ecs command. Valid values: `Shell`.", + }, + "order": { + Type: schema.TypeString, + Optional: true, + Description: "The order of ecs command query result.", + }, + "name_regex": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsValidRegExp, + Description: "A Name Regex of Resource.", + }, + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "commands": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs command.", + }, + "command_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs command.", + }, + "name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the ecs command.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The create time of the ecs command.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The update time of the ecs command.", + }, + "type": { + Type: schema.TypeString, + Computed: true, + Description: "The type of the ecs command.", + }, + "timeout": { + Type: schema.TypeInt, + Computed: true, + Description: "The timeout of the ecs command.", + }, + "working_dir": { + Type: schema.TypeString, + Computed: true, + Description: "The working directory of the ecs command.", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "The user name of the ecs command.", + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: "The description of the ecs command.", + }, + "command_provider": { + Type: schema.TypeString, + Computed: true, + Description: "The provider of the public command.", + }, + "command_content": { + Type: schema.TypeString, + Computed: true, + Description: "The base64 encoded content of the ecs command.", + }, + "invocation_times": { + Type: schema.TypeInt, + Computed: true, + Description: "The invocation times of the ecs command. Public commands do not display the invocation times.", + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcengineEcsCommandsRead(d *schema.ResourceData, meta interface{}) error { + service := NewEcsCommandService(meta.(*ve.SdkClient)) + return ve.DefaultDispatcher().Data(service, d, DataSourceVolcengineEcsCommands()) +} diff --git a/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go b/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go new file mode 100644 index 00000000..ae9bd287 --- /dev/null +++ b/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go @@ -0,0 +1,127 @@ +package ecs_command + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +EcsCommand can be imported using the id, e.g. +``` +$ terraform import volcengine_ecs_command.default cmd-ychkepkhtim0tr3bcsw1 +``` + +*/ + +func ResourceVolcengineEcsCommand() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcengineEcsCommandCreate, + Read: resourceVolcengineEcsCommandRead, + Update: resourceVolcengineEcsCommandUpdate, + Delete: resourceVolcengineEcsCommandDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "The name of the ecs command.", + }, + "description": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The description of the ecs command.", + }, + "command_content": { + Type: schema.TypeString, + Required: true, + Description: "The base64 encoded content of the ecs command.", + }, + "working_dir": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The working directory of the ecs command.", + }, + "username": { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The user name of the ecs command.", + }, + "timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ValidateFunc: validation.IntBetween(10, 600), + Description: "The timeout of the ecs command. Valid value range: 10-600.", + }, + + "invocation_times": { + Type: schema.TypeInt, + Computed: true, + Description: "The invocation times of the ecs command. Public commands do not display the invocation times.", + }, + "created_at": { + Type: schema.TypeString, + Computed: true, + Description: "The create time of the ecs command.", + }, + "updated_at": { + Type: schema.TypeString, + Computed: true, + Description: "The update time of the ecs command.", + }, + }, + } + return resource +} + +func resourceVolcengineEcsCommandCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsCommandService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Create(service, d, ResourceVolcengineEcsCommand()) + if err != nil { + return fmt.Errorf("error on creating ecs command %q, %s", d.Id(), err) + } + return resourceVolcengineEcsCommandRead(d, meta) +} + +func resourceVolcengineEcsCommandRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsCommandService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Read(service, d, ResourceVolcengineEcsCommand()) + if err != nil { + return fmt.Errorf("error on reading ecs command %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcengineEcsCommandUpdate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsCommandService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Update(service, d, ResourceVolcengineEcsCommand()) + if err != nil { + return fmt.Errorf("error on updating ecs command %q, %s", d.Id(), err) + } + return resourceVolcengineEcsCommandRead(d, meta) +} + +func resourceVolcengineEcsCommandDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsCommandService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Delete(service, d, ResourceVolcengineEcsCommand()) + if err != nil { + return fmt.Errorf("error on deleting ecs command %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/ecs/ecs_command/service_volcengine_ecs_command.go b/volcengine/ecs/ecs_command/service_volcengine_ecs_command.go new file mode 100644 index 00000000..df6079ae --- /dev/null +++ b/volcengine/ecs/ecs_command/service_volcengine_ecs_command.go @@ -0,0 +1,248 @@ +package ecs_command + +import ( + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcengineEcsCommandService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewEcsCommandService(c *ve.SdkClient) *VolcengineEcsCommandService { + return &VolcengineEcsCommandService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcengineEcsCommandService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcengineEcsCommandService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 20, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "DescribeCommands" + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + results, err = ve.ObtainSdkValue("Result.Commands", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Commands is not Slice") + } + return data, err + }) +} + +func (s *VolcengineEcsCommandService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ok bool + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + req := map[string]interface{}{ + "CommandId": id, + } + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + if data, ok = v.(map[string]interface{}); !ok { + return data, errors.New("Value is not map ") + } + } + if len(data) == 0 { + return data, fmt.Errorf("ecs command %s is not exist ", id) + } + return data, err +} + +func (s *VolcengineEcsCommandService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{} +} + +func (VolcengineEcsCommandService) WithResourceResponseHandlers(data map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return data, nil, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcengineEcsCommandService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "CreateCommand", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeDefault, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + (*call.SdkParam)["Type"] = "Shell" + return true, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.CommandId", *resp) + d.SetId(id.(string)) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcengineEcsCommandService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "ModifyCommand", + ConvertMode: ve.RequestConvertInConvert, + ContentType: ve.ContentTypeDefault, + Convert: map[string]ve.RequestConvert{ + "name": { + TargetField: "Name", + }, + "description": { + TargetField: "Description", + }, + "command_content": { + TargetField: "CommandContent", + }, + "working_dir": { + TargetField: "WorkingDir", + }, + "username": { + TargetField: "Username", + }, + "timeout": { + TargetField: "Timeout", + }, + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + if len(*call.SdkParam) > 0 { + (*call.SdkParam)["CommandId"] = d.Id() + return true, nil + } + return false, nil + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcengineEcsCommandService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "DeleteCommand", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeDefault, + SdkParam: &map[string]interface{}{ + "CommandId": resourceData.Id(), + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + return ve.CheckResourceUtilRemoved(d, s.ReadResource, 5*time.Minute) + }, + CallError: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall, baseErr error) error { + //出现错误后重试 + return resource.Retry(15*time.Minute, func() *resource.RetryError { + _, callErr := s.ReadResource(d, "") + if callErr != nil { + if ve.ResourceNotFoundError(callErr) { + return nil + } else { + return resource.NonRetryableError(fmt.Errorf("error on reading ecs command on delete %q, %w", d.Id(), callErr)) + } + } + _, callErr = call.ExecuteCall(d, client, call) + if callErr == nil { + return nil + } + return resource.RetryableError(callErr) + }) + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcengineEcsCommandService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "command_provider": { + TargetField: "Provider", + }, + }, + NameField: "Name", + IdField: "CommandId", + CollectField: "commands", + ResponseConverts: map[string]ve.ResponseConvert{ + "CommandId": { + TargetField: "id", + KeepDefault: true, + }, + "Provider": { + TargetField: "command_provider", + }, + }, + } +} + +func (s *VolcengineEcsCommandService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "ecs", + Version: "2020-04-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} diff --git a/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go b/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go new file mode 100644 index 00000000..49a640ae --- /dev/null +++ b/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go @@ -0,0 +1,202 @@ +package ecs_invocation + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcengineEcsInvocations() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcengineEcsInvocationsRead, + Schema: map[string]*schema.Schema{ + "invocation_id": { + Type: schema.TypeString, + Optional: true, + Description: "The id of ecs invocation.", + }, + "invocation_name": { + Type: schema.TypeString, + Optional: true, + Description: "The name of ecs invocation. This field support fuzzy query.", + }, + "command_id": { + Type: schema.TypeString, + Optional: true, + Description: "The id of ecs command.", + }, + "command_name": { + Type: schema.TypeString, + Optional: true, + Description: "The name of ecs command. This field support fuzzy query.", + }, + "command_type": { + Type: schema.TypeString, + Optional: true, + Description: "The type of ecs command. Valid values: `Shell`.", + }, + "repeat_mode": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "Once", + "Rate", + "Fixed", + }, false), + Description: "The repeat mode of ecs invocation. Valid values: `Once`, `Rate`, `Fixed`.", + }, + "invocation_status": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + "Pending", "Scheduled", "Running", "Success", + "Failed", "Stopped", "PartialFailed", "Finished", + }, false), + Description: "The status of ecs invocation. Valid values: `Pending`, `Scheduled`, `Running`, `Success`, `Failed`, `Stopped`, `PartialFailed`, `Finished`.", + }, + "name_regex": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringIsValidRegExp, + Description: "A Name Regex of Resource.", + }, + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "invocations": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs invocation.", + }, + "invocation_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs invocation.", + }, + "invocation_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the ecs invocation.", + }, + "invocation_description": { + Type: schema.TypeString, + Computed: true, + Description: "The description of the ecs invocation.", + }, + "command_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs command.", + }, + "command_name": { + Type: schema.TypeString, + Computed: true, + Description: "The name of the ecs command.", + }, + "command_description": { + Type: schema.TypeString, + Computed: true, + Description: "The description of the ecs command.", + }, + "command_type": { + Type: schema.TypeString, + Computed: true, + Description: "The type of the ecs command.", + }, + "command_provider": { + Type: schema.TypeString, + Computed: true, + Description: "The provider of the ecs command.", + }, + "invocation_status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the ecs invocation.", + }, + "command_content": { + Type: schema.TypeString, + Computed: true, + Description: "The base64 encoded content of the ecs command.", + }, + "timeout": { + Type: schema.TypeInt, + Computed: true, + Description: "The timeout of the ecs command.", + }, + "working_dir": { + Type: schema.TypeString, + Computed: true, + Description: "The working directory of the ecs command.", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "The user name of the ecs command.", + }, + "start_time": { + Type: schema.TypeString, + Computed: true, + Description: "The start time of the ecs invocation.", + }, + "end_time": { + Type: schema.TypeString, + Computed: true, + Description: "The end time of the ecs invocation.", + }, + "instance_number": { + Type: schema.TypeInt, + Computed: true, + Description: "The instance number of the ecs invocation.", + }, + "instance_ids": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "The list of ECS instance IDs.", + }, + "repeat_mode": { + Type: schema.TypeString, + Computed: true, + Description: "The repeat mode of the ecs invocation.", + }, + "frequency": { + Type: schema.TypeString, + Computed: true, + Description: "The frequency of the ecs invocation.", + }, + "launch_time": { + Type: schema.TypeString, + Computed: true, + Description: "The launch time of the ecs invocation.", + }, + "recurrence_end_time": { + Type: schema.TypeString, + Computed: true, + Description: "The recurrence end time of the ecs invocation.", + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcengineEcsInvocationsRead(d *schema.ResourceData, meta interface{}) error { + service := NewEcsInvocationService(meta.(*ve.SdkClient)) + return ve.DefaultDispatcher().Data(service, d, DataSourceVolcengineEcsInvocations()) +} diff --git a/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go b/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go new file mode 100644 index 00000000..7e96cd24 --- /dev/null +++ b/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go @@ -0,0 +1,180 @@ +package ecs_invocation + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +/* + +Import +EcsInvocation can be imported using the id, e.g. +``` +$ terraform import volcengine_ecs_invocation.default ivk-ychnxnm45dl8j0mm**** +``` + +*/ + +func ResourceVolcengineEcsInvocation() *schema.Resource { + resource := &schema.Resource{ + Create: resourceVolcengineEcsInvocationCreate, + Read: resourceVolcengineEcsInvocationRead, + Delete: resourceVolcengineEcsInvocationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + Schema: map[string]*schema.Schema{ + "command_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The command id of the ecs invocation.", + }, + "instance_ids": { + Type: schema.TypeSet, + Required: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + Description: "The list of ECS instance IDs.", + }, + "invocation_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The name of the ecs invocation.", + }, + "invocation_description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Description: "The description of the ecs invocation.", + }, + "username": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "The user name of the ecs command. When this field is not specified, use the value of the field with the same name in ecs command as the default value.", + }, + "working_dir": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Description: "The working directory of the ecs invocation. When this field is not specified, use the value of the field with the same name in ecs command as the default value.", + }, + "timeout": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(10, 600), + Description: "The timeout of the ecs command. Valid value range: 10-600. When this field is not specified, use the value of the field with the same name in ecs command as the default value.", + }, + "repeat_mode": { + Type: schema.TypeString, + Optional: true, + Default: "Once", + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + "Once", + "Rate", + "Fixed", + }, false), + Description: "The repeat mode of the ecs invocation. Valid values: `Once`, `Rate`, `Fixed`.", + }, + "frequency": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if d.Get("repeat_mode").(string) == "Once" { + return true + } + return false + }, + Description: "The frequency of the ecs invocation. This field is valid when the value of the repeat_mode field is `Rate` or `Fixed`.", + }, + "launch_time": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if d.Get("repeat_mode").(string) == "Rate" { + return false + } + return true + }, + Description: "The launch time of the ecs invocation. RFC3339 format. This field is valid when the value of the repeat_mode field is `Rate`.", + }, + "recurrence_end_time": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if d.Get("repeat_mode").(string) == "Rate" { + return false + } + return true + }, + Description: "The recurrence end time of the ecs invocation. RFC3339 format. This field is valid when the value of the repeat_mode field is `Rate`.", + }, + + "invocation_status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of the ecs invocation.", + }, + "start_time": { + Type: schema.TypeString, + Computed: true, + Description: "The start time of the ecs invocation.", + }, + "end_time": { + Type: schema.TypeString, + Computed: true, + Description: "The end time of the ecs invocation.", + }, + }, + } + return resource +} + +func resourceVolcengineEcsInvocationCreate(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsInvocationService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Create(service, d, ResourceVolcengineEcsInvocation()) + if err != nil { + return fmt.Errorf("error on creating ecs invocation %q, %s", d.Id(), err) + } + return resourceVolcengineEcsInvocationRead(d, meta) +} + +func resourceVolcengineEcsInvocationRead(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsInvocationService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Read(service, d, ResourceVolcengineEcsInvocation()) + if err != nil { + return fmt.Errorf("error on reading ecs invocation %q, %s", d.Id(), err) + } + return err +} + +func resourceVolcengineEcsInvocationDelete(d *schema.ResourceData, meta interface{}) (err error) { + service := NewEcsInvocationService(meta.(*ve.SdkClient)) + err = ve.DefaultDispatcher().Delete(service, d, ResourceVolcengineEcsInvocation()) + if err != nil { + return fmt.Errorf("error on deleting ecs invocation %q, %s", d.Id(), err) + } + return err +} diff --git a/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go b/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go new file mode 100644 index 00000000..7ddf8c5c --- /dev/null +++ b/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go @@ -0,0 +1,316 @@ +package ecs_invocation + +import ( + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcengineEcsInvocationService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewEcsInvocationService(c *ve.SdkClient) *VolcengineEcsInvocationService { + return &VolcengineEcsInvocationService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcengineEcsInvocationService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcengineEcsInvocationService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 20, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "DescribeInvocations" + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + results, err = ve.ObtainSdkValue("Result.Invocations", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.Invocations is not Slice") + } + + for _, v := range data { + instanceIds := make([]string, 0) + invocation, ok := v.(map[string]interface{}) + if !ok { + return data, fmt.Errorf(" Invocation is not map ") + } + action := "DescribeInvocationInstances" + req := map[string]interface{}{ + "InvocationId": invocation["InvocationId"], + } + logger.Debug(logger.ReqFormat, action, req) + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &req) + logger.Debug(logger.RespFormat, action, req, resp) + results, err := ve.ObtainSdkValue("Result.InvocationInstances", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + instances, ok := results.([]interface{}) + if !ok { + return data, errors.New("Result.InvocationInstances is not Slice") + } + if len(instances) == 0 { + return data, fmt.Errorf("invocation %s does not contain any instances", invocation["InvocationId"]) + } + for _, v1 := range instances { + instance, ok := v1.(map[string]interface{}) + if !ok { + return data, fmt.Errorf(" invocation instance is not map ") + } + instanceIds = append(instanceIds, instance["InstanceId"].(string)) + } + invocation["InstanceIds"] = instanceIds + } + + return data, err + }) +} + +func (s *VolcengineEcsInvocationService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + var ( + results []interface{} + ok bool + ) + if id == "" { + id = s.ReadResourceId(resourceData.Id()) + } + req := map[string]interface{}{ + "InvocationId": id, + } + results, err = s.ReadResources(req) + if err != nil { + return data, err + } + for _, v := range results { + if data, ok = v.(map[string]interface{}); !ok { + return data, errors.New("Value is not map ") + } + } + if len(data) == 0 { + return data, fmt.Errorf("ecs invocation %s is not exist ", id) + } + + // 处理 launch_time、recurrence_end_time 传参与查询结果不一致的问题 + if mode := resourceData.Get("repeat_mode"); mode.(string) == "Rate" { + layout := "2006-01-02T15:04:05Z" + launchTimeExpr, exist1 := resourceData.GetOkExists("launch_time") + endTimeExpr, exist2 := resourceData.GetOkExists("recurrence_end_time") + if !exist1 || !exist2 { + return data, fmt.Errorf(" launch_time or recurrence_end_time is not exist ") + } + launchTime, err := ParseUTCTime(launchTimeExpr.(string)) + if err != nil { + return data, err + } + endTime, err := ParseUTCTime(endTimeExpr.(string)) + if err != nil { + return data, err + } + lt := launchTime.Format(layout) + et := endTime.Format(layout) + if lt == data["LaunchTime"].(string) { + data["LaunchTime"] = launchTimeExpr + } + if et == data["RecurrenceEndTime"].(string) { + data["RecurrenceEndTime"] = endTimeExpr + } + } + + return data, err +} + +func ParseUTCTime(timeExpr string) (time.Time, error) { + timeWithoutSecond, err := ParseUTCTimeWithoutSecond(timeExpr) + if err != nil { + timeWithSecond, err := ParseUTCTimeWithSecond(timeExpr) + if err != nil { + return time.Time{}, err + } else { + return timeWithSecond, nil + } + } else { + return timeWithoutSecond, nil + } +} + +func ParseUTCTimeWithoutSecond(timeExpr string) (time.Time, error) { + t, err := time.Parse("2006-01-02T15:04Z", timeExpr) + if err != nil { + return time.Time{}, fmt.Errorf("parse time failed, error: %v, time expr: %v", err, timeExpr) + } + + return t, nil +} + +func ParseUTCTimeWithSecond(timeExpr string) (time.Time, error) { + t, err := time.Parse("2006-01-02T15:04:05Z", timeExpr) + if err != nil { + return time.Time{}, fmt.Errorf("parse time failed, error: %v, time expr: %v", err, timeExpr) + } + + t = t.Add(time.Duration(t.Second()) * time.Second * -1) + + return t, nil +} + +func (s *VolcengineEcsInvocationService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return &resource.StateChangeConf{ + Pending: []string{}, + Delay: 1 * time.Second, + MinTimeout: 1 * time.Second, + Target: target, + Timeout: timeout, + Refresh: func() (result interface{}, state string, err error) { + var ( + demo map[string]interface{} + status interface{} + ) + //no failed status. + demo, err = s.ReadResource(resourceData, id) + if err != nil { + return nil, "", err + } + status, err = ve.ObtainSdkValue("InvocationStatus", demo) + if err != nil { + return nil, "", err + } + return demo, status.(string), err + }, + } +} + +func (VolcengineEcsInvocationService) WithResourceResponseHandlers(invocation map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return invocation, nil, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcengineEcsInvocationService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "InvokeCommand", + ConvertMode: ve.RequestConvertAll, + ContentType: ve.ContentTypeDefault, + Convert: map[string]ve.RequestConvert{ + "instance_ids": { + TargetField: "InstanceIds", + ConvertType: ve.ConvertWithN, + }, + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + resp, err := s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + logger.Debug(logger.RespFormat, call.Action, resp, err) + return resp, err + }, + AfterCall: func(d *schema.ResourceData, client *ve.SdkClient, resp *map[string]interface{}, call ve.SdkCall) error { + id, _ := ve.ObtainSdkValue("Result.InvocationId", *resp) + d.SetId(id.(string)) + return nil + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcengineEcsInvocationService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcengineEcsInvocationService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + callback := ve.Callback{ + Call: ve.SdkCall{ + Action: "StopInvocation", + ConvertMode: ve.RequestConvertIgnore, + ContentType: ve.ContentTypeDefault, + SdkParam: &map[string]interface{}{ + "InvocationId": resourceData.Id(), + }, + BeforeCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (bool, error) { + status := d.Get("invocation_status") + mode := d.Get("repeat_mode") + if mode.(string) == "Once" || (status.(string) != "Pending" && status.(string) != "Scheduled") { + return false, nil + } else { + (*call.SdkParam)["InvocationId"] = d.Id() + return true, nil + } + }, + ExecuteCall: func(d *schema.ResourceData, client *ve.SdkClient, call ve.SdkCall) (*map[string]interface{}, error) { + logger.Debug(logger.RespFormat, call.Action, call.SdkParam) + return s.Client.UniversalClient.DoCall(getUniversalInfo(call.Action), call.SdkParam) + }, + Refresh: &ve.StateRefresh{ + Target: []string{"Stopped"}, + Timeout: resourceData.Timeout(schema.TimeoutDelete), + }, + }, + } + return []ve.Callback{callback} +} + +func (s *VolcengineEcsInvocationService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + NameField: "InvocationName", + IdField: "InvocationId", + CollectField: "invocations", + ResponseConverts: map[string]ve.ResponseConvert{ + "InvocationId": { + TargetField: "id", + KeepDefault: true, + }, + }, + } +} + +func (s *VolcengineEcsInvocationService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "ecs", + Version: "2020-04-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} diff --git a/volcengine/provider.go b/volcengine/provider.go index 81501ab4..9489cb26 100644 --- a/volcengine/provider.go +++ b/volcengine/provider.go @@ -79,10 +79,12 @@ import ( "github.com/volcengine/terraform-provider-volcengine/volcengine/cr/cr_vpc_endpoint" "github.com/volcengine/terraform-provider-volcengine/volcengine/ebs/volume" "github.com/volcengine/terraform-provider-volcengine/volcengine/ebs/volume_attach" + "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_command" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_deployment_set" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_deployment_set_associate" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_instance" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_instance_state" + "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_invocation" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_key_pair" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_key_pair_associate" "github.com/volcengine/terraform-provider-volcengine/volcengine/ecs/ecs_launch_template" @@ -266,6 +268,8 @@ func Provider() terraform.ResourceProvider { "volcengine_ecs_deployment_sets": ecs_deployment_set.DataSourceVolcengineEcsDeploymentSets(), "volcengine_ecs_key_pairs": ecs_key_pair.DataSourceVolcengineEcsKeyPairs(), "volcengine_ecs_launch_templates": ecs_launch_template.DataSourceVolcengineEcsLaunchTemplates(), + "volcengine_ecs_commands": ecs_command.DataSourceVolcengineEcsCommands(), + "volcengine_ecs_invocations": ecs_invocation.DataSourceVolcengineEcsInvocations(), // ================ NAT ================ "volcengine_snat_entries": snat_entry.DataSourceVolcengineSnatEntries(), @@ -441,6 +445,8 @@ func Provider() terraform.ResourceProvider { "volcengine_ecs_key_pair": ecs_key_pair.ResourceVolcengineEcsKeyPair(), "volcengine_ecs_key_pair_associate": ecs_key_pair_associate.ResourceVolcengineEcsKeyPairAssociate(), "volcengine_ecs_launch_template": ecs_launch_template.ResourceVolcengineEcsLaunchTemplate(), + "volcengine_ecs_command": ecs_command.ResourceVolcengineEcsCommand(), + "volcengine_ecs_invocation": ecs_invocation.ResourceVolcengineEcsInvocation(), // ================ NAT ================ "volcengine_snat_entry": snat_entry.ResourceVolcengineSnatEntry(), From a0ae1cd792dd2c2c15acb8fa8573e51acc0eab02 Mon Sep 17 00:00:00 2001 From: "maoshuai.17" Date: Sun, 25 Jun 2023 14:08:36 +0800 Subject: [PATCH 2/7] feat: add ecs invocation results --- example/dataEcsInvocationResults/main.tf | 4 + example/dataEcsInvocations/main.tf | 1 + .../data_source_volcengine_ecs_commands.go | 2 +- .../resource_volcengine_ecs_command.go | 2 +- .../data_source_volcengine_ecs_invocations.go | 18 ++- .../resource_volcengine_ecs_invocation.go | 2 +- .../service_volcengine_ecs_invocation.go | 20 +++ ...ource_volcengine_ecs_invocation_results.go | 131 ++++++++++++++++ ...ervice_volcengine_ecs_invocation_result.go | 140 ++++++++++++++++++ 9 files changed, 310 insertions(+), 10 deletions(-) create mode 100644 example/dataEcsInvocationResults/main.tf create mode 100644 volcengine/ecs/ecs_invocation_result/data_source_volcengine_ecs_invocation_results.go create mode 100644 volcengine/ecs/ecs_invocation_result/service_volcengine_ecs_invocation_result.go diff --git a/example/dataEcsInvocationResults/main.tf b/example/dataEcsInvocationResults/main.tf new file mode 100644 index 00000000..3b191b16 --- /dev/null +++ b/example/dataEcsInvocationResults/main.tf @@ -0,0 +1,4 @@ +data "volcengine_ecs_invocation_results" "default" { + invocation_id = "ivk-ych9y4vujvl8j01c****" + invocation_result_status = ["Success"] +} \ No newline at end of file diff --git a/example/dataEcsInvocations/main.tf b/example/dataEcsInvocations/main.tf index 295eb905..f9f225ed 100644 --- a/example/dataEcsInvocations/main.tf +++ b/example/dataEcsInvocations/main.tf @@ -1,3 +1,4 @@ data "volcengine_ecs_invocations" "default" { invocation_id = "ivk-ych9y4vujvl8j01c****" + invocation_status = ["Success"] } \ No newline at end of file diff --git a/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go b/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go index d46fd228..cb216b6f 100644 --- a/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go +++ b/volcengine/ecs/ecs_command/data_source_volcengine_ecs_commands.go @@ -100,7 +100,7 @@ func DataSourceVolcengineEcsCommands() *schema.Resource { "username": { Type: schema.TypeString, Computed: true, - Description: "The user name of the ecs command.", + Description: "The username of the ecs command.", }, "description": { Type: schema.TypeString, diff --git a/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go b/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go index ae9bd287..db5f132e 100644 --- a/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go +++ b/volcengine/ecs/ecs_command/resource_volcengine_ecs_command.go @@ -60,7 +60,7 @@ func ResourceVolcengineEcsCommand() *schema.Resource { Type: schema.TypeString, Optional: true, Computed: true, - Description: "The user name of the ecs command.", + Description: "The username of the ecs command.", }, "timeout": { Type: schema.TypeInt, diff --git a/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go b/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go index 49a640ae..f449bc42 100644 --- a/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go +++ b/volcengine/ecs/ecs_invocation/data_source_volcengine_ecs_invocations.go @@ -46,13 +46,17 @@ func DataSourceVolcengineEcsInvocations() *schema.Resource { Description: "The repeat mode of ecs invocation. Valid values: `Once`, `Rate`, `Fixed`.", }, "invocation_status": { - Type: schema.TypeString, + Type: schema.TypeSet, Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - "Pending", "Scheduled", "Running", "Success", - "Failed", "Stopped", "PartialFailed", "Finished", - }, false), - Description: "The status of ecs invocation. Valid values: `Pending`, `Scheduled`, `Running`, `Success`, `Failed`, `Stopped`, `PartialFailed`, `Finished`.", + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "Pending", "Scheduled", "Running", "Success", + "Failed", "Stopped", "PartialFailed", "Finished", + }, false), + }, + Set: schema.HashString, + Description: "The list of status of ecs invocation. Valid values: `Pending`, `Scheduled`, `Running`, `Success`, `Failed`, `Stopped`, `PartialFailed`, `Finished`.", }, "name_regex": { Type: schema.TypeString, @@ -144,7 +148,7 @@ func DataSourceVolcengineEcsInvocations() *schema.Resource { "username": { Type: schema.TypeString, Computed: true, - Description: "The user name of the ecs command.", + Description: "The username of the ecs command.", }, "start_time": { Type: schema.TypeString, diff --git a/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go b/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go index 7e96cd24..8d6eb13a 100644 --- a/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go +++ b/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go @@ -64,7 +64,7 @@ func ResourceVolcengineEcsInvocation() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: true, - Description: "The user name of the ecs command. When this field is not specified, use the value of the field with the same name in ecs command as the default value.", + Description: "The username of the ecs command. When this field is not specified, use the value of the field with the same name in ecs command as the default value.", }, "working_dir": { Type: schema.TypeString, diff --git a/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go b/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go index 7ddf8c5c..ee6ab449 100644 --- a/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go +++ b/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "time" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" @@ -289,6 +290,25 @@ func (s *VolcengineEcsInvocationService) RemoveResource(resourceData *schema.Res func (s *VolcengineEcsInvocationService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "invocation_status": { + TargetField: "InvocationStatus", + Convert: func(data *schema.ResourceData, i interface{}) interface{} { + var status string + statusSet, ok := data.GetOk("invocation_status") + if !ok { + return status + } + statusList := statusSet.(*schema.Set).List() + statusArr := make([]string, 0) + for _, value := range statusList { + statusArr = append(statusArr, value.(string)) + } + status = strings.Join(statusArr, ",") + return status + }, + }, + }, NameField: "InvocationName", IdField: "InvocationId", CollectField: "invocations", diff --git a/volcengine/ecs/ecs_invocation_result/data_source_volcengine_ecs_invocation_results.go b/volcengine/ecs/ecs_invocation_result/data_source_volcengine_ecs_invocation_results.go new file mode 100644 index 00000000..702b1d62 --- /dev/null +++ b/volcengine/ecs/ecs_invocation_result/data_source_volcengine_ecs_invocation_results.go @@ -0,0 +1,131 @@ +package ecs_invocation_result + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + ve "github.com/volcengine/terraform-provider-volcengine/common" +) + +func DataSourceVolcengineEcsInvocationResults() *schema.Resource { + return &schema.Resource{ + Read: dataSourceVolcengineEcsInvocationResultsRead, + Schema: map[string]*schema.Schema{ + "invocation_id": { + Type: schema.TypeString, + Required: true, + Description: "The id of ecs invocation.", + }, + "instance_id": { + Type: schema.TypeString, + Optional: true, + Description: "The id of ecs instance.", + }, + "command_id": { + Type: schema.TypeString, + Optional: true, + Description: "The id of ecs command.", + }, + "invocation_result_status": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + "Pending", "Running", "Success", "Failed", "Timeout", + }, false), + }, + Set: schema.HashString, + Description: "The list of status of ecs invocation in a single instance. Valid values: `Pending`, `Running`, `Success`, `Failed`, `Timeout`.", + }, + "output_file": { + Type: schema.TypeString, + Optional: true, + Description: "File name where to save data source results.", + }, + "total_count": { + Type: schema.TypeInt, + Computed: true, + Description: "The total count of query.", + }, + "invocation_results": { + Description: "The collection of query.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs invocation result.", + }, + "invocation_result_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs invocation result.", + }, + "invocation_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs invocation.", + }, + "instance_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs instance.", + }, + "command_id": { + Type: schema.TypeString, + Computed: true, + Description: "The id of the ecs command.", + }, + "invocation_result_status": { + Type: schema.TypeString, + Computed: true, + Description: "The status of ecs invocation in a single instance.", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "The username of the ecs command.", + }, + "output": { + Type: schema.TypeString, + Computed: true, + Description: "The base64 encoded output message of the ecs invocation. ", + }, + "exit_code": { + Type: schema.TypeInt, + Computed: true, + Description: "The exit code of the ecs command.", + }, + "error_code": { + Type: schema.TypeString, + Computed: true, + Description: "The error code of the ecs invocation.", + }, + "error_message": { + Type: schema.TypeString, + Computed: true, + Description: "The error message of the ecs invocation.", + }, + "start_time": { + Type: schema.TypeString, + Computed: true, + Description: "The start time of the ecs invocation in the instance.", + }, + "end_time": { + Type: schema.TypeString, + Computed: true, + Description: "The end time of the ecs invocation in the instance.", + }, + }, + }, + }, + }, + } +} + +func dataSourceVolcengineEcsInvocationResultsRead(d *schema.ResourceData, meta interface{}) error { + service := NewEcsInvocationResultService(meta.(*ve.SdkClient)) + return ve.DefaultDispatcher().Data(service, d, DataSourceVolcengineEcsInvocationResults()) +} diff --git a/volcengine/ecs/ecs_invocation_result/service_volcengine_ecs_invocation_result.go b/volcengine/ecs/ecs_invocation_result/service_volcengine_ecs_invocation_result.go new file mode 100644 index 00000000..749071c9 --- /dev/null +++ b/volcengine/ecs/ecs_invocation_result/service_volcengine_ecs_invocation_result.go @@ -0,0 +1,140 @@ +package ecs_invocation_result + +import ( + "encoding/json" + "errors" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + ve "github.com/volcengine/terraform-provider-volcengine/common" + "github.com/volcengine/terraform-provider-volcengine/logger" +) + +type VolcengineEcsInvocationResultService struct { + Client *ve.SdkClient + Dispatcher *ve.Dispatcher +} + +func NewEcsInvocationResultService(c *ve.SdkClient) *VolcengineEcsInvocationResultService { + return &VolcengineEcsInvocationResultService{ + Client: c, + Dispatcher: &ve.Dispatcher{}, + } +} + +func (s *VolcengineEcsInvocationResultService) GetClient() *ve.SdkClient { + return s.Client +} + +func (s *VolcengineEcsInvocationResultService) ReadResources(m map[string]interface{}) (data []interface{}, err error) { + var ( + resp *map[string]interface{} + results interface{} + ok bool + ) + return ve.WithPageNumberQuery(m, "PageSize", "PageNumber", 20, 1, func(condition map[string]interface{}) ([]interface{}, error) { + action := "DescribeInvocationResults" + bytes, _ := json.Marshal(condition) + logger.Debug(logger.ReqFormat, action, string(bytes)) + if condition == nil { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), nil) + if err != nil { + return data, err + } + } else { + resp, err = s.Client.UniversalClient.DoCall(getUniversalInfo(action), &condition) + if err != nil { + return data, err + } + } + respBytes, _ := json.Marshal(resp) + logger.Debug(logger.RespFormat, action, condition, string(respBytes)) + results, err = ve.ObtainSdkValue("Result.InvocationResults", *resp) + if err != nil { + return data, err + } + if results == nil { + results = []interface{}{} + } + if data, ok = results.([]interface{}); !ok { + return data, errors.New("Result.InvocationResults is not Slice") + } + + return data, err + }) +} + +func (s *VolcengineEcsInvocationResultService) ReadResource(resourceData *schema.ResourceData, id string) (data map[string]interface{}, err error) { + return data, err +} + +func (s *VolcengineEcsInvocationResultService) RefreshResourceState(resourceData *schema.ResourceData, target []string, timeout time.Duration, id string) *resource.StateChangeConf { + return nil +} + +func (VolcengineEcsInvocationResultService) WithResourceResponseHandlers(data map[string]interface{}) []ve.ResourceResponseHandler { + handler := func() (map[string]interface{}, map[string]ve.ResponseConvert, error) { + return data, nil, nil + } + return []ve.ResourceResponseHandler{handler} +} + +func (s *VolcengineEcsInvocationResultService) CreateResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcengineEcsInvocationResultService) ModifyResource(resourceData *schema.ResourceData, resource *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcengineEcsInvocationResultService) RemoveResource(resourceData *schema.ResourceData, r *schema.Resource) []ve.Callback { + return []ve.Callback{} +} + +func (s *VolcengineEcsInvocationResultService) DatasourceResources(*schema.ResourceData, *schema.Resource) ve.DataSourceInfo { + return ve.DataSourceInfo{ + RequestConverts: map[string]ve.RequestConvert{ + "invocation_result_status": { + TargetField: "InvocationResultStatus", + Convert: func(data *schema.ResourceData, i interface{}) interface{} { + var status string + statusSet, ok := data.GetOk("invocation_result_status") + if !ok { + return status + } + statusList := statusSet.(*schema.Set).List() + statusArr := make([]string, 0) + for _, value := range statusList { + statusArr = append(statusArr, value.(string)) + } + status = strings.Join(statusArr, ",") + return status + }, + }, + }, + IdField: "InvocationResultId", + CollectField: "invocation_results", + ResponseConverts: map[string]ve.ResponseConvert{ + "InvocationResultId": { + TargetField: "id", + KeepDefault: true, + }, + }, + } +} + +func (s *VolcengineEcsInvocationResultService) ReadResourceId(id string) string { + return id +} + +func getUniversalInfo(actionName string) ve.UniversalInfo { + return ve.UniversalInfo{ + ServiceName: "ecs", + Version: "2020-04-01", + HttpMethod: ve.GET, + ContentType: ve.Default, + Action: actionName, + } +} From caae795494450157a0cc45ff30f7d556fc24a3a2 Mon Sep 17 00:00:00 2001 From: "maoshuai.17" Date: Tue, 11 Jul 2023 11:53:36 +0800 Subject: [PATCH 3/7] feat: opt invocation frequency --- example/ecsInvocation/main.tf | 1 - .../resource_volcengine_ecs_invocation.go | 20 +++++----- .../service_volcengine_ecs_invocation.go | 37 ++++++++++--------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/example/ecsInvocation/main.tf b/example/ecsInvocation/main.tf index 3ce3f4e9..b35075c1 100644 --- a/example/ecsInvocation/main.tf +++ b/example/ecsInvocation/main.tf @@ -7,7 +7,6 @@ resource "volcengine_ecs_invocation" "foo" { timeout = 90 working_dir = "/home" repeat_mode = "Rate" -# frequency = "2023-06-20T08:28:00Z" frequency = "5m" launch_time = "2023-06-20T09:48:00Z" recurrence_end_time = "2023-06-20T09:59:00Z" diff --git a/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go b/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go index 8d6eb13a..74c6e8fe 100644 --- a/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go +++ b/volcengine/ecs/ecs_invocation/resource_volcengine_ecs_invocation.go @@ -98,30 +98,28 @@ func ResourceVolcengineEcsInvocation() *schema.Resource { Optional: true, ForceNew: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if d.Get("repeat_mode").(string) == "Once" { - return true + if d.Get("repeat_mode").(string) == "Rate" { + return false } - return false + return true }, - Description: "The frequency of the ecs invocation. This field is valid when the value of the repeat_mode field is `Rate` or `Fixed`.", + Description: "The frequency of the ecs invocation. This field is valid and required when the value of the repeat_mode field is `Rate`.", }, "launch_time": { Type: schema.TypeString, Optional: true, - Computed: true, ForceNew: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if d.Get("repeat_mode").(string) == "Rate" { - return false + if d.Get("repeat_mode").(string) == "Once" { + return true } - return true + return false }, - Description: "The launch time of the ecs invocation. RFC3339 format. This field is valid when the value of the repeat_mode field is `Rate`.", + Description: "The launch time of the ecs invocation. RFC3339 format. This field is valid and required when the value of the repeat_mode field is `Rate` or `Fixed`.", }, "recurrence_end_time": { Type: schema.TypeString, Optional: true, - Computed: true, ForceNew: true, DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { if d.Get("repeat_mode").(string) == "Rate" { @@ -129,7 +127,7 @@ func ResourceVolcengineEcsInvocation() *schema.Resource { } return true }, - Description: "The recurrence end time of the ecs invocation. RFC3339 format. This field is valid when the value of the repeat_mode field is `Rate`.", + Description: "The recurrence end time of the ecs invocation. RFC3339 format. This field is valid and required when the value of the repeat_mode field is `Rate`.", }, "invocation_status": { diff --git a/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go b/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go index ee6ab449..0f74fafa 100644 --- a/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go +++ b/volcengine/ecs/ecs_invocation/service_volcengine_ecs_invocation.go @@ -129,28 +129,29 @@ func (s *VolcengineEcsInvocationService) ReadResource(resourceData *schema.Resou } // 处理 launch_time、recurrence_end_time 传参与查询结果不一致的问题 - if mode := resourceData.Get("repeat_mode"); mode.(string) == "Rate" { + if mode := resourceData.Get("repeat_mode"); mode.(string) != "Once" { layout := "2006-01-02T15:04:05Z" launchTimeExpr, exist1 := resourceData.GetOkExists("launch_time") endTimeExpr, exist2 := resourceData.GetOkExists("recurrence_end_time") - if !exist1 || !exist2 { - return data, fmt.Errorf(" launch_time or recurrence_end_time is not exist ") - } - launchTime, err := ParseUTCTime(launchTimeExpr.(string)) - if err != nil { - return data, err - } - endTime, err := ParseUTCTime(endTimeExpr.(string)) - if err != nil { - return data, err - } - lt := launchTime.Format(layout) - et := endTime.Format(layout) - if lt == data["LaunchTime"].(string) { - data["LaunchTime"] = launchTimeExpr + if exist1 && launchTimeExpr.(string) != "" { + launchTime, err := ParseUTCTime(launchTimeExpr.(string)) + if err != nil { + return data, err + } + lt := launchTime.Format(layout) + if lt == data["LaunchTime"].(string) { + data["LaunchTime"] = launchTimeExpr + } } - if et == data["RecurrenceEndTime"].(string) { - data["RecurrenceEndTime"] = endTimeExpr + if exist2 && endTimeExpr.(string) != "" { + endTime, err := ParseUTCTime(endTimeExpr.(string)) + if err != nil { + return data, err + } + et := endTime.Format(layout) + if et == data["RecurrenceEndTime"].(string) { + data["RecurrenceEndTime"] = endTimeExpr + } } } From 174f611f123e533211754a54d86769c045e75edc Mon Sep 17 00:00:00 2001 From: "maoshuai.17" Date: Wed, 30 Aug 2023 15:13:05 +0800 Subject: [PATCH 4/7] feat: update docs and version --- common/common_volcengine_version.go | 2 +- website/docs/d/ecs_commands.html.markdown | 45 ++++++++++++++++ website/docs/d/ecs_invocations.html.markdown | 57 ++++++++++++++++++++ website/docs/r/ecs_command.html.markdown | 44 +++++++++++++++ website/docs/r/ecs_invocation.html.markdown | 54 +++++++++++++++++++ website/volcengine.erb | 12 +++++ 6 files changed, 213 insertions(+), 1 deletion(-) create mode 100644 website/docs/d/ecs_commands.html.markdown create mode 100644 website/docs/d/ecs_invocations.html.markdown create mode 100644 website/docs/r/ecs_command.html.markdown create mode 100644 website/docs/r/ecs_invocation.html.markdown diff --git a/common/common_volcengine_version.go b/common/common_volcengine_version.go index 1144af1c..1f4be772 100644 --- a/common/common_volcengine_version.go +++ b/common/common_volcengine_version.go @@ -2,5 +2,5 @@ package common const ( TerraformProviderName = "terraform-provider-volcengine" - TerraformProviderVersion = "0.0.105" + TerraformProviderVersion = "0.0.106" ) diff --git a/website/docs/d/ecs_commands.html.markdown b/website/docs/d/ecs_commands.html.markdown new file mode 100644 index 00000000..eb102684 --- /dev/null +++ b/website/docs/d/ecs_commands.html.markdown @@ -0,0 +1,45 @@ +--- +subcategory: "ECS" +layout: "volcengine" +page_title: "Volcengine: volcengine_ecs_commands" +sidebar_current: "docs-volcengine-datasource-ecs_commands" +description: |- + Use this data source to query detailed information of ecs commands +--- +# volcengine_ecs_commands +Use this data source to query detailed information of ecs commands +## Example Usage +```hcl +data "volcengine_ecs_commands" "default" { + command_id = "cmd-ychkepkhtim0tr3b****" +} +``` +## Argument Reference +The following arguments are supported: +* `command_id` - (Optional) The id of ecs command. +* `command_provider` - (Optional) The provider of public command. When this field is not specified, query for custom commands. +* `name_regex` - (Optional) A Name Regex of Resource. +* `name` - (Optional) The name of ecs command. This field support fuzzy query. +* `order` - (Optional) The order of ecs command query result. +* `output_file` - (Optional) File name where to save data source results. +* `type` - (Optional) The type of ecs command. Valid values: `Shell`. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `commands` - The collection of query. + * `command_content` - The base64 encoded content of the ecs command. + * `command_id` - The id of the ecs command. + * `command_provider` - The provider of the public command. + * `created_at` - The create time of the ecs command. + * `description` - The description of the ecs command. + * `id` - The id of the ecs command. + * `invocation_times` - The invocation times of the ecs command. Public commands do not display the invocation times. + * `name` - The name of the ecs command. + * `timeout` - The timeout of the ecs command. + * `type` - The type of the ecs command. + * `updated_at` - The update time of the ecs command. + * `username` - The username of the ecs command. + * `working_dir` - The working directory of the ecs command. +* `total_count` - The total count of query. + + diff --git a/website/docs/d/ecs_invocations.html.markdown b/website/docs/d/ecs_invocations.html.markdown new file mode 100644 index 00000000..af40fef5 --- /dev/null +++ b/website/docs/d/ecs_invocations.html.markdown @@ -0,0 +1,57 @@ +--- +subcategory: "ECS" +layout: "volcengine" +page_title: "Volcengine: volcengine_ecs_invocations" +sidebar_current: "docs-volcengine-datasource-ecs_invocations" +description: |- + Use this data source to query detailed information of ecs invocations +--- +# volcengine_ecs_invocations +Use this data source to query detailed information of ecs invocations +## Example Usage +```hcl +data "volcengine_ecs_invocations" "default" { + invocation_id = "ivk-ych9y4vujvl8j01c****" + invocation_status = ["Success"] +} +``` +## Argument Reference +The following arguments are supported: +* `command_id` - (Optional) The id of ecs command. +* `command_name` - (Optional) The name of ecs command. This field support fuzzy query. +* `command_type` - (Optional) The type of ecs command. Valid values: `Shell`. +* `invocation_id` - (Optional) The id of ecs invocation. +* `invocation_name` - (Optional) The name of ecs invocation. This field support fuzzy query. +* `invocation_status` - (Optional) The list of status of ecs invocation. Valid values: `Pending`, `Scheduled`, `Running`, `Success`, `Failed`, `Stopped`, `PartialFailed`, `Finished`. +* `name_regex` - (Optional) A Name Regex of Resource. +* `output_file` - (Optional) File name where to save data source results. +* `repeat_mode` - (Optional) The repeat mode of ecs invocation. Valid values: `Once`, `Rate`, `Fixed`. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `invocations` - The collection of query. + * `command_content` - The base64 encoded content of the ecs command. + * `command_description` - The description of the ecs command. + * `command_id` - The id of the ecs command. + * `command_name` - The name of the ecs command. + * `command_provider` - The provider of the ecs command. + * `command_type` - The type of the ecs command. + * `end_time` - The end time of the ecs invocation. + * `frequency` - The frequency of the ecs invocation. + * `id` - The id of the ecs invocation. + * `instance_ids` - The list of ECS instance IDs. + * `instance_number` - The instance number of the ecs invocation. + * `invocation_description` - The description of the ecs invocation. + * `invocation_id` - The id of the ecs invocation. + * `invocation_name` - The name of the ecs invocation. + * `invocation_status` - The status of the ecs invocation. + * `launch_time` - The launch time of the ecs invocation. + * `recurrence_end_time` - The recurrence end time of the ecs invocation. + * `repeat_mode` - The repeat mode of the ecs invocation. + * `start_time` - The start time of the ecs invocation. + * `timeout` - The timeout of the ecs command. + * `username` - The username of the ecs command. + * `working_dir` - The working directory of the ecs command. +* `total_count` - The total count of query. + + diff --git a/website/docs/r/ecs_command.html.markdown b/website/docs/r/ecs_command.html.markdown new file mode 100644 index 00000000..280b690d --- /dev/null +++ b/website/docs/r/ecs_command.html.markdown @@ -0,0 +1,44 @@ +--- +subcategory: "ECS" +layout: "volcengine" +page_title: "Volcengine: volcengine_ecs_command" +sidebar_current: "docs-volcengine-resource-ecs_command" +description: |- + Provides a resource to manage ecs command +--- +# volcengine_ecs_command +Provides a resource to manage ecs command +## Example Usage +```hcl +resource "volcengine_ecs_command" "foo" { + name = "tf-test" + description = "tf" + working_dir = "/home" + username = "root" + timeout = 100 + command_content = "IyEvYmluL2Jhc2gKCgplY2hvICJvcGVyYXRpb24gc3VjY2VzcyEi" +} +``` +## Argument Reference +The following arguments are supported: +* `command_content` - (Required) The base64 encoded content of the ecs command. +* `name` - (Required) The name of the ecs command. +* `description` - (Optional) The description of the ecs command. +* `timeout` - (Optional) The timeout of the ecs command. Valid value range: 10-600. +* `username` - (Optional) The username of the ecs command. +* `working_dir` - (Optional) The working directory of the ecs command. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. +* `created_at` - The create time of the ecs command. +* `invocation_times` - The invocation times of the ecs command. Public commands do not display the invocation times. +* `updated_at` - The update time of the ecs command. + + +## Import +EcsCommand can be imported using the id, e.g. +``` +$ terraform import volcengine_ecs_command.default cmd-ychkepkhtim0tr3bcsw1 +``` + diff --git a/website/docs/r/ecs_invocation.html.markdown b/website/docs/r/ecs_invocation.html.markdown new file mode 100644 index 00000000..821ea2af --- /dev/null +++ b/website/docs/r/ecs_invocation.html.markdown @@ -0,0 +1,54 @@ +--- +subcategory: "ECS" +layout: "volcengine" +page_title: "Volcengine: volcengine_ecs_invocation" +sidebar_current: "docs-volcengine-resource-ecs_invocation" +description: |- + Provides a resource to manage ecs invocation +--- +# volcengine_ecs_invocation +Provides a resource to manage ecs invocation +## Example Usage +```hcl +resource "volcengine_ecs_invocation" "foo" { + command_id = "cmd-ychkepkhtim0tr3b****" + instance_ids = ["i-ychmz92487l8j00o****"] + invocation_name = "tf-test" + invocation_description = "tf" + username = "root" + timeout = 90 + working_dir = "/home" + repeat_mode = "Rate" + frequency = "5m" + launch_time = "2023-06-20T09:48:00Z" + recurrence_end_time = "2023-06-20T09:59:00Z" +} +``` +## Argument Reference +The following arguments are supported: +* `command_id` - (Required, ForceNew) The command id of the ecs invocation. +* `instance_ids` - (Required, ForceNew) The list of ECS instance IDs. +* `invocation_name` - (Required, ForceNew) The name of the ecs invocation. +* `username` - (Required, ForceNew) The username of the ecs command. When this field is not specified, use the value of the field with the same name in ecs command as the default value. +* `frequency` - (Optional, ForceNew) The frequency of the ecs invocation. This field is valid and required when the value of the repeat_mode field is `Rate`. +* `invocation_description` - (Optional, ForceNew) The description of the ecs invocation. +* `launch_time` - (Optional, ForceNew) The launch time of the ecs invocation. RFC3339 format. This field is valid and required when the value of the repeat_mode field is `Rate` or `Fixed`. +* `recurrence_end_time` - (Optional, ForceNew) The recurrence end time of the ecs invocation. RFC3339 format. This field is valid and required when the value of the repeat_mode field is `Rate`. +* `repeat_mode` - (Optional, ForceNew) The repeat mode of the ecs invocation. Valid values: `Once`, `Rate`, `Fixed`. +* `timeout` - (Optional, ForceNew) The timeout of the ecs command. Valid value range: 10-600. When this field is not specified, use the value of the field with the same name in ecs command as the default value. +* `working_dir` - (Optional, ForceNew) The working directory of the ecs invocation. When this field is not specified, use the value of the field with the same name in ecs command as the default value. + +## Attributes Reference +In addition to all arguments above, the following attributes are exported: +* `id` - ID of the resource. +* `end_time` - The end time of the ecs invocation. +* `invocation_status` - The status of the ecs invocation. +* `start_time` - The start time of the ecs invocation. + + +## Import +EcsInvocation can be imported using the id, e.g. +``` +$ terraform import volcengine_ecs_invocation.default ivk-ychnxnm45dl8j0mm**** +``` + diff --git a/website/volcengine.erb b/website/volcengine.erb index cc8663ae..6b5a7e14 100644 --- a/website/volcengine.erb +++ b/website/volcengine.erb @@ -340,12 +340,18 @@
  • Data Sources