From f9fa39091521c1aefec1c3011f005075aac41dee Mon Sep 17 00:00:00 2001 From: diegoazion <114952459+diegoazion@users.noreply.github.com> Date: Wed, 5 Jul 2023 18:30:11 -0300 Subject: [PATCH] Feat edge application origins (#73) * feat: creating support to edge application Origins #minor * feat: doc supporting to edge application #minor --- .gitignore | 3 +- docs/data-sources/edge_application_origin.md | 72 +++ .../data-sources/edge_applications_origins.md | 83 +++ docs/resources/edge_application_origin.md | 104 +++ docs/resources/edge_function.md | 5 +- .../data-source.tf | 6 + .../data-source.tf | 3 + .../azion_edge_application_origin/import.sh | 1 + .../azion_edge_application_origin/resource.tf | 19 + internal/config.go | 20 +- ...a_source_edge_application_main_settings.go | 3 +- .../data_source_edge_application_origin.go | 257 ++++++++ ..._source_edge_applications_main_settings.go | 3 +- .../data_source_edge_applications_origins.go | 320 ++++++++++ internal/provider.go | 3 + internal/resource_edgeFunction.go | 5 + internal/resource_edge_application_origin.go | 599 ++++++++++++++++++ internal/resource_record.go | 25 +- internal/utils/utils.go | 22 + 19 files changed, 1517 insertions(+), 36 deletions(-) create mode 100644 docs/data-sources/edge_application_origin.md create mode 100644 docs/data-sources/edge_applications_origins.md create mode 100644 docs/resources/edge_application_origin.md create mode 100644 examples/data-sources/azion_edge_application_origin/data-source.tf create mode 100644 examples/data-sources/azion_edge_applications_origins/data-source.tf create mode 100644 examples/resources/azion_edge_application_origin/import.sh create mode 100644 examples/resources/azion_edge_application_origin/resource.tf create mode 100644 internal/data_source_edge_application_origin.go create mode 100644 internal/data_source_edge_applications_origins.go create mode 100644 internal/resource_edge_application_origin.go diff --git a/.gitignore b/.gitignore index 4b2e63b..b506e0e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ examples/.terraform.lock.hcl .terraform.* *.tfstate terraform.tfstate.backup -terraform-provider-azion \ No newline at end of file +terraform-provider-azion +/.idea/aws.xml diff --git a/docs/data-sources/edge_application_origin.md b/docs/data-sources/edge_application_origin.md new file mode 100644 index 0000000..9f27f32 --- /dev/null +++ b/docs/data-sources/edge_application_origin.md @@ -0,0 +1,72 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "azion_edge_application_origin Data Source - terraform-provider-azion" +subcategory: "" +description: |- + +--- + +# azion_edge_application_origin (Data Source) + + + +## Example Usage + +```terraform +data "azion_edge_application_origin" "example" { + edge_application_id = "" + origin = { + origin_key = "" + } +} +``` + + +## Schema + +### Required + +- `edge_application_id` (Number) The edge application identifier. +- `origin` (Attributes) (see [below for nested schema](#nestedatt--origin)) + +### Read-Only + +- `id` (String) Identifier of the data source. +- `schema_version` (Number) Schema Version. + + +### Nested Schema for `origin` + +Required: + +- `origin_key` (String) Origin key. + +Read-Only: + +- `addresses` (Attributes List) (see [below for nested schema](#nestedatt--origin--addresses)) +- `connection_timeout` (Number) Connection timeout in seconds. +- `hmac_access_key` (String) HMAC access key. +- `hmac_authentication` (Boolean) Whether HMAC authentication is enabled. +- `hmac_region_name` (String) HMAC region name. +- `hmac_secret_key` (String) HMAC secret key. +- `host_header` (String) Host header value. +- `is_origin_redirection_enabled` (Boolean) Whether origin redirection is enabled. +- `method` (String) HTTP method used by the origin. +- `name` (String) Name of the origin. +- `origin_id` (Number) The origin identifier to target for the resource. +- `origin_path` (String) Path of the origin. +- `origin_protocol_policy` (String) Origin protocol policy. +- `origin_type` (String) Type of the origin. +- `timeout_between_bytes` (Number) Timeout between bytes in seconds. + + +### Nested Schema for `origin.addresses` + +Read-Only: + +- `address` (String) Address of the origin. +- `is_active` (Boolean) Status of the origin. +- `server_role` (String) Server role of the origin. +- `weight` (String) Weight of the origin. + + diff --git a/docs/data-sources/edge_applications_origins.md b/docs/data-sources/edge_applications_origins.md new file mode 100644 index 0000000..6323bcb --- /dev/null +++ b/docs/data-sources/edge_applications_origins.md @@ -0,0 +1,83 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "azion_edge_applications_origins Data Source - terraform-provider-azion" +subcategory: "" +description: |- + +--- + +# azion_edge_applications_origins (Data Source) + + + +## Example Usage + +```terraform +data "azion_edge_applications_origins" "example" { + edge_application_id = "" +} +``` + + +## Schema + +### Required + +- `edge_application_id` (Number) The edge application identifier. + +### Optional + +- `page` (Number) The page number of edge applications. +- `page_size` (Number) The Page Size number of edge applications. + +### Read-Only + +- `counter` (Number) The total number of edge applications. +- `id` (String) Identifier of the data source. +- `links` (Attributes) (see [below for nested schema](#nestedatt--links)) +- `results` (Attributes List) (see [below for nested schema](#nestedatt--results)) +- `schema_version` (Number) Schema Version. +- `total_pages` (Number) The total number of pages. + + +### Nested Schema for `links` + +Read-Only: + +- `next` (String) +- `previous` (String) + + + +### Nested Schema for `results` + +Read-Only: + +- `addresses` (Attributes List) (see [below for nested schema](#nestedatt--results--addresses)) +- `connection_timeout` (Number) Connection timeout in seconds. +- `hmac_access_key` (String) HMAC access key. +- `hmac_authentication` (Boolean) Whether HMAC authentication is enabled. +- `hmac_region_name` (String) HMAC region name. +- `hmac_secret_key` (String) HMAC secret key. +- `host_header` (String) Host header value. +- `is_origin_redirection_enabled` (Boolean) Whether origin redirection is enabled. +- `method` (String) HTTP method used by the origin. +- `name` (String) Name of the origin. +- `origin_id` (Number) The origin identifier to target for the resource. +- `origin_key` (String) Origin key. +- `origin_path` (String) Path of the origin. +- `origin_protocol_policy` (String) Origin protocol policy. +- `origin_type` (String) Type of the origin. +- `timeout_between_bytes` (Number) Timeout between bytes in seconds. + + +### Nested Schema for `results.addresses` + +Read-Only: + +- `address` (String) Address of the origin. +- `is_active` (Boolean) Status of the origin. +- `server_role` (String) Server role of the origin. +- `weight` (String) Weight of the origin. + + diff --git a/docs/resources/edge_application_origin.md b/docs/resources/edge_application_origin.md new file mode 100644 index 0000000..58d4722 --- /dev/null +++ b/docs/resources/edge_application_origin.md @@ -0,0 +1,104 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "azion_edge_application_origin Resource - terraform-provider-azion" +subcategory: "" +description: |- + +--- + +# azion_edge_application_origin (Resource) + + + +## Example Usage + +```terraform +resource "azion_edge_application_origin" "example" { + edge_application_id = + origin = { + name = "Terraform Example" + origin_type = "single_origin" + addresses: [ + { + "address": "terraform.org" + } + ], + origin_protocol_policy: "http", + host_header: "$${host}", + origin_path: "/requests", + hmac_authentication: false, + hmac_region_name: "", + hmac_access_key: "", + hmac_secret_key: "" + } +} +``` + + +## Schema + +### Required + +- `edge_application_id` (Number) The edge application identifier. +- `origin` (Attributes) Origin configuration. (see [below for nested schema](#nestedatt--origin)) + +### Read-Only + +- `id` (String) The ID of this resource. +- `last_updated` (String) Timestamp of the last Terraform update of the resource. +- `schema_version` (Number) + + +### Nested Schema for `origin` + +Required: + +- `addresses` (Attributes List) (see [below for nested schema](#nestedatt--origin--addresses)) +- `host_header` (String) Host header value that will be delivered to the origin. +~> **Note about Host Header** +Accepted values: `${host}`(default) and must be specified with `$${host}` +- `name` (String) Origin name. + +Optional: + +- `connection_timeout` (Number) Connection timeout in seconds. +- `hmac_access_key` (String) HMAC access key. +- `hmac_authentication` (Boolean) Whether HMAC authentication is enabled. +- `hmac_region_name` (String) HMAC region name. +- `hmac_secret_key` (String) HMAC secret key. +- `origin_path` (String) Path of the origin. +- `origin_protocol_policy` (String) Protocols for connection to the origin. +~> **Note about Origin Protocol Policy** +Accepted values: `preserve`(default), `http` and `https` +- `origin_type` (String) Identifies the source of a record. +~> **Note about Origin Type** +Accepted values: `single_origin`(default), `load_balancer` and `live_ingest` +- `timeout_between_bytes` (Number) Timeout between bytes in seconds. + +Read-Only: + +- `is_origin_redirection_enabled` (Boolean) Whether origin redirection is enabled. +- `method` (String) HTTP method used by the origin. +- `origin_id` (Number) Origin identifier. +- `origin_key` (String) Origin key. + + +### Nested Schema for `origin.addresses` + +Required: + +- `address` (String) Address of the origin. + +Optional: + +- `is_active` (Boolean) Status of the origin. +- `server_role` (String) Server role of the origin. +- `weight` (String) Weight of the origin. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import azion_edge_application_origin.example / +``` diff --git a/docs/resources/edge_function.md b/docs/resources/edge_function.md index dca5b3f..e3a463a 100644 --- a/docs/resources/edge_function.md +++ b/docs/resources/edge_function.md @@ -3,7 +3,10 @@ page_title: "azion_edge_function Resource - terraform-provider-azion" subcategory: "" description: |- - + ~> Note about Json_Args + Parameter json_args must be specified with jsonencode function + ~> Note about Code + Parameter code may be specified with local_file in - https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file --- # azion_edge_function (Resource) diff --git a/examples/data-sources/azion_edge_application_origin/data-source.tf b/examples/data-sources/azion_edge_application_origin/data-source.tf new file mode 100644 index 0000000..8fee07a --- /dev/null +++ b/examples/data-sources/azion_edge_application_origin/data-source.tf @@ -0,0 +1,6 @@ +data "azion_edge_application_origin" "example" { + edge_application_id = "" + origin = { + origin_key = "" + } +} diff --git a/examples/data-sources/azion_edge_applications_origins/data-source.tf b/examples/data-sources/azion_edge_applications_origins/data-source.tf new file mode 100644 index 0000000..955a755 --- /dev/null +++ b/examples/data-sources/azion_edge_applications_origins/data-source.tf @@ -0,0 +1,3 @@ +data "azion_edge_applications_origins" "example" { + edge_application_id = "" +} \ No newline at end of file diff --git a/examples/resources/azion_edge_application_origin/import.sh b/examples/resources/azion_edge_application_origin/import.sh new file mode 100644 index 0000000..a48fa8d --- /dev/null +++ b/examples/resources/azion_edge_application_origin/import.sh @@ -0,0 +1 @@ +terraform import azion_edge_application_origin.example / \ No newline at end of file diff --git a/examples/resources/azion_edge_application_origin/resource.tf b/examples/resources/azion_edge_application_origin/resource.tf new file mode 100644 index 0000000..a9f9dd2 --- /dev/null +++ b/examples/resources/azion_edge_application_origin/resource.tf @@ -0,0 +1,19 @@ +resource "azion_edge_application_origin" "example" { + edge_application_id = + origin = { + name = "Terraform Example" + origin_type = "single_origin" + addresses: [ + { + "address": "terraform.org" + } + ], + origin_protocol_policy: "http", + host_header: "$${host}", + origin_path: "/requests", + hmac_authentication: false, + hmac_region_name: "", + hmac_access_key: "", + hmac_secret_key: "" + } +} \ No newline at end of file diff --git a/internal/config.go b/internal/config.go index 3ca2942..9678a82 100644 --- a/internal/config.go +++ b/internal/config.go @@ -19,16 +19,16 @@ type apiClient struct { edgefunctionsConfig *edgefunctions.Configuration edgefunctionsApi *edgefunctions.APIClient - edgeAplicationsConfig *edgeapplications.Configuration - edgeAplicationsApi *edgeapplications.APIClient + edgeApplicationsConfig *edgeapplications.Configuration + edgeApplicationsApi *edgeapplications.APIClient } func Client(APIToken string, userAgent string) *apiClient { client := &apiClient{ - idnsConfig: idns.NewConfiguration(), - domainsConfig: domains.NewConfiguration(), - edgefunctionsConfig: edgefunctions.NewConfiguration(), - edgeAplicationsConfig: edgeapplications.NewConfiguration(), + idnsConfig: idns.NewConfiguration(), + domainsConfig: domains.NewConfiguration(), + edgefunctionsConfig: edgefunctions.NewConfiguration(), + edgeApplicationsConfig: edgeapplications.NewConfiguration(), } envApiEntrypoint := os.Getenv("AZION_API_ENTRYPOINT") @@ -52,10 +52,10 @@ func Client(APIToken string, userAgent string) *apiClient { client.edgefunctionsConfig.UserAgent = userAgent client.edgefunctionsApi = edgefunctions.NewAPIClient(client.edgefunctionsConfig) - client.edgeAplicationsConfig.AddDefaultHeader("Authorization", "token "+APIToken) - client.edgeAplicationsConfig.AddDefaultHeader("Accept", "application/json; version=3") - client.edgeAplicationsConfig.UserAgent = userAgent - client.edgeAplicationsApi = edgeapplications.NewAPIClient(client.edgeAplicationsConfig) + client.edgeApplicationsConfig.AddDefaultHeader("Authorization", "token "+APIToken) + client.edgeApplicationsConfig.AddDefaultHeader("Accept", "application/json; version=3") + client.edgeApplicationsConfig.UserAgent = userAgent + client.edgeApplicationsApi = edgeapplications.NewAPIClient(client.edgeApplicationsConfig) return client } diff --git a/internal/data_source_edge_application_main_settings.go b/internal/data_source_edge_application_main_settings.go index 7c40b83..7fdf266 100644 --- a/internal/data_source_edge_application_main_settings.go +++ b/internal/data_source_edge_application_main_settings.go @@ -177,7 +177,8 @@ func (e *EdgeApplicationDataSource) Read(ctx context.Context, req datasource.Rea return } - edgeApplicationsResponse, response, err := e.client.edgeAplicationsApi.EdgeApplicationsMainSettingsApi.EdgeApplicationsIdGet(ctx, getEdgeApplicationId.ValueString()).Execute() + edgeApplicationsResponse, response, err := e.client.edgeApplicationsApi.EdgeApplicationsMainSettingsApi.EdgeApplicationsIdGet(ctx, getEdgeApplicationId.ValueString()).Execute() + if err != nil { bodyBytes, erro := io.ReadAll(response.Body) if erro != nil { diff --git a/internal/data_source_edge_application_origin.go b/internal/data_source_edge_application_origin.go new file mode 100644 index 0000000..18b3ec1 --- /dev/null +++ b/internal/data_source_edge_application_origin.go @@ -0,0 +1,257 @@ +package provider + +import ( + "context" + "io" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var ( + _ datasource.DataSource = &OriginDataSource{} + _ datasource.DataSourceWithConfigure = &OriginDataSource{} +) + +func dataSourceAzionEdgeApplicationOrigin() datasource.DataSource { + return &OriginDataSource{} +} + +type OriginDataSource struct { + client *apiClient +} + +type OriginDataSourceModel struct { + SchemaVersion types.Int64 `tfsdk:"schema_version"` + ID types.String `tfsdk:"id"` + ApplicationID types.Int64 `tfsdk:"edge_application_id"` + Results OriginResults `tfsdk:"origin"` +} + +type OriginResults struct { + OriginId types.Int64 `tfsdk:"origin_id"` + OriginKey types.String `tfsdk:"origin_key"` + Name types.String `tfsdk:"name"` + OriginType types.String `tfsdk:"origin_type"` + Addresses []OriginAddressResults `tfsdk:"addresses"` + OriginProtocolPolicy types.String `tfsdk:"origin_protocol_policy"` + IsOriginRedirectionEnabled types.Bool `tfsdk:"is_origin_redirection_enabled"` + HostHeader types.String `tfsdk:"host_header"` + Method types.String `tfsdk:"method"` + OriginPath types.String `tfsdk:"origin_path"` + ConnectionTimeout types.Int64 `tfsdk:"connection_timeout"` + TimeoutBetweenBytes types.Int64 `tfsdk:"timeout_between_bytes"` + HMACAuthentication types.Bool `tfsdk:"hmac_authentication"` + HMACRegionName types.String `tfsdk:"hmac_region_name"` + HMACAccessKey types.String `tfsdk:"hmac_access_key"` + HMACSecretKey types.String `tfsdk:"hmac_secret_key"` +} + +type OriginAddressResults struct { + Address types.String `tfsdk:"address"` + Weight types.String `tfsdk:"weight"` + ServerRole types.String `tfsdk:"server_role"` + IsActive types.Bool `tfsdk:"is_active"` +} + +func (o *OriginDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + o.client = req.ProviderData.(*apiClient) +} + +func (o *OriginDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_edge_application_origin" +} + +func (o *OriginDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "Identifier of the data source.", + Computed: true, + }, + "edge_application_id": schema.Int64Attribute{ + Description: "The edge application identifier.", + Required: true, + }, + "schema_version": schema.Int64Attribute{ + Description: "Schema Version.", + Computed: true, + }, + "origin": schema.SingleNestedAttribute{ + Required: true, + Attributes: map[string]schema.Attribute{ + "origin_id": schema.Int64Attribute{ + Description: "The origin identifier to target for the resource.", + Computed: true, + }, + "origin_key": schema.StringAttribute{ + Description: "Origin key.", + Required: true, + }, + "name": schema.StringAttribute{ + Description: "Name of the origin.", + Computed: true, + }, + "origin_type": schema.StringAttribute{ + Description: "Type of the origin.", + Computed: true, + }, + "addresses": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + Description: "Address of the origin.", + Computed: true, + }, + "weight": schema.StringAttribute{ + Description: "Weight of the origin.", + Computed: true, + }, + "server_role": schema.StringAttribute{ + Description: "Server role of the origin.", + Computed: true, + }, + "is_active": schema.BoolAttribute{ + Description: "Status of the origin.", + Computed: true, + }, + }, + }, + }, + "origin_protocol_policy": schema.StringAttribute{ + Description: "Origin protocol policy.", + Computed: true, + }, + "is_origin_redirection_enabled": schema.BoolAttribute{ + Description: "Whether origin redirection is enabled.", + Computed: true, + }, + "host_header": schema.StringAttribute{ + Description: "Host header value.", + Computed: true, + }, + "method": schema.StringAttribute{ + Description: "HTTP method used by the origin.", + Computed: true, + }, + "origin_path": schema.StringAttribute{ + Description: "Path of the origin.", + Computed: true, + }, + "connection_timeout": schema.Int64Attribute{ + Description: "Connection timeout in seconds.", + Computed: true, + }, + "timeout_between_bytes": schema.Int64Attribute{ + Description: "Timeout between bytes in seconds.", + Computed: true, + }, + "hmac_authentication": schema.BoolAttribute{ + Description: "Whether HMAC authentication is enabled.", + Computed: true, + }, + "hmac_region_name": schema.StringAttribute{ + Description: "HMAC region name.", + Computed: true, + }, + "hmac_access_key": schema.StringAttribute{ + Description: "HMAC access key.", + Computed: true, + }, + "hmac_secret_key": schema.StringAttribute{ + Description: "HMAC secret key.", + Computed: true, + }, + }, + }, + }, + } +} + +func (o *OriginDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var edgeApplicationID types.Int64 + var getOriginsKey types.String + diags := req.Config.GetAttribute(ctx, path.Root("origin").AtName("origin_key"), &getOriginsKey) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + if getOriginsKey.ValueString() == "" { + resp.Diagnostics.AddError( + "Edge Application ID error ", + "is not null", + ) + return + } + + diagsEdgeApplicationID := req.Config.GetAttribute(ctx, path.Root("edge_application_id"), &edgeApplicationID) + resp.Diagnostics.Append(diagsEdgeApplicationID...) + if resp.Diagnostics.HasError() { + return + } + + originResponse, response, err := o.client.edgeApplicationsApi.EdgeApplicationsOriginsApi.EdgeApplicationsEdgeApplicationIdOriginsOriginKeyGet(ctx, edgeApplicationID.ValueInt64(), getOriginsKey.ValueString()).Execute() + if err != nil { + bodyBytes, erro := io.ReadAll(response.Body) + if erro != nil { + resp.Diagnostics.AddError( + err.Error(), + "err", + ) + } + bodyString := string(bodyBytes) + resp.Diagnostics.AddError( + err.Error(), + bodyString, + ) + return + } + + var addresses []OriginAddressResults + for _, addr := range originResponse.Results.Addresses { + addresses = append(addresses, OriginAddressResults{ + Address: types.StringValue(addr.GetAddress()), + Weight: types.StringValue(addr.GetWeight()), + ServerRole: types.StringValue(addr.GetServerRole()), + IsActive: types.BoolValue(addr.GetIsActive()), + }) + } + + origin := OriginResults{ + OriginId: types.Int64Value(originResponse.Results.GetOriginId()), + OriginKey: types.StringValue(originResponse.Results.GetOriginKey()), + Name: types.StringValue(originResponse.Results.GetName()), + OriginType: types.StringValue(originResponse.Results.GetOriginType()), + Addresses: addresses, + OriginProtocolPolicy: types.StringValue(originResponse.Results.GetOriginProtocolPolicy()), + IsOriginRedirectionEnabled: types.BoolValue(originResponse.Results.GetIsOriginRedirectionEnabled()), + HostHeader: types.StringValue(originResponse.Results.GetHostHeader()), + Method: types.StringValue(originResponse.Results.GetMethod()), + OriginPath: types.StringValue(originResponse.Results.GetOriginPath()), + ConnectionTimeout: types.Int64Value(originResponse.Results.GetConnectionTimeout()), + TimeoutBetweenBytes: types.Int64Value(originResponse.Results.GetTimeoutBetweenBytes()), + HMACAuthentication: types.BoolValue(originResponse.Results.GetHmacAuthentication()), + HMACRegionName: types.StringValue(originResponse.Results.GetHmacRegionName()), + HMACAccessKey: types.StringValue(originResponse.Results.GetHmacAccessKey()), + HMACSecretKey: types.StringValue(originResponse.Results.GetHmacSecretKey()), + } + + edgeApplicationOriginState := OriginDataSourceModel{ + SchemaVersion: types.Int64Value(originResponse.SchemaVersion), + Results: origin, + } + + edgeApplicationOriginState.ID = types.StringValue("Get By Key Edge Application Origins") + diags = resp.State.Set(ctx, &edgeApplicationOriginState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} diff --git a/internal/data_source_edge_applications_main_settings.go b/internal/data_source_edge_applications_main_settings.go index f632494..85165be 100644 --- a/internal/data_source_edge_applications_main_settings.go +++ b/internal/data_source_edge_applications_main_settings.go @@ -181,7 +181,8 @@ func (e *EdgeApplicationsDataSource) Read(ctx context.Context, req datasource.Re PageSize = types.Int64Value(10) } - edgeAppResponse, response, err := e.client.edgeAplicationsApi.EdgeApplicationsMainSettingsApi.EdgeApplicationsGet(ctx).Page(Page.ValueInt64()).PageSize(PageSize.ValueInt64()).Execute() + edgeAppResponse, response, err := e.client.edgeApplicationsApi.EdgeApplicationsMainSettingsApi.EdgeApplicationsGet(ctx).Page(Page.ValueInt64()).PageSize(PageSize.ValueInt64()).Execute() + if err != nil { bodyBytes, erro := io.ReadAll(response.Body) if erro != nil { diff --git a/internal/data_source_edge_applications_origins.go b/internal/data_source_edge_applications_origins.go new file mode 100644 index 0000000..56c3e86 --- /dev/null +++ b/internal/data_source_edge_applications_origins.go @@ -0,0 +1,320 @@ +package provider + +import ( + "context" + "io" + + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +var ( + _ datasource.DataSource = &OriginsDataSource{} + _ datasource.DataSourceWithConfigure = &OriginsDataSource{} +) + +func dataSourceAzionEdgeApplicationsOrigins() datasource.DataSource { + return &OriginsDataSource{} +} + +type OriginsDataSource struct { + client *apiClient +} + +type OriginsDataSourceModel struct { + SchemaVersion types.Int64 `tfsdk:"schema_version"` + ID types.String `tfsdk:"id"` + ApplicationID types.Int64 `tfsdk:"edge_application_id"` + Counter types.Int64 `tfsdk:"counter"` + TotalPages types.Int64 `tfsdk:"total_pages"` + Page types.Int64 `tfsdk:"page"` + PageSize types.Int64 `tfsdk:"page_size"` + Links *GetEdgeAplicationsOriginsResponseLinks `tfsdk:"links"` + Results []OriginsResults `tfsdk:"results"` +} + +type GetEdgeAplicationsOriginsResponseLinks struct { + Previous types.String `tfsdk:"previous"` + Next types.String `tfsdk:"next"` +} + +type OriginsResults struct { + OriginId types.Int64 `tfsdk:"origin_id"` + OriginKey types.String `tfsdk:"origin_key"` + Name types.String `tfsdk:"name"` + OriginType types.String `tfsdk:"origin_type"` + Addresses []OriginsAddressResults `tfsdk:"addresses"` + OriginProtocolPolicy types.String `tfsdk:"origin_protocol_policy"` + IsOriginRedirectionEnabled types.Bool `tfsdk:"is_origin_redirection_enabled"` + HostHeader types.String `tfsdk:"host_header"` + Method types.String `tfsdk:"method"` + OriginPath types.String `tfsdk:"origin_path"` + ConnectionTimeout types.Int64 `tfsdk:"connection_timeout"` + TimeoutBetweenBytes types.Int64 `tfsdk:"timeout_between_bytes"` + HMACAuthentication types.Bool `tfsdk:"hmac_authentication"` + HMACRegionName types.String `tfsdk:"hmac_region_name"` + HMACAccessKey types.String `tfsdk:"hmac_access_key"` + HMACSecretKey types.String `tfsdk:"hmac_secret_key"` +} + +type OriginsAddressResults struct { + Address types.String `tfsdk:"address"` + Weight types.String `tfsdk:"weight"` + ServerRole types.String `tfsdk:"server_role"` + IsActive types.Bool `tfsdk:"is_active"` +} + +func (o *OriginsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, _ *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + o.client = req.ProviderData.(*apiClient) +} + +func (o *OriginsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_edge_applications_origins" +} + +func (o *OriginsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "Identifier of the data source.", + Computed: true, + }, + "edge_application_id": schema.Int64Attribute{ + Description: "The edge application identifier.", + Required: true, + }, + "counter": schema.Int64Attribute{ + Description: "The total number of edge applications.", + Computed: true, + }, + "page": schema.Int64Attribute{ + Description: "The page number of edge applications.", + Optional: true, + }, + "page_size": schema.Int64Attribute{ + Description: "The Page Size number of edge applications.", + Optional: true, + }, + "total_pages": schema.Int64Attribute{ + Description: "The total number of pages.", + Computed: true, + }, + "links": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "previous": schema.StringAttribute{ + Computed: true, + }, + "next": schema.StringAttribute{ + Computed: true, + }, + }, + }, + "schema_version": schema.Int64Attribute{ + Description: "Schema Version.", + Computed: true, + }, + "results": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "origin_id": schema.Int64Attribute{ + Description: "The origin identifier to target for the resource.", + Computed: true, + }, + "origin_key": schema.StringAttribute{ + Description: "Origin key.", + Computed: true, + }, + "name": schema.StringAttribute{ + Description: "Name of the origin.", + Computed: true, + }, + "origin_type": schema.StringAttribute{ + Description: "Type of the origin.", + Computed: true, + }, + "addresses": schema.ListNestedAttribute{ + Computed: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + Description: "Address of the origin.", + Computed: true, + }, + "weight": schema.StringAttribute{ + Description: "Weight of the origin.", + Computed: true, + }, + "server_role": schema.StringAttribute{ + Description: "Server role of the origin.", + Computed: true, + }, + "is_active": schema.BoolAttribute{ + Description: "Status of the origin.", + Computed: true, + }, + }, + }, + }, + "origin_protocol_policy": schema.StringAttribute{ + Description: "Origin protocol policy.", + Computed: true, + }, + "is_origin_redirection_enabled": schema.BoolAttribute{ + Description: "Whether origin redirection is enabled.", + Computed: true, + }, + "host_header": schema.StringAttribute{ + Description: "Host header value.", + Computed: true, + }, + "method": schema.StringAttribute{ + Description: "HTTP method used by the origin.", + Computed: true, + }, + "origin_path": schema.StringAttribute{ + Description: "Path of the origin.", + Computed: true, + }, + "connection_timeout": schema.Int64Attribute{ + Description: "Connection timeout in seconds.", + Computed: true, + }, + "timeout_between_bytes": schema.Int64Attribute{ + Description: "Timeout between bytes in seconds.", + Computed: true, + }, + "hmac_authentication": schema.BoolAttribute{ + Description: "Whether HMAC authentication is enabled.", + Computed: true, + }, + "hmac_region_name": schema.StringAttribute{ + Description: "HMAC region name.", + Computed: true, + }, + "hmac_access_key": schema.StringAttribute{ + Description: "HMAC access key.", + Computed: true, + }, + "hmac_secret_key": schema.StringAttribute{ + Description: "HMAC secret key.", + Computed: true, + }, + }, + }, + }, + }, + } +} + +func (o *OriginsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var edgeApplicationID types.Int64 + var Page types.Int64 + var PageSize types.Int64 + + diagsEdgeApplicationID := req.Config.GetAttribute(ctx, path.Root("edge_application_id"), &edgeApplicationID) + resp.Diagnostics.Append(diagsEdgeApplicationID...) + if resp.Diagnostics.HasError() { + return + } + + diagsPage := req.Config.GetAttribute(ctx, path.Root("page"), &Page) + resp.Diagnostics.Append(diagsPage...) + if resp.Diagnostics.HasError() { + return + } + + diagsPageSize := req.Config.GetAttribute(ctx, path.Root("page_size"), &PageSize) + resp.Diagnostics.Append(diagsPageSize...) + if resp.Diagnostics.HasError() { + return + } + + if Page.ValueInt64() == 0 { + Page = types.Int64Value(1) + } + if PageSize.ValueInt64() == 0 { + PageSize = types.Int64Value(10) + } + + originsResponse, response, err := o.client.edgeApplicationsApi.EdgeApplicationsOriginsApi.EdgeApplicationsEdgeApplicationIdOriginsGet(ctx, edgeApplicationID.ValueInt64()).Execute() + if err != nil { + bodyBytes, erro := io.ReadAll(response.Body) + if erro != nil { + resp.Diagnostics.AddError( + err.Error(), + "err", + ) + } + bodyString := string(bodyBytes) + resp.Diagnostics.AddError( + err.Error(), + bodyString, + ) + return + } + + var previous, next string + if originsResponse.Links.Previous.Get() != nil { + previous = *originsResponse.Links.Previous.Get() + } + if originsResponse.Links.Next.Get() != nil { + next = *originsResponse.Links.Next.Get() + } + + var origins []OriginsResults + for _, origin := range originsResponse.Results { + var addresses []OriginsAddressResults + for _, addr := range origin.Addresses { + addresses = append(addresses, OriginsAddressResults{ + Address: types.StringValue(addr.GetAddress()), + Weight: types.StringValue(addr.GetWeight()), + ServerRole: types.StringValue(addr.GetServerRole()), + IsActive: types.BoolValue(addr.GetIsActive()), + }) + } + + origins = append(origins, OriginsResults{ + OriginId: types.Int64Value(origin.GetOriginId()), + OriginKey: types.StringValue(origin.GetOriginKey()), + Name: types.StringValue(origin.GetName()), + OriginType: types.StringValue(origin.GetOriginType()), + Addresses: addresses, + OriginProtocolPolicy: types.StringValue(origin.GetOriginProtocolPolicy()), + IsOriginRedirectionEnabled: types.BoolValue(origin.GetIsOriginRedirectionEnabled()), + HostHeader: types.StringValue(origin.GetHostHeader()), + Method: types.StringValue(origin.GetMethod()), + OriginPath: types.StringValue(origin.GetOriginPath()), + ConnectionTimeout: types.Int64Value(origin.GetConnectionTimeout()), + TimeoutBetweenBytes: types.Int64Value(origin.GetTimeoutBetweenBytes()), + HMACAuthentication: types.BoolValue(origin.GetHmacAuthentication()), + HMACRegionName: types.StringValue(origin.GetHmacRegionName()), + HMACAccessKey: types.StringValue(origin.GetHmacAccessKey()), + HMACSecretKey: types.StringValue(origin.GetHmacSecretKey()), + }) + } + + edgeApplicationsOriginsState := OriginsDataSourceModel{ + SchemaVersion: types.Int64Value(originsResponse.SchemaVersion), + Results: origins, + TotalPages: types.Int64Value(originsResponse.TotalPages), + Counter: types.Int64Value(originsResponse.Count), + Links: &GetEdgeAplicationsOriginsResponseLinks{ + Previous: types.StringValue(previous), + Next: types.StringValue(next), + }, + } + + edgeApplicationsOriginsState.ID = types.StringValue("Get All Edge Application Origins") + diags := resp.State.Set(ctx, &edgeApplicationsOriginsState) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} diff --git a/internal/provider.go b/internal/provider.go index 96450db..dede4b3 100644 --- a/internal/provider.go +++ b/internal/provider.go @@ -89,6 +89,8 @@ func (p *azionProvider) DataSources(_ context.Context) []func() datasource.DataS dataSourceAzionEdgeFunction, dataSourceAzionEdgeApplications, dataSourceAzionEdgeApplication, + dataSourceAzionEdgeApplicationsOrigins, + dataSourceAzionEdgeApplicationOrigin, } } @@ -99,6 +101,7 @@ func (p *azionProvider) Resources(_ context.Context) []func() resource.Resource NewDnssecResource, NewDomainResource, NewEdgeFunctionResource, + NewEdgeApplicationOriginResource, } } diff --git a/internal/resource_edgeFunction.go b/internal/resource_edgeFunction.go index e1b9cc2..0da131d 100644 --- a/internal/resource_edgeFunction.go +++ b/internal/resource_edgeFunction.go @@ -59,6 +59,11 @@ func (r *edgeFunctionResource) Metadata(_ context.Context, req resource.Metadata func (r *edgeFunctionResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ + Description: "" + + "~> **Note about Json_Args**\n" + + "Parameter `json_args` must be specified with `jsonencode` function\n\n" + + "~> **Note about Code**\n" + + "Parameter `code` may be specified with local_file in - https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file", Attributes: map[string]schema.Attribute{ "id": schema.StringAttribute{ Computed: true, diff --git a/internal/resource_edge_application_origin.go b/internal/resource_edge_application_origin.go new file mode 100644 index 0000000..db6689f --- /dev/null +++ b/internal/resource_edge_application_origin.go @@ -0,0 +1,599 @@ +package provider + +import ( + "context" + "io" + "strconv" + "strings" + "time" + + "github.com/aziontech/azionapi-go-sdk/edgeapplications" + "github.com/aziontech/terraform-provider-azion/internal/utils" + "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/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +// Ensure the implementation satisfies the expected interfaces. +var ( + _ resource.Resource = &originResource{} + _ resource.ResourceWithConfigure = &originResource{} + _ resource.ResourceWithImportState = &originResource{} +) + +func NewEdgeApplicationOriginResource() resource.Resource { + return &originResource{} +} + +type originResource struct { + client *apiClient +} + +type OriginResourceModel struct { + SchemaVersion types.Int64 `tfsdk:"schema_version"` + Origin *OriginResourceResults `tfsdk:"origin"` + ID types.String `tfsdk:"id"` + ApplicationID types.Int64 `tfsdk:"edge_application_id"` + LastUpdated types.String `tfsdk:"last_updated"` +} + +type OriginResourceResults struct { + OriginID types.Int64 `tfsdk:"origin_id"` + OriginKey types.String `tfsdk:"origin_key"` + Name types.String `tfsdk:"name"` + OriginType types.String `tfsdk:"origin_type"` + Addresses []OriginAddress `tfsdk:"addresses"` + OriginProtocolPolicy types.String `tfsdk:"origin_protocol_policy"` + IsOriginRedirectionEnabled types.Bool `tfsdk:"is_origin_redirection_enabled"` + HostHeader types.String `tfsdk:"host_header"` + Method types.String `tfsdk:"method"` + OriginPath types.String `tfsdk:"origin_path"` + ConnectionTimeout types.Int64 `tfsdk:"connection_timeout"` + TimeoutBetweenBytes types.Int64 `tfsdk:"timeout_between_bytes"` + HMACAuthentication types.Bool `tfsdk:"hmac_authentication"` + HMACRegionName types.String `tfsdk:"hmac_region_name"` + HMACAccessKey types.String `tfsdk:"hmac_access_key"` + HMACSecretKey types.String `tfsdk:"hmac_secret_key"` +} + +type OriginAddress struct { + Address types.String `tfsdk:"address"` + Weight types.String `tfsdk:"weight"` + ServerRole types.String `tfsdk:"server_role"` + IsActive types.Bool `tfsdk:"is_active"` +} + +func (r *originResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_edge_application_origin" +} + +func (r *originResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "edge_application_id": schema.Int64Attribute{ + Description: "The edge application identifier.", + Required: true, + }, + "schema_version": schema.Int64Attribute{ + Computed: true, + }, + "last_updated": schema.StringAttribute{ + Description: "Timestamp of the last Terraform update of the resource.", + Computed: true, + }, + "origin": schema.SingleNestedAttribute{ + Description: "Origin configuration.", + Required: true, + Attributes: map[string]schema.Attribute{ + "origin_id": schema.Int64Attribute{ + Description: "Origin identifier.", + Computed: true, + }, + "origin_key": schema.StringAttribute{ + Description: "Origin key.", + Computed: true, + }, + "name": schema.StringAttribute{ + Description: "Origin name.", + Required: true, + }, + "origin_type": schema.StringAttribute{ + Description: "Identifies the source of a record.\n" + + "~> **Note about Origin Type**\n" + + "Accepted values: `single_origin`(default), `load_balancer` and `live_ingest`\n\n", + Optional: true, + Computed: true, + }, + "addresses": schema.ListNestedAttribute{ + Required: true, + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "address": schema.StringAttribute{ + Description: "Address of the origin.", + Required: true, + }, + "weight": schema.StringAttribute{ + Description: "Weight of the origin.", + Optional: true, + Computed: true, + }, + "server_role": schema.StringAttribute{ + Description: "Server role of the origin.", + Optional: true, + Computed: true, + }, + "is_active": schema.BoolAttribute{ + Description: "Status of the origin.", + Optional: true, + Computed: true, + }, + }, + }, + }, + "origin_protocol_policy": schema.StringAttribute{ + Description: "Protocols for connection to the origin.\n" + + "~> **Note about Origin Protocol Policy**\n" + + "Accepted values: `preserve`(default), `http` and `https`\n\n", + Optional: true, + Computed: true, + }, + "is_origin_redirection_enabled": schema.BoolAttribute{ + Description: "Whether origin redirection is enabled.", + Computed: true, + }, + "host_header": schema.StringAttribute{ + Description: "Host header value that will be delivered to the origin.\n" + + "~> **Note about Host Header**\n" + + "Accepted values: `${host}`(default) and must be specified with `$${host}`\n\n", + Required: true, + }, + "method": schema.StringAttribute{ + Description: "HTTP method used by the origin.", + Computed: true, + }, + "origin_path": schema.StringAttribute{ + Description: "Path of the origin.", + Optional: true, + Computed: true, + }, + "connection_timeout": schema.Int64Attribute{ + Description: "Connection timeout in seconds.", + Optional: true, + Computed: true, + }, + "timeout_between_bytes": schema.Int64Attribute{ + Description: "Timeout between bytes in seconds.", + Optional: true, + Computed: true, + }, + "hmac_authentication": schema.BoolAttribute{ + Description: "Whether HMAC authentication is enabled.", + Optional: true, + Computed: true, + }, + "hmac_region_name": schema.StringAttribute{ + Description: "HMAC region name.", + Optional: true, + Computed: true, + }, + "hmac_access_key": schema.StringAttribute{ + Description: "HMAC access key.", + Optional: true, + Computed: true, + }, + "hmac_secret_key": schema.StringAttribute{ + Description: "HMAC secret key.", + Optional: true, + Computed: true, + }, + }, + }, + }, + } +} + +func (r *originResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + r.client = req.ProviderData.(*apiClient) +} + +func (r *originResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var plan OriginResourceModel + var edgeApplicationID types.Int64 + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + diagsEdgeApplicationID := req.Config.GetAttribute(ctx, path.Root("edge_application_id"), &edgeApplicationID) + resp.Diagnostics.Append(diagsEdgeApplicationID...) + if resp.Diagnostics.HasError() { + return + } + + var addressesRequest []edgeapplications.CreateOriginsRequestAddresses + for _, addr := range plan.Origin.Addresses { + addressesRequest = append(addressesRequest, edgeapplications.CreateOriginsRequestAddresses{ + Address: addr.Address.ValueString(), + }) + } + + var originProtocolPolicy string + if plan.Origin.OriginProtocolPolicy.IsUnknown() { + originProtocolPolicy = "preserve" + } else { + if plan.Origin.OriginProtocolPolicy.ValueString() == "" || plan.Origin.OriginProtocolPolicy.IsNull() { + resp.Diagnostics.AddError("Origin Protocol Policy", + "Is not null, Possible choices are: [preserve(default), http, https]") + return + } + originProtocolPolicy = plan.Origin.OriginProtocolPolicy.ValueString() + } + + var OriginType string + if plan.Origin.OriginType.IsUnknown() { + OriginType = "single_origin" + } else { + if plan.Origin.OriginType.ValueString() == "" || plan.Origin.OriginType.IsNull() { + resp.Diagnostics.AddError("Origin Type", + "Is not null, Possible choices are: [single_origin]") + return + } + OriginType = plan.Origin.OriginType.ValueString() + } + + originRequest := edgeapplications.CreateOriginsRequest{ + Name: plan.Origin.Name.ValueString(), + Addresses: addressesRequest, + OriginType: edgeapplications.PtrString(OriginType), + OriginProtocolPolicy: edgeapplications.PtrString(originProtocolPolicy), + HostHeader: plan.Origin.HostHeader.ValueString(), + OriginPath: edgeapplications.PtrString(plan.Origin.OriginPath.ValueString()), + HmacAuthentication: edgeapplications.PtrBool(plan.Origin.HMACAuthentication.ValueBool()), + HmacRegionName: edgeapplications.PtrString(plan.Origin.HMACRegionName.ValueString()), + HmacAccessKey: edgeapplications.PtrString(plan.Origin.HMACAccessKey.ValueString()), + HmacSecretKey: edgeapplications.PtrString(plan.Origin.HMACSecretKey.ValueString()), + } + + originResponse, response, err := r.client.edgeApplicationsApi.EdgeApplicationsOriginsApi.EdgeApplicationsEdgeApplicationIdOriginsPost(ctx, edgeApplicationID.ValueInt64()).CreateOriginsRequest(originRequest).Execute() + if err != nil { + bodyBytes, erro := io.ReadAll(response.Body) + if erro != nil { + resp.Diagnostics.AddError( + err.Error(), + "err", + ) + } + bodyString := string(bodyBytes) + resp.Diagnostics.AddError( + err.Error(), + bodyString, + ) + return + } + + var addresses []OriginAddress + for _, addr := range originResponse.Results.Addresses { + addresses = append(addresses, OriginAddress{ + Address: types.StringValue(addr.GetAddress()), + Weight: types.StringValue(addr.GetWeight()), + ServerRole: types.StringValue(addr.GetServerRole()), + IsActive: types.BoolValue(addr.GetIsActive()), + }) + } + + plan.Origin = &OriginResourceResults{ + OriginID: types.Int64Value(originResponse.Results.GetOriginId()), + OriginKey: types.StringValue(originResponse.Results.GetOriginKey()), + Name: types.StringValue(originResponse.Results.GetName()), + OriginType: types.StringValue(originResponse.Results.GetOriginType()), + Addresses: addresses, + OriginProtocolPolicy: types.StringValue(originResponse.Results.GetOriginProtocolPolicy()), + IsOriginRedirectionEnabled: types.BoolValue(originResponse.Results.GetIsOriginRedirectionEnabled()), + HostHeader: types.StringValue(originResponse.Results.GetHostHeader()), + Method: types.StringValue(originResponse.Results.GetMethod()), + OriginPath: types.StringValue(originResponse.Results.GetOriginPath()), + ConnectionTimeout: types.Int64Value(originResponse.Results.GetConnectionTimeout()), + TimeoutBetweenBytes: types.Int64Value(originResponse.Results.GetTimeoutBetweenBytes()), + HMACAuthentication: types.BoolValue(originResponse.Results.GetHmacAuthentication()), + HMACRegionName: types.StringValue(originResponse.Results.GetHmacRegionName()), + HMACAccessKey: types.StringValue(originResponse.Results.GetHmacAccessKey()), + HMACSecretKey: types.StringValue(originResponse.Results.GetHmacSecretKey()), + } + + plan.SchemaVersion = types.Int64Value(originResponse.SchemaVersion) + plan.ID = types.StringValue(strconv.FormatInt(originResponse.Results.OriginId, 10)) + plan.LastUpdated = types.StringValue(time.Now().Format(time.RFC850)) + + diags = resp.State.Set(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *originResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var state OriginResourceModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + var ApplicationID int64 + var OriginKey string + valueFromCmd := strings.Split(state.ID.ValueString(), "/") + if len(valueFromCmd) > 1 { + ApplicationID = int64(utils.AtoiNoError(valueFromCmd[0], resp)) + OriginKey = valueFromCmd[1] + } else { + ApplicationID = state.ApplicationID.ValueInt64() + OriginKey = state.Origin.OriginKey.ValueString() + } + + if OriginKey == "" { + resp.Diagnostics.AddError( + "Origin Key error ", + "is not null", + ) + return + } + + originResponse, response, err := r.client.edgeApplicationsApi.EdgeApplicationsOriginsApi.EdgeApplicationsEdgeApplicationIdOriginsOriginKeyGet(ctx, ApplicationID, OriginKey).Execute() + if err != nil { + bodyBytes, erro := io.ReadAll(response.Body) + if erro != nil { + resp.Diagnostics.AddError( + err.Error(), + "err", + ) + } + bodyString := string(bodyBytes) + resp.Diagnostics.AddError( + err.Error(), + bodyString, + ) + return + } + + var addresses []OriginAddress + for _, addr := range originResponse.Results.Addresses { + addresses = append(addresses, OriginAddress{ + Address: types.StringValue(addr.GetAddress()), + Weight: types.StringValue(addr.GetWeight()), + ServerRole: types.StringValue(addr.GetServerRole()), + IsActive: types.BoolValue(addr.GetIsActive()), + }) + } + + state.Origin = &OriginResourceResults{ + OriginID: types.Int64Value(originResponse.Results.GetOriginId()), + OriginKey: types.StringValue(originResponse.Results.GetOriginKey()), + Name: types.StringValue(originResponse.Results.GetName()), + OriginType: types.StringValue(originResponse.Results.GetOriginType()), + Addresses: addresses, + OriginProtocolPolicy: types.StringValue(originResponse.Results.GetOriginProtocolPolicy()), + IsOriginRedirectionEnabled: types.BoolValue(originResponse.Results.GetIsOriginRedirectionEnabled()), + HostHeader: types.StringValue(originResponse.Results.GetHostHeader()), + Method: types.StringValue(originResponse.Results.GetMethod()), + OriginPath: types.StringValue(originResponse.Results.GetOriginPath()), + ConnectionTimeout: types.Int64Value(originResponse.Results.GetConnectionTimeout()), + TimeoutBetweenBytes: types.Int64Value(originResponse.Results.GetTimeoutBetweenBytes()), + HMACAuthentication: types.BoolValue(originResponse.Results.GetHmacAuthentication()), + HMACRegionName: types.StringValue(originResponse.Results.GetHmacRegionName()), + HMACAccessKey: types.StringValue(originResponse.Results.GetHmacAccessKey()), + HMACSecretKey: types.StringValue(originResponse.Results.GetHmacSecretKey()), + } + state.ID = types.StringValue(strconv.FormatInt(originResponse.Results.OriginId, 10)) + state.ApplicationID = types.Int64Value(ApplicationID) + state.SchemaVersion = types.Int64Value(originResponse.SchemaVersion) + + diags = resp.State.Set(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *originResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var plan OriginResourceModel + var edgeApplicationID types.Int64 + var originKey types.String + diags := req.Plan.Get(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + + var state OriginResourceModel + diagsOrigin := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diagsOrigin...) + if resp.Diagnostics.HasError() { + return + } + + if plan.Origin.OriginKey.ValueString() == "" { + originKey = state.Origin.OriginKey + } else { + originKey = plan.Origin.OriginKey + } + + if originKey.String() == "" { + resp.Diagnostics.AddError( + "Origin Key error ", + "is not null", + ) + return + } + + if plan.ApplicationID.IsNull() { + edgeApplicationID = state.ApplicationID + } else { + edgeApplicationID = plan.ApplicationID + } + + if edgeApplicationID.IsNull() { + resp.Diagnostics.AddError( + "Edge Application ID error ", + "is not null", + ) + return + } + + var addressesRequest []edgeapplications.CreateOriginsRequestAddresses + for _, addr := range plan.Origin.Addresses { + addressesRequest = append(addressesRequest, edgeapplications.CreateOriginsRequestAddresses{ + Address: addr.Address.ValueString(), + }) + } + + var originProtocolPolicy string + if plan.Origin.OriginProtocolPolicy.IsUnknown() { + originProtocolPolicy = "preserve" + } else { + if plan.Origin.OriginProtocolPolicy.ValueString() == "" || plan.Origin.OriginProtocolPolicy.IsNull() { + resp.Diagnostics.AddError("Origin Protocol Policy", + "Is not null, Possible choices are: [preserve(default), http, https]") + return + } + originProtocolPolicy = plan.Origin.OriginProtocolPolicy.ValueString() + } + + var OriginType string + if plan.Origin.OriginType.IsUnknown() { + OriginType = "single_origin" + } else { + if plan.Origin.OriginType.ValueString() == "" || plan.Origin.OriginType.IsNull() { + resp.Diagnostics.AddError("Origin Type", + "Is not null, Possible choices are: [single_origin]") + return + } + OriginType = plan.Origin.OriginType.ValueString() + } + + originRequest := edgeapplications.UpdateOriginsRequest{ + Name: plan.Origin.Name.ValueString(), + Addresses: addressesRequest, + OriginType: edgeapplications.PtrString(OriginType), + OriginProtocolPolicy: edgeapplications.PtrString(originProtocolPolicy), + HostHeader: plan.Origin.HostHeader.ValueString(), + OriginPath: edgeapplications.PtrString(plan.Origin.OriginPath.ValueString()), + HmacAuthentication: edgeapplications.PtrBool(plan.Origin.HMACAuthentication.ValueBool()), + HmacRegionName: edgeapplications.PtrString(plan.Origin.HMACRegionName.ValueString()), + HmacAccessKey: edgeapplications.PtrString(plan.Origin.HMACAccessKey.ValueString()), + HmacSecretKey: edgeapplications.PtrString(plan.Origin.HMACSecretKey.ValueString()), + } + + originResponse, response, err := r.client.edgeApplicationsApi.EdgeApplicationsOriginsApi.EdgeApplicationsEdgeApplicationIdOriginsOriginKeyPut(ctx, edgeApplicationID.ValueInt64(), originKey.ValueString()).UpdateOriginsRequest(originRequest).Execute() + if err != nil { + bodyBytes, erro := io.ReadAll(response.Body) + if erro != nil { + resp.Diagnostics.AddError( + err.Error(), + "err", + ) + } + bodyString := string(bodyBytes) + resp.Diagnostics.AddError( + err.Error(), + bodyString, + ) + return + } + + var addresses []OriginAddress + for _, addr := range originResponse.Results.Addresses { + addresses = append(addresses, OriginAddress{ + Address: types.StringValue(addr.GetAddress()), + Weight: types.StringValue(addr.GetWeight()), + ServerRole: types.StringValue(addr.GetServerRole()), + IsActive: types.BoolValue(addr.GetIsActive()), + }) + } + + plan.Origin = &OriginResourceResults{ + OriginID: types.Int64Value(originResponse.Results.GetOriginId()), + OriginKey: types.StringValue(originResponse.Results.GetOriginKey()), + Name: types.StringValue(originResponse.Results.GetName()), + OriginType: types.StringValue(originResponse.Results.GetOriginType()), + Addresses: addresses, + OriginProtocolPolicy: types.StringValue(originResponse.Results.GetOriginProtocolPolicy()), + IsOriginRedirectionEnabled: types.BoolValue(originResponse.Results.GetIsOriginRedirectionEnabled()), + HostHeader: types.StringValue(originResponse.Results.GetHostHeader()), + Method: types.StringValue(originResponse.Results.GetMethod()), + OriginPath: types.StringValue(originResponse.Results.GetOriginPath()), + ConnectionTimeout: types.Int64Value(originResponse.Results.GetConnectionTimeout()), + TimeoutBetweenBytes: types.Int64Value(originResponse.Results.GetTimeoutBetweenBytes()), + HMACAuthentication: types.BoolValue(originResponse.Results.GetHmacAuthentication()), + HMACRegionName: types.StringValue(originResponse.Results.GetHmacRegionName()), + HMACAccessKey: types.StringValue(originResponse.Results.GetHmacAccessKey()), + HMACSecretKey: types.StringValue(originResponse.Results.GetHmacSecretKey()), + } + + plan.SchemaVersion = types.Int64Value(originResponse.SchemaVersion) + plan.ID = types.StringValue(strconv.FormatInt(originResponse.Results.OriginId, 10)) + plan.LastUpdated = types.StringValue(time.Now().Format(time.RFC850)) + + diags = resp.State.Set(ctx, &plan) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } +} + +func (r *originResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var state OriginResourceModel + diags := req.State.Get(ctx, &state) + resp.Diagnostics.Append(diags...) + if resp.Diagnostics.HasError() { + return + } + edgeApplicationID := state.ApplicationID.ValueInt64() + + if state.Origin.OriginKey.ValueString() == "" { + resp.Diagnostics.AddError( + "Origin Key error ", + "is not null", + ) + return + } + + if state.ApplicationID.IsNull() { + resp.Diagnostics.AddError( + "Edge Application ID error ", + "is not null", + ) + return + } + response, err := r.client.edgeApplicationsApi.EdgeApplicationsOriginsApi.EdgeApplicationsEdgeApplicationIdOriginsOriginKeyDelete(ctx, edgeApplicationID, state.Origin.OriginKey.ValueString()).Execute() + if err != nil { + bodyBytes, erro := io.ReadAll(response.Body) + if erro != nil { + resp.Diagnostics.AddError( + err.Error(), + "err", + ) + } + bodyString := string(bodyBytes) + resp.Diagnostics.AddError( + err.Error(), + bodyString, + ) + return + } +} + +func (r *originResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) +} diff --git a/internal/resource_record.go b/internal/resource_record.go index e69ca98..23011db 100644 --- a/internal/resource_record.go +++ b/internal/resource_record.go @@ -4,12 +4,12 @@ import ( "context" "fmt" "io" - "math" "strconv" "strings" "time" "github.com/aziontech/azionapi-go-sdk/idns" + "github.com/aziontech/terraform-provider-azion/internal/utils" "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" @@ -209,25 +209,6 @@ func (r *recordResource) Create(ctx context.Context, req resource.CreateRequest, } } -func AtoiNoError(strToConv string, resp *resource.ReadResponse) int32 { - intReturn, err := strconv.ParseInt(strToConv, 10, 64) - if err != nil { - resp.Diagnostics.AddError( - "Value Conversion error ", - "Could not convert String to Int", - ) - return 0 - } - if intReturn > math.MaxInt32 || intReturn < math.MinInt32 { - resp.Diagnostics.AddError( - "Value Overflow error", - "Converted value exceeds the range of int32", - ) - return 0 - } - return int32(intReturn) -} - func errorPrint(errCode int, err error) (string, string) { var usrMsg string switch errCode { @@ -256,11 +237,11 @@ func (r *recordResource) Read(ctx context.Context, req resource.ReadRequest, res } valueFromCmd := strings.Split(state.ZoneId.ValueString(), "/") - idZone := AtoiNoError(valueFromCmd[0], resp) + idZone := utils.AtoiNoError(valueFromCmd[0], resp) state.ZoneId = types.StringValue(valueFromCmd[0]) var idRecord int32 if len(valueFromCmd) > 1 { - idRecord = AtoiNoError(valueFromCmd[1], resp) + idRecord = utils.AtoiNoError(valueFromCmd[1], resp) } recordsResponse, httpResponse, err := r.client.idnsApi.RecordsApi.GetZoneRecords(ctx, idZone).Execute() diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 4b13c9a..1ee3609 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -3,8 +3,11 @@ package utils import ( "encoding/json" "fmt" + "math" + "strconv" "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" ) @@ -65,3 +68,22 @@ func ConvertInterfaceToString(jsonArgs interface{}) (string, error) { return string(jsonArgsStr), err } + +func AtoiNoError(strToConv string, resp *resource.ReadResponse) int32 { + intReturn, err := strconv.ParseInt(strToConv, 10, 64) + if err != nil { + resp.Diagnostics.AddError( + "Value Conversion error ", + "Could not convert String to Int", + ) + return 0 + } + if intReturn > math.MaxInt32 || intReturn < math.MinInt32 { + resp.Diagnostics.AddError( + "Value Overflow error", + "Converted value exceeds the range of int32", + ) + return 0 + } + return int32(intReturn) +}