diff --git a/.goreleaser.yml b/.goreleaser.yml index d2bed25..280ae29 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -57,5 +57,3 @@ release: name_template: "{{ .ProjectName }}_{{ .Version }}_manifest.json" # If you want to manually examine the release before its live, uncomment this line: # draft: true -changelog: - skip: true diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 05e9046..c627188 100755 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -3,8 +3,8 @@ id: 5a857039-7f4b-42d5-86fd-449767242ed2 management: docChecksum: 8a2ff4be25db818a35891d602baa4a25 docVersion: 1.0.0 - speakeasyVersion: 1.303.0 - generationVersion: 2.339.1 + speakeasyVersion: 1.303.4 + generationVersion: 2.340.2 releaseVersion: 0.8.2 configChecksum: 7ce13d26abba12900e05100bdca957a2 repoURL: https://github.com/epilot-dev/terraform-provider-epilot-workflow.git @@ -21,7 +21,7 @@ features: unions: 2.85.0 terraform: additionalDependencies: 0.1.0 - core: 3.21.2 + core: 3.21.3 deprecations: 2.81.1 globalSecurity: 2.81.6 globalServerURLs: 2.82.1 diff --git a/examples/resources/epilot-workflow_workflow_definition/resource.tf b/examples/resources/epilot-workflow_workflow_definition/resource.tf new file mode 100644 index 0000000..3405316 --- /dev/null +++ b/examples/resources/epilot-workflow_workflow_definition/resource.tf @@ -0,0 +1,22 @@ +terraform { + required_providers { + epilot-workflow = { + source = "epilot-dev/epilot-workflow" + version = "1.0.1" + } + + } +} + +provider "epilot-workflow" { + # Configuration options + bearer_auth = var.bearer_auth +} + +variable "bearer_auth" { + type = string +} + +resource "epilot-workflow_workflow_definition" "my_workflowdefinition" { + +} \ No newline at end of file diff --git a/internal/provider/workflowdefinition_data_source.go b/internal/provider/workflowdefinition_data_source.go new file mode 100644 index 0000000..5b63484 --- /dev/null +++ b/internal/provider/workflowdefinition_data_source.go @@ -0,0 +1,579 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + tfTypes "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/provider/types" + "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/sdk" + "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/sdk/models/operations" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure provider defined types fully satisfy framework interfaces. +var _ datasource.DataSource = &WorkflowDefinitionDataSource{} +var _ datasource.DataSourceWithConfigure = &WorkflowDefinitionDataSource{} + +func NewWorkflowDefinitionDataSource() datasource.DataSource { + return &WorkflowDefinitionDataSource{} +} + +// WorkflowDefinitionDataSource is the data source implementation. +type WorkflowDefinitionDataSource struct { + client *sdk.SDK +} + +// WorkflowDefinitionDataSourceModel describes the data model. +type WorkflowDefinitionDataSourceModel struct { + AssignedTo []types.String `tfsdk:"assigned_to"` + ClosingReasons []tfTypes.ClosingReasonID `tfsdk:"closing_reasons"` + CreationTime types.String `tfsdk:"creation_time"` + Description types.String `tfsdk:"description"` + DueDate types.String `tfsdk:"due_date"` + DynamicDueDate *tfTypes.DynamicDueDate `tfsdk:"dynamic_due_date"` + EnableECPWorkflow types.Bool `tfsdk:"enable_ecp_workflow"` + Flow []tfTypes.Flow `tfsdk:"flow"` + ID types.String `tfsdk:"id"` + LastUpdateTime types.String `tfsdk:"last_update_time"` + Name types.String `tfsdk:"name"` + UpdateEntityAttributes []tfTypes.UpdateEntityAttributes `tfsdk:"update_entity_attributes"` + UserIds []types.Number `tfsdk:"user_ids"` +} + +// Metadata returns the data source type name. +func (r *WorkflowDefinitionDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_workflow_definition" +} + +// Schema defines the schema for the data source. +func (r *WorkflowDefinitionDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "WorkflowDefinition DataSource", + + Attributes: map[string]schema.Attribute{ + "assigned_to": schema.ListAttribute{ + Computed: true, + ElementType: types.StringType, + }, + "closing_reasons": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + }, + }, + }, + "creation_time": schema.StringAttribute{ + Computed: true, + Description: `ISO String Date & Time`, + }, + "description": schema.StringAttribute{ + Computed: true, + }, + "due_date": schema.StringAttribute{ + Computed: true, + }, + "dynamic_due_date": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "action_type_condition": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["WORKFLOW_STARTED", "STEP_CLOSED"]`, + }, + "number_of_units": schema.NumberAttribute{ + Computed: true, + }, + "step_id": schema.StringAttribute{ + Computed: true, + }, + "time_period": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["days", "weeks", "months"]`, + }, + }, + Description: `set a Duedate for a step then a specific`, + }, + "enable_ecp_workflow": schema.BoolAttribute{ + Computed: true, + Description: `Indicates whether this workflow is available for End Customer Portal or not. By default it's not.`, + }, + "flow": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "section": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "order": schema.NumberAttribute{ + Computed: true, + }, + "steps": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "assigned_to": schema.ListAttribute{ + Computed: true, + ElementType: types.StringType, + }, + "automation_config": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "flow_id": schema.StringAttribute{ + Computed: true, + Description: `Id of the configured automation to run`, + }, + }, + }, + "description": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Computed: true, + }, + "value": schema.StringAttribute{ + Computed: true, + }, + }, + Description: `Longer information regarding Task`, + }, + "due_date": schema.StringAttribute{ + Computed: true, + }, + "dynamic_due_date": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "action_type_condition": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["WORKFLOW_STARTED", "STEP_CLOSED"]`, + }, + "number_of_units": schema.NumberAttribute{ + Computed: true, + }, + "step_id": schema.StringAttribute{ + Computed: true, + }, + "time_period": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["days", "weeks", "months"]`, + }, + }, + Description: `set a Duedate for a step then a specific`, + }, + "ecp": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "execution_type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["MANUAL", "AUTOMATION"]`, + }, + "id": schema.StringAttribute{ + Computed: true, + }, + "installer": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "order": schema.NumberAttribute{ + Computed: true, + }, + "requirements": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "condition": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["CLOSED"]`, + }, + "definition_id": schema.StringAttribute{ + Computed: true, + }, + "type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["STEP", "SECTION"]`, + }, + }, + }, + Description: `requirements that need to be fulfilled in order to enable the step execution`, + }, + "type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["STEP", "SECTION"]`, + }, + "user_ids": schema.ListAttribute{ + Computed: true, + ElementType: types.NumberType, + Description: `This field is deprecated. Please use assignedTo`, + }, + }, + }, + }, + "type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["STEP", "SECTION"]`, + }, + }, + Description: `A group of Steps that define the progress of the Workflow`, + }, + "step": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "assigned_to": schema.ListAttribute{ + Computed: true, + ElementType: types.StringType, + }, + "automation_config": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "flow_id": schema.StringAttribute{ + Computed: true, + Description: `Id of the configured automation to run`, + }, + }, + }, + "description": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Computed: true, + }, + "value": schema.StringAttribute{ + Computed: true, + }, + }, + Description: `Longer information regarding Task`, + }, + "due_date": schema.StringAttribute{ + Computed: true, + }, + "dynamic_due_date": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "action_type_condition": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["WORKFLOW_STARTED", "STEP_CLOSED"]`, + }, + "number_of_units": schema.NumberAttribute{ + Computed: true, + }, + "step_id": schema.StringAttribute{ + Computed: true, + }, + "time_period": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["days", "weeks", "months"]`, + }, + }, + Description: `set a Duedate for a step then a specific`, + }, + "ecp": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "execution_type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["MANUAL", "AUTOMATION"]`, + }, + "id": schema.StringAttribute{ + Computed: true, + }, + "installer": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "order": schema.NumberAttribute{ + Computed: true, + }, + "requirements": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "condition": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["CLOSED"]`, + }, + "definition_id": schema.StringAttribute{ + Computed: true, + }, + "type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["STEP", "SECTION"]`, + }, + }, + }, + Description: `requirements that need to be fulfilled in order to enable the step execution`, + }, + "type": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["STEP", "SECTION"]`, + }, + "user_ids": schema.ListAttribute{ + Computed: true, + ElementType: types.NumberType, + Description: `This field is deprecated. Please use assignedTo`, + }, + }, + Description: `Action that needs to be done in a Workflow`, + }, + }, + }, + }, + "id": schema.StringAttribute{ + Required: true, + Description: `Short uuid (length 8) to identify the Workflow Definition.`, + }, + "last_update_time": schema.StringAttribute{ + Computed: true, + Description: `ISO String Date & Time`, + }, + "name": schema.StringAttribute{ + Computed: true, + }, + "update_entity_attributes": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "source": schema.StringAttribute{ + Computed: true, + Description: `must be one of ["workflow_status", "current_section", "current_step"]`, + }, + "target": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "entity_attribute": schema.StringAttribute{ + Computed: true, + }, + "entity_schema": schema.StringAttribute{ + Computed: true, + }, + }, + }, + }, + }, + }, + "user_ids": schema.ListAttribute{ + Computed: true, + ElementType: types.NumberType, + Description: `This field is deprecated. Please use assignedTo`, + }, + }, + } +} + +func (r *WorkflowDefinitionDataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*sdk.SDK) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected DataSource Configure Type", + fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = client +} + +func (r *WorkflowDefinitionDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data *WorkflowDefinitionDataSourceModel + var item types.Object + + resp.Diagnostics.Append(req.Config.Get(ctx, &item)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + + if resp.Diagnostics.HasError() { + return + } + + definitionID := data.ID.ValueString() + request := operations.GetDefinitionRequest{ + DefinitionID: definitionID, + } + res, err := r.client.Workflows.GetDefinition(ctx, request) + if err != nil { + resp.Diagnostics.AddError("failure to invoke API", err.Error()) + if res != nil && res.RawResponse != nil { + resp.Diagnostics.AddError("unexpected http request/response", debugResponse(res.RawResponse)) + } + return + } + if res == nil { + resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) + return + } + if res.StatusCode == 404 { + resp.State.RemoveResource(ctx) + return + } + if res.StatusCode != 200 { + resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) + return + } + if !(res.WorkflowDefinition != nil) { + resp.Diagnostics.AddError("unexpected response from API. Got an unexpected response body", debugResponse(res.RawResponse)) + return + } + data.RefreshFromSharedWorkflowDefinition(res.WorkflowDefinition) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/internal/provider/workflowdefinition_resource.go b/internal/provider/workflowdefinition_resource.go new file mode 100644 index 0000000..f83992b --- /dev/null +++ b/internal/provider/workflowdefinition_resource.go @@ -0,0 +1,1029 @@ +// Code generated by Speakeasy (https://speakeasyapi.dev). DO NOT EDIT. + +package provider + +import ( + "context" + "fmt" + tfTypes "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/provider/types" + "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/sdk" + "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/sdk/models/operations" + "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/validators" + speakeasy_listvalidators "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/validators/listvalidators" + speakeasy_numbervalidators "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/validators/numbervalidators" + speakeasy_objectvalidators "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/validators/objectvalidators" + speakeasy_stringvalidators "github.com/epilot-dev/terraform-provider-epilot-workflow/internal/validators/stringvalidators" + "github.com/hashicorp/terraform-plugin-framework-validators/objectvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure provider defined types fully satisfy framework interfaces. +var _ resource.Resource = &WorkflowDefinitionResource{} +var _ resource.ResourceWithImportState = &WorkflowDefinitionResource{} + +func NewWorkflowDefinitionResource() resource.Resource { + return &WorkflowDefinitionResource{} +} + +// WorkflowDefinitionResource defines the resource implementation. +type WorkflowDefinitionResource struct { + client *sdk.SDK +} + +// WorkflowDefinitionResourceModel describes the resource data model. +type WorkflowDefinitionResourceModel struct { + AssignedTo []types.String `tfsdk:"assigned_to"` + ClosingReasons []tfTypes.ClosingReasonID `tfsdk:"closing_reasons"` + CreationTime types.String `tfsdk:"creation_time"` + Description types.String `tfsdk:"description"` + DueDate types.String `tfsdk:"due_date"` + DynamicDueDate *tfTypes.DynamicDueDate `tfsdk:"dynamic_due_date"` + EnableECPWorkflow types.Bool `tfsdk:"enable_ecp_workflow"` + Flow []tfTypes.Flow `tfsdk:"flow"` + ID types.String `tfsdk:"id"` + LastUpdateTime types.String `tfsdk:"last_update_time"` + Name types.String `tfsdk:"name"` + UpdateEntityAttributes []tfTypes.UpdateEntityAttributes `tfsdk:"update_entity_attributes"` + UserIds []types.Number `tfsdk:"user_ids"` +} + +func (r *WorkflowDefinitionResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_workflow_definition" +} + +func (r *WorkflowDefinitionResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + MarkdownDescription: "WorkflowDefinition Resource", + Attributes: map[string]schema.Attribute{ + "assigned_to": schema.ListAttribute{ + Computed: true, + Optional: true, + ElementType: types.StringType, + }, + "closing_reasons": schema.ListNestedAttribute{ + Computed: true, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + }, + }, + }, + "creation_time": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `ISO String Date & Time`, + }, + "description": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "due_date": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "dynamic_due_date": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "action_type_condition": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["WORKFLOW_STARTED", "STEP_CLOSED"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "WORKFLOW_STARTED", + "STEP_CLOSED", + ), + }, + }, + "number_of_units": schema.NumberAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.Number{ + speakeasy_numbervalidators.NotNull(), + }, + }, + "step_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "time_period": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["days", "weeks", "months"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "days", + "weeks", + "months", + ), + }, + }, + }, + Description: `set a Duedate for a step then a specific`, + }, + "enable_ecp_workflow": schema.BoolAttribute{ + Computed: true, + Optional: true, + Description: `Indicates whether this workflow is available for End Customer Portal or not. By default it's not.`, + }, + "flow": schema.ListNestedAttribute{ + Required: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "section": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + "order": schema.NumberAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.Number{ + speakeasy_numbervalidators.NotNull(), + }, + }, + "steps": schema.ListNestedAttribute{ + Computed: true, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "assigned_to": schema.ListAttribute{ + Computed: true, + Optional: true, + ElementType: types.StringType, + }, + "automation_config": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "flow_id": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Id of the configured automation to run. Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + }, + }, + "description": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Computed: true, + Optional: true, + }, + "value": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + Description: `Longer information regarding Task`, + }, + "due_date": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "dynamic_due_date": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "action_type_condition": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["WORKFLOW_STARTED", "STEP_CLOSED"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "WORKFLOW_STARTED", + "STEP_CLOSED", + ), + }, + }, + "number_of_units": schema.NumberAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.Number{ + speakeasy_numbervalidators.NotNull(), + }, + }, + "step_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "time_period": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["days", "weeks", "months"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "days", + "weeks", + "months", + ), + }, + }, + }, + Description: `set a Duedate for a step then a specific`, + }, + "ecp": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + Optional: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "execution_type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `must be one of ["MANUAL", "AUTOMATION"]`, + Validators: []validator.String{ + stringvalidator.OneOf( + "MANUAL", + "AUTOMATION", + ), + }, + }, + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "installer": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + Optional: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + "order": schema.NumberAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.Number{ + speakeasy_numbervalidators.NotNull(), + }, + }, + "requirements": schema.ListNestedAttribute{ + Computed: true, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "condition": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["CLOSED"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "CLOSED", + ), + }, + }, + "definition_id": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + "type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["STEP", "SECTION"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "STEP", + "SECTION", + ), + }, + }, + }, + }, + Description: `requirements that need to be fulfilled in order to enable the step execution`, + }, + "type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["STEP", "SECTION"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "STEP", + "SECTION", + ), + }, + }, + "user_ids": schema.ListAttribute{ + Computed: true, + Optional: true, + ElementType: types.NumberType, + Description: `This field is deprecated. Please use assignedTo`, + }, + }, + }, + Description: `Not Null`, + Validators: []validator.List{ + speakeasy_listvalidators.NotNull(), + }, + }, + "type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["STEP", "SECTION"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "STEP", + "SECTION", + ), + }, + }, + }, + Description: `A group of Steps that define the progress of the Workflow`, + Validators: []validator.Object{ + objectvalidator.ConflictsWith(path.Expressions{ + path.MatchRelative().AtParent().AtName("step"), + }...), + }, + }, + "step": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "assigned_to": schema.ListAttribute{ + Computed: true, + Optional: true, + ElementType: types.StringType, + }, + "automation_config": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "flow_id": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Id of the configured automation to run. Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + }, + }, + "description": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "enabled": schema.BoolAttribute{ + Computed: true, + Optional: true, + }, + "value": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + Description: `Longer information regarding Task`, + }, + "due_date": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "dynamic_due_date": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "action_type_condition": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["WORKFLOW_STARTED", "STEP_CLOSED"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "WORKFLOW_STARTED", + "STEP_CLOSED", + ), + }, + }, + "number_of_units": schema.NumberAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.Number{ + speakeasy_numbervalidators.NotNull(), + }, + }, + "step_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "time_period": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["days", "weeks", "months"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "days", + "weeks", + "months", + ), + }, + }, + }, + Description: `set a Duedate for a step then a specific`, + }, + "ecp": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + Optional: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "execution_type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `must be one of ["MANUAL", "AUTOMATION"]`, + Validators: []validator.String{ + stringvalidator.OneOf( + "MANUAL", + "AUTOMATION", + ), + }, + }, + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "installer": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "enabled": schema.BoolAttribute{ + Computed: true, + Optional: true, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + }, + "label": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + Description: `Details regarding ECP for the workflow step`, + }, + "journey": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "journey_id": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + }, + }, + }, + "name": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + "order": schema.NumberAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.Number{ + speakeasy_numbervalidators.NotNull(), + }, + }, + "requirements": schema.ListNestedAttribute{ + Computed: true, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "condition": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["CLOSED"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "CLOSED", + ), + }, + }, + "definition_id": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + "type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["STEP", "SECTION"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "STEP", + "SECTION", + ), + }, + }, + }, + }, + Description: `requirements that need to be fulfilled in order to enable the step execution`, + }, + "type": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["STEP", "SECTION"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "STEP", + "SECTION", + ), + }, + }, + "user_ids": schema.ListAttribute{ + Computed: true, + Optional: true, + ElementType: types.NumberType, + Description: `This field is deprecated. Please use assignedTo`, + }, + }, + Description: `Action that needs to be done in a Workflow`, + Validators: []validator.Object{ + objectvalidator.ConflictsWith(path.Expressions{ + path.MatchRelative().AtParent().AtName("section"), + }...), + }, + }, + }, + Validators: []validator.Object{ + validators.ExactlyOneChild(), + }, + }, + }, + "id": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Id of the definition to de deleted.`, + }, + "last_update_time": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `ISO String Date & Time`, + }, + "name": schema.StringAttribute{ + Required: true, + }, + "update_entity_attributes": schema.ListNestedAttribute{ + Computed: true, + Optional: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "source": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null; must be one of ["workflow_status", "current_section", "current_step"]`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + stringvalidator.OneOf( + "workflow_status", + "current_section", + "current_step", + ), + }, + }, + "target": schema.SingleNestedAttribute{ + Computed: true, + Optional: true, + Attributes: map[string]schema.Attribute{ + "entity_attribute": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + "entity_schema": schema.StringAttribute{ + Computed: true, + Optional: true, + Description: `Not Null`, + Validators: []validator.String{ + speakeasy_stringvalidators.NotNull(), + }, + }, + }, + Description: `Not Null`, + Validators: []validator.Object{ + speakeasy_objectvalidators.NotNull(), + }, + }, + }, + }, + }, + "user_ids": schema.ListAttribute{ + Computed: true, + Optional: true, + ElementType: types.NumberType, + Description: `This field is deprecated. Please use assignedTo`, + }, + }, + } +} + +func (r *WorkflowDefinitionResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + // Prevent panic if the provider has not been configured. + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*sdk.SDK) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *sdk.SDK, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + r.client = client +} + +func (r *WorkflowDefinitionResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data *WorkflowDefinitionResourceModel + var plan types.Object + + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(plan.As(ctx, &data, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + + if resp.Diagnostics.HasError() { + return + } + + request := *data.ToSharedWorkflowDefinition() + res, err := r.client.Workflows.CreateDefinition(ctx, request) + if err != nil { + resp.Diagnostics.AddError("failure to invoke API", err.Error()) + if res != nil && res.RawResponse != nil { + resp.Diagnostics.AddError("unexpected http request/response", debugResponse(res.RawResponse)) + } + return + } + if res == nil { + resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) + return + } + if res.StatusCode != 200 { + resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) + return + } + if !(res.WorkflowDefinition != nil) { + resp.Diagnostics.AddError("unexpected response from API. Got an unexpected response body", debugResponse(res.RawResponse)) + return + } + data.RefreshFromSharedWorkflowDefinition(res.WorkflowDefinition) + refreshPlan(ctx, plan, &data, resp.Diagnostics) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *WorkflowDefinitionResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var data *WorkflowDefinitionResourceModel + var item types.Object + + resp.Diagnostics.Append(req.State.Get(ctx, &item)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + + if resp.Diagnostics.HasError() { + return + } + + definitionID := data.ID.ValueString() + request := operations.GetDefinitionRequest{ + DefinitionID: definitionID, + } + res, err := r.client.Workflows.GetDefinition(ctx, request) + if err != nil { + resp.Diagnostics.AddError("failure to invoke API", err.Error()) + if res != nil && res.RawResponse != nil { + resp.Diagnostics.AddError("unexpected http request/response", debugResponse(res.RawResponse)) + } + return + } + if res == nil { + resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) + return + } + if res.StatusCode == 404 { + resp.State.RemoveResource(ctx) + return + } + if res.StatusCode != 200 { + resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) + return + } + if !(res.WorkflowDefinition != nil) { + resp.Diagnostics.AddError("unexpected response from API. Got an unexpected response body", debugResponse(res.RawResponse)) + return + } + data.RefreshFromSharedWorkflowDefinition(res.WorkflowDefinition) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *WorkflowDefinitionResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var data *WorkflowDefinitionResourceModel + var plan types.Object + + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + merge(ctx, req, resp, &data) + if resp.Diagnostics.HasError() { + return + } + + workflowDefinition := *data.ToSharedWorkflowDefinition() + definitionID := data.ID.ValueString() + request := operations.UpdateDefinitionRequest{ + WorkflowDefinition: workflowDefinition, + DefinitionID: definitionID, + } + res, err := r.client.Workflows.UpdateDefinition(ctx, request) + if err != nil { + resp.Diagnostics.AddError("failure to invoke API", err.Error()) + if res != nil && res.RawResponse != nil { + resp.Diagnostics.AddError("unexpected http request/response", debugResponse(res.RawResponse)) + } + return + } + if res == nil { + resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) + return + } + if res.StatusCode != 200 { + resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) + return + } + if !(res.WorkflowDefinition != nil) { + resp.Diagnostics.AddError("unexpected response from API. Got an unexpected response body", debugResponse(res.RawResponse)) + return + } + data.RefreshFromSharedWorkflowDefinition(res.WorkflowDefinition) + refreshPlan(ctx, plan, &data, resp.Diagnostics) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *WorkflowDefinitionResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data *WorkflowDefinitionResourceModel + var item types.Object + + resp.Diagnostics.Append(req.State.Get(ctx, &item)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(item.As(ctx, &data, basetypes.ObjectAsOptions{ + UnhandledNullAsEmpty: true, + UnhandledUnknownAsEmpty: true, + })...) + + if resp.Diagnostics.HasError() { + return + } + + definitionID := data.ID.ValueString() + request := operations.DeleteDefinitionRequest{ + DefinitionID: definitionID, + } + res, err := r.client.Workflows.DeleteDefinition(ctx, request) + if err != nil { + resp.Diagnostics.AddError("failure to invoke API", err.Error()) + if res != nil && res.RawResponse != nil { + resp.Diagnostics.AddError("unexpected http request/response", debugResponse(res.RawResponse)) + } + return + } + if res == nil { + resp.Diagnostics.AddError("unexpected response from API", fmt.Sprintf("%v", res)) + return + } + if res.StatusCode != 204 { + resp.Diagnostics.AddError(fmt.Sprintf("unexpected response from API. Got an unexpected response code %v", res.StatusCode), debugResponse(res.RawResponse)) + return + } + +} + +func (r *WorkflowDefinitionResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), req.ID)...) +} diff --git a/internal/sdk/sdk.go b/internal/sdk/sdk.go index ede1e96..62c385c 100644 --- a/internal/sdk/sdk.go +++ b/internal/sdk/sdk.go @@ -137,8 +137,8 @@ func New(opts ...SDKOption) *SDK { Language: "go", OpenAPIDocVersion: "1.0.0", SDKVersion: "0.0.1", - GenVersion: "2.339.1", - UserAgent: "speakeasy-sdk/go 0.0.1 2.339.1 1.0.0 github.com/epilot-dev/terraform-provider-epilot-workflow/internal/sdk", + GenVersion: "2.340.2", + UserAgent: "speakeasy-sdk/go 0.0.1 2.340.2 1.0.0 github.com/epilot-dev/terraform-provider-epilot-workflow/internal/sdk", Hooks: hooks.New(), }, }