diff --git a/.cds/terraform-provider-ovh.pip.yml b/.cds/terraform-provider-ovh.pip.yml index 566da64b1..083441196 100644 --- a/.cds/terraform-provider-ovh.pip.yml +++ b/.cds/terraform-provider-ovh.pip.yml @@ -58,6 +58,9 @@ parameters: skipthistest.vrack: type: boolean description: Skip vRack tests + skipthistest.vrackservices: + type: boolean + description: Skip VrackServices tests skipthistest.okms: type: boolean description: Skip OKMS tests diff --git a/.cds/terraform-provider-ovh.yml b/.cds/terraform-provider-ovh.yml index ecaa10335..0687d0a90 100644 --- a/.cds/terraform-provider-ovh.yml +++ b/.cds/terraform-provider-ovh.yml @@ -773,6 +773,18 @@ workflow: pipeline: terraform-provider-ovh-testacc when: - success + Tests_VrackServices: + application: terraform-provider-ovh + depends_on: + - terraform-provider-ovh-pre-sweepers + environment: acctests + one_at_a_time: true + parameters: + testargs: -run 'VrackServices' + skipthispipeline: "{{.workflow.terraform-provider-ovh.pip.skipthistest.vrackservices}}" + pipeline: terraform-provider-ovh-testacc + when: + - success Tests_IPFirewall: application: terraform-provider-ovh depends_on: diff --git a/README.md b/README.md index 86a5168cf..6c01896d1 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ export OVH_CLOUD_PROJECT_FAILOVER_IP_TEST="..." export OVH_CLOUD_PROJECT_FAILOVER_IP_ROUTED_TO_1_TEST="..." export OVH_CLOUD_PROJECT_FAILOVER_IP_ROUTED_TO_2_TEST="..." export OVH_VRACK_SERVICE_TEST="..." +export OVH_VRACK_SERVICES_SERVICE_TEST="..." export OVH_ZONE_TEST="..." export OVH_DOMAIN_NS1_HOST_TEST="..." export OVH_DOMAIN_NS1_IP_TEST="..." diff --git a/docs/data-sources/vrackservices.md b/docs/data-sources/vrackservices.md new file mode 100644 index 000000000..891de25a6 --- /dev/null +++ b/docs/data-sources/vrackservices.md @@ -0,0 +1,138 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "ovh_vrackservices Data Source - terraform-provider-ovh" +subcategory: "Vrack Services" +description: |- + Retrieve a vRack Services +--- + +# ovh_vrackservices (Data Source) + +Retrieve a vRack Services + + + + +## Schema + +### Required + +- `vrack_services_id` (String) Vrack services ID + +### Read-Only + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the current target specification value +- `created_at` (String) Date of the vRack Services delivery +- `current_state` (Attributes) Current configuration applied to the vRack Services (see [below for nested schema](#nestedatt--current_state)) +- `current_tasks` (Attributes List) Asynchronous operations ongoing on the vRack Services (see [below for nested schema](#nestedatt--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--iam)) +- `id` (String) Unique identifier +- `resource_status` (String) Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status +- `target_spec` (Attributes) Last target specification of the vRack Services (see [below for nested schema](#nestedatt--target_spec)) +- `updated_at` (String) Date of the Last vRack Services update + + +### Nested Schema for `current_state` + +Read-Only: + +- `product_status` (String) Product status of the vRack Services +- `region` (String) Region of the vRack Services. List of compatible regions can be retrieved from /reference/region +- `subnets` (Attributes List) Subnets of the current vRack Services (see [below for nested schema](#nestedatt--current_state--subnets)) + + +### Nested Schema for `current_state.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format +- `display_name` (String) Display name of the subnet +- `service_endpoints` (Attributes List) Service endpoints of the subnet (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed services IPs (see [below for nested schema](#nestedatt--current_state--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation + + +### Nested Schema for `current_state.subnets.service_endpoints` + +Read-Only: + +- `endpoints` (Attributes List) Endpoints representing the IPs assigned to the managed services (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints--endpoints)) +- `managed_service_urn` (String) IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call. + + +### Nested Schema for `current_state.subnets.service_endpoints.endpoints` + +Read-Only: + +- `description` (String) IP description defined in the managed service +- `ip` (String) IP address assigned by OVHcloud + + + + +### Nested Schema for `current_state.subnets.service_range` + +Read-Only: + +- `cidr` (String) CIDR dedicated to the subnet's services +- `remaining_ips` (Number) Number of remaining IPs in the service range +- `reserved_ips` (Number) Number of service range IPs reserved by OVHcloud +- `used_ips` (Number) Number of service range IPs assigned to the managed services + + + + + +### Nested Schema for `current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the task details +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `state` (String) Resource state +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `target_spec` + +Read-Only: + +- `subnets` (Attributes List) Target specification of the subnets. Maximum one subnet per vRack Services (see [below for nested schema](#nestedatt--target_spec--subnets)) + + +### Nested Schema for `target_spec.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24 +- `display_name` (String) Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$` +- `service_endpoints` (Attributes List) Target specification of the Service Endpoints (see [below for nested schema](#nestedatt--target_spec--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed service IPs (see [below for nested schema](#nestedatt--target_spec--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic) + + +### Nested Schema for `target_spec.subnets.service_endpoints` + +Read-Only: + +- `managed_service_urn` (String) IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call + + + +### Nested Schema for `target_spec.subnets.service_range` + +Read-Only: + +- `cidr` (String) IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29 diff --git a/docs/data-sources/vrackservicess.md b/docs/data-sources/vrackservicess.md new file mode 100644 index 000000000..df1a15963 --- /dev/null +++ b/docs/data-sources/vrackservicess.md @@ -0,0 +1,142 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "ovh_vrackservicess Data Source - terraform-provider-ovh" +subcategory: "Vrack Services" +description: |- + List all vRack Services +--- + +# ovh_vrackservicess (Data Source) + +List all vRack Services + + + + +## Schema + +### Read-Only + +- `vrackservicess` (Attributes Set) (see [below for nested schema](#nestedatt--vrackservicess)) + + +### Nested Schema for `vrackservicess` + +Read-Only: + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the current target specification value +- `created_at` (String) Date of the vRack Services delivery +- `current_state` (Attributes) Current configuration applied to the vRack Services (see [below for nested schema](#nestedatt--vrackservicess--current_state)) +- `current_tasks` (Attributes List) Asynchronous operations ongoing on the vRack Services (see [below for nested schema](#nestedatt--vrackservicess--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--vrackservicess--iam)) +- `id` (String) Unique identifier +- `resource_status` (String) Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status +- `target_spec` (Attributes) Last target specification of the vRack Services (see [below for nested schema](#nestedatt--vrackservicess--target_spec)) +- `updated_at` (String) Date of the Last vRack Services update + + +### Nested Schema for `vrackservicess.current_state` + +Read-Only: + +- `product_status` (String) Product status of the vRack Services +- `region` (String) Region of the vRack Services. List of compatible regions can be retrieved from /reference/region +- `subnets` (Attributes List) Subnets of the current vRack Services (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets)) +- `vrack_id` (String) vRack associated to the vRack Services + + +### Nested Schema for `vrackservicess.current_state.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format +- `display_name` (String) Display name of the subnet +- `service_endpoints` (Attributes List) Service endpoints of the subnet (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed services IPs (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation + + +### Nested Schema for `vrackservicess.current_state.subnets.service_endpoints` + +Read-Only: + +- `endpoints` (Attributes List) Endpoints representing the IPs assigned to the managed services (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets--service_endpoints--endpoints)) +- `managed_service_urn` (String) IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call. + + +### Nested Schema for `vrackservicess.current_state.subnets.service_endpoints.endpoints` + +Read-Only: + +- `description` (String) IP description defined in the managed service +- `ip` (String) IP address assigned by OVHcloud + + + + +### Nested Schema for `vrackservicess.current_state.subnets.service_range` + +Read-Only: + +- `cidr` (String) CIDR dedicated to the subnet's services +- `remaining_ips` (Number) Number of remaining IPs in the service range +- `reserved_ips` (Number) Number of service range IPs reserved by OVHcloud +- `used_ips` (Number) Number of service range IPs assigned to the managed services + + + + + +### Nested Schema for `vrackservicess.current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the task details +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `vrackservicess.iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `state` (String) Resource state +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `vrackservicess.target_spec` + +Read-Only: + +- `subnets` (Attributes List) Target specification of the subnets. Maximum one subnet per vRack Services (see [below for nested schema](#nestedatt--vrackservicess--target_spec--subnets)) + + +### Nested Schema for `vrackservicess.target_spec.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24 +- `display_name` (String) Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$` +- `service_endpoints` (Attributes List) Target specification of the Service Endpoints (see [below for nested schema](#nestedatt--vrackservicess--target_spec--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed service IPs (see [below for nested schema](#nestedatt--vrackservicess--target_spec--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic) + + +### Nested Schema for `vrackservicess.target_spec.subnets.service_endpoints` + +Read-Only: + +- `managed_service_urn` (String) IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call + + + +### Nested Schema for `vrackservicess.target_spec.subnets.service_range` + +Read-Only: + +- `cidr` (String) IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29 diff --git a/docs/index.md b/docs/index.md index 2d4fc4f38..65b1687ed 100644 --- a/docs/index.md +++ b/docs/index.md @@ -284,6 +284,10 @@ In order to run the Acceptance Tests for development, the following environment * `OVH_TESTACC_ORDER_VRACK` - set this variable to "yes" will order vracks. +* `OVH_TESTACC_ORDER_VRACKSERVICES` - set this variable to "yes" will order and test Vrack Services. + +* `OVH_TESTACC_VRACK_SERVICES_ID_TEST` - The ID of your vRack Service. + * `OVH_TESTACC_ORDER_CLOUDPROJECT` - set this variable to "yes" will order cloud projects. * `OVH_TESTACC_ORDER_DOMAIN` - set this variable to "mydomain.ovh" to run tests for domain zones. diff --git a/docs/resources/vrackservices.md b/docs/resources/vrackservices.md new file mode 100644 index 000000000..0214c3105 --- /dev/null +++ b/docs/resources/vrackservices.md @@ -0,0 +1,478 @@ +--- +page_title: "ovh_vrackservices Resource - terraform-provider-ovh" +subcategory: "Vrack Services" +description: |- + +--- + +# ovh_vrackservices (Resource) + +Orders a Vrack Services. + +## Important + +-> **NOTE** To order a product through Terraform, your account needs to have a default payment method defined. This can be done in the [OVHcloud Control Panel](https://www.ovh.com/manager/#/dedicated/billing/payment/method) or via API with the [/me/payment/method](https://api.ovh.com/console/#/me/payment/method~GET) endpoint. + +~> **WARNING** `BANK_ACCOUNT` is not supported anymore, please update your default payment_method to `SEPA_DIRECT_DEBIT` + +## Example Usage + +### Example 1 - Simple Vrack Services order + +```terraform +locals { + region = "eu-west-lim" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [] + } +} +``` + +### Example 2 - Vrack Services basic configuration + +```terraform +locals { + region = "eu-west-lim" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + service_range = { + cidr = "192.168.0.0/29" + } + service_endpoints = [] + }, + ] + } +} +``` + +### Example 3 - Vrack Services associated to a vRack + +```terraform +locals { + region = "eu-west-lim" + vrack_name = "pn-000000" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [] + } +} + +resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = local.vrack_name + vrack_services = ovh_vrackservices.my-vrackservices.id +} + +``` + +### Example 4 - Vrack Services configuration with a managed service + +```terraform +locals { + region = "eu-west-lim" + efs_name = "example-efs-service-name-000e75d3d4c1" +} + +data "ovh_me" "myaccount" {} + +data "ovh_storage_efs" "my-efs" { + service_name = local.efs_name +} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + display_name = "my.subnet" + service_range = { + cidr = "192.168.0.0/29" + } + vlan = 30 + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.my-efs.iam.urn + } + ] + }, + ] + } +} +``` + +### Example 5 - Vrack Services complete configuration + +```terraform +# Once this plan executed, your ovh_vrackservices resource must be updated in your state using : +# `terraform plan -refresh-only` +# `terraform apply -refresh-only -auto-approve` + +locals { + region = "eu-west-lim" + efs_name = "example-efs-service-name-000e75d3d4c1" + vrack_name = "pn-000000" +} + +data "ovh_me" "myaccount" {} + +data "ovh_storage_efs" "my-efs" { + service_name = local.efs_name +} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = locals.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + display_name = "my.subnet" + service_range = { + cidr = "192.168.0.0/29" + } + vlan = 30 + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.my-efs.iam.urn + } + ] + }, + ] + } +} + +resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = local.vrack_name + vrack_services = ovh_vrackservices.my-vrackservices.id +} + +``` + +## Schema + +### Required + +- `target_spec` (Attributes) Target specification of the vRack Services (see [below for nested schema](#nestedatt--target_spec)) + +### Optional + +- `ovh_subsidiary` (String) OVH subsidiaries +- `plan` (Attributes List) (see [below for nested schema](#nestedatt--plan)) +- `plan_option` (Attributes List) (see [below for nested schema](#nestedatt--plan_option)) + +### Read-Only + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the target specification value the request is based on +- `created_at` (String) Date of the vRack Services delivery +- `current_state` (Attributes) Current configuration applied to the vRack Services (see [below for nested schema](#nestedatt--current_state)) +- `current_tasks` (Attributes List) Asynchronous operations ongoing on the vRack Services (see [below for nested schema](#nestedatt--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--iam)) +- `id` (String) Unique identifier +- `order` (Attributes) Details about an Order (see [below for nested schema](#nestedatt--order)) +- `resource_status` (String) Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status +- `updated_at` (String) Date of the Last vRack Services update + + +### Nested Schema for `target_spec` + +Required: + +- `subnets` (Attributes List) Target specification of the subnets. Maximum one subnet per vRack Services (see [below for nested schema](#nestedatt--target_spec--subnets)) + + +### Nested Schema for `target_spec.subnets` + +Required: + +- `cidr` (String) IPv4 CIDR notation (e.g., 192.0.2.0/24) +- `service_endpoints` (Attributes List) Target specification of the Service Endpoints (see [below for nested schema](#nestedatt--target_spec--subnets--service_endpoints)) +- `service_range` (Attributes) Target specification of the range dedicated to the subnet's services (see [below for nested schema](#nestedatt--target_spec--subnets--service_range)) + +Optional: + +- `display_name` (String) Display name of the subnet. Format must follow `^[a-zA-Z0-9-_.]{0,40}$` +- `vlan` (Number) Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic) + + +### Nested Schema for `target_spec.subnets.service_endpoints` + +Required: + +- `managed_service_urn` (String) IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call + + + +### Nested Schema for `target_spec.subnets.service_range` + +Required: + +- `cidr` (String) IPv4 CIDR notation (e.g., 192.0.2.0/24) + + + + + +### Nested Schema for `plan` + +Required: + +- `duration` (String) Duration selected for the purchase of the product +- `plan_code` (String) Identifier of the option offer +- `pricing_mode` (String) Pricing mode selected for the purchase of the product + +Optional: + +- `configuration` (Attributes List) (see [below for nested schema](#nestedatt--plan--configuration)) +- `item_id` (Number) Cart item to be linked +- `quantity` (Number) Quantity of product desired + + +### Nested Schema for `plan.configuration` + +Required: + +- `label` (String) Label for your configuration item +- `value` (String) Value or resource URL on API.OVH.COM of your configuration item + + + + +### Nested Schema for `plan_option` + +Required: + +- `duration` (String) Duration selected for the purchase of the product +- `plan_code` (String) Identifier of the option offer +- `pricing_mode` (String) Pricing mode selected for the purchase of the product +- `quantity` (Number) Quantity of product desired + +Optional: + +- `configuration` (Attributes List) (see [below for nested schema](#nestedatt--plan_option--configuration)) + + +### Nested Schema for `plan_option.configuration` + +Required: + +- `label` (String) Label for your configuration item +- `value` (String) Value or resource URL on API.OVH.COM of your configuration item + + + + +### Nested Schema for `current_state` + +Read-Only: + +- `product_status` (String) Product status of the vRack Services +- `region` (String) Region of the vRack Services. List of compatible regions can be retrieved from /reference/region +- `subnets` (Attributes List) Subnets of the current vRack Services (see [below for nested schema](#nestedatt--current_state--subnets)) + + +### Nested Schema for `current_state.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format +- `display_name` (String) Display name of the subnet +- `service_endpoints` (Attributes List) Service endpoints of the subnet (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed services IPs (see [below for nested schema](#nestedatt--current_state--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation + + +### Nested Schema for `current_state.subnets.service_endpoints` + +Read-Only: + +- `endpoints` (Attributes List) Endpoints representing the IPs assigned to the managed services (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints--endpoints)) +- `managed_service_urn` (String) IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call. + + +### Nested Schema for `current_state.subnets.service_endpoints.endpoints` + +Read-Only: + +- `description` (String) IP description defined in the managed service +- `ip` (String) IP address assigned by OVHcloud + + + + +### Nested Schema for `current_state.subnets.service_range` + +Read-Only: + +- `cidr` (String) CIDR dedicated to the subnet's services +- `remaining_ips` (Number) Number of remaining IPs in the service range +- `reserved_ips` (Number) Number of service range IPs reserved by OVHcloud +- `used_ips` (Number) Number of service range IPs assigned to the managed services + + + + + +### Nested Schema for `current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the related resource +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `tags` (Map of String) Resource tags. Tags that were internally computed are prefixed with ovh: +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `order` + +Read-Only: + +- `date` (String) +- `details` (Attributes List) (see [below for nested schema](#nestedatt--order--details)) +- `expiration_date` (String) +- `order_id` (Number) + + +### Nested Schema for `order.details` + +Read-Only: + +- `description` (String) +- `detail_type` (String) Product type of item in order +- `domain` (String) +- `order_detail_id` (Number) +- `quantity` (String) + + +## Timeouts + +```terraform +resource "ovh_vrackservices" "my-vrackservices" { + # ... + + timeouts { + create = "1h" + } +} +``` + +* `create` - (Default 30m) + +## Import + +A VrackServices can be imported using the `id`. Using the following configuration: + +```terraform +import { + to = ovh_vrackservices.vrackservices + id = "vrs-xxx-xxx-xxx-xxx" +} +``` + +You can then run: + +```bash +$ terraform plan -generate-config-out=vrackservices.tf +$ terraform apply +``` + +The file `vrackservices.tf` will then contain the imported resource's configuration, that can be copied next to the `import` block above. See https://developer.hashicorp.com/terraform/language/import/generating-configuration for more details. diff --git a/examples/data-sources/vrackservices.tf/data-source.tf b/examples/data-sources/vrackservices.tf/data-source.tf new file mode 100644 index 000000000..1bae13068 --- /dev/null +++ b/examples/data-sources/vrackservices.tf/data-source.tf @@ -0,0 +1 @@ +data "ovh_vrackservicess" "vrackservicess" {} \ No newline at end of file diff --git a/examples/data-sources/vrackservicess.tf/data-source.tf b/examples/data-sources/vrackservicess.tf/data-source.tf new file mode 100644 index 000000000..e46ba7265 --- /dev/null +++ b/examples/data-sources/vrackservicess.tf/data-source.tf @@ -0,0 +1,3 @@ +data "ovh_vrackservices" "vrs-xxx-xxx-xxx-xxx" { + vrack_services_id = "vrs-xxx-xxx-xxx-xxx" +} diff --git a/examples/resources/vrackservices/example_1.tf b/examples/resources/vrackservices/example_1.tf new file mode 100644 index 000000000..4514ce229 --- /dev/null +++ b/examples/resources/vrackservices/example_1.tf @@ -0,0 +1,28 @@ +# Vrack Service order + +locals { + region = "eu-west-lim" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [] + } +} diff --git a/examples/resources/vrackservices/example_2.tf b/examples/resources/vrackservices/example_2.tf new file mode 100644 index 000000000..d45e8a9b0 --- /dev/null +++ b/examples/resources/vrackservices/example_2.tf @@ -0,0 +1,36 @@ +# Basic configuration + +locals { + region = "eu-west-lim" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + service_range = { + cidr = "192.168.0.0/29" + } + service_endpoints = [] + }, + ] + } +} \ No newline at end of file diff --git a/examples/resources/vrackservices/example_3.tf b/examples/resources/vrackservices/example_3.tf new file mode 100644 index 000000000..ee4c4df84 --- /dev/null +++ b/examples/resources/vrackservices/example_3.tf @@ -0,0 +1,34 @@ +# Vrack Services associated to a vRack + +locals { + region = "eu-west-lim" + vrack_name = "pn-000000" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [] + } +} + +resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = local.vrack_name + vrack_services = ovh_vrackservices.my-vrackservices.id +} diff --git a/examples/resources/vrackservices/example_4.tf b/examples/resources/vrackservices/example_4.tf new file mode 100644 index 000000000..c10ed3e55 --- /dev/null +++ b/examples/resources/vrackservices/example_4.tf @@ -0,0 +1,47 @@ +# Configuration with a managed service + +locals { + region = "eu-west-lim" + efs_name = "example-efs-service-name-000e75d3d4c1" +} + +data "ovh_me" "myaccount" {} + +data "ovh_storage_efs" "my-efs" { + service_name = local.efs_name +} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + display_name = "my.subnet" + service_range = { + cidr = "192.168.0.0/29" + } + vlan = 30 + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.my-efs.iam.urn + } + ] + }, + ] + } +} \ No newline at end of file diff --git a/examples/resources/vrackservices/example_5.tf b/examples/resources/vrackservices/example_5.tf new file mode 100644 index 000000000..55cc6d775 --- /dev/null +++ b/examples/resources/vrackservices/example_5.tf @@ -0,0 +1,56 @@ +# Complete Vrack Services configuration +# Once this plan executed, your ovh_vrackservices resource must be updated in your state using : +# `terraform plan -refresh-only` +# `terraform apply -refresh-only -auto-approve` + +locals { + region = "eu-west-lim" + efs_name = "example-efs-service-name-000e75d3d4c1" + vrack_name = "pn-000000" +} + +data "ovh_me" "myaccount" {} + +data "ovh_storage_efs" "my-efs" { + service_name = local.efs_name +} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = locals.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + display_name = "my.subnet" + service_range = { + cidr = "192.168.0.0/29" + } + vlan = 30 + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.my-efs.iam.urn + } + ] + }, + ] + } +} + +resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = local.vrack_name + vrack_services = ovh_vrackservices.my-vrackservices.id +} diff --git a/examples/resources/vrackservices/import.sh b/examples/resources/vrackservices/import.sh new file mode 100644 index 000000000..ad8d885ea --- /dev/null +++ b/examples/resources/vrackservices/import.sh @@ -0,0 +1 @@ +terraform import ovh_vrackservices.my-vrackservices vrs-xxx-xxx-xxx-xxx \ No newline at end of file diff --git a/ovh/data_vrackservices.go b/ovh/data_vrackservices.go new file mode 100644 index 000000000..ead3b7419 --- /dev/null +++ b/ovh/data_vrackservices.go @@ -0,0 +1,69 @@ +package ovh + +import ( + "context" + "fmt" + "net/url" + + "github.com/hashicorp/terraform-plugin-framework/datasource" +) + +var _ datasource.DataSourceWithConfigure = (*vrackservicesDataSource)(nil) + +func NewVrackservicesDataSource() datasource.DataSource { + return &vrackservicesDataSource{} +} + +type vrackservicesDataSource struct { + config *Config +} + +func (d *vrackservicesDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_vrackservices" +} + +func (d *vrackservicesDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + config, ok := req.ProviderData.(*Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.config = config +} + +func (d *vrackservicesDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = VrackservicesDataSourceSchema(ctx) +} + +func (d *vrackservicesDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data VrackservicesModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Read API call logic + endpoint := "/v2/vrackServices/resource/" + url.PathEscape(data.VrackServicesId.ValueString()) + "" + + if err := d.config.OVHClient.Get(endpoint, &data); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/ovh/data_vrackservices_gen.go b/ovh/data_vrackservices_gen.go new file mode 100644 index 000000000..582ca9482 --- /dev/null +++ b/ovh/data_vrackservices_gen.go @@ -0,0 +1,377 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package ovh + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/types" + ovhtypes "github.com/ovh/terraform-provider-ovh/v2/ovh/types" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func VrackservicesDataSourceSchema(ctx context.Context) schema.Schema { + attrs := map[string]schema.Attribute{ + "checksum": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Computed hash used to control concurrent modification requests. Here, it represents the current target specification value", + MarkdownDescription: "Computed hash used to control concurrent modification requests. Here, it represents the current target specification value", + }, + "created_at": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Date of the vRack Services delivery", + MarkdownDescription: "Date of the vRack Services delivery", + }, + "current_state": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "product_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Product status of the vRack Services", + MarkdownDescription: "Product status of the vRack Services", + }, + "region": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Region of the vRack Services. List of compatible regions can be retrieved from /reference/region", + MarkdownDescription: "Region of the vRack Services. List of compatible regions can be retrieved from /reference/region", + }, + "subnets": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range of the subnet in CIDR format", + MarkdownDescription: "IP address range of the subnet in CIDR format", + }, + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Display name of the subnet", + MarkdownDescription: "Display name of the subnet", + }, + "service_endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP description defined in the managed service", + MarkdownDescription: "IP description defined in the managed service", + }, + "ip": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address assigned by OVHcloud", + MarkdownDescription: "IP address assigned by OVHcloud", + }, + }, + CustomType: CurrentStateSubnetsServiceEndpointsEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceEndpointsEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + Computed: true, + Description: "Endpoints representing the IPs assigned to the managed services", + MarkdownDescription: "Endpoints representing the IPs assigned to the managed services", + }, + "managed_service_urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call.", + MarkdownDescription: "IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call.", + }, + }, + CustomType: CurrentStateSubnetsServiceEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsValue](ctx), + Computed: true, + Description: "Service endpoints of the subnet", + MarkdownDescription: "Service endpoints of the subnet", + }, + "service_range": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "CIDR dedicated to the subnet's services", + MarkdownDescription: "CIDR dedicated to the subnet's services", + }, + "remaining_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of remaining IPs in the service range", + MarkdownDescription: "Number of remaining IPs in the service range", + }, + "reserved_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of service range IPs reserved by OVHcloud", + MarkdownDescription: "Number of service range IPs reserved by OVHcloud", + }, + "used_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of service range IPs assigned to the managed services", + MarkdownDescription: "Number of service range IPs assigned to the managed services", + }, + }, + CustomType: CurrentStateSubnetsServiceRangeType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Defines a smaller subnet dedicated to the managed services IPs", + MarkdownDescription: "Defines a smaller subnet dedicated to the managed services IPs", + }, + "vlan": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Unique inner VLAN that allows subnets segregation", + MarkdownDescription: "Unique inner VLAN that allows subnets segregation", + }, + }, + CustomType: CurrentStateSubnetsType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateSubnetsValue](ctx), + Computed: true, + Description: "Subnets of the current vRack Services", + MarkdownDescription: "Subnets of the current vRack Services", + }, + }, + CustomType: VrackServicesCurrentStateType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackServicesCurrentStateValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Current configuration applied to the vRack Services", + MarkdownDescription: "Current configuration applied to the vRack Services", + }, + "current_tasks": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Identifier of the current task", + MarkdownDescription: "Identifier of the current task", + }, + "link": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Link to the task details", + MarkdownDescription: "Link to the task details", + }, + "status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Current global status of the current task", + MarkdownDescription: "Current global status of the current task", + }, + "type": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Type of the current task", + MarkdownDescription: "Type of the current task", + }, + }, + CustomType: CurrentTasksType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentTasksValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentTasksValue](ctx), + Computed: true, + Description: "Asynchronous operations ongoing on the vRack Services", + MarkdownDescription: "Asynchronous operations ongoing on the vRack Services", + }, + "iam": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Resource display name", + MarkdownDescription: "Resource display name", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier of the resource", + MarkdownDescription: "Unique identifier of the resource", + }, + "state": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Resource state", + MarkdownDescription: "Resource state", + }, + "tags": schema.MapAttribute{ + CustomType: ovhtypes.NewTfMapNestedType[ovhtypes.TfStringValue](ctx), + Computed: true, + Description: "Resource tags. Tags that were internally computed are prefixed with ovh:", + MarkdownDescription: "Resource tags. Tags that were internally computed are prefixed with ovh:", + }, + "urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique resource name used in policies", + MarkdownDescription: "Unique resource name used in policies", + }, + }, + CustomType: VrackservicessIamType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessIamValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "IAM resource metadata", + MarkdownDescription: "IAM resource metadata", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier", + MarkdownDescription: "Unique identifier", + }, + "resource_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status", + MarkdownDescription: "Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status", + }, + "target_spec": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "subnets": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24", + MarkdownDescription: "IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24", + }, + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$`", + MarkdownDescription: "Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$`", + }, + "service_endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "managed_service_urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call", + MarkdownDescription: "IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call", + }, + }, + CustomType: TargetSpecSubnetsServiceEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[TargetSpecSubnetsServiceEndpointsValue](ctx), + Computed: true, + Description: "Target specification of the Service Endpoints", + MarkdownDescription: "Target specification of the Service Endpoints", + }, + "service_range": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29", + MarkdownDescription: "IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29", + }, + }, + CustomType: TargetSpecSubnetsServiceRangeType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Defines a smaller subnet dedicated to the managed service IPs", + MarkdownDescription: "Defines a smaller subnet dedicated to the managed service IPs", + }, + "vlan": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic)", + MarkdownDescription: "Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic)", + }, + }, + CustomType: TargetSpecSubnetsType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecSubnetsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[TargetSpecSubnetsValue](ctx), + Computed: true, + Description: "Target specification of the subnets. Maximum one subnet per vRack Services", + MarkdownDescription: "Target specification of the subnets. Maximum one subnet per vRack Services", + }, + }, + CustomType: VrackServicesTargetSpecType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackServicesTargetSpecValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Last target specification of the vRack Services", + MarkdownDescription: "Last target specification of the vRack Services", + }, + "updated_at": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Date of the Last vRack Services update", + MarkdownDescription: "Date of the Last vRack Services update", + }, + "vrack_services_id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + Description: "Vrack services ID", + MarkdownDescription: "Vrack services ID", + }, + } + + return schema.Schema{ + Description: "Retrieve a vRack Services", + Attributes: attrs, + } +} + +type VrackservicesModel struct { + Checksum ovhtypes.TfStringValue `tfsdk:"checksum" json:"checksum"` + CreatedAt ovhtypes.TfStringValue `tfsdk:"created_at" json:"createdAt"` + CurrentState VrackServicesCurrentStateValue `tfsdk:"current_state" json:"currentState"` + CurrentTasks ovhtypes.TfListNestedValue[CurrentTasksValue] `tfsdk:"current_tasks" json:"currentTasks"` + Iam VrackservicessIamValue `tfsdk:"iam" json:"iam"` + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + ResourceStatus ovhtypes.TfStringValue `tfsdk:"resource_status" json:"resourceStatus"` + TargetSpec VrackServicesTargetSpecValue `tfsdk:"target_spec" json:"targetSpec"` + UpdatedAt ovhtypes.TfStringValue `tfsdk:"updated_at" json:"updatedAt"` + VrackServicesId ovhtypes.TfStringValue `tfsdk:"vrack_services_id" json:"vrackServicesId"` +} diff --git a/ovh/data_vrackservices_test.go b/ovh/data_vrackservices_test.go new file mode 100644 index 000000000..7f7a7364f --- /dev/null +++ b/ovh/data_vrackservices_test.go @@ -0,0 +1,35 @@ +package ovh + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +const testAccVrackservicesDatasourceConfig_Basic = ` +data "ovh_vrackservices" "vrackservices" { + vrack_services_id = "%s" +} +` + +func TestAccVrackservicesDataSource_basic(t *testing.T) { + id := os.Getenv("OVH_TESTACC_VRACK_SERVICES_ID_TEST") + config := fmt.Sprintf(testAccVrackservicesDatasourceConfig_Basic, id) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckVrackServicesData(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.ovh_vrackservices.vrackservices", "id", id), + resource.TestCheckResourceAttr("data.ovh_vrackservices.vrackservices", "vrack_services_id", id), + resource.TestCheckResourceAttr("data.ovh_vrackservices.vrackservices", "resource_status", "READY"), + ), + }, + }, + }) +} diff --git a/ovh/data_vrackservicess.go b/ovh/data_vrackservicess.go new file mode 100644 index 000000000..d1cba14fc --- /dev/null +++ b/ovh/data_vrackservicess.go @@ -0,0 +1,68 @@ +package ovh + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-framework/datasource" +) + +var _ datasource.DataSourceWithConfigure = (*vrackservicessDataSource)(nil) + +func NewVrackservicessDataSource() datasource.DataSource { + return &vrackservicessDataSource{} +} + +type vrackservicessDataSource struct { + config *Config +} + +func (d *vrackservicessDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_vrackservicess" +} + +func (d *vrackservicessDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + config, ok := req.ProviderData.(*Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.config = config +} + +func (d *vrackservicessDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = VrackservicessDataSourceSchema(ctx) +} + +func (d *vrackservicessDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var data VrackservicessModel + + // Read Terraform configuration data into the model + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + + if resp.Diagnostics.HasError() { + return + } + + // Read API call logic + endpoint := "/v2/vrackServices/resource" + + if err := d.config.OVHClient.Get(endpoint, &data.Vrackservicess); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} diff --git a/ovh/data_vrackservicess_gen.go b/ovh/data_vrackservicess_gen.go new file mode 100644 index 000000000..6fd39c35f --- /dev/null +++ b/ovh/data_vrackservicess_gen.go @@ -0,0 +1,6459 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package ovh + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + ovhtypes "github.com/ovh/terraform-provider-ovh/v2/ovh/types" + + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" +) + +func VrackservicessDataSourceSchema(ctx context.Context) schema.Schema { + attrs := map[string]schema.Attribute{ + "vrackservicess": schema.SetNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "checksum": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Computed hash used to control concurrent modification requests. Here, it represents the current target specification value", + MarkdownDescription: "Computed hash used to control concurrent modification requests. Here, it represents the current target specification value", + }, + "created_at": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Date of the vRack Services delivery", + MarkdownDescription: "Date of the vRack Services delivery", + }, + "current_state": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "product_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Product status of the vRack Services", + MarkdownDescription: "Product status of the vRack Services", + }, + "region": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Region of the vRack Services. List of compatible regions can be retrieved from /reference/region", + MarkdownDescription: "Region of the vRack Services. List of compatible regions can be retrieved from /reference/region", + }, + "subnets": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range of the subnet in CIDR format", + MarkdownDescription: "IP address range of the subnet in CIDR format", + }, + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Display name of the subnet", + MarkdownDescription: "Display name of the subnet", + }, + "service_endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP description defined in the managed service", + MarkdownDescription: "IP description defined in the managed service", + }, + "ip": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address assigned by OVHcloud", + MarkdownDescription: "IP address assigned by OVHcloud", + }, + }, + CustomType: VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + Computed: true, + Description: "Endpoints representing the IPs assigned to the managed services", + MarkdownDescription: "Endpoints representing the IPs assigned to the managed services", + }, + "managed_service_urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call.", + MarkdownDescription: "IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call.", + }, + }, + CustomType: VrackservicessCurrentStateSubnetsServiceEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessCurrentStateSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsServiceEndpointsValue](ctx), + Computed: true, + Description: "Service endpoints of the subnet", + MarkdownDescription: "Service endpoints of the subnet", + }, + "service_range": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "CIDR dedicated to the subnet's services", + MarkdownDescription: "CIDR dedicated to the subnet's services", + }, + "remaining_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of remaining IPs in the service range", + MarkdownDescription: "Number of remaining IPs in the service range", + }, + "reserved_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of service range IPs reserved by OVHcloud", + MarkdownDescription: "Number of service range IPs reserved by OVHcloud", + }, + "used_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of service range IPs assigned to the managed services", + MarkdownDescription: "Number of service range IPs assigned to the managed services", + }, + }, + CustomType: VrackservicessCurrentStateSubnetsServiceRangeType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessCurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Defines a smaller subnet dedicated to the managed services IPs", + MarkdownDescription: "Defines a smaller subnet dedicated to the managed services IPs", + }, + "vlan": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Unique inner VLAN that allows subnets segregation", + MarkdownDescription: "Unique inner VLAN that allows subnets segregation", + }, + }, + CustomType: VrackservicessCurrentStateSubnetsType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessCurrentStateSubnetsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsValue](ctx), + Computed: true, + Description: "Subnets of the current vRack Services", + MarkdownDescription: "Subnets of the current vRack Services", + }, + "vrack_id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "vRack associated to the vRack Services", + MarkdownDescription: "vRack associated to the vRack Services", + }, + }, + CustomType: VrackservicessCurrentStateType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessCurrentStateValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Current configuration applied to the vRack Services", + MarkdownDescription: "Current configuration applied to the vRack Services", + }, + "current_tasks": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Identifier of the current task", + MarkdownDescription: "Identifier of the current task", + }, + "link": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Link to the task details", + MarkdownDescription: "Link to the task details", + }, + "status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Current global status of the current task", + MarkdownDescription: "Current global status of the current task", + }, + "type": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Type of the current task", + MarkdownDescription: "Type of the current task", + }, + }, + CustomType: VrackservicessCurrentTasksType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessCurrentTasksValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessCurrentTasksValue](ctx), + Computed: true, + Description: "Asynchronous operations ongoing on the vRack Services", + MarkdownDescription: "Asynchronous operations ongoing on the vRack Services", + }, + "iam": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Resource display name", + MarkdownDescription: "Resource display name", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier of the resource", + MarkdownDescription: "Unique identifier of the resource", + }, + "state": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Resource state", + MarkdownDescription: "Resource state", + }, + "tags": schema.MapAttribute{ + CustomType: ovhtypes.NewTfMapNestedType[ovhtypes.TfStringValue](ctx), + Computed: true, + Description: "Resource tags. Tags that were internally computed are prefixed with ovh:", + MarkdownDescription: "Resource tags. Tags that were internally computed are prefixed with ovh:", + }, + "urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique resource name used in policies", + MarkdownDescription: "Unique resource name used in policies", + }, + }, + CustomType: VrackservicessIamType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessIamValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "IAM resource metadata", + MarkdownDescription: "IAM resource metadata", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier", + MarkdownDescription: "Unique identifier", + }, + "resource_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status", + MarkdownDescription: "Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status", + }, + "target_spec": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "subnets": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24", + MarkdownDescription: "IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24", + }, + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$`", + MarkdownDescription: "Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$`", + }, + "service_endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "managed_service_urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call", + MarkdownDescription: "IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call", + }, + }, + CustomType: VrackservicessTargetSpecSubnetsServiceEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessTargetSpecSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessTargetSpecSubnetsServiceEndpointsValue](ctx), + Computed: true, + Description: "Target specification of the Service Endpoints", + MarkdownDescription: "Target specification of the Service Endpoints", + }, + "service_range": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29", + MarkdownDescription: "IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29", + }, + }, + CustomType: VrackservicessTargetSpecSubnetsServiceRangeType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessTargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Defines a smaller subnet dedicated to the managed service IPs", + MarkdownDescription: "Defines a smaller subnet dedicated to the managed service IPs", + }, + "vlan": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic)", + MarkdownDescription: "Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic)", + }, + }, + CustomType: VrackservicessTargetSpecSubnetsType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessTargetSpecSubnetsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessTargetSpecSubnetsValue](ctx), + Computed: true, + Description: "Target specification of the subnets. Maximum one subnet per vRack Services", + MarkdownDescription: "Target specification of the subnets. Maximum one subnet per vRack Services", + }, + }, + CustomType: VrackservicessTargetSpecType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessTargetSpecValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Last target specification of the vRack Services", + MarkdownDescription: "Last target specification of the vRack Services", + }, + "updated_at": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Date of the Last vRack Services update", + MarkdownDescription: "Date of the Last vRack Services update", + }, + }, + CustomType: VrackservicessType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackservicessValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackservicessValue](ctx), + Computed: true, + }, + } + + return schema.Schema{ + Description: "List all vRack Services", + Attributes: attrs, + } +} + +type VrackservicessModel struct { + Vrackservicess ovhtypes.TfListNestedValue[VrackservicessValue] `tfsdk:"vrackservicess" json:"vrackservicess"` +} + +func (v *VrackservicessModel) MergeWith(other *VrackservicessModel) { + + if (v.Vrackservicess.IsUnknown() || v.Vrackservicess.IsNull()) && !other.Vrackservicess.IsUnknown() { + v.Vrackservicess = other.Vrackservicess + } + +} + +var _ basetypes.ObjectTypable = VrackservicessType{} + +type VrackservicessType struct { + basetypes.ObjectType +} + +func (t VrackservicessType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessType) String() string { + return "VrackservicessType" +} + +func (t VrackservicessType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + checksumAttribute, ok := attributes["checksum"] + + if !ok { + diags.AddError( + "Attribute Missing", + `checksum is missing from object`) + + return nil, diags + } + + checksumVal, ok := checksumAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`checksum expected to be ovhtypes.TfStringValue, was: %T`, checksumAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return nil, diags + } + + createdAtVal, ok := createdAtAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be ovhtypes.TfStringValue, was: %T`, createdAtAttribute)) + } + + currentStateAttribute, ok := attributes["current_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `current_state is missing from object`) + + return nil, diags + } + + currentStateVal, ok := currentStateAttribute.(VrackservicessCurrentStateValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`current_state expected to be VrackservicessCurrentStateValue, was: %T`, currentStateAttribute)) + } + + currentTasksAttribute, ok := attributes["current_tasks"] + + if !ok { + diags.AddError( + "Attribute Missing", + `current_tasks is missing from object`) + + return nil, diags + } + + currentTasksVal, ok := currentTasksAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentTasksValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`current_tasks expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentTasksValue], was: %T`, currentTasksAttribute)) + } + + iamAttribute, ok := attributes["iam"] + + if !ok { + diags.AddError( + "Attribute Missing", + `iam is missing from object`) + + return nil, diags + } + + iamVal, ok := iamAttribute.(VrackservicessIamValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`iam expected to be VrackservicessIamValue, was: %T`, iamAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + resourceStatusAttribute, ok := attributes["resource_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `resource_status is missing from object`) + + return nil, diags + } + + resourceStatusVal, ok := resourceStatusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`resource_status expected to be ovhtypes.TfStringValue, was: %T`, resourceStatusAttribute)) + } + + targetSpecAttribute, ok := attributes["target_spec"] + + if !ok { + diags.AddError( + "Attribute Missing", + `target_spec is missing from object`) + + return nil, diags + } + + targetSpecVal, ok := targetSpecAttribute.(VrackservicessTargetSpecValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`target_spec expected to be VrackservicessTargetSpecValue, was: %T`, targetSpecAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return nil, diags + } + + updatedAtVal, ok := updatedAtAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be ovhtypes.TfStringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessValue{ + Checksum: checksumVal, + CreatedAt: createdAtVal, + CurrentState: currentStateVal, + CurrentTasks: currentTasksVal, + Iam: iamVal, + Id: idVal, + ResourceStatus: resourceStatusVal, + TargetSpec: targetSpecVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessValueNull() VrackservicessValue { + return VrackservicessValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessValueUnknown() VrackservicessValue { + return VrackservicessValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessValue Attribute Value", + "While creating a VrackservicessValue value, a missing attribute value was detected. "+ + "A VrackservicessValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessValue Attribute Type", + "While creating a VrackservicessValue value, an invalid attribute value was detected. "+ + "A VrackservicessValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessValue Attribute Value", + "While creating a VrackservicessValue value, an extra attribute value was detected. "+ + "A VrackservicessValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessValueUnknown(), diags + } + + checksumAttribute, ok := attributes["checksum"] + + if !ok { + diags.AddError( + "Attribute Missing", + `checksum is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + checksumVal, ok := checksumAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`checksum expected to be ovhtypes.TfStringValue, was: %T`, checksumAttribute)) + } + + createdAtAttribute, ok := attributes["created_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `created_at is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + createdAtVal, ok := createdAtAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`created_at expected to be ovhtypes.TfStringValue, was: %T`, createdAtAttribute)) + } + + currentStateAttribute, ok := attributes["current_state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `current_state is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + currentStateVal, ok := currentStateAttribute.(VrackservicessCurrentStateValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`current_state expected to be VrackservicessCurrentStateValue, was: %T`, currentStateAttribute)) + } + + currentTasksAttribute, ok := attributes["current_tasks"] + + if !ok { + diags.AddError( + "Attribute Missing", + `current_tasks is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + currentTasksVal, ok := currentTasksAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentTasksValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`current_tasks expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentTasksValue], was: %T`, currentTasksAttribute)) + } + + iamAttribute, ok := attributes["iam"] + + if !ok { + diags.AddError( + "Attribute Missing", + `iam is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + iamVal, ok := iamAttribute.(VrackservicessIamValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`iam expected to be VrackservicessIamValue, was: %T`, iamAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + resourceStatusAttribute, ok := attributes["resource_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `resource_status is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + resourceStatusVal, ok := resourceStatusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`resource_status expected to be ovhtypes.TfStringValue, was: %T`, resourceStatusAttribute)) + } + + targetSpecAttribute, ok := attributes["target_spec"] + + if !ok { + diags.AddError( + "Attribute Missing", + `target_spec is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + targetSpecVal, ok := targetSpecAttribute.(VrackservicessTargetSpecValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`target_spec expected to be VrackservicessTargetSpecValue, was: %T`, targetSpecAttribute)) + } + + updatedAtAttribute, ok := attributes["updated_at"] + + if !ok { + diags.AddError( + "Attribute Missing", + `updated_at is missing from object`) + + return NewVrackservicessValueUnknown(), diags + } + + updatedAtVal, ok := updatedAtAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`updated_at expected to be ovhtypes.TfStringValue, was: %T`, updatedAtAttribute)) + } + + if diags.HasError() { + return NewVrackservicessValueUnknown(), diags + } + + return VrackservicessValue{ + Checksum: checksumVal, + CreatedAt: createdAtVal, + CurrentState: currentStateVal, + CurrentTasks: currentTasksVal, + Iam: iamVal, + Id: idVal, + ResourceStatus: resourceStatusVal, + TargetSpec: targetSpecVal, + UpdatedAt: updatedAtVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessValue { + object, diags := NewVrackservicessValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessValueMust(VrackservicessValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessType) ValueType(ctx context.Context) attr.Value { + return VrackservicessValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessValue{} + +type VrackservicessValue struct { + Checksum ovhtypes.TfStringValue `tfsdk:"checksum" json:"checksum"` + CreatedAt ovhtypes.TfStringValue `tfsdk:"created_at" json:"createdAt"` + CurrentState VrackservicessCurrentStateValue `tfsdk:"current_state" json:"currentState"` + CurrentTasks ovhtypes.TfListNestedValue[VrackservicessCurrentTasksValue] `tfsdk:"current_tasks" json:"currentTasks"` + Iam VrackservicessIamValue `tfsdk:"iam" json:"iam"` + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + ResourceStatus ovhtypes.TfStringValue `tfsdk:"resource_status" json:"resourceStatus"` + TargetSpec VrackservicessTargetSpecValue `tfsdk:"target_spec" json:"targetSpec"` + UpdatedAt ovhtypes.TfStringValue `tfsdk:"updated_at" json:"updatedAt"` + state attr.ValueState +} + +func (v *VrackservicessValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessValue VrackservicessValue + + var tmp JsonVrackservicessValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Checksum = tmp.Checksum + v.CreatedAt = tmp.CreatedAt + v.CurrentState = tmp.CurrentState + v.CurrentTasks = tmp.CurrentTasks + v.Iam = tmp.Iam + v.Id = tmp.Id + v.ResourceStatus = tmp.ResourceStatus + v.TargetSpec = tmp.TargetSpec + v.UpdatedAt = tmp.UpdatedAt + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessValue) MergeWith(other *VrackservicessValue) { + + if (v.Checksum.IsUnknown() || v.Checksum.IsNull()) && !other.Checksum.IsUnknown() { + v.Checksum = other.Checksum + } + + if (v.CreatedAt.IsUnknown() || v.CreatedAt.IsNull()) && !other.CreatedAt.IsUnknown() { + v.CreatedAt = other.CreatedAt + } + + if (v.CurrentState.IsUnknown() || v.CurrentState.IsNull()) && !other.CurrentState.IsUnknown() { + v.CurrentState = other.CurrentState + } + + if (v.CurrentTasks.IsUnknown() || v.CurrentTasks.IsNull()) && !other.CurrentTasks.IsUnknown() { + v.CurrentTasks = other.CurrentTasks + } + + if (v.Iam.IsUnknown() || v.Iam.IsNull()) && !other.Iam.IsUnknown() { + v.Iam = other.Iam + } + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if (v.ResourceStatus.IsUnknown() || v.ResourceStatus.IsNull()) && !other.ResourceStatus.IsUnknown() { + v.ResourceStatus = other.ResourceStatus + } + + if (v.TargetSpec.IsUnknown() || v.TargetSpec.IsNull()) && !other.TargetSpec.IsUnknown() { + v.TargetSpec = other.TargetSpec + } + + if (v.UpdatedAt.IsUnknown() || v.UpdatedAt.IsNull()) && !other.UpdatedAt.IsUnknown() { + v.UpdatedAt = other.UpdatedAt + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "checksum": v.Checksum, + "createdAt": v.CreatedAt, + "currentState": v.CurrentState, + "currentTasks": v.CurrentTasks, + "iam": v.Iam, + "id": v.Id, + "resourceStatus": v.ResourceStatus, + "targetSpec": v.TargetSpec, + "updatedAt": v.UpdatedAt, + } +} +func (v VrackservicessValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 9) + + var val tftypes.Value + var err error + + attrTypes["checksum"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["created_at"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["current_state"] = basetypes.ObjectType{ + AttrTypes: VrackservicessCurrentStateValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["current_tasks"] = basetypes.ListType{ + ElemType: VrackservicessCurrentTasksValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["iam"] = basetypes.ObjectType{ + AttrTypes: VrackservicessIamValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["resource_status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["target_spec"] = basetypes.ObjectType{ + AttrTypes: VrackservicessTargetSpecValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["updated_at"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 9) + + val, err = v.Checksum.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["checksum"] = val + + val, err = v.CreatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["created_at"] = val + + val, err = v.CurrentState.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["current_state"] = val + + val, err = v.CurrentTasks.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["current_tasks"] = val + + val, err = v.Iam.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["iam"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.ResourceStatus.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["resource_status"] = val + + val, err = v.TargetSpec.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["target_spec"] = val + + val, err = v.UpdatedAt.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["updated_at"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessValue) String() string { + return "VrackservicessValue" +} + +func (v VrackservicessValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "checksum": ovhtypes.TfStringType{}, + "created_at": ovhtypes.TfStringType{}, + "current_state": VrackservicessCurrentStateType{ + basetypes.ObjectType{ + AttrTypes: VrackservicessCurrentStateValue{}.AttributeTypes(ctx), + }, + }, + "current_tasks": ovhtypes.NewTfListNestedType[VrackservicessCurrentTasksValue](ctx), + "iam": VrackservicessIamType{ + basetypes.ObjectType{ + AttrTypes: VrackservicessIamValue{}.AttributeTypes(ctx), + }, + }, + "id": ovhtypes.TfStringType{}, + "resource_status": ovhtypes.TfStringType{}, + "target_spec": VrackservicessTargetSpecType{ + basetypes.ObjectType{ + AttrTypes: VrackservicessTargetSpecValue{}.AttributeTypes(ctx), + }, + }, + "updated_at": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "checksum": v.Checksum, + "created_at": v.CreatedAt, + "current_state": v.CurrentState, + "current_tasks": v.CurrentTasks, + "iam": v.Iam, + "id": v.Id, + "resource_status": v.ResourceStatus, + "target_spec": v.TargetSpec, + "updated_at": v.UpdatedAt, + }) + + return objVal, diags +} + +func (v VrackservicessValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Checksum.Equal(other.Checksum) { + return false + } + + if !v.CreatedAt.Equal(other.CreatedAt) { + return false + } + + if !v.CurrentState.Equal(other.CurrentState) { + return false + } + + if !v.CurrentTasks.Equal(other.CurrentTasks) { + return false + } + + if !v.Iam.Equal(other.Iam) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.ResourceStatus.Equal(other.ResourceStatus) { + return false + } + + if !v.TargetSpec.Equal(other.TargetSpec) { + return false + } + + if !v.UpdatedAt.Equal(other.UpdatedAt) { + return false + } + + return true +} + +func (v VrackservicessValue) Type(ctx context.Context) attr.Type { + return VrackservicessType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "checksum": ovhtypes.TfStringType{}, + "created_at": ovhtypes.TfStringType{}, + "current_state": VrackservicessCurrentStateValue{}.Type(ctx), + "current_tasks": ovhtypes.NewTfListNestedType[VrackservicessCurrentTasksValue](ctx), + "iam": VrackservicessIamValue{}.Type(ctx), + "id": ovhtypes.TfStringType{}, + "resource_status": ovhtypes.TfStringType{}, + "target_spec": VrackservicessTargetSpecValue{}.Type(ctx), + "updated_at": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessCurrentStateType{} + +type VrackservicessCurrentStateType struct { + basetypes.ObjectType +} + +func (t VrackservicessCurrentStateType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessCurrentStateType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessCurrentStateType) String() string { + return "VrackservicessCurrentStateType" +} + +func (t VrackservicessCurrentStateType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + productStatusAttribute, ok := attributes["product_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `product_status is missing from object`) + + return nil, diags + } + + productStatusVal, ok := productStatusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`product_status expected to be ovhtypes.TfStringValue, was: %T`, productStatusAttribute)) + } + + regionAttribute, ok := attributes["region"] + + if !ok { + diags.AddError( + "Attribute Missing", + `region is missing from object`) + + return nil, diags + } + + regionVal, ok := regionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`region expected to be ovhtypes.TfStringValue, was: %T`, regionAttribute)) + } + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return nil, diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsValue], was: %T`, subnetsAttribute)) + } + + vrackIdAttribute, ok := attributes["vrack_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vrack_id is missing from object`) + + return nil, diags + } + + vrackIdVal, ok := vrackIdAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vrack_id expected to be ovhtypes.TfStringValue, was: %T`, vrackIdAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessCurrentStateValue{ + ProductStatus: productStatusVal, + Region: regionVal, + Subnets: subnetsVal, + VrackId: vrackIdVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateValueNull() VrackservicessCurrentStateValue { + return VrackservicessCurrentStateValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessCurrentStateValueUnknown() VrackservicessCurrentStateValue { + return VrackservicessCurrentStateValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessCurrentStateValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessCurrentStateValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessCurrentStateValue Attribute Value", + "While creating a VrackservicessCurrentStateValue value, a missing attribute value was detected. "+ + "A VrackservicessCurrentStateValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessCurrentStateValue Attribute Type", + "While creating a VrackservicessCurrentStateValue value, an invalid attribute value was detected. "+ + "A VrackservicessCurrentStateValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessCurrentStateValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessCurrentStateValue Attribute Value", + "While creating a VrackservicessCurrentStateValue value, an extra attribute value was detected. "+ + "A VrackservicessCurrentStateValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessCurrentStateValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessCurrentStateValueUnknown(), diags + } + + productStatusAttribute, ok := attributes["product_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `product_status is missing from object`) + + return NewVrackservicessCurrentStateValueUnknown(), diags + } + + productStatusVal, ok := productStatusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`product_status expected to be ovhtypes.TfStringValue, was: %T`, productStatusAttribute)) + } + + regionAttribute, ok := attributes["region"] + + if !ok { + diags.AddError( + "Attribute Missing", + `region is missing from object`) + + return NewVrackservicessCurrentStateValueUnknown(), diags + } + + regionVal, ok := regionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`region expected to be ovhtypes.TfStringValue, was: %T`, regionAttribute)) + } + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return NewVrackservicessCurrentStateValueUnknown(), diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsValue], was: %T`, subnetsAttribute)) + } + + vrackIdAttribute, ok := attributes["vrack_id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vrack_id is missing from object`) + + return NewVrackservicessCurrentStateValueUnknown(), diags + } + + vrackIdVal, ok := vrackIdAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vrack_id expected to be ovhtypes.TfStringValue, was: %T`, vrackIdAttribute)) + } + + if diags.HasError() { + return NewVrackservicessCurrentStateValueUnknown(), diags + } + + return VrackservicessCurrentStateValue{ + ProductStatus: productStatusVal, + Region: regionVal, + Subnets: subnetsVal, + VrackId: vrackIdVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessCurrentStateValue { + object, diags := NewVrackservicessCurrentStateValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessCurrentStateValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessCurrentStateType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessCurrentStateValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessCurrentStateValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessCurrentStateValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessCurrentStateValueMust(VrackservicessCurrentStateValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessCurrentStateType) ValueType(ctx context.Context) attr.Value { + return VrackservicessCurrentStateValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessCurrentStateValue{} + +type VrackservicessCurrentStateValue struct { + ProductStatus ovhtypes.TfStringValue `tfsdk:"product_status" json:"productStatus"` + Region ovhtypes.TfStringValue `tfsdk:"region" json:"region"` + Subnets ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsValue] `tfsdk:"subnets" json:"subnets"` + VrackId ovhtypes.TfStringValue `tfsdk:"vrack_id" json:"vrackId"` + state attr.ValueState +} + +func (v *VrackservicessCurrentStateValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessCurrentStateValue VrackservicessCurrentStateValue + + var tmp JsonVrackservicessCurrentStateValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.ProductStatus = tmp.ProductStatus + v.Region = tmp.Region + v.Subnets = tmp.Subnets + v.VrackId = tmp.VrackId + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessCurrentStateValue) MergeWith(other *VrackservicessCurrentStateValue) { + + if (v.ProductStatus.IsUnknown() || v.ProductStatus.IsNull()) && !other.ProductStatus.IsUnknown() { + v.ProductStatus = other.ProductStatus + } + + if (v.Region.IsUnknown() || v.Region.IsNull()) && !other.Region.IsUnknown() { + v.Region = other.Region + } + + if (v.Subnets.IsUnknown() || v.Subnets.IsNull()) && !other.Subnets.IsUnknown() { + v.Subnets = other.Subnets + } + + if (v.VrackId.IsUnknown() || v.VrackId.IsNull()) && !other.VrackId.IsUnknown() { + v.VrackId = other.VrackId + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessCurrentStateValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "productStatus": v.ProductStatus, + "region": v.Region, + "subnets": v.Subnets, + "vrackId": v.VrackId, + } +} +func (v VrackservicessCurrentStateValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["product_status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["region"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["subnets"] = basetypes.ListType{ + ElemType: VrackservicessCurrentStateSubnetsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["vrack_id"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.ProductStatus.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["product_status"] = val + + val, err = v.Region.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["region"] = val + + val, err = v.Subnets.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["subnets"] = val + + val, err = v.VrackId.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["vrack_id"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessCurrentStateValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessCurrentStateValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessCurrentStateValue) String() string { + return "VrackservicessCurrentStateValue" +} + +func (v VrackservicessCurrentStateValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "product_status": ovhtypes.TfStringType{}, + "region": ovhtypes.TfStringType{}, + "subnets": ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsValue](ctx), + "vrack_id": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "product_status": v.ProductStatus, + "region": v.Region, + "subnets": v.Subnets, + "vrack_id": v.VrackId, + }) + + return objVal, diags +} + +func (v VrackservicessCurrentStateValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessCurrentStateValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ProductStatus.Equal(other.ProductStatus) { + return false + } + + if !v.Region.Equal(other.Region) { + return false + } + + if !v.Subnets.Equal(other.Subnets) { + return false + } + + if !v.VrackId.Equal(other.VrackId) { + return false + } + + return true +} + +func (v VrackservicessCurrentStateValue) Type(ctx context.Context) attr.Type { + return VrackservicessCurrentStateType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessCurrentStateValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "product_status": ovhtypes.TfStringType{}, + "region": ovhtypes.TfStringType{}, + "subnets": ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsValue](ctx), + "vrack_id": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessCurrentStateSubnetsType{} + +type VrackservicessCurrentStateSubnetsType struct { + basetypes.ObjectType +} + +func (t VrackservicessCurrentStateSubnetsType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessCurrentStateSubnetsType) String() string { + return "VrackservicessCurrentStateSubnetsType" +} + +func (t VrackservicessCurrentStateSubnetsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return nil, diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return nil, diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return nil, diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(VrackservicessCurrentStateSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be VrackservicessCurrentStateSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return nil, diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessCurrentStateSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsValueNull() VrackservicessCurrentStateSubnetsValue { + return VrackservicessCurrentStateSubnetsValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessCurrentStateSubnetsValueUnknown() VrackservicessCurrentStateSubnetsValue { + return VrackservicessCurrentStateSubnetsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessCurrentStateSubnetsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessCurrentStateSubnetsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessCurrentStateSubnetsValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsValue value, a missing attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessCurrentStateSubnetsValue Attribute Type", + "While creating a VrackservicessCurrentStateSubnetsValue value, an invalid attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessCurrentStateSubnetsValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsValue value, an extra attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessCurrentStateSubnetsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(VrackservicessCurrentStateSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be VrackservicessCurrentStateSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsValueUnknown(), diags + } + + return VrackservicessCurrentStateSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessCurrentStateSubnetsValue { + object, diags := NewVrackservicessCurrentStateSubnetsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessCurrentStateSubnetsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessCurrentStateSubnetsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessCurrentStateSubnetsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessCurrentStateSubnetsValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessCurrentStateSubnetsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessCurrentStateSubnetsValueMust(VrackservicessCurrentStateSubnetsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessCurrentStateSubnetsType) ValueType(ctx context.Context) attr.Value { + return VrackservicessCurrentStateSubnetsValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessCurrentStateSubnetsValue{} + +type VrackservicessCurrentStateSubnetsValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + DisplayName ovhtypes.TfStringValue `tfsdk:"display_name" json:"displayName"` + ServiceEndpoints ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsValue] `tfsdk:"service_endpoints" json:"serviceEndpoints"` + ServiceRange VrackservicessCurrentStateSubnetsServiceRangeValue `tfsdk:"service_range" json:"serviceRange"` + Vlan ovhtypes.TfInt64Value `tfsdk:"vlan" json:"vlan"` + state attr.ValueState +} + +func (v *VrackservicessCurrentStateSubnetsValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessCurrentStateSubnetsValue VrackservicessCurrentStateSubnetsValue + + var tmp JsonVrackservicessCurrentStateSubnetsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + v.DisplayName = tmp.DisplayName + v.ServiceEndpoints = tmp.ServiceEndpoints + v.ServiceRange = tmp.ServiceRange + v.Vlan = tmp.Vlan + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessCurrentStateSubnetsValue) MergeWith(other *VrackservicessCurrentStateSubnetsValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.DisplayName.IsUnknown() || v.DisplayName.IsNull()) && !other.DisplayName.IsUnknown() { + v.DisplayName = other.DisplayName + } + + if (v.ServiceEndpoints.IsUnknown() || v.ServiceEndpoints.IsNull()) && !other.ServiceEndpoints.IsUnknown() { + v.ServiceEndpoints = other.ServiceEndpoints + } + + if (v.ServiceRange.IsUnknown() || v.ServiceRange.IsNull()) && !other.ServiceRange.IsUnknown() { + v.ServiceRange = other.ServiceRange + } + + if (v.Vlan.IsUnknown() || v.Vlan.IsNull()) && !other.Vlan.IsUnknown() { + v.Vlan = other.Vlan + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessCurrentStateSubnetsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + "displayName": v.DisplayName, + "serviceEndpoints": v.ServiceEndpoints, + "serviceRange": v.ServiceRange, + "vlan": v.Vlan, + } +} +func (v VrackservicessCurrentStateSubnetsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["display_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["service_endpoints"] = basetypes.ListType{ + ElemType: VrackservicessCurrentStateSubnetsServiceEndpointsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["service_range"] = basetypes.ObjectType{ + AttrTypes: VrackservicessCurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["vlan"] = basetypes.Int64Type{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + val, err = v.DisplayName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["display_name"] = val + + val, err = v.ServiceEndpoints.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_endpoints"] = val + + val, err = v.ServiceRange.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_range"] = val + + val, err = v.Vlan.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["vlan"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessCurrentStateSubnetsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessCurrentStateSubnetsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessCurrentStateSubnetsValue) String() string { + return "VrackservicessCurrentStateSubnetsValue" +} + +func (v VrackservicessCurrentStateSubnetsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsServiceEndpointsValue](ctx), + "service_range": VrackservicessCurrentStateSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: VrackservicessCurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + "vlan": ovhtypes.TfInt64Type{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + "display_name": v.DisplayName, + "service_endpoints": v.ServiceEndpoints, + "service_range": v.ServiceRange, + "vlan": v.Vlan, + }) + + return objVal, diags +} + +func (v VrackservicessCurrentStateSubnetsValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + if !v.DisplayName.Equal(other.DisplayName) { + return false + } + + if !v.ServiceEndpoints.Equal(other.ServiceEndpoints) { + return false + } + + if !v.ServiceRange.Equal(other.ServiceRange) { + return false + } + + if !v.Vlan.Equal(other.Vlan) { + return false + } + + return true +} + +func (v VrackservicessCurrentStateSubnetsValue) Type(ctx context.Context) attr.Type { + return VrackservicessCurrentStateSubnetsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessCurrentStateSubnetsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsServiceEndpointsValue](ctx), + "service_range": VrackservicessCurrentStateSubnetsServiceRangeValue{}.Type(ctx), + "vlan": ovhtypes.TfInt64Type{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessCurrentStateSubnetsServiceEndpointsType{} + +type VrackservicessCurrentStateSubnetsServiceEndpointsType struct { + basetypes.ObjectType +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsServiceEndpointsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsType) String() string { + return "VrackservicessCurrentStateSubnetsServiceEndpointsType" +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + endpointsAttribute, ok := attributes["endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `endpoints is missing from object`) + + return nil, diags + } + + endpointsVal, ok := endpointsAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`endpoints expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue], was: %T`, endpointsAttribute)) + } + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return nil, diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessCurrentStateSubnetsServiceEndpointsValue{ + Endpoints: endpointsVal, + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsValueNull() VrackservicessCurrentStateSubnetsServiceEndpointsValue { + return VrackservicessCurrentStateSubnetsServiceEndpointsValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsValueUnknown() VrackservicessCurrentStateSubnetsServiceEndpointsValue { + return VrackservicessCurrentStateSubnetsServiceEndpointsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessCurrentStateSubnetsServiceEndpointsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsServiceEndpointsValue value, a missing attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceEndpointsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Type", + "While creating a VrackservicessCurrentStateSubnetsServiceEndpointsValue value, an invalid attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceEndpointsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsServiceEndpointsValue value, an extra attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceEndpointsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessCurrentStateSubnetsServiceEndpointsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + endpointsAttribute, ok := attributes["endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `endpoints is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + endpointsVal, ok := endpointsAttribute.(ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`endpoints expected to be ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue], was: %T`, endpointsAttribute)) + } + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + return VrackservicessCurrentStateSubnetsServiceEndpointsValue{ + Endpoints: endpointsVal, + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessCurrentStateSubnetsServiceEndpointsValue { + object, diags := NewVrackservicessCurrentStateSubnetsServiceEndpointsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessCurrentStateSubnetsServiceEndpointsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessCurrentStateSubnetsServiceEndpointsValueMust(VrackservicessCurrentStateSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsType) ValueType(ctx context.Context) attr.Value { + return VrackservicessCurrentStateSubnetsServiceEndpointsValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessCurrentStateSubnetsServiceEndpointsValue{} + +type VrackservicessCurrentStateSubnetsServiceEndpointsValue struct { + Endpoints ovhtypes.TfListNestedValue[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue] `tfsdk:"endpoints" json:"endpoints"` + ManagedServiceUrn ovhtypes.TfStringValue `tfsdk:"managed_service_urn" json:"managedServiceUrn"` + state attr.ValueState +} + +func (v *VrackservicessCurrentStateSubnetsServiceEndpointsValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessCurrentStateSubnetsServiceEndpointsValue VrackservicessCurrentStateSubnetsServiceEndpointsValue + + var tmp JsonVrackservicessCurrentStateSubnetsServiceEndpointsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Endpoints = tmp.Endpoints + v.ManagedServiceUrn = tmp.ManagedServiceUrn + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessCurrentStateSubnetsServiceEndpointsValue) MergeWith(other *VrackservicessCurrentStateSubnetsServiceEndpointsValue) { + + if (v.Endpoints.IsUnknown() || v.Endpoints.IsNull()) && !other.Endpoints.IsUnknown() { + v.Endpoints = other.Endpoints + } + + if (v.ManagedServiceUrn.IsUnknown() || v.ManagedServiceUrn.IsNull()) && !other.ManagedServiceUrn.IsUnknown() { + v.ManagedServiceUrn = other.ManagedServiceUrn + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "endpoints": v.Endpoints, + "managedServiceUrn": v.ManagedServiceUrn, + } +} +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["endpoints"] = basetypes.ListType{ + ElemType: VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["managed_service_urn"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Endpoints.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["endpoints"] = val + + val, err = v.ManagedServiceUrn.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["managed_service_urn"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) String() string { + return "VrackservicessCurrentStateSubnetsServiceEndpointsValue" +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "endpoints": ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + "managed_service_urn": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "endpoints": v.Endpoints, + "managed_service_urn": v.ManagedServiceUrn, + }) + + return objVal, diags +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsServiceEndpointsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Endpoints.Equal(other.Endpoints) { + return false + } + + if !v.ManagedServiceUrn.Equal(other.ManagedServiceUrn) { + return false + } + + return true +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) Type(ctx context.Context) attr.Type { + return VrackservicessCurrentStateSubnetsServiceEndpointsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "endpoints": ovhtypes.NewTfListNestedType[VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + "managed_service_urn": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType{} + +type VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType struct { + basetypes.ObjectType +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType) String() string { + return "VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType" +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + descriptionAttribute, ok := attributes["description"] + + if !ok { + diags.AddError( + "Attribute Missing", + `description is missing from object`) + + return nil, diags + } + + descriptionVal, ok := descriptionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`description expected to be ovhtypes.TfStringValue, was: %T`, descriptionAttribute)) + } + + ipAttribute, ok := attributes["ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ip is missing from object`) + + return nil, diags + } + + ipVal, ok := ipAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ip expected to be ovhtypes.TfStringValue, was: %T`, ipAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{ + Description: descriptionVal, + Ip: ipVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueNull() VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue { + return VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown() VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue { + return VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue value, a missing attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Type", + "While creating a VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue value, an invalid attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue value, an extra attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + descriptionAttribute, ok := attributes["description"] + + if !ok { + diags.AddError( + "Attribute Missing", + `description is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + descriptionVal, ok := descriptionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`description expected to be ovhtypes.TfStringValue, was: %T`, descriptionAttribute)) + } + + ipAttribute, ok := attributes["ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ip is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + ipVal, ok := ipAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ip expected to be ovhtypes.TfStringValue, was: %T`, ipAttribute)) + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + return VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{ + Description: descriptionVal, + Ip: ipVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue { + object, diags := NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValueMust(VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType) ValueType(ctx context.Context) attr.Value { + return VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue{} + +type VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue struct { + Description ovhtypes.TfStringValue `tfsdk:"description" json:"description"` + Ip ovhtypes.TfStringValue `tfsdk:"ip" json:"ip"` + state attr.ValueState +} + +func (v *VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue + + var tmp JsonVrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Description = tmp.Description + v.Ip = tmp.Ip + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) MergeWith(other *VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) { + + if (v.Description.IsUnknown() || v.Description.IsNull()) && !other.Description.IsUnknown() { + v.Description = other.Description + } + + if (v.Ip.IsUnknown() || v.Ip.IsNull()) && !other.Ip.IsUnknown() { + v.Ip = other.Ip + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "description": v.Description, + "ip": v.Ip, + } +} +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ip"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Description.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["description"] = val + + val, err = v.Ip.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ip"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) String() string { + return "VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue" +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "description": ovhtypes.TfStringType{}, + "ip": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "description": v.Description, + "ip": v.Ip, + }) + + return objVal, diags +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Description.Equal(other.Description) { + return false + } + + if !v.Ip.Equal(other.Ip) { + return false + } + + return true +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) Type(ctx context.Context) attr.Type { + return VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessCurrentStateSubnetsServiceEndpointsEndpointsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "description": ovhtypes.TfStringType{}, + "ip": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessCurrentStateSubnetsServiceRangeType{} + +type VrackservicessCurrentStateSubnetsServiceRangeType struct { + basetypes.ObjectType +} + +func (t VrackservicessCurrentStateSubnetsServiceRangeType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsServiceRangeType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessCurrentStateSubnetsServiceRangeType) String() string { + return "VrackservicessCurrentStateSubnetsServiceRangeType" +} + +func (t VrackservicessCurrentStateSubnetsServiceRangeType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + remainingIpsAttribute, ok := attributes["remaining_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `remaining_ips is missing from object`) + + return nil, diags + } + + remainingIpsVal, ok := remainingIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`remaining_ips expected to be ovhtypes.TfInt64Value, was: %T`, remainingIpsAttribute)) + } + + reservedIpsAttribute, ok := attributes["reserved_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `reserved_ips is missing from object`) + + return nil, diags + } + + reservedIpsVal, ok := reservedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`reserved_ips expected to be ovhtypes.TfInt64Value, was: %T`, reservedIpsAttribute)) + } + + usedIpsAttribute, ok := attributes["used_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `used_ips is missing from object`) + + return nil, diags + } + + usedIpsVal, ok := usedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`used_ips expected to be ovhtypes.TfInt64Value, was: %T`, usedIpsAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessCurrentStateSubnetsServiceRangeValue{ + Cidr: cidrVal, + RemainingIps: remainingIpsVal, + ReservedIps: reservedIpsVal, + UsedIps: usedIpsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsServiceRangeValueNull() VrackservicessCurrentStateSubnetsServiceRangeValue { + return VrackservicessCurrentStateSubnetsServiceRangeValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown() VrackservicessCurrentStateSubnetsServiceRangeValue { + return VrackservicessCurrentStateSubnetsServiceRangeValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessCurrentStateSubnetsServiceRangeValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessCurrentStateSubnetsServiceRangeValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsServiceRangeValue value, a missing attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceRangeValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Type", + "While creating a VrackservicessCurrentStateSubnetsServiceRangeValue value, an invalid attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceRangeValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Value", + "While creating a VrackservicessCurrentStateSubnetsServiceRangeValue value, an extra attribute value was detected. "+ + "A VrackservicessCurrentStateSubnetsServiceRangeValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessCurrentStateSubnetsServiceRangeValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + remainingIpsAttribute, ok := attributes["remaining_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `remaining_ips is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + remainingIpsVal, ok := remainingIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`remaining_ips expected to be ovhtypes.TfInt64Value, was: %T`, remainingIpsAttribute)) + } + + reservedIpsAttribute, ok := attributes["reserved_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `reserved_ips is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + reservedIpsVal, ok := reservedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`reserved_ips expected to be ovhtypes.TfInt64Value, was: %T`, reservedIpsAttribute)) + } + + usedIpsAttribute, ok := attributes["used_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `used_ips is missing from object`) + + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + usedIpsVal, ok := usedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`used_ips expected to be ovhtypes.TfInt64Value, was: %T`, usedIpsAttribute)) + } + + if diags.HasError() { + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + return VrackservicessCurrentStateSubnetsServiceRangeValue{ + Cidr: cidrVal, + RemainingIps: remainingIpsVal, + ReservedIps: reservedIpsVal, + UsedIps: usedIpsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentStateSubnetsServiceRangeValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessCurrentStateSubnetsServiceRangeValue { + object, diags := NewVrackservicessCurrentStateSubnetsServiceRangeValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessCurrentStateSubnetsServiceRangeValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessCurrentStateSubnetsServiceRangeType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessCurrentStateSubnetsServiceRangeValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessCurrentStateSubnetsServiceRangeValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessCurrentStateSubnetsServiceRangeValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessCurrentStateSubnetsServiceRangeValueMust(VrackservicessCurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessCurrentStateSubnetsServiceRangeType) ValueType(ctx context.Context) attr.Value { + return VrackservicessCurrentStateSubnetsServiceRangeValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessCurrentStateSubnetsServiceRangeValue{} + +type VrackservicessCurrentStateSubnetsServiceRangeValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + RemainingIps ovhtypes.TfInt64Value `tfsdk:"remaining_ips" json:"remainingIps"` + ReservedIps ovhtypes.TfInt64Value `tfsdk:"reserved_ips" json:"reservedIps"` + UsedIps ovhtypes.TfInt64Value `tfsdk:"used_ips" json:"usedIps"` + state attr.ValueState +} + +func (v *VrackservicessCurrentStateSubnetsServiceRangeValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessCurrentStateSubnetsServiceRangeValue VrackservicessCurrentStateSubnetsServiceRangeValue + + var tmp JsonVrackservicessCurrentStateSubnetsServiceRangeValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + v.RemainingIps = tmp.RemainingIps + v.ReservedIps = tmp.ReservedIps + v.UsedIps = tmp.UsedIps + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessCurrentStateSubnetsServiceRangeValue) MergeWith(other *VrackservicessCurrentStateSubnetsServiceRangeValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.RemainingIps.IsUnknown() || v.RemainingIps.IsNull()) && !other.RemainingIps.IsUnknown() { + v.RemainingIps = other.RemainingIps + } + + if (v.ReservedIps.IsUnknown() || v.ReservedIps.IsNull()) && !other.ReservedIps.IsUnknown() { + v.ReservedIps = other.ReservedIps + } + + if (v.UsedIps.IsUnknown() || v.UsedIps.IsNull()) && !other.UsedIps.IsUnknown() { + v.UsedIps = other.UsedIps + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + "remainingIps": v.RemainingIps, + "reservedIps": v.ReservedIps, + "usedIps": v.UsedIps, + } +} +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["remaining_ips"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["reserved_ips"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["used_ips"] = basetypes.Int64Type{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + val, err = v.RemainingIps.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["remaining_ips"] = val + + val, err = v.ReservedIps.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["reserved_ips"] = val + + val, err = v.UsedIps.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["used_ips"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) String() string { + return "VrackservicessCurrentStateSubnetsServiceRangeValue" +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "remaining_ips": ovhtypes.TfInt64Type{}, + "reserved_ips": ovhtypes.TfInt64Type{}, + "used_ips": ovhtypes.TfInt64Type{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + "remaining_ips": v.RemainingIps, + "reserved_ips": v.ReservedIps, + "used_ips": v.UsedIps, + }) + + return objVal, diags +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessCurrentStateSubnetsServiceRangeValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + if !v.RemainingIps.Equal(other.RemainingIps) { + return false + } + + if !v.ReservedIps.Equal(other.ReservedIps) { + return false + } + + if !v.UsedIps.Equal(other.UsedIps) { + return false + } + + return true +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) Type(ctx context.Context) attr.Type { + return VrackservicessCurrentStateSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessCurrentStateSubnetsServiceRangeValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "remaining_ips": ovhtypes.TfInt64Type{}, + "reserved_ips": ovhtypes.TfInt64Type{}, + "used_ips": ovhtypes.TfInt64Type{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessCurrentTasksType{} + +type VrackservicessCurrentTasksType struct { + basetypes.ObjectType +} + +func (t VrackservicessCurrentTasksType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessCurrentTasksType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessCurrentTasksType) String() string { + return "VrackservicessCurrentTasksType" +} + +func (t VrackservicessCurrentTasksType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + linkAttribute, ok := attributes["link"] + + if !ok { + diags.AddError( + "Attribute Missing", + `link is missing from object`) + + return nil, diags + } + + linkVal, ok := linkAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`link expected to be ovhtypes.TfStringValue, was: %T`, linkAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + typeAttribute, ok := attributes["type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `type is missing from object`) + + return nil, diags + } + + typeVal, ok := typeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`type expected to be ovhtypes.TfStringValue, was: %T`, typeAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessCurrentTasksValue{ + Id: idVal, + Link: linkVal, + Status: statusVal, + VrackservicessCurrentTasksType: typeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentTasksValueNull() VrackservicessCurrentTasksValue { + return VrackservicessCurrentTasksValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessCurrentTasksValueUnknown() VrackservicessCurrentTasksValue { + return VrackservicessCurrentTasksValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessCurrentTasksValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessCurrentTasksValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessCurrentTasksValue Attribute Value", + "While creating a VrackservicessCurrentTasksValue value, a missing attribute value was detected. "+ + "A VrackservicessCurrentTasksValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentTasksValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessCurrentTasksValue Attribute Type", + "While creating a VrackservicessCurrentTasksValue value, an invalid attribute value was detected. "+ + "A VrackservicessCurrentTasksValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessCurrentTasksValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessCurrentTasksValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessCurrentTasksValue Attribute Value", + "While creating a VrackservicessCurrentTasksValue value, an extra attribute value was detected. "+ + "A VrackservicessCurrentTasksValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessCurrentTasksValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessCurrentTasksValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewVrackservicessCurrentTasksValueUnknown(), diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + linkAttribute, ok := attributes["link"] + + if !ok { + diags.AddError( + "Attribute Missing", + `link is missing from object`) + + return NewVrackservicessCurrentTasksValueUnknown(), diags + } + + linkVal, ok := linkAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`link expected to be ovhtypes.TfStringValue, was: %T`, linkAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewVrackservicessCurrentTasksValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + typeAttribute, ok := attributes["type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `type is missing from object`) + + return NewVrackservicessCurrentTasksValueUnknown(), diags + } + + typeVal, ok := typeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`type expected to be ovhtypes.TfStringValue, was: %T`, typeAttribute)) + } + + if diags.HasError() { + return NewVrackservicessCurrentTasksValueUnknown(), diags + } + + return VrackservicessCurrentTasksValue{ + Id: idVal, + Link: linkVal, + Status: statusVal, + VrackservicessCurrentTasksType: typeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessCurrentTasksValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessCurrentTasksValue { + object, diags := NewVrackservicessCurrentTasksValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessCurrentTasksValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessCurrentTasksType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessCurrentTasksValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessCurrentTasksValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessCurrentTasksValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessCurrentTasksValueMust(VrackservicessCurrentTasksValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessCurrentTasksType) ValueType(ctx context.Context) attr.Value { + return VrackservicessCurrentTasksValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessCurrentTasksValue{} + +type VrackservicessCurrentTasksValue struct { + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + Link ovhtypes.TfStringValue `tfsdk:"link" json:"link"` + Status ovhtypes.TfStringValue `tfsdk:"status" json:"status"` + VrackservicessCurrentTasksType ovhtypes.TfStringValue `tfsdk:"type" json:"type"` + state attr.ValueState +} + +func (v *VrackservicessCurrentTasksValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessCurrentTasksValue VrackservicessCurrentTasksValue + + var tmp JsonVrackservicessCurrentTasksValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Id = tmp.Id + v.Link = tmp.Link + v.Status = tmp.Status + v.VrackservicessCurrentTasksType = tmp.VrackservicessCurrentTasksType + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessCurrentTasksValue) MergeWith(other *VrackservicessCurrentTasksValue) { + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if (v.Link.IsUnknown() || v.Link.IsNull()) && !other.Link.IsUnknown() { + v.Link = other.Link + } + + if (v.Status.IsUnknown() || v.Status.IsNull()) && !other.Status.IsUnknown() { + v.Status = other.Status + } + + if (v.VrackservicessCurrentTasksType.IsUnknown() || v.VrackservicessCurrentTasksType.IsNull()) && !other.VrackservicessCurrentTasksType.IsUnknown() { + v.VrackservicessCurrentTasksType = other.VrackservicessCurrentTasksType + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessCurrentTasksValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "id": v.Id, + "link": v.Link, + "status": v.Status, + "type": v.VrackservicessCurrentTasksType, + } +} +func (v VrackservicessCurrentTasksValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["link"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["type"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Link.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["link"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.VrackservicessCurrentTasksType.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["type"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessCurrentTasksValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessCurrentTasksValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessCurrentTasksValue) String() string { + return "VrackservicessCurrentTasksValue" +} + +func (v VrackservicessCurrentTasksValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "id": ovhtypes.TfStringType{}, + "link": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + "type": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "id": v.Id, + "link": v.Link, + "status": v.Status, + "type": v.VrackservicessCurrentTasksType, + }) + + return objVal, diags +} + +func (v VrackservicessCurrentTasksValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessCurrentTasksValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Link.Equal(other.Link) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.VrackservicessCurrentTasksType.Equal(other.VrackservicessCurrentTasksType) { + return false + } + + return true +} + +func (v VrackservicessCurrentTasksValue) Type(ctx context.Context) attr.Type { + return VrackservicessCurrentTasksType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessCurrentTasksValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": ovhtypes.TfStringType{}, + "link": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + "type": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessIamType{} + +type VrackservicessIamType struct { + basetypes.ObjectType +} + +func (t VrackservicessIamType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessIamType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessIamType) String() string { + return "VrackservicessIamType" +} + +func (t VrackservicessIamType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return nil, diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + stateAttribute, ok := attributes["state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `state is missing from object`) + + return nil, diags + } + + stateVal, ok := stateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`state expected to be ovhtypes.TfStringValue, was: %T`, stateAttribute)) + } + + tagsAttribute, ok := attributes["tags"] + + if !ok { + diags.AddError( + "Attribute Missing", + `tags is missing from object`) + + return nil, diags + } + + tagsVal, ok := tagsAttribute.(ovhtypes.TfMapNestedValue[ovhtypes.TfStringValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`tags expected to be ovhtypes.TfMapNestedValue[ovhtypes.TfStringValue], was: %T`, tagsAttribute)) + } + + urnAttribute, ok := attributes["urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `urn is missing from object`) + + return nil, diags + } + + urnVal, ok := urnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`urn expected to be ovhtypes.TfStringValue, was: %T`, urnAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessIamValue{ + DisplayName: displayNameVal, + Id: idVal, + State: stateVal, + Tags: tagsVal, + Urn: urnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessIamValueNull() VrackservicessIamValue { + return VrackservicessIamValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessIamValueUnknown() VrackservicessIamValue { + return VrackservicessIamValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessIamValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessIamValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessIamValue Attribute Value", + "While creating a VrackservicessIamValue value, a missing attribute value was detected. "+ + "A VrackservicessIamValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessIamValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessIamValue Attribute Type", + "While creating a VrackservicessIamValue value, an invalid attribute value was detected. "+ + "A VrackservicessIamValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessIamValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessIamValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessIamValue Attribute Value", + "While creating a VrackservicessIamValue value, an extra attribute value was detected. "+ + "A VrackservicessIamValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessIamValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessIamValueUnknown(), diags + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return NewVrackservicessIamValueUnknown(), diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewVrackservicessIamValueUnknown(), diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + stateAttribute, ok := attributes["state"] + + if !ok { + diags.AddError( + "Attribute Missing", + `state is missing from object`) + + return NewVrackservicessIamValueUnknown(), diags + } + + stateVal, ok := stateAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`state expected to be ovhtypes.TfStringValue, was: %T`, stateAttribute)) + } + + tagsAttribute, ok := attributes["tags"] + + if !ok { + diags.AddError( + "Attribute Missing", + `tags is missing from object`) + + return NewVrackservicessIamValueUnknown(), diags + } + + tagsVal, ok := tagsAttribute.(ovhtypes.TfMapNestedValue[ovhtypes.TfStringValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`tags expected to be ovhtypes.TfMapNestedValue[ovhtypes.TfStringValue], was: %T`, tagsAttribute)) + } + + urnAttribute, ok := attributes["urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `urn is missing from object`) + + return NewVrackservicessIamValueUnknown(), diags + } + + urnVal, ok := urnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`urn expected to be ovhtypes.TfStringValue, was: %T`, urnAttribute)) + } + + if diags.HasError() { + return NewVrackservicessIamValueUnknown(), diags + } + + return VrackservicessIamValue{ + DisplayName: displayNameVal, + Id: idVal, + State: stateVal, + Tags: tagsVal, + Urn: urnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessIamValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessIamValue { + object, diags := NewVrackservicessIamValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessIamValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessIamType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessIamValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessIamValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessIamValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessIamValueMust(VrackservicessIamValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessIamType) ValueType(ctx context.Context) attr.Value { + return VrackservicessIamValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessIamValue{} + +type VrackservicessIamValue struct { + DisplayName ovhtypes.TfStringValue `tfsdk:"display_name" json:"displayName"` + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + State ovhtypes.TfStringValue `tfsdk:"state" json:"state"` + Tags ovhtypes.TfMapNestedValue[ovhtypes.TfStringValue] `tfsdk:"tags" json:"tags"` + Urn ovhtypes.TfStringValue `tfsdk:"urn" json:"urn"` + state attr.ValueState +} + +func (v *VrackservicessIamValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessIamValue VrackservicessIamValue + + var tmp JsonVrackservicessIamValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.DisplayName = tmp.DisplayName + v.Id = tmp.Id + v.State = tmp.State + v.Tags = tmp.Tags + v.Urn = tmp.Urn + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessIamValue) MergeWith(other *VrackservicessIamValue) { + + if (v.DisplayName.IsUnknown() || v.DisplayName.IsNull()) && !other.DisplayName.IsUnknown() { + v.DisplayName = other.DisplayName + } + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if (v.State.IsUnknown() || v.State.IsNull()) && !other.State.IsUnknown() { + v.State = other.State + } + + if (v.Tags.IsUnknown() || v.Tags.IsNull()) && !other.Tags.IsUnknown() { + v.Tags = other.Tags + } + + if (v.Urn.IsUnknown() || v.Urn.IsNull()) && !other.Urn.IsUnknown() { + v.Urn = other.Urn + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessIamValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "displayName": v.DisplayName, + "id": v.Id, + "state": v.State, + "tags": v.Tags, + "urn": v.Urn, + } +} +func (v VrackservicessIamValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["display_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["state"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["tags"] = basetypes.MapType{ + ElemType: types.StringType, + }.TerraformType(ctx) + attrTypes["urn"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.DisplayName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["display_name"] = val + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.State.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["state"] = val + + val, err = v.Tags.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["tags"] = val + + val, err = v.Urn.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["urn"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessIamValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessIamValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessIamValue) String() string { + return "VrackservicessIamValue" +} + +func (v VrackservicessIamValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "display_name": ovhtypes.TfStringType{}, + "id": ovhtypes.TfStringType{}, + "state": ovhtypes.TfStringType{}, + "tags": ovhtypes.NewTfMapNestedType[ovhtypes.TfStringValue](ctx), + "urn": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "display_name": v.DisplayName, + "id": v.Id, + "state": v.State, + "tags": v.Tags, + "urn": v.Urn, + }) + + return objVal, diags +} + +func (v VrackservicessIamValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessIamValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.DisplayName.Equal(other.DisplayName) { + return false + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.State.Equal(other.State) { + return false + } + + if !v.Tags.Equal(other.Tags) { + return false + } + + if !v.Urn.Equal(other.Urn) { + return false + } + + return true +} + +func (v VrackservicessIamValue) Type(ctx context.Context) attr.Type { + return VrackservicessIamType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessIamValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "display_name": ovhtypes.TfStringType{}, + "id": ovhtypes.TfStringType{}, + "state": ovhtypes.TfStringType{}, + "tags": ovhtypes.NewTfMapNestedType[ovhtypes.TfStringValue](ctx), + "urn": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessTargetSpecType{} + +type VrackservicessTargetSpecType struct { + basetypes.ObjectType +} + +func (t VrackservicessTargetSpecType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessTargetSpecType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessTargetSpecType) String() string { + return "VrackservicessTargetSpecType" +} + +func (t VrackservicessTargetSpecType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return nil, diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsValue], was: %T`, subnetsAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessTargetSpecValue{ + Subnets: subnetsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecValueNull() VrackservicessTargetSpecValue { + return VrackservicessTargetSpecValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessTargetSpecValueUnknown() VrackservicessTargetSpecValue { + return VrackservicessTargetSpecValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessTargetSpecValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessTargetSpecValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessTargetSpecValue Attribute Value", + "While creating a VrackservicessTargetSpecValue value, a missing attribute value was detected. "+ + "A VrackservicessTargetSpecValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessTargetSpecValue Attribute Type", + "While creating a VrackservicessTargetSpecValue value, an invalid attribute value was detected. "+ + "A VrackservicessTargetSpecValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessTargetSpecValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessTargetSpecValue Attribute Value", + "While creating a VrackservicessTargetSpecValue value, an extra attribute value was detected. "+ + "A VrackservicessTargetSpecValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessTargetSpecValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessTargetSpecValueUnknown(), diags + } + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return NewVrackservicessTargetSpecValueUnknown(), diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsValue], was: %T`, subnetsAttribute)) + } + + if diags.HasError() { + return NewVrackservicessTargetSpecValueUnknown(), diags + } + + return VrackservicessTargetSpecValue{ + Subnets: subnetsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessTargetSpecValue { + object, diags := NewVrackservicessTargetSpecValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessTargetSpecValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessTargetSpecType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessTargetSpecValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessTargetSpecValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessTargetSpecValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessTargetSpecValueMust(VrackservicessTargetSpecValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessTargetSpecType) ValueType(ctx context.Context) attr.Value { + return VrackservicessTargetSpecValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessTargetSpecValue{} + +type VrackservicessTargetSpecValue struct { + Subnets ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsValue] `tfsdk:"subnets" json:"subnets"` + state attr.ValueState +} + +func (v *VrackservicessTargetSpecValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessTargetSpecValue VrackservicessTargetSpecValue + + var tmp JsonVrackservicessTargetSpecValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Subnets = tmp.Subnets + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessTargetSpecValue) MergeWith(other *VrackservicessTargetSpecValue) { + + if (v.Subnets.IsUnknown() || v.Subnets.IsNull()) && !other.Subnets.IsUnknown() { + v.Subnets = other.Subnets + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessTargetSpecValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "subnets": v.Subnets, + } +} +func (v VrackservicessTargetSpecValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["subnets"] = basetypes.ListType{ + ElemType: VrackservicessTargetSpecSubnetsValue{}.Type(ctx), + }.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.Subnets.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["subnets"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessTargetSpecValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessTargetSpecValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessTargetSpecValue) String() string { + return "VrackservicessTargetSpecValue" +} + +func (v VrackservicessTargetSpecValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "subnets": ovhtypes.NewTfListNestedType[VrackservicessTargetSpecSubnetsValue](ctx), + }, + map[string]attr.Value{ + "subnets": v.Subnets, + }) + + return objVal, diags +} + +func (v VrackservicessTargetSpecValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessTargetSpecValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Subnets.Equal(other.Subnets) { + return false + } + + return true +} + +func (v VrackservicessTargetSpecValue) Type(ctx context.Context) attr.Type { + return VrackservicessTargetSpecType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessTargetSpecValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "subnets": ovhtypes.NewTfListNestedType[VrackservicessTargetSpecSubnetsValue](ctx), + } +} + +var _ basetypes.ObjectTypable = VrackservicessTargetSpecSubnetsType{} + +type VrackservicessTargetSpecSubnetsType struct { + basetypes.ObjectType +} + +func (t VrackservicessTargetSpecSubnetsType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessTargetSpecSubnetsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessTargetSpecSubnetsType) String() string { + return "VrackservicessTargetSpecSubnetsType" +} + +func (t VrackservicessTargetSpecSubnetsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return nil, diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return nil, diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return nil, diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(VrackservicessTargetSpecSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be VrackservicessTargetSpecSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return nil, diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessTargetSpecSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecSubnetsValueNull() VrackservicessTargetSpecSubnetsValue { + return VrackservicessTargetSpecSubnetsValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessTargetSpecSubnetsValueUnknown() VrackservicessTargetSpecSubnetsValue { + return VrackservicessTargetSpecSubnetsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessTargetSpecSubnetsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessTargetSpecSubnetsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessTargetSpecSubnetsValue Attribute Value", + "While creating a VrackservicessTargetSpecSubnetsValue value, a missing attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessTargetSpecSubnetsValue Attribute Type", + "While creating a VrackservicessTargetSpecSubnetsValue value, an invalid attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessTargetSpecSubnetsValue Attribute Value", + "While creating a VrackservicessTargetSpecSubnetsValue value, an extra attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessTargetSpecSubnetsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(VrackservicessTargetSpecSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be VrackservicessTargetSpecSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return NewVrackservicessTargetSpecSubnetsValueUnknown(), diags + } + + return VrackservicessTargetSpecSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecSubnetsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessTargetSpecSubnetsValue { + object, diags := NewVrackservicessTargetSpecSubnetsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessTargetSpecSubnetsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessTargetSpecSubnetsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessTargetSpecSubnetsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessTargetSpecSubnetsValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessTargetSpecSubnetsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessTargetSpecSubnetsValueMust(VrackservicessTargetSpecSubnetsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessTargetSpecSubnetsType) ValueType(ctx context.Context) attr.Value { + return VrackservicessTargetSpecSubnetsValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessTargetSpecSubnetsValue{} + +type VrackservicessTargetSpecSubnetsValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + DisplayName ovhtypes.TfStringValue `tfsdk:"display_name" json:"displayName"` + ServiceEndpoints ovhtypes.TfListNestedValue[VrackservicessTargetSpecSubnetsServiceEndpointsValue] `tfsdk:"service_endpoints" json:"serviceEndpoints"` + ServiceRange VrackservicessTargetSpecSubnetsServiceRangeValue `tfsdk:"service_range" json:"serviceRange"` + Vlan ovhtypes.TfInt64Value `tfsdk:"vlan" json:"vlan"` + state attr.ValueState +} + +func (v *VrackservicessTargetSpecSubnetsValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessTargetSpecSubnetsValue VrackservicessTargetSpecSubnetsValue + + var tmp JsonVrackservicessTargetSpecSubnetsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + v.DisplayName = tmp.DisplayName + v.ServiceEndpoints = tmp.ServiceEndpoints + v.ServiceRange = tmp.ServiceRange + v.Vlan = tmp.Vlan + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessTargetSpecSubnetsValue) MergeWith(other *VrackservicessTargetSpecSubnetsValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.DisplayName.IsUnknown() || v.DisplayName.IsNull()) && !other.DisplayName.IsUnknown() { + v.DisplayName = other.DisplayName + } + + if (v.ServiceEndpoints.IsUnknown() || v.ServiceEndpoints.IsNull()) && !other.ServiceEndpoints.IsUnknown() { + v.ServiceEndpoints = other.ServiceEndpoints + } + + if (v.ServiceRange.IsUnknown() || v.ServiceRange.IsNull()) && !other.ServiceRange.IsUnknown() { + v.ServiceRange = other.ServiceRange + } + + if (v.Vlan.IsUnknown() || v.Vlan.IsNull()) && !other.Vlan.IsUnknown() { + v.Vlan = other.Vlan + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessTargetSpecSubnetsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + "displayName": v.DisplayName, + "serviceEndpoints": v.ServiceEndpoints, + "serviceRange": v.ServiceRange, + "vlan": v.Vlan, + } +} +func (v VrackservicessTargetSpecSubnetsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["display_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["service_endpoints"] = basetypes.ListType{ + ElemType: VrackservicessTargetSpecSubnetsServiceEndpointsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["service_range"] = basetypes.ObjectType{ + AttrTypes: VrackservicessTargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["vlan"] = basetypes.Int64Type{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + val, err = v.DisplayName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["display_name"] = val + + val, err = v.ServiceEndpoints.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_endpoints"] = val + + val, err = v.ServiceRange.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_range"] = val + + val, err = v.Vlan.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["vlan"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessTargetSpecSubnetsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessTargetSpecSubnetsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessTargetSpecSubnetsValue) String() string { + return "VrackservicessTargetSpecSubnetsValue" +} + +func (v VrackservicessTargetSpecSubnetsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[VrackservicessTargetSpecSubnetsServiceEndpointsValue](ctx), + "service_range": VrackservicessTargetSpecSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: VrackservicessTargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + "vlan": ovhtypes.TfInt64Type{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + "display_name": v.DisplayName, + "service_endpoints": v.ServiceEndpoints, + "service_range": v.ServiceRange, + "vlan": v.Vlan, + }) + + return objVal, diags +} + +func (v VrackservicessTargetSpecSubnetsValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessTargetSpecSubnetsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + if !v.DisplayName.Equal(other.DisplayName) { + return false + } + + if !v.ServiceEndpoints.Equal(other.ServiceEndpoints) { + return false + } + + if !v.ServiceRange.Equal(other.ServiceRange) { + return false + } + + if !v.Vlan.Equal(other.Vlan) { + return false + } + + return true +} + +func (v VrackservicessTargetSpecSubnetsValue) Type(ctx context.Context) attr.Type { + return VrackservicessTargetSpecSubnetsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessTargetSpecSubnetsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[VrackservicessTargetSpecSubnetsServiceEndpointsValue](ctx), + "service_range": VrackservicessTargetSpecSubnetsServiceRangeValue{}.Type(ctx), + "vlan": ovhtypes.TfInt64Type{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessTargetSpecSubnetsServiceEndpointsType{} + +type VrackservicessTargetSpecSubnetsServiceEndpointsType struct { + basetypes.ObjectType +} + +func (t VrackservicessTargetSpecSubnetsServiceEndpointsType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessTargetSpecSubnetsServiceEndpointsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessTargetSpecSubnetsServiceEndpointsType) String() string { + return "VrackservicessTargetSpecSubnetsServiceEndpointsType" +} + +func (t VrackservicessTargetSpecSubnetsServiceEndpointsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return nil, diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessTargetSpecSubnetsServiceEndpointsValue{ + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecSubnetsServiceEndpointsValueNull() VrackservicessTargetSpecSubnetsServiceEndpointsValue { + return VrackservicessTargetSpecSubnetsServiceEndpointsValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessTargetSpecSubnetsServiceEndpointsValueUnknown() VrackservicessTargetSpecSubnetsServiceEndpointsValue { + return VrackservicessTargetSpecSubnetsServiceEndpointsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessTargetSpecSubnetsServiceEndpointsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessTargetSpecSubnetsServiceEndpointsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Value", + "While creating a VrackservicessTargetSpecSubnetsServiceEndpointsValue value, a missing attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsServiceEndpointsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Type", + "While creating a VrackservicessTargetSpecSubnetsServiceEndpointsValue value, an invalid attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsServiceEndpointsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Value", + "While creating a VrackservicessTargetSpecSubnetsServiceEndpointsValue value, an extra attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsServiceEndpointsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessTargetSpecSubnetsServiceEndpointsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueUnknown(), diags + } + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueUnknown(), diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueUnknown(), diags + } + + return VrackservicessTargetSpecSubnetsServiceEndpointsValue{ + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecSubnetsServiceEndpointsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessTargetSpecSubnetsServiceEndpointsValue { + object, diags := NewVrackservicessTargetSpecSubnetsServiceEndpointsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessTargetSpecSubnetsServiceEndpointsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessTargetSpecSubnetsServiceEndpointsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessTargetSpecSubnetsServiceEndpointsValueMust(VrackservicessTargetSpecSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessTargetSpecSubnetsServiceEndpointsType) ValueType(ctx context.Context) attr.Value { + return VrackservicessTargetSpecSubnetsServiceEndpointsValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessTargetSpecSubnetsServiceEndpointsValue{} + +type VrackservicessTargetSpecSubnetsServiceEndpointsValue struct { + ManagedServiceUrn ovhtypes.TfStringValue `tfsdk:"managed_service_urn" json:"managedServiceUrn"` + state attr.ValueState +} + +func (v *VrackservicessTargetSpecSubnetsServiceEndpointsValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessTargetSpecSubnetsServiceEndpointsValue VrackservicessTargetSpecSubnetsServiceEndpointsValue + + var tmp JsonVrackservicessTargetSpecSubnetsServiceEndpointsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.ManagedServiceUrn = tmp.ManagedServiceUrn + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessTargetSpecSubnetsServiceEndpointsValue) MergeWith(other *VrackservicessTargetSpecSubnetsServiceEndpointsValue) { + + if (v.ManagedServiceUrn.IsUnknown() || v.ManagedServiceUrn.IsNull()) && !other.ManagedServiceUrn.IsUnknown() { + v.ManagedServiceUrn = other.ManagedServiceUrn + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "managedServiceUrn": v.ManagedServiceUrn, + } +} +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["managed_service_urn"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.ManagedServiceUrn.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["managed_service_urn"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) String() string { + return "VrackservicessTargetSpecSubnetsServiceEndpointsValue" +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "managed_service_urn": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "managed_service_urn": v.ManagedServiceUrn, + }) + + return objVal, diags +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessTargetSpecSubnetsServiceEndpointsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ManagedServiceUrn.Equal(other.ManagedServiceUrn) { + return false + } + + return true +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) Type(ctx context.Context) attr.Type { + return VrackservicessTargetSpecSubnetsServiceEndpointsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessTargetSpecSubnetsServiceEndpointsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "managed_service_urn": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackservicessTargetSpecSubnetsServiceRangeType{} + +type VrackservicessTargetSpecSubnetsServiceRangeType struct { + basetypes.ObjectType +} + +func (t VrackservicessTargetSpecSubnetsServiceRangeType) Equal(o attr.Type) bool { + other, ok := o.(VrackservicessTargetSpecSubnetsServiceRangeType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackservicessTargetSpecSubnetsServiceRangeType) String() string { + return "VrackservicessTargetSpecSubnetsServiceRangeType" +} + +func (t VrackservicessTargetSpecSubnetsServiceRangeType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackservicessTargetSpecSubnetsServiceRangeValue{ + Cidr: cidrVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecSubnetsServiceRangeValueNull() VrackservicessTargetSpecSubnetsServiceRangeValue { + return VrackservicessTargetSpecSubnetsServiceRangeValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackservicessTargetSpecSubnetsServiceRangeValueUnknown() VrackservicessTargetSpecSubnetsServiceRangeValue { + return VrackservicessTargetSpecSubnetsServiceRangeValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackservicessTargetSpecSubnetsServiceRangeValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackservicessTargetSpecSubnetsServiceRangeValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Value", + "While creating a VrackservicessTargetSpecSubnetsServiceRangeValue value, a missing attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsServiceRangeValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Type", + "While creating a VrackservicessTargetSpecSubnetsServiceRangeValue value, an invalid attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsServiceRangeValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Value", + "While creating a VrackservicessTargetSpecSubnetsServiceRangeValue value, an extra attribute value was detected. "+ + "A VrackservicessTargetSpecSubnetsServiceRangeValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackservicessTargetSpecSubnetsServiceRangeValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackservicessTargetSpecSubnetsServiceRangeValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewVrackservicessTargetSpecSubnetsServiceRangeValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + if diags.HasError() { + return NewVrackservicessTargetSpecSubnetsServiceRangeValueUnknown(), diags + } + + return VrackservicessTargetSpecSubnetsServiceRangeValue{ + Cidr: cidrVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackservicessTargetSpecSubnetsServiceRangeValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackservicessTargetSpecSubnetsServiceRangeValue { + object, diags := NewVrackservicessTargetSpecSubnetsServiceRangeValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackservicessTargetSpecSubnetsServiceRangeValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackservicessTargetSpecSubnetsServiceRangeType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackservicessTargetSpecSubnetsServiceRangeValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackservicessTargetSpecSubnetsServiceRangeValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackservicessTargetSpecSubnetsServiceRangeValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackservicessTargetSpecSubnetsServiceRangeValueMust(VrackservicessTargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackservicessTargetSpecSubnetsServiceRangeType) ValueType(ctx context.Context) attr.Value { + return VrackservicessTargetSpecSubnetsServiceRangeValue{} +} + +var _ basetypes.ObjectValuable = VrackservicessTargetSpecSubnetsServiceRangeValue{} + +type VrackservicessTargetSpecSubnetsServiceRangeValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + state attr.ValueState +} + +func (v *VrackservicessTargetSpecSubnetsServiceRangeValue) UnmarshalJSON(data []byte) error { + type JsonVrackservicessTargetSpecSubnetsServiceRangeValue VrackservicessTargetSpecSubnetsServiceRangeValue + + var tmp JsonVrackservicessTargetSpecSubnetsServiceRangeValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackservicessTargetSpecSubnetsServiceRangeValue) MergeWith(other *VrackservicessTargetSpecSubnetsServiceRangeValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + } +} +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) String() string { + return "VrackservicessTargetSpecSubnetsServiceRangeValue" +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + }) + + return objVal, diags +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) Equal(o attr.Value) bool { + other, ok := o.(VrackservicessTargetSpecSubnetsServiceRangeValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + return true +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) Type(ctx context.Context) attr.Type { + return VrackservicessTargetSpecSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackservicessTargetSpecSubnetsServiceRangeValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + } +} diff --git a/ovh/data_vrackservicess_test.go b/ovh/data_vrackservicess_test.go new file mode 100644 index 000000000..85db4996e --- /dev/null +++ b/ovh/data_vrackservicess_test.go @@ -0,0 +1,20 @@ +package ovh + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccVrackservicessDataSource_basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckCredentials(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: "data ovh_vrackservicess vrackservicess {}", + Check: resource.TestCheckResourceAttrSet("data.ovh_vrackservicess.vrackservicess", "vrackservicess.#"), + }, + }, + }) +} diff --git a/ovh/provider_new.go b/ovh/provider_new.go index b8bf7008d..c4da7f9e3 100644 --- a/ovh/provider_new.go +++ b/ovh/provider_new.go @@ -284,6 +284,8 @@ func (p *OvhProvider) DataSources(_ context.Context) []func() datasource.DataSou NewStorageEfsShareAccessPathDataSource, NewVmwareCloudDirectorBackupDataSource, NewVmwareCloudDirectorOrganizationDataSource, + NewVrackservicessDataSource, + NewVrackservicesDataSource, } } @@ -331,6 +333,7 @@ func (p *OvhProvider) Resources(_ context.Context) []func() resource.Resource { NewVrackDedicatedCloudResource, NewVrackIpv6RoutedSubrangeResource, NewVrackDedicatedCloudDatacenterResource, + NewVrackServicesResource, } } diff --git a/ovh/provider_test.go b/ovh/provider_test.go index ed6b0f965..d530780b3 100644 --- a/ovh/provider_test.go +++ b/ovh/provider_test.go @@ -455,6 +455,23 @@ func testAccPreCheckVRackIpWithRegion(t *testing.T) { checkEnvOrSkip(t, "OVH_VRACK_IP_REGION") } +// Checks that the environment variables needed to order /vrackServices and basic acceptance tests +// are set. +func testAccPreCheckVrackServices(t *testing.T) { + testAccPreCheckCredentials(t) + checkEnvOrSkip(t, "OVH_TESTACC_ORDER_VRACK_SERVICES") + checkEnvOrSkip(t, "OVH_VRACK_SERVICES_REGION") + checkEnvOrSkip(t, "OVH_VRACK_SERVICE_TEST") + checkEnvOrSkip(t, "OVH_STORAGE_EFS_SERVICE_TEST") +} + +// Checks that the environment variables needed to /vrackServices datasource basic acceptance tests +// are set. +func testAccPreCheckVrackServicesData(t *testing.T) { + testAccPreCheckCredentials(t) + checkEnvOrSkip(t, "OVH_TESTACC_VRACK_SERVICES_ID_TEST") +} + // Checks that the environment variables needed for the /me/paymentMean acceptance tests // are set. func testAccPreCheckMePaymentMean(t *testing.T) { diff --git a/ovh/resource_vrackservices.go b/ovh/resource_vrackservices.go new file mode 100644 index 000000000..93cc3ef49 --- /dev/null +++ b/ovh/resource_vrackservices.go @@ -0,0 +1,263 @@ +package ovh + +import ( + "context" + "fmt" + "log" + "net/url" + + "github.com/ovh/go-ovh/ovh" + "github.com/ovh/terraform-provider-ovh/v2/ovh/helpers" + ovhtypes "github.com/ovh/terraform-provider-ovh/v2/ovh/types" + + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +var _ resource.ResourceWithConfigure = (*vrackServicesResource)(nil) +var _ resource.ResourceWithImportState = (*vrackServicesResource)(nil) + +func NewVrackServicesResource() resource.Resource { + return &vrackServicesResource{} +} + +type vrackServicesResource struct { + config *Config +} + +func (r *vrackServicesResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = req.ProviderTypeName + "_vrackservices" +} + +func (d *vrackServicesResource) Configure(_ context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + config, ok := req.ProviderData.(*Config) + if !ok { + resp.Diagnostics.AddError( + "Unexpected Resource Configure Type", + fmt.Sprintf("Expected *Config, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + return + } + + d.config = config +} + +func (d *vrackServicesResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + resp.Schema = VrackServicesResourceSchema(ctx) +} + +func (d *vrackServicesResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), req.ID)...) +} + +func (r *vrackServicesResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + var data VrackServicesModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + // Create order and wait for service to be delivered + order := data.ToOrder() + if err := orderCreate(order, r.config, "vrackServices", true, defaultOrderTimeout); err != nil { + resp.Diagnostics.AddError("failed to create order", err.Error()) + } + + // Find service name from order + orderID := order.Order.OrderId.ValueInt64() + plans := []PlanValue{} + resp.Diagnostics.Append(data.Plan.ElementsAs(ctx, &plans, false)...) + if resp.Diagnostics.HasError() { + return + } + + // Retrieve service name + serviceName, err := serviceNameFromOrder(r.config.OVHClient, orderID, plans[0].PlanCode.ValueString()) + if err != nil { + resp.Diagnostics.AddError("failed to retrieve service name", err.Error()) + } + data.Id = ovhtypes.TfStringValue{ + StringValue: basetypes.NewStringValue(serviceName), + } + + // Read created resource to get the Checksum for update + var createdData VrackServicesModel + endpoint := "/v2/vrackServices/resource/" + url.PathEscape(data.Id.ValueString()) + if err := r.config.OVHClient.GetWithContext(ctx, endpoint, &createdData); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + data.Checksum = ovhtypes.TfStringValue{ + StringValue: basetypes.NewStringValue(createdData.Checksum.ValueString()), + } + + // Update resource + endpoint = "/v2/vrackServices/resource/" + url.PathEscape(data.Id.ValueString()) + if err := r.config.OVHClient.Put(endpoint, data.ToUpdate(), nil); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Put %s", endpoint), + err.Error(), + ) + return + } + + // Wait for udpate + if err := helpers.WaitForAPIv2ResourceStatusReady(ctx, r.config.OVHClient, endpoint); err != nil { + resp.Diagnostics.AddError("Error waiting for resource to be ready", err.Error()) + return + } + + // Fetch up-to-date service info + var responseData VrackServicesModel + if err := r.config.OVHClient.Get(endpoint, &responseData); err != nil { + resp.Diagnostics.AddError(fmt.Sprintf("Error calling Get %s", endpoint), err.Error()) + return + } + + data.MergeWith(&responseData, true) + + // Save data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *vrackServicesResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + var data, responseData VrackServicesModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + endpoint := "/v2/vrackServices/resource/" + url.PathEscape(data.Id.ValueString()) + if err := r.config.OVHClient.GetWithContext(ctx, endpoint, &responseData); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Get %s", endpoint), + err.Error(), + ) + return + } + + data.MergeWith(&responseData, true) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +func (r *vrackServicesResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { + var responseData, data, planData VrackServicesModel + + // Read Terraform plan data into the model + resp.Diagnostics.Append(req.Plan.Get(ctx, &planData)...) + if resp.Diagnostics.HasError() { + return + } + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + // Update resource + endpoint := "/v2/vrackServices/resource/" + url.PathEscape(data.Id.ValueString()) + + if !planData.TargetSpec.IsNull() && !planData.TargetSpec.IsUnknown() { + // Add the checksum with its current value + updateData := planData.ToUpdate() + updateData.Checksum = &data.Checksum + if err := r.config.OVHClient.Put(endpoint, updateData, nil); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Error calling Put %s", endpoint), + err.Error(), + ) + return + } + } + + // Wait for udpate + if err := helpers.WaitForAPIv2ResourceStatusReady(ctx, r.config.OVHClient, endpoint); err != nil { + resp.Diagnostics.AddError("Error waiting for resource to be ready", err.Error()) + return + } + + // Fetch up-to-date service info + if err := r.config.OVHClient.Get(endpoint, &responseData); err != nil { + resp.Diagnostics.AddError(fmt.Sprintf("Error calling Get %s", endpoint), err.Error()) + return + } + + responseData.MergeWith(&planData, false) + + // Save updated data into Terraform state + resp.Diagnostics.Append(resp.State.Set(ctx, &responseData)...) +} + +func (r *vrackServicesResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + var data VrackServicesModel + + // Read Terraform prior state data into the model + resp.Diagnostics.Append(req.State.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + + // Check terminate business rules + if !data.TargetSpec.Subnets.IsNull() && !data.TargetSpec.Subnets.IsUnknown() { + for _, elem := range data.TargetSpec.Subnets.Elements() { + subnet := elem.(TargetSpecSubnetsValue) + if subnet.ServiceEndpoints.IsNull() || subnet.ServiceEndpoints.IsUnknown() { + continue + } + + if len(subnet.ServiceEndpoints.Elements()) > 0 { + resp.Diagnostics.AddError("failed to delete resource", + "every existing ServiceEndpoints must be deleted before terminate the resource") + return + } + } + } + + resourceName := data.Id.ValueString() + serviceID, err := serviceIdFromResourceName(r.config.OVHClient, resourceName) + if err != nil { + resp.Diagnostics.AddError("failed to get service id to terminate service", err.Error()) + return + } + + terminate := func() (string, error) { + log.Printf("[DEBUG] Will terminate service %s", resourceName) + endpoint := fmt.Sprintf("/services/%d/terminate", serviceID) + if err := r.config.OVHClient.Post(endpoint, nil, nil); err != nil { + if errOvh, ok := err.(*ovh.APIError); ok && (errOvh.Code == 404 || errOvh.Code == 460) { + return "", nil + } + return "", fmt.Errorf("calling Post %s:\n\t %q", endpoint, err) + } + return resourceName, nil + } + + confirmTerminate := func(token string) error { + log.Printf("[DEBUG] Will confirm termination of service %s", resourceName) + endpoint := fmt.Sprintf("/services/%d/terminate/confirm", serviceID) + if err := r.config.OVHClient.Post(endpoint, &ConfirmTerminationOpts{Token: token}, nil); err != nil { + return fmt.Errorf("calling Post %s:\n\t %q", endpoint, err) + } + return nil + } + + if err := orderDelete(r.config, terminate, confirmTerminate); err != nil { + resp.Diagnostics.AddError("failed to delete resource", err.Error()) + return + } +} diff --git a/ovh/resource_vrackservices_gen.go b/ovh/resource_vrackservices_gen.go new file mode 100644 index 000000000..cf59fb711 --- /dev/null +++ b/ovh/resource_vrackservices_gen.go @@ -0,0 +1,5313 @@ +// Code generated by terraform-plugin-framework-generator DO NOT EDIT. + +package ovh + +import ( + "context" + "encoding/json" + "fmt" + "strings" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" + "github.com/hashicorp/terraform-plugin-go/tftypes" + ovhtypes "github.com/ovh/terraform-provider-ovh/v2/ovh/types" + + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" +) + +func VrackServicesResourceSchema(ctx context.Context) schema.Schema { + attrs := map[string]schema.Attribute{ + "checksum": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Computed hash used to control concurrent modification requests. Here, it represents the target specification value the request is based on", + MarkdownDescription: "Computed hash used to control concurrent modification requests. Here, it represents the target specification value the request is based on", + }, + "created_at": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Date of the vRack Services delivery", + MarkdownDescription: "Date of the vRack Services delivery", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), // This attribut does not change + }, + }, + "current_state": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "product_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Product status of the vRack Services", + MarkdownDescription: "Product status of the vRack Services", + }, + "region": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Region of the vRack Services. List of compatible regions can be retrieved from /reference/region", + MarkdownDescription: "Region of the vRack Services. List of compatible regions can be retrieved from /reference/region", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), // This attribut does not change + }, + }, + "subnets": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address range of the subnet in CIDR format", + MarkdownDescription: "IP address range of the subnet in CIDR format", + }, + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Display name of the subnet", + MarkdownDescription: "Display name of the subnet", + }, + "service_endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "description": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP description defined in the managed service", + MarkdownDescription: "IP description defined in the managed service", + }, + "ip": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IP address assigned by OVHcloud", + MarkdownDescription: "IP address assigned by OVHcloud", + }, + }, + CustomType: CurrentStateSubnetsServiceEndpointsEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceEndpointsEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + Computed: true, + Description: "Endpoints representing the IPs assigned to the managed services", + MarkdownDescription: "Endpoints representing the IPs assigned to the managed services", + }, + "managed_service_urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call.", + MarkdownDescription: "IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call.", + }, + }, + CustomType: CurrentStateSubnetsServiceEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsValue](ctx), + Computed: true, + Description: "Service endpoints of the subnet", + MarkdownDescription: "Service endpoints of the subnet", + }, + "service_range": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "CIDR dedicated to the subnet's services", + MarkdownDescription: "CIDR dedicated to the subnet's services", + }, + "remaining_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of remaining IPs in the service range", + MarkdownDescription: "Number of remaining IPs in the service range", + }, + "reserved_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of service range IPs reserved by OVHcloud", + MarkdownDescription: "Number of service range IPs reserved by OVHcloud", + }, + "used_ips": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Number of service range IPs assigned to the managed services", + MarkdownDescription: "Number of service range IPs assigned to the managed services", + }, + }, + CustomType: CurrentStateSubnetsServiceRangeType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Defines a smaller subnet dedicated to the managed services IPs", + MarkdownDescription: "Defines a smaller subnet dedicated to the managed services IPs", + }, + "vlan": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Computed: true, + Description: "Unique inner VLAN that allows subnets segregation", + MarkdownDescription: "Unique inner VLAN that allows subnets segregation", + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), // This attribut does not change + }, + }, + }, + CustomType: CurrentStateSubnetsType{ + ObjectType: types.ObjectType{ + AttrTypes: CurrentStateSubnetsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[CurrentStateSubnetsValue](ctx), + Computed: true, + Description: "Subnets of the current vRack Services", + MarkdownDescription: "Subnets of the current vRack Services", + }, + }, + CustomType: VrackServicesCurrentStateType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackServicesCurrentStateValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "Current configuration applied to the vRack Services", + MarkdownDescription: "Current configuration applied to the vRack Services", + }, + "current_tasks": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Identifier of the current task", + MarkdownDescription: "Identifier of the current task", + }, + "link": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Link to the related resource", + MarkdownDescription: "Link to the related resource", + }, + "status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Current global status of the current task", + MarkdownDescription: "Current global status of the current task", + }, + "type": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Type of the current task", + MarkdownDescription: "Type of the current task", + }, + }, + CustomType: VrackServicesCurrentTasksType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackServicesCurrentTasksValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[VrackServicesCurrentTasksValue](ctx), + Computed: true, + Description: "Asynchronous operations ongoing on the vRack Services", + MarkdownDescription: "Asynchronous operations ongoing on the vRack Services", + }, + "iam": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Resource display name", + MarkdownDescription: "Resource display name", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier of the resource", + MarkdownDescription: "Unique identifier of the resource", + }, + "tags": schema.MapAttribute{ + CustomType: ovhtypes.NewTfMapNestedType[ovhtypes.TfStringValue](ctx), + Computed: true, + Description: "Resource tags. Tags that were internally computed are prefixed with ovh:", + MarkdownDescription: "Resource tags. Tags that were internally computed are prefixed with ovh:", + }, + "urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique resource name used in policies", + MarkdownDescription: "Unique resource name used in policies", + }, + }, + CustomType: IamType{ + ObjectType: types.ObjectType{ + AttrTypes: IamValue{}.AttributeTypes(ctx), + }, + }, + Computed: true, + Description: "IAM resource metadata", + MarkdownDescription: "IAM resource metadata", + }, + "id": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Unique identifier", + MarkdownDescription: "Unique identifier", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), // This attribut does not change + }, + }, + "resource_status": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status", + MarkdownDescription: "Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status", + }, + "target_spec": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "subnets": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + Description: "IPv4 CIDR notation (e.g., 192.0.2.0/24)", + MarkdownDescription: "IPv4 CIDR notation (e.g., 192.0.2.0/24)", + }, + "display_name": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Optional: true, + Description: "Display name of the subnet. Format must follow `^[a-zA-Z0-9-_.]{0,40}$`", + MarkdownDescription: "Display name of the subnet. Format must follow `^[a-zA-Z0-9-_.]{0,40}$`", + }, + "service_endpoints": schema.ListNestedAttribute{ + NestedObject: schema.NestedAttributeObject{ + Attributes: map[string]schema.Attribute{ + "managed_service_urn": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + Description: "IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call", + MarkdownDescription: "IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call", + }, + }, + CustomType: TargetSpecSubnetsServiceEndpointsType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[TargetSpecSubnetsServiceEndpointsValue](ctx), + Required: true, + Description: "Target specification of the Service Endpoints", + MarkdownDescription: "Target specification of the Service Endpoints", + }, + "service_range": schema.SingleNestedAttribute{ + Attributes: map[string]schema.Attribute{ + "cidr": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Required: true, + Description: "IPv4 CIDR notation (e.g., 192.0.2.0/24)", + MarkdownDescription: "IPv4 CIDR notation (e.g., 192.0.2.0/24)", + }, + }, + CustomType: TargetSpecSubnetsServiceRangeType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + Required: true, + Description: "Target specification of the range dedicated to the subnet's services", + MarkdownDescription: "Target specification of the range dedicated to the subnet's services", + }, + "vlan": schema.Int64Attribute{ + CustomType: ovhtypes.TfInt64Type{}, + Optional: true, + Description: "Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic)", + MarkdownDescription: "Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic)", + }, + }, + CustomType: TargetSpecSubnetsType{ + ObjectType: types.ObjectType{ + AttrTypes: TargetSpecSubnetsValue{}.AttributeTypes(ctx), + }, + }, + }, + CustomType: ovhtypes.NewTfListNestedType[TargetSpecSubnetsValue](ctx), + Required: true, + Description: "Target specification of the subnets. Maximum one subnet per vRack Services", + MarkdownDescription: "Target specification of the subnets. Maximum one subnet per vRack Services", + }, + }, + CustomType: VrackServicesTargetSpecType{ + ObjectType: types.ObjectType{ + AttrTypes: VrackServicesTargetSpecValue{}.AttributeTypes(ctx), + }, + }, + Required: true, + Description: "Target specification of the vRack Services", + MarkdownDescription: "Target specification of the vRack Services", + }, + "updated_at": schema.StringAttribute{ + CustomType: ovhtypes.TfStringType{}, + Computed: true, + Description: "Date of the Last vRack Services update", + MarkdownDescription: "Date of the Last vRack Services update", + }, + } + for k, v := range OrderResourceSchema(ctx).Attributes { + attrs[k] = v + } + + return schema.Schema{ + Attributes: attrs, + } +} + +type VrackServicesModel struct { + Checksum ovhtypes.TfStringValue `tfsdk:"checksum" json:"checksum"` + CreatedAt ovhtypes.TfStringValue `tfsdk:"created_at" json:"createdAt"` + CurrentState VrackServicesCurrentStateValue `tfsdk:"current_state" json:"currentState"` + CurrentTasks ovhtypes.TfListNestedValue[VrackServicesCurrentTasksValue] `tfsdk:"current_tasks" json:"currentTasks"` + Iam IamValue `tfsdk:"iam" json:"iam"` + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + ResourceStatus ovhtypes.TfStringValue `tfsdk:"resource_status" json:"resourceStatus"` + TargetSpec VrackServicesTargetSpecValue `tfsdk:"target_spec" json:"targetSpec"` + UpdatedAt ovhtypes.TfStringValue `tfsdk:"updated_at" json:"updatedAt"` + Order OrderValue `tfsdk:"order" json:"order"` + OvhSubsidiary ovhtypes.TfStringValue `tfsdk:"ovh_subsidiary" json:"ovhSubsidiary"` + Plan ovhtypes.TfListNestedValue[PlanValue] `tfsdk:"plan" json:"plan"` + PlanOption ovhtypes.TfListNestedValue[PlanOptionValue] `tfsdk:"plan_option" json:"planOption"` +} + +func (v *VrackServicesModel) MergeWith(other *VrackServicesModel, overrideChecksum bool) { + if overrideChecksum { + v.Checksum = other.Checksum + } + if (v.Checksum.IsUnknown() || v.Checksum.IsNull()) && !other.Checksum.IsUnknown() { + v.Checksum = other.Checksum + } + + // Always update properties that can be updated via an other resource (ovh_vrack_vrackservices) + if !other.UpdatedAt.IsUnknown() { + v.UpdatedAt = other.UpdatedAt + } + if !other.ResourceStatus.IsUnknown() { + v.ResourceStatus = other.ResourceStatus + } + + if (v.CreatedAt.IsUnknown() || v.CreatedAt.IsNull()) && !other.CreatedAt.IsUnknown() { + v.CreatedAt = other.CreatedAt + } + + if v.CurrentState.IsUnknown() && !other.CurrentState.IsUnknown() { + v.CurrentState = other.CurrentState + } else if !other.CurrentState.IsUnknown() { + v.CurrentState.MergeWith(&other.CurrentState) + } + + if (v.CurrentTasks.IsUnknown() || v.CurrentTasks.IsNull()) && !other.CurrentTasks.IsUnknown() { + v.CurrentTasks = other.CurrentTasks + } else if !other.CurrentTasks.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.CurrentTasks.Elements() + newElems := other.CurrentTasks.Elements() + + if len(elems) != len(newElems) { + v.CurrentTasks = other.CurrentTasks + } else { + for idx, e := range elems { + tmp := e.(VrackServicesCurrentTasksValue) + tmp2 := newElems[idx].(VrackServicesCurrentTasksValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.CurrentTasks = ovhtypes.TfListNestedValue[VrackServicesCurrentTasksValue]{ + ListValue: basetypes.NewListValueMust(VrackServicesCurrentTasksValue{}.Type(context.Background()), newSlice), + } + } + } + + if v.Iam.IsUnknown() && !other.Iam.IsUnknown() { + v.Iam = other.Iam + } else if !other.Iam.IsUnknown() { + v.Iam.MergeWith(&other.Iam) + } + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if v.TargetSpec.IsUnknown() && !other.TargetSpec.IsUnknown() { + v.TargetSpec = other.TargetSpec + } else if !other.TargetSpec.IsUnknown() { + v.TargetSpec.MergeWith(&other.TargetSpec) + } + + if (v.Order.IsUnknown() || v.Order.IsNull()) && !other.Order.IsUnknown() { + v.Order = other.Order + } + + if (v.OvhSubsidiary.IsUnknown() || v.OvhSubsidiary.IsNull()) && !other.OvhSubsidiary.IsUnknown() { + v.OvhSubsidiary = other.OvhSubsidiary + } + + if (v.Plan.IsUnknown() || v.Plan.IsNull()) && !other.Plan.IsUnknown() { + v.Plan = other.Plan + } + + if (v.PlanOption.IsUnknown() || v.PlanOption.IsNull()) && !other.PlanOption.IsUnknown() { + v.PlanOption = other.PlanOption + } + +} + +func (v *VrackServicesModel) ToOrder() *OrderModel { + return &OrderModel{ + Order: v.Order, + OvhSubsidiary: v.OvhSubsidiary, + Plan: v.Plan, + PlanOption: v.PlanOption, + } +} + +type VrackServicesWritableModel struct { + Checksum *ovhtypes.TfStringValue `tfsdk:"checksum" json:"checksum,omitempty"` + TargetSpec *VrackServicesTargetSpecWritableValue `tfsdk:"target_spec" json:"targetSpec,omitempty"` +} + +func (v VrackServicesModel) ToCreate() *VrackServicesWritableModel { + res := &VrackServicesWritableModel{} + + if !v.Checksum.IsUnknown() { + res.Checksum = &v.Checksum + } + + if !v.TargetSpec.IsUnknown() { + res.TargetSpec = v.TargetSpec.ToCreate() + } + + return res +} + +func (v VrackServicesModel) ToUpdate() *VrackServicesWritableModel { + res := &VrackServicesWritableModel{} + + if !v.Checksum.IsUnknown() { + res.Checksum = &v.Checksum + } + + if !v.TargetSpec.IsUnknown() { + res.TargetSpec = v.TargetSpec.ToUpdate() + } + + return res +} + +var _ basetypes.ObjectTypable = VrackServicesCurrentStateType{} + +type VrackServicesCurrentStateType struct { + basetypes.ObjectType +} + +func (t VrackServicesCurrentStateType) Equal(o attr.Type) bool { + other, ok := o.(VrackServicesCurrentStateType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackServicesCurrentStateType) String() string { + return "VrackServicesCurrentStateType" +} + +func (t VrackServicesCurrentStateType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + productStatusAttribute, ok := attributes["product_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `product_status is missing from object`) + + return nil, diags + } + + productStatusVal, ok := productStatusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`product_status expected to be ovhtypes.TfStringValue, was: %T`, productStatusAttribute)) + } + + regionAttribute, ok := attributes["region"] + + if !ok { + diags.AddError( + "Attribute Missing", + `region is missing from object`) + + return nil, diags + } + + regionVal, ok := regionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`region expected to be ovhtypes.TfStringValue, was: %T`, regionAttribute)) + } + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return nil, diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[CurrentStateSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[CurrentStateSubnetsValue], was: %T`, subnetsAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackServicesCurrentStateValue{ + ProductStatus: productStatusVal, + Region: regionVal, + Subnets: subnetsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackServicesCurrentStateValueNull() VrackServicesCurrentStateValue { + return VrackServicesCurrentStateValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackServicesCurrentStateValueUnknown() VrackServicesCurrentStateValue { + return VrackServicesCurrentStateValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackServicesCurrentStateValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackServicesCurrentStateValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackServicesCurrentStateValue Attribute Value", + "While creating a VrackServicesCurrentStateValue value, a missing attribute value was detected. "+ + "A VrackServicesCurrentStateValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackServicesCurrentStateValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackServicesCurrentStateValue Attribute Type", + "While creating a VrackServicesCurrentStateValue value, an invalid attribute value was detected. "+ + "A VrackServicesCurrentStateValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackServicesCurrentStateValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackServicesCurrentStateValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackServicesCurrentStateValue Attribute Value", + "While creating a VrackServicesCurrentStateValue value, an extra attribute value was detected. "+ + "A VrackServicesCurrentStateValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackServicesCurrentStateValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackServicesCurrentStateValueUnknown(), diags + } + + productStatusAttribute, ok := attributes["product_status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `product_status is missing from object`) + + return NewVrackServicesCurrentStateValueUnknown(), diags + } + + productStatusVal, ok := productStatusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`product_status expected to be ovhtypes.TfStringValue, was: %T`, productStatusAttribute)) + } + + regionAttribute, ok := attributes["region"] + + if !ok { + diags.AddError( + "Attribute Missing", + `region is missing from object`) + + return NewVrackServicesCurrentStateValueUnknown(), diags + } + + regionVal, ok := regionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`region expected to be ovhtypes.TfStringValue, was: %T`, regionAttribute)) + } + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return NewVrackServicesCurrentStateValueUnknown(), diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[CurrentStateSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[CurrentStateSubnetsValue], was: %T`, subnetsAttribute)) + } + + if diags.HasError() { + return NewVrackServicesCurrentStateValueUnknown(), diags + } + + return VrackServicesCurrentStateValue{ + ProductStatus: productStatusVal, + Region: regionVal, + Subnets: subnetsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackServicesCurrentStateValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackServicesCurrentStateValue { + object, diags := NewVrackServicesCurrentStateValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackServicesCurrentStateValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackServicesCurrentStateType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackServicesCurrentStateValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackServicesCurrentStateValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackServicesCurrentStateValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackServicesCurrentStateValueMust(VrackServicesCurrentStateValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackServicesCurrentStateType) ValueType(ctx context.Context) attr.Value { + return VrackServicesCurrentStateValue{} +} + +var _ basetypes.ObjectValuable = VrackServicesCurrentStateValue{} + +type VrackServicesCurrentStateValue struct { + ProductStatus ovhtypes.TfStringValue `tfsdk:"product_status" json:"productStatus"` + Region ovhtypes.TfStringValue `tfsdk:"region" json:"region"` + Subnets ovhtypes.TfListNestedValue[CurrentStateSubnetsValue] `tfsdk:"subnets" json:"subnets"` + state attr.ValueState +} + +func (v *VrackServicesCurrentStateValue) UnmarshalJSON(data []byte) error { + type JsonVrackServicesCurrentStateValue VrackServicesCurrentStateValue + + var tmp JsonVrackServicesCurrentStateValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.ProductStatus = tmp.ProductStatus + v.Region = tmp.Region + v.Subnets = tmp.Subnets + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackServicesCurrentStateValue) MergeWith(other *VrackServicesCurrentStateValue) { + + // Always update properties that can be updated via an other resource (ovh_vrack_vrackservices) + if !other.ProductStatus.IsUnknown() { + v.ProductStatus = other.ProductStatus + } + + if (v.Region.IsUnknown() || v.Region.IsNull()) && !other.Region.IsUnknown() { + v.Region = other.Region + } + + if (v.Subnets.IsUnknown() || v.Subnets.IsNull()) && !other.Subnets.IsUnknown() { + v.Subnets = other.Subnets + } else if !other.Subnets.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.Subnets.Elements() + newElems := other.Subnets.Elements() + + if len(elems) != len(newElems) { + v.Subnets = other.Subnets + } else { + for idx, e := range elems { + tmp := e.(CurrentStateSubnetsValue) + tmp2 := newElems[idx].(CurrentStateSubnetsValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.Subnets = ovhtypes.TfListNestedValue[CurrentStateSubnetsValue]{ + ListValue: basetypes.NewListValueMust(CurrentStateSubnetsValue{}.Type(context.Background()), newSlice), + } + } + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackServicesCurrentStateValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "productStatus": v.ProductStatus, + "region": v.Region, + "subnets": v.Subnets, + } +} +func (v VrackServicesCurrentStateValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["product_status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["region"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["subnets"] = basetypes.ListType{ + ElemType: CurrentStateSubnetsValue{}.Type(ctx), + }.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.ProductStatus.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["product_status"] = val + + val, err = v.Region.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["region"] = val + + val, err = v.Subnets.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["subnets"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackServicesCurrentStateValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackServicesCurrentStateValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackServicesCurrentStateValue) String() string { + return "VrackServicesCurrentStateValue" +} + +func (v VrackServicesCurrentStateValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "product_status": ovhtypes.TfStringType{}, + "region": ovhtypes.TfStringType{}, + "subnets": ovhtypes.NewTfListNestedType[CurrentStateSubnetsValue](ctx), + }, + map[string]attr.Value{ + "product_status": v.ProductStatus, + "region": v.Region, + "subnets": v.Subnets, + }) + + return objVal, diags +} + +func (v VrackServicesCurrentStateValue) Equal(o attr.Value) bool { + other, ok := o.(VrackServicesCurrentStateValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ProductStatus.Equal(other.ProductStatus) { + return false + } + + if !v.Region.Equal(other.Region) { + return false + } + + if !v.Subnets.Equal(other.Subnets) { + return false + } + + return true +} + +func (v VrackServicesCurrentStateValue) Type(ctx context.Context) attr.Type { + return VrackServicesCurrentStateType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackServicesCurrentStateValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "product_status": ovhtypes.TfStringType{}, + "region": ovhtypes.TfStringType{}, + "subnets": ovhtypes.NewTfListNestedType[CurrentStateSubnetsValue](ctx), + } +} + +var _ basetypes.ObjectTypable = CurrentStateSubnetsType{} + +type CurrentStateSubnetsType struct { + basetypes.ObjectType +} + +func (t CurrentStateSubnetsType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateSubnetsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateSubnetsType) String() string { + return "CurrentStateSubnetsType" +} + +func (t CurrentStateSubnetsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return nil, diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return nil, diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return nil, diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(CurrentStateSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be CurrentStateSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return nil, diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsValueNull() CurrentStateSubnetsValue { + return CurrentStateSubnetsValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateSubnetsValueUnknown() CurrentStateSubnetsValue { + return CurrentStateSubnetsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateSubnetsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateSubnetsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateSubnetsValue Attribute Value", + "While creating a CurrentStateSubnetsValue value, a missing attribute value was detected. "+ + "A CurrentStateSubnetsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateSubnetsValue Attribute Type", + "While creating a CurrentStateSubnetsValue value, an invalid attribute value was detected. "+ + "A CurrentStateSubnetsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateSubnetsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateSubnetsValue Attribute Value", + "While creating a CurrentStateSubnetsValue value, an extra attribute value was detected. "+ + "A CurrentStateSubnetsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateSubnetsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateSubnetsValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewCurrentStateSubnetsValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return NewCurrentStateSubnetsValueUnknown(), diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return NewCurrentStateSubnetsValueUnknown(), diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return NewCurrentStateSubnetsValueUnknown(), diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(CurrentStateSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be CurrentStateSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return NewCurrentStateSubnetsValueUnknown(), diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return NewCurrentStateSubnetsValueUnknown(), diags + } + + return CurrentStateSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateSubnetsValue { + object, diags := NewCurrentStateSubnetsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateSubnetsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateSubnetsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateSubnetsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateSubnetsValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateSubnetsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateSubnetsValueMust(CurrentStateSubnetsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateSubnetsType) ValueType(ctx context.Context) attr.Value { + return CurrentStateSubnetsValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateSubnetsValue{} + +type CurrentStateSubnetsValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + DisplayName ovhtypes.TfStringValue `tfsdk:"display_name" json:"displayName"` + ServiceEndpoints ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsValue] `tfsdk:"service_endpoints" json:"serviceEndpoints"` + ServiceRange CurrentStateSubnetsServiceRangeValue `tfsdk:"service_range" json:"serviceRange"` + Vlan ovhtypes.TfInt64Value `tfsdk:"vlan" json:"vlan"` + state attr.ValueState +} + +func (v *CurrentStateSubnetsValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateSubnetsValue CurrentStateSubnetsValue + + var tmp JsonCurrentStateSubnetsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + v.DisplayName = tmp.DisplayName + v.ServiceEndpoints = tmp.ServiceEndpoints + v.ServiceRange = tmp.ServiceRange + v.Vlan = tmp.Vlan + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateSubnetsValue) MergeWith(other *CurrentStateSubnetsValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.DisplayName.IsUnknown() || v.DisplayName.IsNull()) && !other.DisplayName.IsUnknown() { + v.DisplayName = other.DisplayName + } + + if (v.ServiceEndpoints.IsUnknown() || v.ServiceEndpoints.IsNull()) && !other.ServiceEndpoints.IsUnknown() { + v.ServiceEndpoints = other.ServiceEndpoints + } else if !other.ServiceEndpoints.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.ServiceEndpoints.Elements() + newElems := other.ServiceEndpoints.Elements() + + if len(elems) != len(newElems) { + v.ServiceEndpoints = other.ServiceEndpoints + } else { + for idx, e := range elems { + tmp := e.(CurrentStateSubnetsServiceEndpointsValue) + tmp2 := newElems[idx].(CurrentStateSubnetsServiceEndpointsValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.ServiceEndpoints = ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsValue]{ + ListValue: basetypes.NewListValueMust(CurrentStateSubnetsServiceEndpointsValue{}.Type(context.Background()), newSlice), + } + } + } + + if v.ServiceRange.IsUnknown() && !other.ServiceRange.IsUnknown() { + v.ServiceRange = other.ServiceRange + } else if !other.ServiceRange.IsUnknown() { + v.ServiceRange.MergeWith(&other.ServiceRange) + } + + if (v.Vlan.IsUnknown() || v.Vlan.IsNull()) && !other.Vlan.IsUnknown() { + v.Vlan = other.Vlan + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateSubnetsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + "displayName": v.DisplayName, + "serviceEndpoints": v.ServiceEndpoints, + "serviceRange": v.ServiceRange, + "vlan": v.Vlan, + } +} +func (v CurrentStateSubnetsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["display_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["service_endpoints"] = basetypes.ListType{ + ElemType: CurrentStateSubnetsServiceEndpointsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["service_range"] = basetypes.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["vlan"] = basetypes.Int64Type{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + val, err = v.DisplayName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["display_name"] = val + + val, err = v.ServiceEndpoints.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_endpoints"] = val + + val, err = v.ServiceRange.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_range"] = val + + val, err = v.Vlan.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["vlan"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateSubnetsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateSubnetsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateSubnetsValue) String() string { + return "CurrentStateSubnetsValue" +} + +func (v CurrentStateSubnetsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsValue](ctx), + "service_range": CurrentStateSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: CurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + "vlan": ovhtypes.TfInt64Type{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + "display_name": v.DisplayName, + "service_endpoints": v.ServiceEndpoints, + "service_range": v.ServiceRange, + "vlan": v.Vlan, + }) + + return objVal, diags +} + +func (v CurrentStateSubnetsValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateSubnetsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + if !v.DisplayName.Equal(other.DisplayName) { + return false + } + + if !v.ServiceEndpoints.Equal(other.ServiceEndpoints) { + return false + } + + if !v.ServiceRange.Equal(other.ServiceRange) { + return false + } + + if !v.Vlan.Equal(other.Vlan) { + return false + } + + return true +} + +func (v CurrentStateSubnetsValue) Type(ctx context.Context) attr.Type { + return CurrentStateSubnetsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateSubnetsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsValue](ctx), + "service_range": CurrentStateSubnetsServiceRangeValue{}.Type(ctx), + "vlan": ovhtypes.TfInt64Type{}, + } +} + +var _ basetypes.ObjectTypable = CurrentStateSubnetsServiceEndpointsType{} + +type CurrentStateSubnetsServiceEndpointsType struct { + basetypes.ObjectType +} + +func (t CurrentStateSubnetsServiceEndpointsType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateSubnetsServiceEndpointsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateSubnetsServiceEndpointsType) String() string { + return "CurrentStateSubnetsServiceEndpointsType" +} + +func (t CurrentStateSubnetsServiceEndpointsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + endpointsAttribute, ok := attributes["endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `endpoints is missing from object`) + + return nil, diags + } + + endpointsVal, ok := endpointsAttribute.(ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`endpoints expected to be ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsEndpointsValue], was: %T`, endpointsAttribute)) + } + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return nil, diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateSubnetsServiceEndpointsValue{ + Endpoints: endpointsVal, + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsServiceEndpointsValueNull() CurrentStateSubnetsServiceEndpointsValue { + return CurrentStateSubnetsServiceEndpointsValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateSubnetsServiceEndpointsValueUnknown() CurrentStateSubnetsServiceEndpointsValue { + return CurrentStateSubnetsServiceEndpointsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateSubnetsServiceEndpointsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateSubnetsServiceEndpointsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateSubnetsServiceEndpointsValue Attribute Value", + "While creating a CurrentStateSubnetsServiceEndpointsValue value, a missing attribute value was detected. "+ + "A CurrentStateSubnetsServiceEndpointsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateSubnetsServiceEndpointsValue Attribute Type", + "While creating a CurrentStateSubnetsServiceEndpointsValue value, an invalid attribute value was detected. "+ + "A CurrentStateSubnetsServiceEndpointsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateSubnetsServiceEndpointsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateSubnetsServiceEndpointsValue Attribute Value", + "While creating a CurrentStateSubnetsServiceEndpointsValue value, an extra attribute value was detected. "+ + "A CurrentStateSubnetsServiceEndpointsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateSubnetsServiceEndpointsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + endpointsAttribute, ok := attributes["endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `endpoints is missing from object`) + + return NewCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + endpointsVal, ok := endpointsAttribute.(ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`endpoints expected to be ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsEndpointsValue], was: %T`, endpointsAttribute)) + } + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return NewCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return NewCurrentStateSubnetsServiceEndpointsValueUnknown(), diags + } + + return CurrentStateSubnetsServiceEndpointsValue{ + Endpoints: endpointsVal, + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsServiceEndpointsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateSubnetsServiceEndpointsValue { + object, diags := NewCurrentStateSubnetsServiceEndpointsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateSubnetsServiceEndpointsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateSubnetsServiceEndpointsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateSubnetsServiceEndpointsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateSubnetsServiceEndpointsValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateSubnetsServiceEndpointsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateSubnetsServiceEndpointsValueMust(CurrentStateSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateSubnetsServiceEndpointsType) ValueType(ctx context.Context) attr.Value { + return CurrentStateSubnetsServiceEndpointsValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateSubnetsServiceEndpointsValue{} + +type CurrentStateSubnetsServiceEndpointsValue struct { + Endpoints ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsEndpointsValue] `tfsdk:"endpoints" json:"endpoints"` + ManagedServiceUrn ovhtypes.TfStringValue `tfsdk:"managed_service_urn" json:"managedServiceURN"` + state attr.ValueState +} + +func (v *CurrentStateSubnetsServiceEndpointsValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateSubnetsServiceEndpointsValue CurrentStateSubnetsServiceEndpointsValue + + var tmp JsonCurrentStateSubnetsServiceEndpointsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Endpoints = tmp.Endpoints + v.ManagedServiceUrn = tmp.ManagedServiceUrn + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateSubnetsServiceEndpointsValue) MergeWith(other *CurrentStateSubnetsServiceEndpointsValue) { + + if (v.Endpoints.IsUnknown() || v.Endpoints.IsNull()) && !other.Endpoints.IsUnknown() { + v.Endpoints = other.Endpoints + } else if !other.Endpoints.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.Endpoints.Elements() + newElems := other.Endpoints.Elements() + + if len(elems) != len(newElems) { + v.Endpoints = other.Endpoints + } else { + for idx, e := range elems { + tmp := e.(CurrentStateSubnetsServiceEndpointsEndpointsValue) + tmp2 := newElems[idx].(CurrentStateSubnetsServiceEndpointsEndpointsValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.Endpoints = ovhtypes.TfListNestedValue[CurrentStateSubnetsServiceEndpointsEndpointsValue]{ + ListValue: basetypes.NewListValueMust(CurrentStateSubnetsServiceEndpointsEndpointsValue{}.Type(context.Background()), newSlice), + } + } + } + + if (v.ManagedServiceUrn.IsUnknown() || v.ManagedServiceUrn.IsNull()) && !other.ManagedServiceUrn.IsUnknown() { + v.ManagedServiceUrn = other.ManagedServiceUrn + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateSubnetsServiceEndpointsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "endpoints": v.Endpoints, + "managedServiceURN": v.ManagedServiceUrn, + } +} +func (v CurrentStateSubnetsServiceEndpointsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["endpoints"] = basetypes.ListType{ + ElemType: CurrentStateSubnetsServiceEndpointsEndpointsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["managed_service_urn"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Endpoints.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["endpoints"] = val + + val, err = v.ManagedServiceUrn.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["managed_service_urn"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateSubnetsServiceEndpointsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateSubnetsServiceEndpointsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateSubnetsServiceEndpointsValue) String() string { + return "CurrentStateSubnetsServiceEndpointsValue" +} + +func (v CurrentStateSubnetsServiceEndpointsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "endpoints": ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + "managed_service_urn": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "endpoints": v.Endpoints, + "managed_service_urn": v.ManagedServiceUrn, + }) + + return objVal, diags +} + +func (v CurrentStateSubnetsServiceEndpointsValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateSubnetsServiceEndpointsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Endpoints.Equal(other.Endpoints) { + return false + } + + if !v.ManagedServiceUrn.Equal(other.ManagedServiceUrn) { + return false + } + + return true +} + +func (v CurrentStateSubnetsServiceEndpointsValue) Type(ctx context.Context) attr.Type { + return CurrentStateSubnetsServiceEndpointsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateSubnetsServiceEndpointsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "endpoints": ovhtypes.NewTfListNestedType[CurrentStateSubnetsServiceEndpointsEndpointsValue](ctx), + "managed_service_urn": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = CurrentStateSubnetsServiceEndpointsEndpointsType{} + +type CurrentStateSubnetsServiceEndpointsEndpointsType struct { + basetypes.ObjectType +} + +func (t CurrentStateSubnetsServiceEndpointsEndpointsType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateSubnetsServiceEndpointsEndpointsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateSubnetsServiceEndpointsEndpointsType) String() string { + return "CurrentStateSubnetsServiceEndpointsEndpointsType" +} + +func (t CurrentStateSubnetsServiceEndpointsEndpointsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + descriptionAttribute, ok := attributes["description"] + + if !ok { + diags.AddError( + "Attribute Missing", + `description is missing from object`) + + return nil, diags + } + + descriptionVal, ok := descriptionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`description expected to be ovhtypes.TfStringValue, was: %T`, descriptionAttribute)) + } + + ipAttribute, ok := attributes["ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ip is missing from object`) + + return nil, diags + } + + ipVal, ok := ipAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ip expected to be ovhtypes.TfStringValue, was: %T`, ipAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateSubnetsServiceEndpointsEndpointsValue{ + Description: descriptionVal, + Ip: ipVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsServiceEndpointsEndpointsValueNull() CurrentStateSubnetsServiceEndpointsEndpointsValue { + return CurrentStateSubnetsServiceEndpointsEndpointsValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown() CurrentStateSubnetsServiceEndpointsEndpointsValue { + return CurrentStateSubnetsServiceEndpointsEndpointsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateSubnetsServiceEndpointsEndpointsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateSubnetsServiceEndpointsEndpointsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Value", + "While creating a CurrentStateSubnetsServiceEndpointsEndpointsValue value, a missing attribute value was detected. "+ + "A CurrentStateSubnetsServiceEndpointsEndpointsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Type", + "While creating a CurrentStateSubnetsServiceEndpointsEndpointsValue value, an invalid attribute value was detected. "+ + "A CurrentStateSubnetsServiceEndpointsEndpointsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Value", + "While creating a CurrentStateSubnetsServiceEndpointsEndpointsValue value, an extra attribute value was detected. "+ + "A CurrentStateSubnetsServiceEndpointsEndpointsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateSubnetsServiceEndpointsEndpointsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + descriptionAttribute, ok := attributes["description"] + + if !ok { + diags.AddError( + "Attribute Missing", + `description is missing from object`) + + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + descriptionVal, ok := descriptionAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`description expected to be ovhtypes.TfStringValue, was: %T`, descriptionAttribute)) + } + + ipAttribute, ok := attributes["ip"] + + if !ok { + diags.AddError( + "Attribute Missing", + `ip is missing from object`) + + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + ipVal, ok := ipAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`ip expected to be ovhtypes.TfStringValue, was: %T`, ipAttribute)) + } + + if diags.HasError() { + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), diags + } + + return CurrentStateSubnetsServiceEndpointsEndpointsValue{ + Description: descriptionVal, + Ip: ipVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsServiceEndpointsEndpointsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateSubnetsServiceEndpointsEndpointsValue { + object, diags := NewCurrentStateSubnetsServiceEndpointsEndpointsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateSubnetsServiceEndpointsEndpointsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateSubnetsServiceEndpointsEndpointsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateSubnetsServiceEndpointsEndpointsValueMust(CurrentStateSubnetsServiceEndpointsEndpointsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateSubnetsServiceEndpointsEndpointsType) ValueType(ctx context.Context) attr.Value { + return CurrentStateSubnetsServiceEndpointsEndpointsValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateSubnetsServiceEndpointsEndpointsValue{} + +type CurrentStateSubnetsServiceEndpointsEndpointsValue struct { + Description ovhtypes.TfStringValue `tfsdk:"description" json:"description"` + Ip ovhtypes.TfStringValue `tfsdk:"ip" json:"ip"` + state attr.ValueState +} + +func (v *CurrentStateSubnetsServiceEndpointsEndpointsValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateSubnetsServiceEndpointsEndpointsValue CurrentStateSubnetsServiceEndpointsEndpointsValue + + var tmp JsonCurrentStateSubnetsServiceEndpointsEndpointsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Description = tmp.Description + v.Ip = tmp.Ip + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateSubnetsServiceEndpointsEndpointsValue) MergeWith(other *CurrentStateSubnetsServiceEndpointsEndpointsValue) { + + if (v.Description.IsUnknown() || v.Description.IsNull()) && !other.Description.IsUnknown() { + v.Description = other.Description + } + + if (v.Ip.IsUnknown() || v.Ip.IsNull()) && !other.Ip.IsUnknown() { + v.Ip = other.Ip + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "description": v.Description, + "ip": v.Ip, + } +} +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["description"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["ip"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Description.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["description"] = val + + val, err = v.Ip.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["ip"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) String() string { + return "CurrentStateSubnetsServiceEndpointsEndpointsValue" +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "description": ovhtypes.TfStringType{}, + "ip": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "description": v.Description, + "ip": v.Ip, + }) + + return objVal, diags +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateSubnetsServiceEndpointsEndpointsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Description.Equal(other.Description) { + return false + } + + if !v.Ip.Equal(other.Ip) { + return false + } + + return true +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) Type(ctx context.Context) attr.Type { + return CurrentStateSubnetsServiceEndpointsEndpointsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateSubnetsServiceEndpointsEndpointsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "description": ovhtypes.TfStringType{}, + "ip": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = CurrentStateSubnetsServiceRangeType{} + +type CurrentStateSubnetsServiceRangeType struct { + basetypes.ObjectType +} + +func (t CurrentStateSubnetsServiceRangeType) Equal(o attr.Type) bool { + other, ok := o.(CurrentStateSubnetsServiceRangeType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t CurrentStateSubnetsServiceRangeType) String() string { + return "CurrentStateSubnetsServiceRangeType" +} + +func (t CurrentStateSubnetsServiceRangeType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + remainingIpsAttribute, ok := attributes["remaining_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `remaining_ips is missing from object`) + + return nil, diags + } + + remainingIpsVal, ok := remainingIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`remaining_ips expected to be ovhtypes.TfInt64Value, was: %T`, remainingIpsAttribute)) + } + + reservedIpsAttribute, ok := attributes["reserved_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `reserved_ips is missing from object`) + + return nil, diags + } + + reservedIpsVal, ok := reservedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`reserved_ips expected to be ovhtypes.TfInt64Value, was: %T`, reservedIpsAttribute)) + } + + usedIpsAttribute, ok := attributes["used_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `used_ips is missing from object`) + + return nil, diags + } + + usedIpsVal, ok := usedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`used_ips expected to be ovhtypes.TfInt64Value, was: %T`, usedIpsAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return CurrentStateSubnetsServiceRangeValue{ + Cidr: cidrVal, + RemainingIps: remainingIpsVal, + ReservedIps: reservedIpsVal, + UsedIps: usedIpsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsServiceRangeValueNull() CurrentStateSubnetsServiceRangeValue { + return CurrentStateSubnetsServiceRangeValue{ + state: attr.ValueStateNull, + } +} + +func NewCurrentStateSubnetsServiceRangeValueUnknown() CurrentStateSubnetsServiceRangeValue { + return CurrentStateSubnetsServiceRangeValue{ + state: attr.ValueStateUnknown, + } +} + +func NewCurrentStateSubnetsServiceRangeValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (CurrentStateSubnetsServiceRangeValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing CurrentStateSubnetsServiceRangeValue Attribute Value", + "While creating a CurrentStateSubnetsServiceRangeValue value, a missing attribute value was detected. "+ + "A CurrentStateSubnetsServiceRangeValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid CurrentStateSubnetsServiceRangeValue Attribute Type", + "While creating a CurrentStateSubnetsServiceRangeValue value, an invalid attribute value was detected. "+ + "A CurrentStateSubnetsServiceRangeValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("CurrentStateSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("CurrentStateSubnetsServiceRangeValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra CurrentStateSubnetsServiceRangeValue Attribute Value", + "While creating a CurrentStateSubnetsServiceRangeValue value, an extra attribute value was detected. "+ + "A CurrentStateSubnetsServiceRangeValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra CurrentStateSubnetsServiceRangeValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + remainingIpsAttribute, ok := attributes["remaining_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `remaining_ips is missing from object`) + + return NewCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + remainingIpsVal, ok := remainingIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`remaining_ips expected to be ovhtypes.TfInt64Value, was: %T`, remainingIpsAttribute)) + } + + reservedIpsAttribute, ok := attributes["reserved_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `reserved_ips is missing from object`) + + return NewCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + reservedIpsVal, ok := reservedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`reserved_ips expected to be ovhtypes.TfInt64Value, was: %T`, reservedIpsAttribute)) + } + + usedIpsAttribute, ok := attributes["used_ips"] + + if !ok { + diags.AddError( + "Attribute Missing", + `used_ips is missing from object`) + + return NewCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + usedIpsVal, ok := usedIpsAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`used_ips expected to be ovhtypes.TfInt64Value, was: %T`, usedIpsAttribute)) + } + + if diags.HasError() { + return NewCurrentStateSubnetsServiceRangeValueUnknown(), diags + } + + return CurrentStateSubnetsServiceRangeValue{ + Cidr: cidrVal, + RemainingIps: remainingIpsVal, + ReservedIps: reservedIpsVal, + UsedIps: usedIpsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewCurrentStateSubnetsServiceRangeValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) CurrentStateSubnetsServiceRangeValue { + object, diags := NewCurrentStateSubnetsServiceRangeValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewCurrentStateSubnetsServiceRangeValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t CurrentStateSubnetsServiceRangeType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewCurrentStateSubnetsServiceRangeValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewCurrentStateSubnetsServiceRangeValueUnknown(), nil + } + + if in.IsNull() { + return NewCurrentStateSubnetsServiceRangeValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewCurrentStateSubnetsServiceRangeValueMust(CurrentStateSubnetsServiceRangeValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t CurrentStateSubnetsServiceRangeType) ValueType(ctx context.Context) attr.Value { + return CurrentStateSubnetsServiceRangeValue{} +} + +var _ basetypes.ObjectValuable = CurrentStateSubnetsServiceRangeValue{} + +type CurrentStateSubnetsServiceRangeValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + RemainingIps ovhtypes.TfInt64Value `tfsdk:"remaining_ips" json:"remainingIps"` + ReservedIps ovhtypes.TfInt64Value `tfsdk:"reserved_ips" json:"reservedIps"` + UsedIps ovhtypes.TfInt64Value `tfsdk:"used_ips" json:"usedIps"` + state attr.ValueState +} + +func (v *CurrentStateSubnetsServiceRangeValue) UnmarshalJSON(data []byte) error { + type JsonCurrentStateSubnetsServiceRangeValue CurrentStateSubnetsServiceRangeValue + + var tmp JsonCurrentStateSubnetsServiceRangeValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + v.RemainingIps = tmp.RemainingIps + v.ReservedIps = tmp.ReservedIps + v.UsedIps = tmp.UsedIps + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *CurrentStateSubnetsServiceRangeValue) MergeWith(other *CurrentStateSubnetsServiceRangeValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.RemainingIps.IsUnknown() || v.RemainingIps.IsNull()) && !other.RemainingIps.IsUnknown() { + v.RemainingIps = other.RemainingIps + } + + if (v.ReservedIps.IsUnknown() || v.ReservedIps.IsNull()) && !other.ReservedIps.IsUnknown() { + v.ReservedIps = other.ReservedIps + } + + if (v.UsedIps.IsUnknown() || v.UsedIps.IsNull()) && !other.UsedIps.IsUnknown() { + v.UsedIps = other.UsedIps + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v CurrentStateSubnetsServiceRangeValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + "remainingIps": v.RemainingIps, + "reservedIps": v.ReservedIps, + "usedIps": v.UsedIps, + } +} +func (v CurrentStateSubnetsServiceRangeValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["remaining_ips"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["reserved_ips"] = basetypes.Int64Type{}.TerraformType(ctx) + attrTypes["used_ips"] = basetypes.Int64Type{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + val, err = v.RemainingIps.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["remaining_ips"] = val + + val, err = v.ReservedIps.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["reserved_ips"] = val + + val, err = v.UsedIps.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["used_ips"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v CurrentStateSubnetsServiceRangeValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v CurrentStateSubnetsServiceRangeValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v CurrentStateSubnetsServiceRangeValue) String() string { + return "CurrentStateSubnetsServiceRangeValue" +} + +func (v CurrentStateSubnetsServiceRangeValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "remaining_ips": ovhtypes.TfInt64Type{}, + "reserved_ips": ovhtypes.TfInt64Type{}, + "used_ips": ovhtypes.TfInt64Type{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + "remaining_ips": v.RemainingIps, + "reserved_ips": v.ReservedIps, + "used_ips": v.UsedIps, + }) + + return objVal, diags +} + +func (v CurrentStateSubnetsServiceRangeValue) Equal(o attr.Value) bool { + other, ok := o.(CurrentStateSubnetsServiceRangeValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + if !v.RemainingIps.Equal(other.RemainingIps) { + return false + } + + if !v.ReservedIps.Equal(other.ReservedIps) { + return false + } + + if !v.UsedIps.Equal(other.UsedIps) { + return false + } + + return true +} + +func (v CurrentStateSubnetsServiceRangeValue) Type(ctx context.Context) attr.Type { + return CurrentStateSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v CurrentStateSubnetsServiceRangeValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "remaining_ips": ovhtypes.TfInt64Type{}, + "reserved_ips": ovhtypes.TfInt64Type{}, + "used_ips": ovhtypes.TfInt64Type{}, + } +} + +var _ basetypes.ObjectTypable = VrackServicesCurrentTasksType{} + +type VrackServicesCurrentTasksType struct { + basetypes.ObjectType +} + +func (t VrackServicesCurrentTasksType) Equal(o attr.Type) bool { + other, ok := o.(VrackServicesCurrentTasksType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackServicesCurrentTasksType) String() string { + return "VrackServicesCurrentTasksType" +} + +func (t VrackServicesCurrentTasksType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return nil, diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + linkAttribute, ok := attributes["link"] + + if !ok { + diags.AddError( + "Attribute Missing", + `link is missing from object`) + + return nil, diags + } + + linkVal, ok := linkAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`link expected to be ovhtypes.TfStringValue, was: %T`, linkAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return nil, diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + typeAttribute, ok := attributes["type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `type is missing from object`) + + return nil, diags + } + + typeVal, ok := typeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`type expected to be ovhtypes.TfStringValue, was: %T`, typeAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackServicesCurrentTasksValue{ + Id: idVal, + Link: linkVal, + Status: statusVal, + VrackServicesCurrentTasksType: typeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackServicesCurrentTasksValueNull() VrackServicesCurrentTasksValue { + return VrackServicesCurrentTasksValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackServicesCurrentTasksValueUnknown() VrackServicesCurrentTasksValue { + return VrackServicesCurrentTasksValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackServicesCurrentTasksValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackServicesCurrentTasksValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackServicesCurrentTasksValue Attribute Value", + "While creating a VrackServicesCurrentTasksValue value, a missing attribute value was detected. "+ + "A VrackServicesCurrentTasksValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackServicesCurrentTasksValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackServicesCurrentTasksValue Attribute Type", + "While creating a VrackServicesCurrentTasksValue value, an invalid attribute value was detected. "+ + "A VrackServicesCurrentTasksValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackServicesCurrentTasksValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackServicesCurrentTasksValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackServicesCurrentTasksValue Attribute Value", + "While creating a VrackServicesCurrentTasksValue value, an extra attribute value was detected. "+ + "A VrackServicesCurrentTasksValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackServicesCurrentTasksValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackServicesCurrentTasksValueUnknown(), diags + } + + idAttribute, ok := attributes["id"] + + if !ok { + diags.AddError( + "Attribute Missing", + `id is missing from object`) + + return NewVrackServicesCurrentTasksValueUnknown(), diags + } + + idVal, ok := idAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`id expected to be ovhtypes.TfStringValue, was: %T`, idAttribute)) + } + + linkAttribute, ok := attributes["link"] + + if !ok { + diags.AddError( + "Attribute Missing", + `link is missing from object`) + + return NewVrackServicesCurrentTasksValueUnknown(), diags + } + + linkVal, ok := linkAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`link expected to be ovhtypes.TfStringValue, was: %T`, linkAttribute)) + } + + statusAttribute, ok := attributes["status"] + + if !ok { + diags.AddError( + "Attribute Missing", + `status is missing from object`) + + return NewVrackServicesCurrentTasksValueUnknown(), diags + } + + statusVal, ok := statusAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`status expected to be ovhtypes.TfStringValue, was: %T`, statusAttribute)) + } + + typeAttribute, ok := attributes["type"] + + if !ok { + diags.AddError( + "Attribute Missing", + `type is missing from object`) + + return NewVrackServicesCurrentTasksValueUnknown(), diags + } + + typeVal, ok := typeAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`type expected to be ovhtypes.TfStringValue, was: %T`, typeAttribute)) + } + + if diags.HasError() { + return NewVrackServicesCurrentTasksValueUnknown(), diags + } + + return VrackServicesCurrentTasksValue{ + Id: idVal, + Link: linkVal, + Status: statusVal, + VrackServicesCurrentTasksType: typeVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackServicesCurrentTasksValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackServicesCurrentTasksValue { + object, diags := NewVrackServicesCurrentTasksValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackServicesCurrentTasksValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackServicesCurrentTasksType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackServicesCurrentTasksValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackServicesCurrentTasksValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackServicesCurrentTasksValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackServicesCurrentTasksValueMust(VrackServicesCurrentTasksValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackServicesCurrentTasksType) ValueType(ctx context.Context) attr.Value { + return VrackServicesCurrentTasksValue{} +} + +var _ basetypes.ObjectValuable = VrackServicesCurrentTasksValue{} + +type VrackServicesCurrentTasksValue struct { + Id ovhtypes.TfStringValue `tfsdk:"id" json:"id"` + Link ovhtypes.TfStringValue `tfsdk:"link" json:"link"` + Status ovhtypes.TfStringValue `tfsdk:"status" json:"status"` + VrackServicesCurrentTasksType ovhtypes.TfStringValue `tfsdk:"type" json:"type"` + state attr.ValueState +} + +func (v *VrackServicesCurrentTasksValue) UnmarshalJSON(data []byte) error { + type JsonVrackServicesCurrentTasksValue VrackServicesCurrentTasksValue + + var tmp JsonVrackServicesCurrentTasksValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Id = tmp.Id + v.Link = tmp.Link + v.Status = tmp.Status + v.VrackServicesCurrentTasksType = tmp.VrackServicesCurrentTasksType + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackServicesCurrentTasksValue) MergeWith(other *VrackServicesCurrentTasksValue) { + + if (v.Id.IsUnknown() || v.Id.IsNull()) && !other.Id.IsUnknown() { + v.Id = other.Id + } + + if (v.Link.IsUnknown() || v.Link.IsNull()) && !other.Link.IsUnknown() { + v.Link = other.Link + } + + if (v.Status.IsUnknown() || v.Status.IsNull()) && !other.Status.IsUnknown() { + v.Status = other.Status + } + + if (v.VrackServicesCurrentTasksType.IsUnknown() || v.VrackServicesCurrentTasksType.IsNull()) && !other.VrackServicesCurrentTasksType.IsUnknown() { + v.VrackServicesCurrentTasksType = other.VrackServicesCurrentTasksType + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackServicesCurrentTasksValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "id": v.Id, + "link": v.Link, + "status": v.Status, + "type": v.VrackServicesCurrentTasksType, + } +} +func (v VrackServicesCurrentTasksValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 4) + + var val tftypes.Value + var err error + + attrTypes["id"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["link"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["status"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["type"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 4) + + val, err = v.Id.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["id"] = val + + val, err = v.Link.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["link"] = val + + val, err = v.Status.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["status"] = val + + val, err = v.VrackServicesCurrentTasksType.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["type"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackServicesCurrentTasksValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackServicesCurrentTasksValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackServicesCurrentTasksValue) String() string { + return "VrackServicesCurrentTasksValue" +} + +func (v VrackServicesCurrentTasksValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "id": ovhtypes.TfStringType{}, + "link": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + "type": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "id": v.Id, + "link": v.Link, + "status": v.Status, + "type": v.VrackServicesCurrentTasksType, + }) + + return objVal, diags +} + +func (v VrackServicesCurrentTasksValue) Equal(o attr.Value) bool { + other, ok := o.(VrackServicesCurrentTasksValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Id.Equal(other.Id) { + return false + } + + if !v.Link.Equal(other.Link) { + return false + } + + if !v.Status.Equal(other.Status) { + return false + } + + if !v.VrackServicesCurrentTasksType.Equal(other.VrackServicesCurrentTasksType) { + return false + } + + return true +} + +func (v VrackServicesCurrentTasksValue) Type(ctx context.Context) attr.Type { + return VrackServicesCurrentTasksType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackServicesCurrentTasksValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "id": ovhtypes.TfStringType{}, + "link": ovhtypes.TfStringType{}, + "status": ovhtypes.TfStringType{}, + "type": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = VrackServicesTargetSpecType{} + +type VrackServicesTargetSpecType struct { + basetypes.ObjectType +} + +func (t VrackServicesTargetSpecType) Equal(o attr.Type) bool { + other, ok := o.(VrackServicesTargetSpecType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t VrackServicesTargetSpecType) String() string { + return "VrackServicesTargetSpecType" +} + +func (t VrackServicesTargetSpecType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return nil, diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[TargetSpecSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[TargetSpecSubnetsValue], was: %T`, subnetsAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return VrackServicesTargetSpecValue{ + Subnets: subnetsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackServicesTargetSpecValueNull() VrackServicesTargetSpecValue { + return VrackServicesTargetSpecValue{ + state: attr.ValueStateNull, + } +} + +func NewVrackServicesTargetSpecValueUnknown() VrackServicesTargetSpecValue { + return VrackServicesTargetSpecValue{ + state: attr.ValueStateUnknown, + } +} + +func NewVrackServicesTargetSpecValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (VrackServicesTargetSpecValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing VrackServicesTargetSpecValue Attribute Value", + "While creating a VrackServicesTargetSpecValue value, a missing attribute value was detected. "+ + "A VrackServicesTargetSpecValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackServicesTargetSpecValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid VrackServicesTargetSpecValue Attribute Type", + "While creating a VrackServicesTargetSpecValue value, an invalid attribute value was detected. "+ + "A VrackServicesTargetSpecValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("VrackServicesTargetSpecValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("VrackServicesTargetSpecValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra VrackServicesTargetSpecValue Attribute Value", + "While creating a VrackServicesTargetSpecValue value, an extra attribute value was detected. "+ + "A VrackServicesTargetSpecValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra VrackServicesTargetSpecValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewVrackServicesTargetSpecValueUnknown(), diags + } + + subnetsAttribute, ok := attributes["subnets"] + + if !ok { + diags.AddError( + "Attribute Missing", + `subnets is missing from object`) + + return NewVrackServicesTargetSpecValueUnknown(), diags + } + + subnetsVal, ok := subnetsAttribute.(ovhtypes.TfListNestedValue[TargetSpecSubnetsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`subnets expected to be ovhtypes.TfListNestedValue[TargetSpecSubnetsValue], was: %T`, subnetsAttribute)) + } + + if diags.HasError() { + return NewVrackServicesTargetSpecValueUnknown(), diags + } + + return VrackServicesTargetSpecValue{ + Subnets: subnetsVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewVrackServicesTargetSpecValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) VrackServicesTargetSpecValue { + object, diags := NewVrackServicesTargetSpecValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewVrackServicesTargetSpecValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t VrackServicesTargetSpecType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewVrackServicesTargetSpecValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewVrackServicesTargetSpecValueUnknown(), nil + } + + if in.IsNull() { + return NewVrackServicesTargetSpecValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewVrackServicesTargetSpecValueMust(VrackServicesTargetSpecValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t VrackServicesTargetSpecType) ValueType(ctx context.Context) attr.Value { + return VrackServicesTargetSpecValue{} +} + +var _ basetypes.ObjectValuable = VrackServicesTargetSpecValue{} + +type VrackServicesTargetSpecValue struct { + Subnets ovhtypes.TfListNestedValue[TargetSpecSubnetsValue] `tfsdk:"subnets" json:"subnets"` + state attr.ValueState +} + +type VrackServicesTargetSpecWritableValue struct { + *VrackServicesTargetSpecValue `json:"-"` + Subnets *ovhtypes.TfListNestedValue[TargetSpecSubnetsValue] `json:"subnets,omitempty"` +} + +func (v VrackServicesTargetSpecValue) ToCreate() *VrackServicesTargetSpecWritableValue { + res := &VrackServicesTargetSpecWritableValue{} + + if !v.Subnets.IsNull() { + res.Subnets = &v.Subnets + } + + return res +} + +func (v VrackServicesTargetSpecValue) ToUpdate() *VrackServicesTargetSpecWritableValue { + res := &VrackServicesTargetSpecWritableValue{} + + if !v.Subnets.IsNull() { + res.Subnets = &v.Subnets + } + + return res +} + +func (v *VrackServicesTargetSpecValue) UnmarshalJSON(data []byte) error { + type JsonVrackServicesTargetSpecValue VrackServicesTargetSpecValue + + var tmp JsonVrackServicesTargetSpecValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Subnets = tmp.Subnets + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *VrackServicesTargetSpecValue) MergeWith(other *VrackServicesTargetSpecValue) { + + if (v.Subnets.IsUnknown() || v.Subnets.IsNull()) && !other.Subnets.IsUnknown() { + v.Subnets = other.Subnets + } else if !other.Subnets.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.Subnets.Elements() + newElems := other.Subnets.Elements() + + if len(elems) != len(newElems) { + v.Subnets = other.Subnets + } else { + for idx, e := range elems { + tmp := e.(TargetSpecSubnetsValue) + tmp2 := newElems[idx].(TargetSpecSubnetsValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.Subnets = ovhtypes.TfListNestedValue[TargetSpecSubnetsValue]{ + ListValue: basetypes.NewListValueMust(TargetSpecSubnetsValue{}.Type(context.Background()), newSlice), + } + } + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v VrackServicesTargetSpecValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "subnets": v.Subnets, + } +} +func (v VrackServicesTargetSpecValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 2) + + var val tftypes.Value + var err error + + attrTypes["subnets"] = basetypes.ListType{ + ElemType: TargetSpecSubnetsValue{}.Type(ctx), + }.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 2) + + val, err = v.Subnets.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["subnets"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v VrackServicesTargetSpecValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v VrackServicesTargetSpecValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v VrackServicesTargetSpecValue) String() string { + return "VrackServicesTargetSpecValue" +} + +func (v VrackServicesTargetSpecValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "subnets": ovhtypes.NewTfListNestedType[TargetSpecSubnetsValue](ctx), + }, + map[string]attr.Value{ + "subnets": v.Subnets, + }) + + return objVal, diags +} + +func (v VrackServicesTargetSpecValue) Equal(o attr.Value) bool { + other, ok := o.(VrackServicesTargetSpecValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Subnets.Equal(other.Subnets) { + return false + } + + return true +} + +func (v VrackServicesTargetSpecValue) Type(ctx context.Context) attr.Type { + return VrackServicesTargetSpecType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v VrackServicesTargetSpecValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "subnets": ovhtypes.NewTfListNestedType[TargetSpecSubnetsValue](ctx), + } +} + +var _ basetypes.ObjectTypable = TargetSpecSubnetsType{} + +type TargetSpecSubnetsType struct { + basetypes.ObjectType +} + +func (t TargetSpecSubnetsType) Equal(o attr.Type) bool { + other, ok := o.(TargetSpecSubnetsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t TargetSpecSubnetsType) String() string { + return "TargetSpecSubnetsType" +} + +func (t TargetSpecSubnetsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return nil, diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return nil, diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return nil, diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(TargetSpecSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be TargetSpecSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return nil, diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return TargetSpecSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecSubnetsValueNull() TargetSpecSubnetsValue { + return TargetSpecSubnetsValue{ + state: attr.ValueStateNull, + } +} + +func NewTargetSpecSubnetsValueUnknown() TargetSpecSubnetsValue { + return TargetSpecSubnetsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewTargetSpecSubnetsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (TargetSpecSubnetsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing TargetSpecSubnetsValue Attribute Value", + "While creating a TargetSpecSubnetsValue value, a missing attribute value was detected. "+ + "A TargetSpecSubnetsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecSubnetsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid TargetSpecSubnetsValue Attribute Type", + "While creating a TargetSpecSubnetsValue value, an invalid attribute value was detected. "+ + "A TargetSpecSubnetsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecSubnetsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("TargetSpecSubnetsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra TargetSpecSubnetsValue Attribute Value", + "While creating a TargetSpecSubnetsValue value, an extra attribute value was detected. "+ + "A TargetSpecSubnetsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra TargetSpecSubnetsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewTargetSpecSubnetsValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewTargetSpecSubnetsValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + displayNameAttribute, ok := attributes["display_name"] + + if !ok { + diags.AddError( + "Attribute Missing", + `display_name is missing from object`) + + return NewTargetSpecSubnetsValueUnknown(), diags + } + + displayNameVal, ok := displayNameAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`display_name expected to be ovhtypes.TfStringValue, was: %T`, displayNameAttribute)) + } + + serviceEndpointsAttribute, ok := attributes["service_endpoints"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_endpoints is missing from object`) + + return NewTargetSpecSubnetsValueUnknown(), diags + } + + serviceEndpointsVal, ok := serviceEndpointsAttribute.(ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue]) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_endpoints expected to be ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue], was: %T`, serviceEndpointsAttribute)) + } + + serviceRangeAttribute, ok := attributes["service_range"] + + if !ok { + diags.AddError( + "Attribute Missing", + `service_range is missing from object`) + + return NewTargetSpecSubnetsValueUnknown(), diags + } + + serviceRangeVal, ok := serviceRangeAttribute.(TargetSpecSubnetsServiceRangeValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`service_range expected to be TargetSpecSubnetsServiceRangeValue, was: %T`, serviceRangeAttribute)) + } + + vlanAttribute, ok := attributes["vlan"] + + if !ok { + diags.AddError( + "Attribute Missing", + `vlan is missing from object`) + + return NewTargetSpecSubnetsValueUnknown(), diags + } + + vlanVal, ok := vlanAttribute.(ovhtypes.TfInt64Value) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`vlan expected to be ovhtypes.TfInt64Value, was: %T`, vlanAttribute)) + } + + if diags.HasError() { + return NewTargetSpecSubnetsValueUnknown(), diags + } + + return TargetSpecSubnetsValue{ + Cidr: cidrVal, + DisplayName: displayNameVal, + ServiceEndpoints: serviceEndpointsVal, + ServiceRange: serviceRangeVal, + Vlan: vlanVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecSubnetsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) TargetSpecSubnetsValue { + object, diags := NewTargetSpecSubnetsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTargetSpecSubnetsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t TargetSpecSubnetsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTargetSpecSubnetsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewTargetSpecSubnetsValueUnknown(), nil + } + + if in.IsNull() { + return NewTargetSpecSubnetsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewTargetSpecSubnetsValueMust(TargetSpecSubnetsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t TargetSpecSubnetsType) ValueType(ctx context.Context) attr.Value { + return TargetSpecSubnetsValue{} +} + +var _ basetypes.ObjectValuable = TargetSpecSubnetsValue{} + +type TargetSpecSubnetsValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + DisplayName ovhtypes.TfStringValue `tfsdk:"display_name" json:"displayName"` + ServiceEndpoints ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue] `tfsdk:"service_endpoints" json:"serviceEndpoints"` + ServiceRange TargetSpecSubnetsServiceRangeValue `tfsdk:"service_range" json:"serviceRange"` + Vlan ovhtypes.TfInt64Value `tfsdk:"vlan" json:"vlan"` + state attr.ValueState +} + +type TargetSpecSubnetsWritableValue struct { + *TargetSpecSubnetsValue `json:"-"` + Cidr *ovhtypes.TfStringValue `json:"cidr,omitempty"` + DisplayName *ovhtypes.TfStringValue `json:"displayName,omitempty"` + ServiceEndpoints *ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue] `json:"serviceEndpoints,omitempty"` + ServiceRange *TargetSpecSubnetsServiceRangeValue `json:"serviceRange,omitempty"` + Vlan *ovhtypes.TfInt64Value `json:"vlan,omitempty"` +} + +func (v TargetSpecSubnetsValue) ToCreate() *TargetSpecSubnetsWritableValue { + res := &TargetSpecSubnetsWritableValue{} + + if !v.ServiceEndpoints.IsNull() { + res.ServiceEndpoints = &v.ServiceEndpoints + } + + if !v.ServiceRange.IsNull() { + res.ServiceRange = &v.ServiceRange + } + + if !v.Vlan.IsNull() { + res.Vlan = &v.Vlan + } + + if !v.Cidr.IsNull() { + res.Cidr = &v.Cidr + } + + if !v.DisplayName.IsNull() { + res.DisplayName = &v.DisplayName + } + + return res +} + +func (v TargetSpecSubnetsValue) ToUpdate() *TargetSpecSubnetsWritableValue { + res := &TargetSpecSubnetsWritableValue{} + + if !v.ServiceEndpoints.IsNull() { + res.ServiceEndpoints = &v.ServiceEndpoints + } + + if !v.ServiceRange.IsNull() { + res.ServiceRange = &v.ServiceRange + } + + if !v.Vlan.IsNull() { + res.Vlan = &v.Vlan + } + + if !v.Cidr.IsNull() { + res.Cidr = &v.Cidr + } + + if !v.DisplayName.IsNull() { + res.DisplayName = &v.DisplayName + } + + return res +} + +func (v *TargetSpecSubnetsValue) UnmarshalJSON(data []byte) error { + type JsonTargetSpecSubnetsValue TargetSpecSubnetsValue + + var tmp JsonTargetSpecSubnetsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + v.DisplayName = tmp.DisplayName + v.ServiceEndpoints = tmp.ServiceEndpoints + v.ServiceRange = tmp.ServiceRange + v.Vlan = tmp.Vlan + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *TargetSpecSubnetsValue) MergeWith(other *TargetSpecSubnetsValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.DisplayName.IsUnknown() || v.DisplayName.IsNull()) && !other.DisplayName.IsUnknown() { + v.DisplayName = other.DisplayName + } + + if (v.ServiceEndpoints.IsUnknown() || v.ServiceEndpoints.IsNull()) && !other.ServiceEndpoints.IsUnknown() { + v.ServiceEndpoints = other.ServiceEndpoints + } else if !other.ServiceEndpoints.IsUnknown() { + newSlice := make([]attr.Value, 0) + elems := v.ServiceEndpoints.Elements() + newElems := other.ServiceEndpoints.Elements() + + if len(elems) != len(newElems) { + v.ServiceEndpoints = other.ServiceEndpoints + } else { + for idx, e := range elems { + tmp := e.(TargetSpecSubnetsServiceEndpointsValue) + tmp2 := newElems[idx].(TargetSpecSubnetsServiceEndpointsValue) + tmp.MergeWith(&tmp2) + newSlice = append(newSlice, tmp) + } + + v.ServiceEndpoints = ovhtypes.TfListNestedValue[TargetSpecSubnetsServiceEndpointsValue]{ + ListValue: basetypes.NewListValueMust(TargetSpecSubnetsServiceEndpointsValue{}.Type(context.Background()), newSlice), + } + } + } + + if v.ServiceRange.IsUnknown() && !other.ServiceRange.IsUnknown() { + v.ServiceRange = other.ServiceRange + } else if !other.ServiceRange.IsUnknown() { + v.ServiceRange.MergeWith(&other.ServiceRange) + } + + if (v.Vlan.IsUnknown() || v.Vlan.IsNull()) && !other.Vlan.IsUnknown() { + v.Vlan = other.Vlan + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v TargetSpecSubnetsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + "displayName": v.DisplayName, + "serviceEndpoints": v.ServiceEndpoints, + "serviceRange": v.ServiceRange, + "vlan": v.Vlan, + } +} +func (v TargetSpecSubnetsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 5) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["display_name"] = basetypes.StringType{}.TerraformType(ctx) + attrTypes["service_endpoints"] = basetypes.ListType{ + ElemType: TargetSpecSubnetsServiceEndpointsValue{}.Type(ctx), + }.TerraformType(ctx) + attrTypes["service_range"] = basetypes.ObjectType{ + AttrTypes: TargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }.TerraformType(ctx) + attrTypes["vlan"] = basetypes.Int64Type{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 5) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + val, err = v.DisplayName.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["display_name"] = val + + val, err = v.ServiceEndpoints.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_endpoints"] = val + + val, err = v.ServiceRange.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["service_range"] = val + + val, err = v.Vlan.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["vlan"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v TargetSpecSubnetsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v TargetSpecSubnetsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v TargetSpecSubnetsValue) String() string { + return "TargetSpecSubnetsValue" +} + +func (v TargetSpecSubnetsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[TargetSpecSubnetsServiceEndpointsValue](ctx), + "service_range": TargetSpecSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: TargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), + }, + }, + "vlan": ovhtypes.TfInt64Type{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + "display_name": v.DisplayName, + "service_endpoints": v.ServiceEndpoints, + "service_range": v.ServiceRange, + "vlan": v.Vlan, + }) + + return objVal, diags +} + +func (v TargetSpecSubnetsValue) Equal(o attr.Value) bool { + other, ok := o.(TargetSpecSubnetsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + if !v.DisplayName.Equal(other.DisplayName) { + return false + } + + if !v.ServiceEndpoints.Equal(other.ServiceEndpoints) { + return false + } + + if !v.ServiceRange.Equal(other.ServiceRange) { + return false + } + + if !v.Vlan.Equal(other.Vlan) { + return false + } + + return true +} + +func (v TargetSpecSubnetsValue) Type(ctx context.Context) attr.Type { + return TargetSpecSubnetsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v TargetSpecSubnetsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + "display_name": ovhtypes.TfStringType{}, + "service_endpoints": ovhtypes.NewTfListNestedType[TargetSpecSubnetsServiceEndpointsValue](ctx), + "service_range": TargetSpecSubnetsServiceRangeValue{}.Type(ctx), + "vlan": ovhtypes.TfInt64Type{}, + } +} + +var _ basetypes.ObjectTypable = TargetSpecSubnetsServiceEndpointsType{} + +type TargetSpecSubnetsServiceEndpointsType struct { + basetypes.ObjectType +} + +func (t TargetSpecSubnetsServiceEndpointsType) Equal(o attr.Type) bool { + other, ok := o.(TargetSpecSubnetsServiceEndpointsType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t TargetSpecSubnetsServiceEndpointsType) String() string { + return "TargetSpecSubnetsServiceEndpointsType" +} + +func (t TargetSpecSubnetsServiceEndpointsType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return nil, diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return TargetSpecSubnetsServiceEndpointsValue{ + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecSubnetsServiceEndpointsValueNull() TargetSpecSubnetsServiceEndpointsValue { + return TargetSpecSubnetsServiceEndpointsValue{ + state: attr.ValueStateNull, + } +} + +func NewTargetSpecSubnetsServiceEndpointsValueUnknown() TargetSpecSubnetsServiceEndpointsValue { + return TargetSpecSubnetsServiceEndpointsValue{ + state: attr.ValueStateUnknown, + } +} + +func NewTargetSpecSubnetsServiceEndpointsValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (TargetSpecSubnetsServiceEndpointsValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing TargetSpecSubnetsServiceEndpointsValue Attribute Value", + "While creating a TargetSpecSubnetsServiceEndpointsValue value, a missing attribute value was detected. "+ + "A TargetSpecSubnetsServiceEndpointsValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid TargetSpecSubnetsServiceEndpointsValue Attribute Type", + "While creating a TargetSpecSubnetsServiceEndpointsValue value, an invalid attribute value was detected. "+ + "A TargetSpecSubnetsServiceEndpointsValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecSubnetsServiceEndpointsValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("TargetSpecSubnetsServiceEndpointsValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra TargetSpecSubnetsServiceEndpointsValue Attribute Value", + "While creating a TargetSpecSubnetsServiceEndpointsValue value, an extra attribute value was detected. "+ + "A TargetSpecSubnetsServiceEndpointsValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra TargetSpecSubnetsServiceEndpointsValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewTargetSpecSubnetsServiceEndpointsValueUnknown(), diags + } + + managedServiceUrnAttribute, ok := attributes["managed_service_urn"] + + if !ok { + diags.AddError( + "Attribute Missing", + `managed_service_urn is missing from object`) + + return NewTargetSpecSubnetsServiceEndpointsValueUnknown(), diags + } + + managedServiceUrnVal, ok := managedServiceUrnAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`managed_service_urn expected to be ovhtypes.TfStringValue, was: %T`, managedServiceUrnAttribute)) + } + + if diags.HasError() { + return NewTargetSpecSubnetsServiceEndpointsValueUnknown(), diags + } + + return TargetSpecSubnetsServiceEndpointsValue{ + ManagedServiceUrn: managedServiceUrnVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecSubnetsServiceEndpointsValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) TargetSpecSubnetsServiceEndpointsValue { + object, diags := NewTargetSpecSubnetsServiceEndpointsValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTargetSpecSubnetsServiceEndpointsValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t TargetSpecSubnetsServiceEndpointsType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTargetSpecSubnetsServiceEndpointsValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewTargetSpecSubnetsServiceEndpointsValueUnknown(), nil + } + + if in.IsNull() { + return NewTargetSpecSubnetsServiceEndpointsValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewTargetSpecSubnetsServiceEndpointsValueMust(TargetSpecSubnetsServiceEndpointsValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t TargetSpecSubnetsServiceEndpointsType) ValueType(ctx context.Context) attr.Value { + return TargetSpecSubnetsServiceEndpointsValue{} +} + +var _ basetypes.ObjectValuable = TargetSpecSubnetsServiceEndpointsValue{} + +type TargetSpecSubnetsServiceEndpointsValue struct { + ManagedServiceUrn ovhtypes.TfStringValue `tfsdk:"managed_service_urn" json:"managedServiceURN"` + state attr.ValueState +} + +type TargetSpecSubnetsServiceEndpointsWritableValue struct { + *TargetSpecSubnetsServiceEndpointsValue `json:"-"` + ManagedServiceUrn *ovhtypes.TfStringValue `json:"managedServiceURN,omitempty"` +} + +func (v TargetSpecSubnetsServiceEndpointsValue) ToCreate() *TargetSpecSubnetsServiceEndpointsWritableValue { + res := &TargetSpecSubnetsServiceEndpointsWritableValue{} + + if !v.ManagedServiceUrn.IsNull() { + res.ManagedServiceUrn = &v.ManagedServiceUrn + } + + return res +} + +func (v TargetSpecSubnetsServiceEndpointsValue) ToUpdate() *TargetSpecSubnetsServiceEndpointsWritableValue { + res := &TargetSpecSubnetsServiceEndpointsWritableValue{} + + if !v.ManagedServiceUrn.IsNull() { + res.ManagedServiceUrn = &v.ManagedServiceUrn + } + + return res +} + +func (v *TargetSpecSubnetsServiceEndpointsValue) UnmarshalJSON(data []byte) error { + type JsonTargetSpecSubnetsServiceEndpointsValue TargetSpecSubnetsServiceEndpointsValue + + var tmp JsonTargetSpecSubnetsServiceEndpointsValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.ManagedServiceUrn = tmp.ManagedServiceUrn + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *TargetSpecSubnetsServiceEndpointsValue) MergeWith(other *TargetSpecSubnetsServiceEndpointsValue) { + + if (v.ManagedServiceUrn.IsUnknown() || v.ManagedServiceUrn.IsNull()) && !other.ManagedServiceUrn.IsUnknown() { + v.ManagedServiceUrn = other.ManagedServiceUrn + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v TargetSpecSubnetsServiceEndpointsValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "managedServiceUrn": v.ManagedServiceUrn, + } +} +func (v TargetSpecSubnetsServiceEndpointsValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["managed_service_urn"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.ManagedServiceUrn.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["managed_service_urn"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v TargetSpecSubnetsServiceEndpointsValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v TargetSpecSubnetsServiceEndpointsValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v TargetSpecSubnetsServiceEndpointsValue) String() string { + return "TargetSpecSubnetsServiceEndpointsValue" +} + +func (v TargetSpecSubnetsServiceEndpointsValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "managed_service_urn": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "managed_service_urn": v.ManagedServiceUrn, + }) + + return objVal, diags +} + +func (v TargetSpecSubnetsServiceEndpointsValue) Equal(o attr.Value) bool { + other, ok := o.(TargetSpecSubnetsServiceEndpointsValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.ManagedServiceUrn.Equal(other.ManagedServiceUrn) { + return false + } + + return true +} + +func (v TargetSpecSubnetsServiceEndpointsValue) Type(ctx context.Context) attr.Type { + return TargetSpecSubnetsServiceEndpointsType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v TargetSpecSubnetsServiceEndpointsValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "managed_service_urn": ovhtypes.TfStringType{}, + } +} + +var _ basetypes.ObjectTypable = TargetSpecSubnetsServiceRangeType{} + +type TargetSpecSubnetsServiceRangeType struct { + basetypes.ObjectType +} + +func (t TargetSpecSubnetsServiceRangeType) Equal(o attr.Type) bool { + other, ok := o.(TargetSpecSubnetsServiceRangeType) + + if !ok { + return false + } + + return t.ObjectType.Equal(other.ObjectType) +} + +func (t TargetSpecSubnetsServiceRangeType) String() string { + return "TargetSpecSubnetsServiceRangeType" +} + +func (t TargetSpecSubnetsServiceRangeType) ValueFromObject(ctx context.Context, in basetypes.ObjectValue) (basetypes.ObjectValuable, diag.Diagnostics) { + var diags diag.Diagnostics + + attributes := in.Attributes() + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return nil, diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + if diags.HasError() { + return nil, diags + } + + return TargetSpecSubnetsServiceRangeValue{ + Cidr: cidrVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecSubnetsServiceRangeValueNull() TargetSpecSubnetsServiceRangeValue { + return TargetSpecSubnetsServiceRangeValue{ + state: attr.ValueStateNull, + } +} + +func NewTargetSpecSubnetsServiceRangeValueUnknown() TargetSpecSubnetsServiceRangeValue { + return TargetSpecSubnetsServiceRangeValue{ + state: attr.ValueStateUnknown, + } +} + +func NewTargetSpecSubnetsServiceRangeValue(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) (TargetSpecSubnetsServiceRangeValue, diag.Diagnostics) { + var diags diag.Diagnostics + + // Reference: https://github.com/hashicorp/terraform-plugin-framework/issues/521 + ctx := context.Background() + + for name, attributeType := range attributeTypes { + attribute, ok := attributes[name] + + if !ok { + diags.AddError( + "Missing TargetSpecSubnetsServiceRangeValue Attribute Value", + "While creating a TargetSpecSubnetsServiceRangeValue value, a missing attribute value was detected. "+ + "A TargetSpecSubnetsServiceRangeValue must contain values for all attributes, even if null or unknown. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s", name, attributeType.String()), + ) + + continue + } + + if !attributeType.Equal(attribute.Type(ctx)) { + diags.AddError( + "Invalid TargetSpecSubnetsServiceRangeValue Attribute Type", + "While creating a TargetSpecSubnetsServiceRangeValue value, an invalid attribute value was detected. "+ + "A TargetSpecSubnetsServiceRangeValue must use a matching attribute type for the value. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("TargetSpecSubnetsServiceRangeValue Attribute Name (%s) Expected Type: %s\n", name, attributeType.String())+ + fmt.Sprintf("TargetSpecSubnetsServiceRangeValue Attribute Name (%s) Given Type: %s", name, attribute.Type(ctx)), + ) + } + } + + for name := range attributes { + _, ok := attributeTypes[name] + + if !ok { + diags.AddError( + "Extra TargetSpecSubnetsServiceRangeValue Attribute Value", + "While creating a TargetSpecSubnetsServiceRangeValue value, an extra attribute value was detected. "+ + "A TargetSpecSubnetsServiceRangeValue must not contain values beyond the expected attribute types. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + fmt.Sprintf("Extra TargetSpecSubnetsServiceRangeValue Attribute Name: %s", name), + ) + } + } + + if diags.HasError() { + return NewTargetSpecSubnetsServiceRangeValueUnknown(), diags + } + + cidrAttribute, ok := attributes["cidr"] + + if !ok { + diags.AddError( + "Attribute Missing", + `cidr is missing from object`) + + return NewTargetSpecSubnetsServiceRangeValueUnknown(), diags + } + + cidrVal, ok := cidrAttribute.(ovhtypes.TfStringValue) + + if !ok { + diags.AddError( + "Attribute Wrong Type", + fmt.Sprintf(`cidr expected to be ovhtypes.TfStringValue, was: %T`, cidrAttribute)) + } + + if diags.HasError() { + return NewTargetSpecSubnetsServiceRangeValueUnknown(), diags + } + + return TargetSpecSubnetsServiceRangeValue{ + Cidr: cidrVal, + state: attr.ValueStateKnown, + }, diags +} + +func NewTargetSpecSubnetsServiceRangeValueMust(attributeTypes map[string]attr.Type, attributes map[string]attr.Value) TargetSpecSubnetsServiceRangeValue { + object, diags := NewTargetSpecSubnetsServiceRangeValue(attributeTypes, attributes) + + if diags.HasError() { + // This could potentially be added to the diag package. + diagsStrings := make([]string, 0, len(diags)) + + for _, diagnostic := range diags { + diagsStrings = append(diagsStrings, fmt.Sprintf( + "%s | %s | %s", + diagnostic.Severity(), + diagnostic.Summary(), + diagnostic.Detail())) + } + + panic("NewTargetSpecSubnetsServiceRangeValueMust received error(s): " + strings.Join(diagsStrings, "\n")) + } + + return object +} + +func (t TargetSpecSubnetsServiceRangeType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (attr.Value, error) { + if in.Type() == nil { + return NewTargetSpecSubnetsServiceRangeValueNull(), nil + } + + if !in.Type().Equal(t.TerraformType(ctx)) { + return nil, fmt.Errorf("expected %s, got %s", t.TerraformType(ctx), in.Type()) + } + + if !in.IsKnown() { + return NewTargetSpecSubnetsServiceRangeValueUnknown(), nil + } + + if in.IsNull() { + return NewTargetSpecSubnetsServiceRangeValueNull(), nil + } + + attributes := map[string]attr.Value{} + + val := map[string]tftypes.Value{} + + err := in.As(&val) + + if err != nil { + return nil, err + } + + for k, v := range val { + a, err := t.AttrTypes[k].ValueFromTerraform(ctx, v) + + if err != nil { + return nil, err + } + + attributes[k] = a + } + + return NewTargetSpecSubnetsServiceRangeValueMust(TargetSpecSubnetsServiceRangeValue{}.AttributeTypes(ctx), attributes), nil +} + +func (t TargetSpecSubnetsServiceRangeType) ValueType(ctx context.Context) attr.Value { + return TargetSpecSubnetsServiceRangeValue{} +} + +var _ basetypes.ObjectValuable = TargetSpecSubnetsServiceRangeValue{} + +type TargetSpecSubnetsServiceRangeValue struct { + Cidr ovhtypes.TfStringValue `tfsdk:"cidr" json:"cidr"` + state attr.ValueState +} + +type TargetSpecSubnetsServiceRangeWritableValue struct { + *TargetSpecSubnetsServiceRangeValue `json:"-"` + Cidr *ovhtypes.TfStringValue `json:"cidr,omitempty"` +} + +func (v TargetSpecSubnetsServiceRangeValue) ToCreate() *TargetSpecSubnetsServiceRangeWritableValue { + res := &TargetSpecSubnetsServiceRangeWritableValue{} + + if !v.Cidr.IsNull() { + res.Cidr = &v.Cidr + } + + return res +} + +func (v TargetSpecSubnetsServiceRangeValue) ToUpdate() *TargetSpecSubnetsServiceRangeWritableValue { + res := &TargetSpecSubnetsServiceRangeWritableValue{} + + if !v.Cidr.IsNull() { + res.Cidr = &v.Cidr + } + + return res +} + +func (v *TargetSpecSubnetsServiceRangeValue) UnmarshalJSON(data []byte) error { + type JsonTargetSpecSubnetsServiceRangeValue TargetSpecSubnetsServiceRangeValue + + var tmp JsonTargetSpecSubnetsServiceRangeValue + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + v.Cidr = tmp.Cidr + + v.state = attr.ValueStateKnown + + return nil +} + +func (v *TargetSpecSubnetsServiceRangeValue) MergeWith(other *TargetSpecSubnetsServiceRangeValue) { + + if (v.Cidr.IsUnknown() || v.Cidr.IsNull()) && !other.Cidr.IsUnknown() { + v.Cidr = other.Cidr + } + + if (v.state == attr.ValueStateUnknown || v.state == attr.ValueStateNull) && other.state != attr.ValueStateUnknown { + v.state = other.state + } +} + +func (v TargetSpecSubnetsServiceRangeValue) Attributes() map[string]attr.Value { + return map[string]attr.Value{ + "cidr": v.Cidr, + } +} +func (v TargetSpecSubnetsServiceRangeValue) ToTerraformValue(ctx context.Context) (tftypes.Value, error) { + attrTypes := make(map[string]tftypes.Type, 1) + + var val tftypes.Value + var err error + + attrTypes["cidr"] = basetypes.StringType{}.TerraformType(ctx) + + objectType := tftypes.Object{AttributeTypes: attrTypes} + + switch v.state { + case attr.ValueStateKnown: + vals := make(map[string]tftypes.Value, 1) + + val, err = v.Cidr.ToTerraformValue(ctx) + + if err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + vals["cidr"] = val + + if err := tftypes.ValidateValue(objectType, vals); err != nil { + return tftypes.NewValue(objectType, tftypes.UnknownValue), err + } + + return tftypes.NewValue(objectType, vals), nil + case attr.ValueStateNull: + return tftypes.NewValue(objectType, nil), nil + case attr.ValueStateUnknown: + return tftypes.NewValue(objectType, tftypes.UnknownValue), nil + default: + panic(fmt.Sprintf("unhandled Object state in ToTerraformValue: %s", v.state)) + } +} + +func (v TargetSpecSubnetsServiceRangeValue) IsNull() bool { + return v.state == attr.ValueStateNull +} + +func (v TargetSpecSubnetsServiceRangeValue) IsUnknown() bool { + return v.state == attr.ValueStateUnknown +} + +func (v TargetSpecSubnetsServiceRangeValue) String() string { + return "TargetSpecSubnetsServiceRangeValue" +} + +func (v TargetSpecSubnetsServiceRangeValue) ToObjectValue(ctx context.Context) (basetypes.ObjectValue, diag.Diagnostics) { + var diags diag.Diagnostics + + objVal, diags := types.ObjectValue( + map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + }, + map[string]attr.Value{ + "cidr": v.Cidr, + }) + + return objVal, diags +} + +func (v TargetSpecSubnetsServiceRangeValue) Equal(o attr.Value) bool { + other, ok := o.(TargetSpecSubnetsServiceRangeValue) + + if !ok { + return false + } + + if v.state != other.state { + return false + } + + if v.state != attr.ValueStateKnown { + return true + } + + if !v.Cidr.Equal(other.Cidr) { + return false + } + + return true +} + +func (v TargetSpecSubnetsServiceRangeValue) Type(ctx context.Context) attr.Type { + return TargetSpecSubnetsServiceRangeType{ + basetypes.ObjectType{ + AttrTypes: v.AttributeTypes(ctx), + }, + } +} + +func (v TargetSpecSubnetsServiceRangeValue) AttributeTypes(ctx context.Context) map[string]attr.Type { + return map[string]attr.Type{ + "cidr": ovhtypes.TfStringType{}, + } +} diff --git a/ovh/resource_vrackservices_test.go b/ovh/resource_vrackservices_test.go new file mode 100644 index 000000000..a4a2ae831 --- /dev/null +++ b/ovh/resource_vrackservices_test.go @@ -0,0 +1,404 @@ +package ovh + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" +) + +const ( + subnetDisplayName = "tf.test.subnet" + cidr = "192.168.0.0/24" + serviceRangeCidr = "192.168.0.0/29" + vlan = "30" + + subnetDisplayNameUpdated = "tf.test.subnet.updated" + cidrUpdated = "10.120.0.0/24" + serviceRangeCidrUpdated = "10.120.0.0/29" +) + +const testAccStorageEfsConfig = ` + data "ovh_storage_efs" "tf-acc-efs" { + service_name = "%s" + } +` + +// #1 - resourceName +// #2 - region +// #3 - targetSpec +const testAccVrackServicesConfig = ` + data "ovh_me" "myaccount" {} + + resource "ovh_vrackservices" "tf-acc-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = "%s" + } + ] + } + ] + + %s + } +` + +// #1 - vrackServiceName +// #2 - vrackServicesServiceName +const testAccVrackVrackServicesBinding = ` + resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = "%s" + vrack_services = ovh_vrackservices.tf-acc-vrackservices.id + } +` + +func testCheckAttrNull(resource, attr string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resource] + if !ok { + return fmt.Errorf("resource not found") + } + + if _, ok := rs.Primary.Attributes[attr]; ok { + return fmt.Errorf("expected %s to be null", attr) + } + return nil + } +} + +func TestAccResourceVrackServices_basic(t *testing.T) { + region := os.Getenv("OVH_VRACK_SERVICES_REGION") + vrackServiceName := os.Getenv("OVH_VRACK_SERVICE_TEST") + storageEfsServiceName := os.Getenv("OVH_STORAGE_EFS_SERVICE_TEST") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheckVrackServices(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + // Step 1 - input validation + Config: fmt.Sprintf(testAccStorageEfsConfig, storageEfsServiceName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.ovh_storage_efs.tf-acc-efs", "region", region), + ), + }, + { + // Step 2 - order + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + ` + target_spec = { + subnets = [] + } + `, + ), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "0"), + ), + }, + { + // Step 3 - import resource to state + ResourceName: "ovh_vrackservices.tf-acc-vrackservices", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"plan", "ovh_subsidiary", "order"}, + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "0"), + resource.TestMatchResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "id", regexp.MustCompile(`^vrs-[a-z0-9-]+$`)), + ), + }, + { + // Step 4 - associate to a vRack + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + ` + target_spec = { + subnets = [] + } + `) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrack_vrackservices.vrack-vrackservices-binding", "service_name", vrackServiceName), + ), + }, + { + // Step 5 - update resource - add empty subnet + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + fmt.Sprintf(` + target_spec = { + subnets = [ + { + cidr = "%s" + display_name = "%s" + service_range = { + cidr = "%s" + } + service_endpoints = [] + vlan = %s + }, + ] + } + `, cidr, subnetDisplayName, serviceRangeCidr, vlan)) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "1"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.cidr", cidr), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.display_name", subnetDisplayName), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_range.cidr", serviceRangeCidr), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.vlan", vlan), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_endpoints.#", "0"), + ), + }, + { + // Step 6 - update resource - update subnet displayName, vlan, cidr and serviceRangeCidr + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + fmt.Sprintf(` + target_spec = { + subnets = [ + { + cidr = "%s" + display_name = "%s" + service_range = { + cidr = "%s" + } + service_endpoints = [] + }, + ] + } + `, cidrUpdated, subnetDisplayNameUpdated, serviceRangeCidrUpdated)) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "1"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.cidr", cidrUpdated), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.display_name", subnetDisplayNameUpdated), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_range.cidr", serviceRangeCidrUpdated), + testCheckAttrNull("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.vlan"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_endpoints.#", "0"), + ), + }, + { + // Step 7 - update resource - add subnet.service_endpoint + Config: fmt.Sprintf(testAccStorageEfsConfig, storageEfsServiceName) + + fmt.Sprintf(testAccVrackServicesConfig, region, + fmt.Sprintf(` + target_spec = { + subnets = [ + { + cidr = "%s" + display_name = "%s" + service_range = { + cidr = "%s" + } + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.tf-acc-efs.iam.urn + } + ] + }, + ] + } + `, cidrUpdated, subnetDisplayNameUpdated, serviceRangeCidrUpdated), + ) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "ACTIVE"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "1"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.cidr", cidrUpdated), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.display_name", subnetDisplayNameUpdated), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_range.cidr", serviceRangeCidrUpdated), + testCheckAttrNull("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.vlan"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_endpoints.#", "1"), + resource.TestCheckResourceAttr( + "ovh_vrackservices.tf-acc-vrackservices", + "target_spec.subnets.0.service_endpoints.0.managed_service_urn", + fmt.Sprintf("urn:v1:eu:resource:storageNetApp:%s", storageEfsServiceName), + ), + ), + }, + { + // Step 8 - update resource - delete subnet.service_endpoint + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + fmt.Sprintf(` + target_spec = { + subnets = [ + { + cidr = "%s" + display_name = "%s" + service_range = { + cidr = "%s" + } + service_endpoints = [] + }, + ] + } + `, cidrUpdated, subnetDisplayNameUpdated, serviceRangeCidrUpdated)) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "1"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.cidr", cidrUpdated), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.display_name", subnetDisplayNameUpdated), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_range.cidr", serviceRangeCidrUpdated), + testCheckAttrNull("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.vlan"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_endpoints.#", "0"), + ), + }, + { + // Step 9 - update resource - delete empty subnet + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + ` + target_spec = { + subnets = [] + } + `) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "0"), + ), + }, + { + // Step 10 - update resource - add subnet with service_endpoint + Config: fmt.Sprintf(testAccStorageEfsConfig, storageEfsServiceName) + + fmt.Sprintf(testAccVrackServicesConfig, region, + fmt.Sprintf(` + target_spec = { + subnets = [ + { + cidr = "%s" + display_name = "%s" + service_range = { + cidr = "%s" + } + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.tf-acc-efs.iam.urn + } + ] + }, + ] + } + `, cidr, subnetDisplayName, serviceRangeCidr), + ) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "ACTIVE"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "1"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.cidr", cidr), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.display_name", subnetDisplayName), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_range.cidr", serviceRangeCidr), + testCheckAttrNull("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.vlan"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_endpoints.#", "1"), + resource.TestCheckResourceAttr( + "ovh_vrackservices.tf-acc-vrackservices", + "target_spec.subnets.0.service_endpoints.0.managed_service_urn", + fmt.Sprintf("urn:v1:eu:resource:storageNetApp:%s", storageEfsServiceName), + ), + ), + }, + { + // Step 11 - dissociate from vRack + Config: fmt.Sprintf(testAccStorageEfsConfig, storageEfsServiceName) + + fmt.Sprintf(testAccVrackServicesConfig, region, + fmt.Sprintf(` + target_spec = { + subnets = [ + { + cidr = "%s" + display_name = "%s" + service_range = { + cidr = "%s" + } + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.tf-acc-efs.iam.urn + } + ] + }, + ] + } + `, cidr, subnetDisplayName, serviceRangeCidr), + ), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + // VrackServices resource state not updated yet, need a refresh + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "ACTIVE"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "1"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.cidr", cidr), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.display_name", subnetDisplayName), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_range.cidr", serviceRangeCidr), + testCheckAttrNull("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.vlan"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.0.service_endpoints.#", "1"), + resource.TestCheckResourceAttr( + "ovh_vrackservices.tf-acc-vrackservices", + "target_spec.subnets.0.service_endpoints.0.managed_service_urn", + fmt.Sprintf("urn:v1:eu:resource:storageNetApp:%s", storageEfsServiceName), + ), + ), + }, + { + // Step 12 - refresh to force state update on VrackService resource (current_state.product_status) + PlanOnly: true, + RefreshState: true, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + ), + }, + { + // Step 13 - update resource - delete subnet + Config: fmt.Sprintf(testAccVrackServicesConfig, region, + ` + target_spec = { + subnets = [] + } + `) + + fmt.Sprintf(testAccVrackVrackServicesBinding, vrackServiceName), + + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.region", region), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "current_state.product_status", "DRAFT"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "resource_status", "READY"), + resource.TestCheckResourceAttr("ovh_vrackservices.tf-acc-vrackservices", "target_spec.subnets.#", "0"), + ), + }, + }, + }) +} diff --git a/templates/data-sources/vrackservices.md.tmpl b/templates/data-sources/vrackservices.md.tmpl new file mode 100644 index 000000000..891de25a6 --- /dev/null +++ b/templates/data-sources/vrackservices.md.tmpl @@ -0,0 +1,138 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "ovh_vrackservices Data Source - terraform-provider-ovh" +subcategory: "Vrack Services" +description: |- + Retrieve a vRack Services +--- + +# ovh_vrackservices (Data Source) + +Retrieve a vRack Services + + + + +## Schema + +### Required + +- `vrack_services_id` (String) Vrack services ID + +### Read-Only + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the current target specification value +- `created_at` (String) Date of the vRack Services delivery +- `current_state` (Attributes) Current configuration applied to the vRack Services (see [below for nested schema](#nestedatt--current_state)) +- `current_tasks` (Attributes List) Asynchronous operations ongoing on the vRack Services (see [below for nested schema](#nestedatt--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--iam)) +- `id` (String) Unique identifier +- `resource_status` (String) Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status +- `target_spec` (Attributes) Last target specification of the vRack Services (see [below for nested schema](#nestedatt--target_spec)) +- `updated_at` (String) Date of the Last vRack Services update + + +### Nested Schema for `current_state` + +Read-Only: + +- `product_status` (String) Product status of the vRack Services +- `region` (String) Region of the vRack Services. List of compatible regions can be retrieved from /reference/region +- `subnets` (Attributes List) Subnets of the current vRack Services (see [below for nested schema](#nestedatt--current_state--subnets)) + + +### Nested Schema for `current_state.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format +- `display_name` (String) Display name of the subnet +- `service_endpoints` (Attributes List) Service endpoints of the subnet (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed services IPs (see [below for nested schema](#nestedatt--current_state--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation + + +### Nested Schema for `current_state.subnets.service_endpoints` + +Read-Only: + +- `endpoints` (Attributes List) Endpoints representing the IPs assigned to the managed services (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints--endpoints)) +- `managed_service_urn` (String) IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call. + + +### Nested Schema for `current_state.subnets.service_endpoints.endpoints` + +Read-Only: + +- `description` (String) IP description defined in the managed service +- `ip` (String) IP address assigned by OVHcloud + + + + +### Nested Schema for `current_state.subnets.service_range` + +Read-Only: + +- `cidr` (String) CIDR dedicated to the subnet's services +- `remaining_ips` (Number) Number of remaining IPs in the service range +- `reserved_ips` (Number) Number of service range IPs reserved by OVHcloud +- `used_ips` (Number) Number of service range IPs assigned to the managed services + + + + + +### Nested Schema for `current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the task details +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `state` (String) Resource state +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `target_spec` + +Read-Only: + +- `subnets` (Attributes List) Target specification of the subnets. Maximum one subnet per vRack Services (see [below for nested schema](#nestedatt--target_spec--subnets)) + + +### Nested Schema for `target_spec.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24 +- `display_name` (String) Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$` +- `service_endpoints` (Attributes List) Target specification of the Service Endpoints (see [below for nested schema](#nestedatt--target_spec--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed service IPs (see [below for nested schema](#nestedatt--target_spec--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic) + + +### Nested Schema for `target_spec.subnets.service_endpoints` + +Read-Only: + +- `managed_service_urn` (String) IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call + + + +### Nested Schema for `target_spec.subnets.service_range` + +Read-Only: + +- `cidr` (String) IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29 diff --git a/templates/data-sources/vrackservicess.md.tmpl b/templates/data-sources/vrackservicess.md.tmpl new file mode 100644 index 000000000..df1a15963 --- /dev/null +++ b/templates/data-sources/vrackservicess.md.tmpl @@ -0,0 +1,142 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "ovh_vrackservicess Data Source - terraform-provider-ovh" +subcategory: "Vrack Services" +description: |- + List all vRack Services +--- + +# ovh_vrackservicess (Data Source) + +List all vRack Services + + + + +## Schema + +### Read-Only + +- `vrackservicess` (Attributes Set) (see [below for nested schema](#nestedatt--vrackservicess)) + + +### Nested Schema for `vrackservicess` + +Read-Only: + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the current target specification value +- `created_at` (String) Date of the vRack Services delivery +- `current_state` (Attributes) Current configuration applied to the vRack Services (see [below for nested schema](#nestedatt--vrackservicess--current_state)) +- `current_tasks` (Attributes List) Asynchronous operations ongoing on the vRack Services (see [below for nested schema](#nestedatt--vrackservicess--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--vrackservicess--iam)) +- `id` (String) Unique identifier +- `resource_status` (String) Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status +- `target_spec` (Attributes) Last target specification of the vRack Services (see [below for nested schema](#nestedatt--vrackservicess--target_spec)) +- `updated_at` (String) Date of the Last vRack Services update + + +### Nested Schema for `vrackservicess.current_state` + +Read-Only: + +- `product_status` (String) Product status of the vRack Services +- `region` (String) Region of the vRack Services. List of compatible regions can be retrieved from /reference/region +- `subnets` (Attributes List) Subnets of the current vRack Services (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets)) +- `vrack_id` (String) vRack associated to the vRack Services + + +### Nested Schema for `vrackservicess.current_state.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format +- `display_name` (String) Display name of the subnet +- `service_endpoints` (Attributes List) Service endpoints of the subnet (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed services IPs (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation + + +### Nested Schema for `vrackservicess.current_state.subnets.service_endpoints` + +Read-Only: + +- `endpoints` (Attributes List) Endpoints representing the IPs assigned to the managed services (see [below for nested schema](#nestedatt--vrackservicess--current_state--subnets--service_endpoints--endpoints)) +- `managed_service_urn` (String) IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call. + + +### Nested Schema for `vrackservicess.current_state.subnets.service_endpoints.endpoints` + +Read-Only: + +- `description` (String) IP description defined in the managed service +- `ip` (String) IP address assigned by OVHcloud + + + + +### Nested Schema for `vrackservicess.current_state.subnets.service_range` + +Read-Only: + +- `cidr` (String) CIDR dedicated to the subnet's services +- `remaining_ips` (Number) Number of remaining IPs in the service range +- `reserved_ips` (Number) Number of service range IPs reserved by OVHcloud +- `used_ips` (Number) Number of service range IPs assigned to the managed services + + + + + +### Nested Schema for `vrackservicess.current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the task details +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `vrackservicess.iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `state` (String) Resource state +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `vrackservicess.target_spec` + +Read-Only: + +- `subnets` (Attributes List) Target specification of the subnets. Maximum one subnet per vRack Services (see [below for nested schema](#nestedatt--vrackservicess--target_spec--subnets)) + + +### Nested Schema for `vrackservicess.target_spec.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format. Must be a private network address (RFC1918). Authorized range for prefix length: /16 to /24 +- `display_name` (String) Display name of the subnet. Format must follow `^[ a-zA-Z0-9-_.]{0,40}$` +- `service_endpoints` (Attributes List) Target specification of the Service Endpoints (see [below for nested schema](#nestedatt--vrackservicess--target_spec--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed service IPs (see [below for nested schema](#nestedatt--vrackservicess--target_spec--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic) + + +### Nested Schema for `vrackservicess.target_spec.subnets.service_endpoints` + +Read-Only: + +- `managed_service_urn` (String) IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call + + + +### Nested Schema for `vrackservicess.target_spec.subnets.service_range` + +Read-Only: + +- `cidr` (String) IP address range dedicated to the subnet's services in CIDR format. Must be a private network address (RFC1918). Must be a sub-network of the subnet. Authorized range for prefix length: /27 to /29 diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index f5fa12507..fa98f8966 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -236,6 +236,10 @@ In order to run the Acceptance Tests for development, the following environment * `OVH_TESTACC_ORDER_VRACK` - set this variable to "yes" will order vracks. +* `OVH_TESTACC_ORDER_VRACKSERVICES` - set this variable to "yes" will order and test Vrack Services. + +* `OVH_TESTACC_VRACK_SERVICES_ID_TEST` - The ID of your vRack Service. + * `OVH_TESTACC_ORDER_CLOUDPROJECT` - set this variable to "yes" will order cloud projects. * `OVH_TESTACC_ORDER_DOMAIN` - set this variable to "mydomain.ovh" to run tests for domain zones. diff --git a/templates/resources/vrackservices.md.tmpl b/templates/resources/vrackservices.md.tmpl new file mode 100644 index 000000000..84a29f127 --- /dev/null +++ b/templates/resources/vrackservices.md.tmpl @@ -0,0 +1,444 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "ovh_vrackservices Resource - terraform-provider-ovh" +subcategory: "Vrack Services" +description: |- + +--- + +# ovh_vrackservices (Resource) + +Orders a Vrack Services. + +## Important + +-> **NOTE** To order a product through Terraform, your account needs to have a default payment method defined. This can be done in the [OVHcloud Control Panel](https://www.ovh.com/manager/#/dedicated/billing/payment/method) or via API with the [/me/payment/method](https://api.ovh.com/console/#/me/payment/method~GET) endpoint. + +~> **WARNING** `BANK_ACCOUNT` is not supported anymore, please update your default payment_method to `SEPA_DIRECT_DEBIT` + +## Example Usage + +### Example 1 - Simple Vrack Services order + +```terraform +locals { + region = "eu-west-lim" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [] + } +} +``` + +### Example 2 - Vrack Services basic configuration + +```terraform +locals { + region = "eu-west-lim" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + service_range = { + cidr = "192.168.0.0/29" + } + service_endpoints = [] + }, + ] + } +} +``` + +### Example 3 - Vrack Services associated to a vRack + +```terraform +locals { + region = "eu-west-lim" + vrack_name = "pn-000000" +} + +data "ovh_me" "myaccount" {} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [] + } +} + +resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = local.vrack_name + vrack_services = ovh_vrackservices.my-vrackservices.id +} + +``` + +### Example 4 - Vrack Services configuration with a managed service + +```terraform +locals { + region = "eu-west-lim" + efs_name = "example-efs-service-name-000e75d3d4c1" +} + +data "ovh_me" "myaccount" {} + +data "ovh_storage_efs" "my-efs" { + service_name = local.efs_name +} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = local.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + display_name = "my.subnet" + service_range = { + cidr = "192.168.0.0/29" + } + vlan = 30 + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.my-efs.iam.urn + } + ] + }, + ] + } +} +``` + +### Example 5 - Vrack Services complete configuration + +```terraform +# Once this plan executed, your ovh_vrackservices resource must be updated in your state using : +# `terraform plan -refresh-only` +# `terraform apply -refresh-only -auto-approve` + +locals { + region = "eu-west-lim" + efs_name = "example-efs-service-name-000e75d3d4c1" + vrack_name = "pn-000000" +} + +data "ovh_me" "myaccount" {} + +data "ovh_storage_efs" "my-efs" { + service_name = local.efs_name +} + +resource "ovh_vrackservices" "my-vrackservices" { + ovh_subsidiary = data.ovh_me.myaccount.ovh_subsidiary + plan = [ + { + plan_code = "vrack-services" + duration = "P1M" + pricing_mode = "default" + + configuration = [ + { + label = "region_name" + value = locals.region + } + ] + } + ] + target_spec = { + subnets = [ + { + cidr = "192.168.0.0/24" + display_name = "my.subnet" + service_range = { + cidr = "192.168.0.0/29" + } + vlan = 30 + service_endpoints = [ + { + managed_service_urn = data.ovh_storage_efs.my-efs.iam.urn + } + ] + }, + ] + } +} + +resource "ovh_vrack_vrackservices" "vrack-vrackservices-binding" { + service_name = local.vrack_name + vrack_services = ovh_vrackservices.my-vrackservices.id +} + +``` + +## Schema + +### Required + +- `target_spec` (Attributes) Target specification of the vRack Services (see [below for nested schema](#nestedatt--target_spec)) + +### Optional + +- `ovh_subsidiary` (String) OVH subsidiaries +- `plan` (Attributes List) (see [below for nested schema](#nestedatt--plan)) +- `plan_option` (Attributes List) (see [below for nested schema](#nestedatt--plan_option)) + +### Read-Only + +- `checksum` (String) Computed hash used to control concurrent modification requests. Here, it represents the target specification value the request is based on +- `created_at` (String) Date of the vRack Services delivery +- `current_state` (Attributes) Current configuration applied to the vRack Services (see [below for nested schema](#nestedatt--current_state)) +- `current_tasks` (Attributes List) Asynchronous operations ongoing on the vRack Services (see [below for nested schema](#nestedatt--current_tasks)) +- `iam` (Attributes) IAM resource metadata (see [below for nested schema](#nestedatt--iam)) +- `id` (String) Unique identifier +- `order` (Attributes) Details about an Order (see [below for nested schema](#nestedatt--order)) +- `resource_status` (String) Reflects the readiness of the vRack Services. A new target specification request will be accepted only in `READY` status +- `updated_at` (String) Date of the Last vRack Services update + + +### Nested Schema for `target_spec` + +Required: + +- `subnets` (Attributes List) Target specification of the subnets. Maximum one subnet per vRack Services (see [below for nested schema](#nestedatt--target_spec--subnets)) + + +### Nested Schema for `target_spec.subnets` + +Required: + +- `cidr` (String) IPv4 CIDR notation (e.g., 192.0.2.0/24) +- `service_endpoints` (Attributes List) Target specification of the Service Endpoints (see [below for nested schema](#nestedatt--target_spec--subnets--service_endpoints)) +- `service_range` (Attributes) Target specification of the range dedicated to the subnet's services (see [below for nested schema](#nestedatt--target_spec--subnets--service_range)) + +Optional: + +- `display_name` (String) Display name of the subnet. Format must follow `^[a-zA-Z0-9-_.]{0,40}$` +- `vlan` (Number) Unique inner VLAN that allows subnets segregation. Authorized values: [2 - 4094] and `null` (untagged traffic) + + +### Nested Schema for `target_spec.subnets.service_endpoints` + +Required: + +- `managed_service_urn` (String) IAM Resource URN of the managed service. Managed service Region must match vRack Services Region. Compatible managed service types are listed by /reference/compatibleManagedServiceType call + + + +### Nested Schema for `target_spec.subnets.service_range` + +Required: + +- `cidr` (String) IPv4 CIDR notation (e.g., 192.0.2.0/24) + + + + + +### Nested Schema for `plan` + +Required: + +- `duration` (String) Duration selected for the purchase of the product +- `plan_code` (String) Identifier of the option offer +- `pricing_mode` (String) Pricing mode selected for the purchase of the product + +Optional: + +- `configuration` (Attributes List) (see [below for nested schema](#nestedatt--plan--configuration)) +- `item_id` (Number) Cart item to be linked +- `quantity` (Number) Quantity of product desired + + +### Nested Schema for `plan.configuration` + +Required: + +- `label` (String) Label for your configuration item +- `value` (String) Value or resource URL on API.OVH.COM of your configuration item + + + + +### Nested Schema for `plan_option` + +Required: + +- `duration` (String) Duration selected for the purchase of the product +- `plan_code` (String) Identifier of the option offer +- `pricing_mode` (String) Pricing mode selected for the purchase of the product +- `quantity` (Number) Quantity of product desired + +Optional: + +- `configuration` (Attributes List) (see [below for nested schema](#nestedatt--plan_option--configuration)) + + +### Nested Schema for `plan_option.configuration` + +Required: + +- `label` (String) Label for your configuration item +- `value` (String) Value or resource URL on API.OVH.COM of your configuration item + + + + +### Nested Schema for `current_state` + +Read-Only: + +- `product_status` (String) Product status of the vRack Services +- `region` (String) Region of the vRack Services. List of compatible regions can be retrieved from /reference/region +- `subnets` (Attributes List) Subnets of the current vRack Services (see [below for nested schema](#nestedatt--current_state--subnets)) + + +### Nested Schema for `current_state.subnets` + +Read-Only: + +- `cidr` (String) IP address range of the subnet in CIDR format +- `display_name` (String) Display name of the subnet +- `service_endpoints` (Attributes List) Service endpoints of the subnet (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints)) +- `service_range` (Attributes) Defines a smaller subnet dedicated to the managed services IPs (see [below for nested schema](#nestedatt--current_state--subnets--service_range)) +- `vlan` (Number) Unique inner VLAN that allows subnets segregation + + +### Nested Schema for `current_state.subnets.service_endpoints` + +Read-Only: + +- `endpoints` (Attributes List) Endpoints representing the IPs assigned to the managed services (see [below for nested schema](#nestedatt--current_state--subnets--service_endpoints--endpoints)) +- `managed_service_urn` (String) IAM Resource URN of the managed service. Compatible managed service types are listed by /reference/compatibleManagedServiceType call. + + +### Nested Schema for `current_state.subnets.service_endpoints.endpoints` + +Read-Only: + +- `description` (String) IP description defined in the managed service +- `ip` (String) IP address assigned by OVHcloud + + + + +### Nested Schema for `current_state.subnets.service_range` + +Read-Only: + +- `cidr` (String) CIDR dedicated to the subnet's services +- `remaining_ips` (Number) Number of remaining IPs in the service range +- `reserved_ips` (Number) Number of service range IPs reserved by OVHcloud +- `used_ips` (Number) Number of service range IPs assigned to the managed services + + + + + +### Nested Schema for `current_tasks` + +Read-Only: + +- `id` (String) Identifier of the current task +- `link` (String) Link to the related resource +- `status` (String) Current global status of the current task +- `type` (String) Type of the current task + + + +### Nested Schema for `iam` + +Read-Only: + +- `display_name` (String) Resource display name +- `id` (String) Unique identifier of the resource +- `tags` (Map of String) Resource tags. Tags that were internally computed are prefixed with ovh: +- `urn` (String) Unique resource name used in policies + + + +### Nested Schema for `order` + +Read-Only: + +- `date` (String) +- `details` (Attributes List) (see [below for nested schema](#nestedatt--order--details)) +- `expiration_date` (String) +- `order_id` (Number) + + +### Nested Schema for `order.details` + +Read-Only: + +- `description` (String) +- `detail_type` (String) Product type of item in order +- `domain` (String) +- `order_detail_id` (Number) +- `quantity` (String)