diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index e798cca5f..0223e71d0 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -77,6 +77,62 @@ jobs: path: '*.xml' retention-days: 1 + apply-calico-rules: + runs-on: ubuntu-latest + needs: [integration_tests] + if: always() + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: 'recursive' + + - name: Download kubectl and calicoctl for LKE clusters + run: | + curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" + curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" + chmod +x calicoctl-linux-amd64 kubectl + mv calicoctl-linux-amd64 /usr/local/bin/calicoctl + mv kubectl /usr/local/bin/kubectl + + - name: Apply Calico Rules to LKE # Only Running against Matrix USER 4 which includes LKE test suite + run: | + cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh + env: + LINODE_TOKEN: ${{ secrets.LINODE_TOKEN_USER_4 }} + + add-fw-lke-nodes: + runs-on: ubuntu-latest + needs: [integration_tests] + if: always() + + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Linode CLI + run: | + pip install linode-cli + + - name: Create Firewall and Attach to Instances + run: | + FIREWALL_ID=$(linode-cli firewalls create --label "e2e-fw-$(date +%s)" --rules.inbound_policy "DROP" --rules.outbound_policy "ACCEPT" --text --format=id --no-headers) + echo "Created Firewall with ID: $FIREWALL_ID" + + for instance_id in $(linode-cli linodes list --format "id" --text --no-header); do + echo "Attaching firewall to instance: $instance_id" + if linode-cli firewalls device-create "$FIREWALL_ID" --id "$instance_id" --type linode; then + echo "Firewall attached to instance $instance_id successfully." + else + echo "An error occurred while attaching firewall to instance $instance_id. Skipping..." + fi + done + env: + LINODE_CLI_TOKEN: ${{ secrets.LINODE_TOKEN_USER_4 }} # only Matrix test user 4 runs LKE tests process-upload-report: runs-on: ubuntu-latest @@ -120,38 +176,10 @@ jobs: LINODE_CLI_OBJ_ACCESS_KEY: ${{ secrets.LINODE_CLI_OBJ_ACCESS_KEY }} LINODE_CLI_OBJ_SECRET_KEY: ${{ secrets.LINODE_CLI_OBJ_SECRET_KEY }} - - apply-calico-rules: - runs-on: ubuntu-latest - needs: [integration_tests] - if: always() - - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - fetch-depth: 0 - submodules: 'recursive' - - - name: Download kubectl and calicoctl for LKE clusters - run: | - curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" - curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" - chmod +x calicoctl-linux-amd64 kubectl - mv calicoctl-linux-amd64 /usr/local/bin/calicoctl - mv kubectl /usr/local/bin/kubectl - - - name: Apply Calico Rules to LKE # Only Running against Matrix USER 4 which includes LKE test suite - run: | - cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh - env: - LINODE_TOKEN: ${{ secrets.LINODE_TOKEN_USER_4 }} - notify-slack: runs-on: ubuntu-latest needs: [integration_tests] if: always() && github.repository == 'linode/terraform-provider-linode' # Run even if integration tests fail and only on main repository - steps: - name: Notify Slack uses: slackapi/slack-github-action@v1.27.0 @@ -212,3 +240,4 @@ jobs: } env: SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + diff --git a/.github/workflows/integration_tests_pr.yml b/.github/workflows/integration_tests_pr.yml index 26ab634f6..2f01d791f 100644 --- a/.github/workflows/integration_tests_pr.yml +++ b/.github/workflows/integration_tests_pr.yml @@ -55,26 +55,11 @@ jobs: - run: make deps - - name: Download kubectl and calicoctl for LKE clusters - run: | - curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" - curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" - chmod +x calicoctl-linux-amd64 kubectl - mv calicoctl-linux-amd64 /usr/local/bin/calicoctl - mv kubectl /usr/local/bin/kubectl - - run: make PKG_NAME="${{ inputs.module }}" int-test if: ${{ steps.disallowed-character-check.outputs.result == 'pass' }} env: LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} RUN_LONG_TESTS: ${{ inputs.run_long_tests }} - - - name: Apply Calico Rules to LKE - if: always() - run: | - cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh - env: - LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} - name: Get the hash value of the latest commit from the PR branch uses: octokit/graphql-action@v2.x @@ -128,3 +113,60 @@ jobs: conclusion: process.env.conclusion }); return result; + + apply-calico-rules: + runs-on: ubuntu-latest + needs: [integration-fork] + if: ${{ success() || failure() }} + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: 'recursive' + + - name: Download kubectl and calicoctl for LKE clusters + run: | + curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl" + curl -LO "https://github.com/projectcalico/calico/releases/download/v3.25.0/calicoctl-linux-amd64" + chmod +x calicoctl-linux-amd64 kubectl + mv calicoctl-linux-amd64 /usr/local/bin/calicoctl + mv kubectl /usr/local/bin/kubectl + + - name: Apply Calico Rules to LKE + run: | + cd e2e_scripts/cloud_security_scripts/lke_calico_rules/ && ./lke_calico_rules_e2e.sh + env: + LINODE_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} + + add-fw-lke-nodes: + runs-on: ubuntu-latest + needs: [integration-fork] + if: ${{ success() || failure() }} + + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Linode CLI + run: | + pip install linode-cli + + - name: Create Firewall and Attach to Instances + run: | + FIREWALL_ID=$(linode-cli firewalls create --label "e2e-fw-$(date +%s)" --rules.inbound_policy "DROP" --rules.outbound_policy "ACCEPT" --text --format=id --no-headers) + echo "Created Firewall with ID: $FIREWALL_ID" + + for instance_id in $(linode-cli linodes list --format "id" --text --no-header); do + echo "Attaching firewall to instance: $instance_id" + if linode-cli firewalls device-create "$FIREWALL_ID" --id "$instance_id" --type linode; then + echo "Firewall attached to instance $instance_id successfully." + else + echo "An error occurred while attaching firewall to instance $instance_id. Skipping..." + fi + done + env: + LINODE_CLI_TOKEN: ${{ secrets.DX_LINODE_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index da42b7e4a..444c69ffd 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -21,7 +21,7 @@ jobs: uses: actions/checkout@v4 - name: Run Labeler - uses: crazy-max/ghaction-github-labeler@de749cf181958193cb7debf1a9c5bb28922f3e1b + uses: crazy-max/ghaction-github-labeler@b54af0c25861143e7c8813d7cbbf46d2c341680c with: github-token: ${{ secrets.GITHUB_TOKEN }} yaml-file: .github/labels.yml diff --git a/.github/workflows/release-notify-slack.yml b/.github/workflows/release-notify-slack.yml new file mode 100644 index 000000000..5216d0d01 --- /dev/null +++ b/.github/workflows/release-notify-slack.yml @@ -0,0 +1,30 @@ +name: Notify Dev DX Channel on Release +on: + release: + types: [published] + workflow_dispatch: null + +jobs: + notify: + if: github.repository == 'linode/terraform-provider-linode' + runs-on: ubuntu-latest + steps: + - name: Notify Slack - Main Message + id: main_message + uses: slackapi/slack-github-action@v1.27.0 + with: + channel-id: ${{ secrets.DEV_DX_SLACK_CHANNEL_ID }} + payload: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": "*New Release Published: _terraform-provider-linode_ <${{ github.event.release.html_url }}|${{ github.event.release.tag_name }}> is now live!* :tada:" + } + } + ] + } + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} \ No newline at end of file diff --git a/docs/data-sources/lke_types.md b/docs/data-sources/lke_types.md new file mode 100644 index 000000000..9acd3937b --- /dev/null +++ b/docs/data-sources/lke_types.md @@ -0,0 +1,81 @@ +--- +page_title: "Linode: linode_lke_types" +description: |- + Provides information about Linode LKE types that match a set of filters. +--- + +# Data Source: linode_lke_types + +Provides information about Linode LKE types that match a set of filters. +For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/get-lke-types). + +## Example Usage + +Get information about all Linode LKE types with a certain label: + +```hcl +data "linode_lke_types" "specific-label" { + filter { + name = "label" + values = "LKE Standard Availability" + } +} + +output "type_id" { + value = data.linode_lke_types.specific-label.id +} +``` + +Get information about all Linode LKE types: + +```hcl +data "linode_lke_types" "all-types" {} + +output "type_id" { + value = data.linode_lke_types.all-types.*.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* [`filter`](#filter) - (Optional) A set of filters used to select Linode LKE types that meet certain requirements. + +* `order_by` - (Optional) The attribute to order the results by. See the [Filterable Fields section](#filterable-fields) for a list of valid fields. + +* `order` - (Optional) The order in which results should be returned. (`asc`, `desc`; default `asc`) + +### Filter + +* `name` - (Required) The name of the field to filter by. See the [Filterable Fields section](#filterable-fields) for a complete list of filterable fields. + +* `values` - (Required) A list of values for the filter to allow. These values should all be in string form. + +* `match_by` - (Optional) The method to match the field by. (`exact`, `regex`, `substring`; default `exact`) + +## Attributes Reference + +Each Linode LKE type will export the following attributes: + +* `id` - The ID representing the Kubernetes type. + +* `label` - The Kubernetes type label is for display purposes only. + +* `price.0.hourly` - Cost (in US dollars) per hour. + +* `price.0.monthly` - Cost (in US dollars) per month. + +* `region_prices.*.id` - The Region ID for these prices. + +* `region_prices.*.hourly` - Cost per hour for this region, in US dollars. + +* `region_prices.*.monthly` - Cost per month for this region, in US dollars. + +* `transfer` - The monthly outbound transfer amount, in MB. + +## Filterable Fields + +* `label` + +* `transfer` diff --git a/docs/data-sources/network_transfer_prices.md b/docs/data-sources/network_transfer_prices.md new file mode 100644 index 000000000..e39eb377d --- /dev/null +++ b/docs/data-sources/network_transfer_prices.md @@ -0,0 +1,81 @@ +--- +page_title: "Linode: linode_network_transfer_prices" +description: |- + Provides information about Linode Network Transfer Prices that match a set of filters. +--- + +# Data Source: linode_network_transfer_prices + +Provides information about Linode Network Transfer Prices that match a set of filters. +For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/get-network-transfer-prices). + +## Example Usage + +Get information about all Linode Network Transfer Prices with a certain label: + +```hcl +data "linode_network_transfer_prices" "specific-label" { + filter { + name = "label" + values = "Network Transfer" + } +} + +output "price_id" { + value = data.linode_network_transfer_prices.specific-label.id +} +``` + +Get information about all Linode Network Transfer Prices: + +```hcl +data "linode_network_transfer_prices" "all-prices" {} + +output "price_id" { + value = data.linode_network_transfer_prices.all-prices.*.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* [`filter`](#filter) - (Optional) A set of filters used to select Linode Network Transfer Prices that meet certain requirements. + +* `order_by` - (Optional) The attribute to order the results by. See the [Filterable Fields section](#filterable-fields) for a list of valid fields. + +* `order` - (Optional) The order in which results should be returned. (`asc`, `desc`; default `asc`) + +### Filter + +* `name` - (Required) The name of the field to filter by. See the [Filterable Fields section](#filterable-fields) for a complete list of filterable fields. + +* `values` - (Required) A list of values for the filter to allow. These values should all be in string form. + +* `match_by` - (Optional) The method to match the field by. (`exact`, `regex`, `substring`; default `exact`) + +## Attributes Reference + +Each Linode Network Transfer Price will export the following attributes: + +* `id` - The ID representing the Network Transfer Price. + +* `label` - The Network Transfer Price label is for display purposes only. + +* `price.0.hourly` - Cost (in US dollars) per hour. + +* `price.0.monthly` - Cost (in US dollars) per month. + +* `region_prices.*.id` - The Region ID for these prices. + +* `region_prices.*.hourly` - Cost per hour for this region, in US dollars. + +* `region_prices.*.monthly` - Cost per month for this region, in US dollars. + +* `transfer` - The monthly outbound transfer amount, in MB. + +## Filterable Fields + +* `label` + +* `transfer` diff --git a/docs/data-sources/nodebalancer_types.md b/docs/data-sources/nodebalancer_types.md new file mode 100644 index 000000000..9cb2b67ab --- /dev/null +++ b/docs/data-sources/nodebalancer_types.md @@ -0,0 +1,81 @@ +--- +page_title: "Linode: linode_nb_types" +description: |- + Provides information about Linode Node Balancer types that match a set of filters. +--- + +# Data Source: linode_nb_types + +Provides information about Linode Node Balancer types that match a set of filters. +For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/get-node-balancer-types). + +## Example Usage + +Get information about all Linode Node Balancer types with a certain label: + +```hcl +data "linode_nb_types" "specific-label" { + filter { + name = "label" + values = "NodeBalancer" + } +} + +output "type_id" { + value = data.linode_nb_types.specific-label.id +} +``` + +Get information about all Linode Node Balancer types: + +```hcl +data "linode_nb_types" "all-types" {} + +output "type_id" { + value = data.linode_nb_types.all-types.*.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* [`filter`](#filter) - (Optional) A set of filters used to select Linode Node Balancer types that meet certain requirements. + +* `order_by` - (Optional) The attribute to order the results by. See the [Filterable Fields section](#filterable-fields) for a list of valid fields. + +* `order` - (Optional) The order in which results should be returned. (`asc`, `desc`; default `asc`) + +### Filter + +* `name` - (Required) The name of the field to filter by. See the [Filterable Fields section](#filterable-fields) for a complete list of filterable fields. + +* `values` - (Required) A list of values for the filter to allow. These values should all be in string form. + +* `match_by` - (Optional) The method to match the field by. (`exact`, `regex`, `substring`; default `exact`) + +## Attributes Reference + +Each Linode Node Balancer type will export the following attributes: + +* `id` - The ID representing the Node Balancer type. + +* `label` - The Node Balancer type label is for display purposes only. + +* `price.0.hourly` - Cost (in US dollars) per hour. + +* `price.0.monthly` - Cost (in US dollars) per month. + +* `region_prices.*.id` - The Region ID for these prices. + +* `region_prices.*.hourly` - Cost per hour for this region, in US dollars. + +* `region_prices.*.monthly` - Cost per month for this region, in US dollars. + +* `transfer` - The monthly outbound transfer amount, in MB. + +## Filterable Fields + +* `label` + +* `transfer` diff --git a/docs/data-sources/placement_group.md b/docs/data-sources/placement_group.md index 0837012aa..5434cb32a 100644 --- a/docs/data-sources/placement_group.md +++ b/docs/data-sources/placement_group.md @@ -6,8 +6,6 @@ description: |- # Data Source: linode\_placement\_group -**NOTE: Placement Groups may not currently be available to all users.** - `linode_placement_group` provides details about a Linode placement group. For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/get-placement-group). diff --git a/docs/data-sources/placement_groups.md b/docs/data-sources/placement_groups.md index c711a9854..48b0a65e7 100644 --- a/docs/data-sources/placement_groups.md +++ b/docs/data-sources/placement_groups.md @@ -6,8 +6,6 @@ description: |- # Data Source: linode\_placement\_groups -**NOTE: Placement Groups may not currently be available to all users.** - Provides information about a list of Linode Placement Groups that match a set of filters. For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/get-placement-groups). diff --git a/docs/data-sources/volume_types.md b/docs/data-sources/volume_types.md new file mode 100644 index 000000000..313e56101 --- /dev/null +++ b/docs/data-sources/volume_types.md @@ -0,0 +1,81 @@ +--- +page_title: "Linode: linode_volume_types" +description: |- + Provides information about Linode Volume types that match a set of filters. +--- + +# Data Source: linode_volume_types + +Provides information about Linode Volume types that match a set of filters. +For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/get-volume-types). + +## Example Usage + +Get information about all Linode Volume types with a certain label: + +```hcl +data "linode_volume_types" "specific-label" { + filter { + name = "label" + values = "Storage Volume" + } +} + +output "type_id" { + value = data.linode_volume_types.specific-label.id +} +``` + +Get information about all Linode Volume types: + +```hcl +data "linode_volume_types" "all-types" {} + +output "type_id" { + value = data.linode_volume_types.all-types.*.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* [`filter`](#filter) - (Optional) A set of filters used to select Linode Volume types that meet certain requirements. + +* `order_by` - (Optional) The attribute to order the results by. See the [Filterable Fields section](#filterable-fields) for a list of valid fields. + +* `order` - (Optional) The order in which results should be returned. (`asc`, `desc`; default `asc`) + +### Filter + +* `name` - (Required) The name of the field to filter by. See the [Filterable Fields section](#filterable-fields) for a complete list of filterable fields. + +* `values` - (Required) A list of values for the filter to allow. These values should all be in string form. + +* `match_by` - (Optional) The method to match the field by. (`exact`, `regex`, `substring`; default `exact`) + +## Attributes Reference + +Each Linode Volume type will export the following attributes: + +* `id` - The ID representing the Volume type. + +* `label` - The Volume type label is for display purposes only. + +* `price.0.hourly` - Cost (in US dollars) per hour. + +* `price.0.monthly` - Cost (in US dollars) per month. + +* `region_prices.*.id` - The Region ID for these prices. + +* `region_prices.*.hourly` - Cost per hour for this region, in US dollars. + +* `region_prices.*.monthly` - Cost per month for this region, in US dollars. + +* `transfer` - The monthly outbound transfer amount, in MB. + +## Filterable Fields + +* `label` + +* `transfer` diff --git a/docs/resources/instance.md b/docs/resources/instance.md index a40ec4cf3..d8f727d8d 100644 --- a/docs/resources/instance.md +++ b/docs/resources/instance.md @@ -124,8 +124,6 @@ resource "linode_instance_config" "boot_config" { ### Linode Instance Assigned to a Placement Group -**NOTE: Placement Groups may not currently be available to all users.** - The following example shows how one might use this resource to configure a Linode instance assigned to a Placement Group. @@ -383,7 +381,7 @@ This Linode Instance resource exports the following attributes: * `window` - The window ('W0'-'W22') in which your backups will be taken, in UTC. A backups window is a two-hour span of time in which the backup may occur. For example, 'W10' indicates that your backups should be taken between 10:00 and 12:00. If you do not choose a backup window, one will be selected for you automatically. If not set manually, when backups are initially enabled this may come back as Scheduling until the window is automatically selected. -* `placement_group` - Information about the Placement Group this Linode is assigned to. NOTE: Placement Groups may not currently be available to all users. +* `placement_group` - Information about the Placement Group this Linode is assigned to. * `id` - The ID of the Placement Group. diff --git a/docs/resources/nodebalancer_config.md b/docs/resources/nodebalancer_config.md index fd093aa6b..8e40b13cd 100644 --- a/docs/resources/nodebalancer_config.md +++ b/docs/resources/nodebalancer_config.md @@ -41,8 +41,6 @@ The following arguments are supported: * `nodebalancer_id` - (Required) The ID of the NodeBalancer to access. -* `region` - (Required) The region where this nodebalancer_config will be deployed. Examples are `"us-east"`, `"us-west"`, `"ap-south"`, etc. See all regions [here](https://api.linode.com/v4/regions). *Changing `region` forces the creation of a new Linode NodeBalancer Config.*. - - - - * `protocol` - (Optional) The protocol this port is configured to serve. If this is set to https you must include an ssl_cert and an ssl_key. (`http`, `https`, `tcp`) (Defaults to `http`) diff --git a/docs/resources/nodebalancer_node.md b/docs/resources/nodebalancer_node.md index ff45f3b12..fa11a1396 100644 --- a/docs/resources/nodebalancer_node.md +++ b/docs/resources/nodebalancer_node.md @@ -16,49 +16,49 @@ The Linode Guide, [Create a NodeBalancer with Terraform](https://www.linode.com/ The following example shows how one might use this resource to configure NodeBalancer Nodes attached to Linode instances. ```hcl -resource "linode_instance" "web" { - count = "3" - label = "web-${count.index + 1}" - image = "linode/ubuntu22.04" - region = "us-east" - type = "g6-standard-1" - authorized_keys = ["ssh-rsa AAAA...Gw== user@example.local"] - root_pass = "terraform-test" - - private_ip = true +resource "linode_instance" "foo" { + count = "2" + label = "web-${count.index + 1}" + image = "linode/ubuntu24.04" + region = "us-mia" + type = "g6-standard-1" + authorized_keys = ["ssh-rsa AAAA...Gw== user@example.local"] + root_pass = "terraform-test" + + private_ip = true } resource "linode_nodebalancer" "foobar" { - label = "mynodebalancer" - region = "us-east" - client_conn_throttle = 20 + label = "mynodebalancer" + region = "us-mia" + client_conn_throttle = 20 } resource "linode_nodebalancer_config" "foofig" { - nodebalancer_id = linode_nodebalancer.foobar.id - port = 80 - protocol = "http" - check = "http" - check_path = "/foo" - check_attempts = 3 - check_timeout = 30 - stickiness = "http_cookie" - algorithm = "source" + nodebalancer_id = linode_nodebalancer.foobar.id + port = 80 + protocol = "http" + check = "http" + check_path = "/foo" + check_attempts = 3 + check_timeout = 30 + stickiness = "http_cookie" + algorithm = "source" } resource "linode_nodebalancer_node" "foonode" { - count = "3" - nodebalancer_id = linode_nodebalancer.foobar.id - config_id = linode_nodebalancer_config.foofig.id - address = "${element(linode_instance.web.*.private_ip_address, count.index)}:80" - label = "mynodebalancernode" - weight = 50 + count = "2" + nodebalancer_id = linode_nodebalancer.foobar.id + config_id = linode_nodebalancer_config.foofig.id + address = "${element(linode_instance.foo.*.private_ip_address, count.index)}:80" + label = "mynodebalancernode" + weight = 50 lifecycle { // Tell Terraform to implicitly recreate the NodeBalancer node when // the target instance has been marked for recreation. // See: https://github.com/linode/terraform-provider-linode/issues/1224 - replace_triggered_by = [linode_instance.foo.id] + replace_triggered_by = [linode_instance.foo] } } ``` diff --git a/docs/resources/placement_group.md b/docs/resources/placement_group.md index e59c26a2c..6d6191a7c 100644 --- a/docs/resources/placement_group.md +++ b/docs/resources/placement_group.md @@ -9,8 +9,6 @@ description: |- Manages a Linode Placement Group. For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/post-placement-group). -**NOTE: Placement Groups may not currently be available to all users.** - ## Example Usage Create a Placement Group with the local anti-affinity policy: diff --git a/docs/resources/placement_group_assignment.md b/docs/resources/placement_group_assignment.md index ba59c2315..8dc4eeb33 100644 --- a/docs/resources/placement_group_assignment.md +++ b/docs/resources/placement_group_assignment.md @@ -9,8 +9,6 @@ description: |- Manages a single assignment between a Linode and a Placement Group. For more information, see the [Linode APIv4 docs](https://techdocs.akamai.com/linode-api/reference/post-group-add-linode). -**NOTE: Placement Groups may not currently be available to all users.** - To prevent update conflicts, Linodes managed through the `linode_instance` resource should specify `placement_group_externally_managed`: ```terraform diff --git a/go.mod b/go.mod index e4085c31d..393b7d485 100644 --- a/go.mod +++ b/go.mod @@ -5,26 +5,26 @@ go 1.22.0 toolchain go1.22.5 require ( - github.com/aws/aws-sdk-go-v2 v1.32.2 - github.com/aws/aws-sdk-go-v2/config v1.27.23 - github.com/aws/aws-sdk-go-v2/credentials v1.17.23 + github.com/aws/aws-sdk-go-v2 v1.32.3 + github.com/aws/aws-sdk-go-v2/config v1.28.1 + github.com/aws/aws-sdk-go-v2/credentials v1.17.42 github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 - github.com/aws/aws-sdk-go-v2/service/s3 v1.66.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 github.com/aws/smithy-go v1.22.0 github.com/go-resty/resty/v2 v2.14.0 github.com/google/go-cmp v0.6.0 github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-version v1.7.0 - github.com/hashicorp/terraform-plugin-framework v1.12.0 + github.com/hashicorp/terraform-plugin-framework v1.13.0 github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0 github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 - github.com/hashicorp/terraform-plugin-framework-validators v0.14.0 - github.com/hashicorp/terraform-plugin-go v0.24.0 + github.com/hashicorp/terraform-plugin-framework-validators v0.15.0 + github.com/hashicorp/terraform-plugin-go v0.25.0 github.com/hashicorp/terraform-plugin-log v0.9.0 - github.com/hashicorp/terraform-plugin-mux v0.16.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 + github.com/hashicorp/terraform-plugin-mux v0.17.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 github.com/hashicorp/terraform-plugin-testing v1.10.0 github.com/linode/linodego v1.42.0 github.com/linode/linodego/k8s v1.25.2 @@ -39,18 +39,18 @@ require ( github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect @@ -68,14 +68,14 @@ require ( github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.6.1 // indirect + github.com/hashicorp/go-plugin v1.6.2 // indirect github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/hc-install v0.8.0 // indirect - github.com/hashicorp/hcl/v2 v2.21.0 // indirect + github.com/hashicorp/hc-install v0.9.0 // indirect + github.com/hashicorp/hcl/v2 v2.22.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/terraform-exec v0.21.0 // indirect - github.com/hashicorp/terraform-json v0.22.1 // indirect + github.com/hashicorp/terraform-json v0.23.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.1.1 // indirect @@ -100,7 +100,7 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.15.0 // indirect - golang.org/x/mod v0.19.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect golang.org/x/sys v0.26.0 // indirect golang.org/x/term v0.25.0 // indirect @@ -108,9 +108,9 @@ require ( golang.org/x/time v0.6.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect - google.golang.org/grpc v1.66.2 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 1debe410d..f62d6a0bb 100644 --- a/go.sum +++ b/go.sum @@ -9,42 +9,42 @@ github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= -github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= +github.com/aws/aws-sdk-go-v2 v1.32.3 h1:T0dRlFBKcdaUPGNtkBSwHZxrtis8CQU17UpNBZYd0wk= +github.com/aws/aws-sdk-go-v2 v1.32.3/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6 h1:pT3hpW0cOHRJx8Y0DfJUEQuqPild8jRGmSFmBgvydr0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.6/go.mod h1:j/I2++U0xX+cr44QjHay4Cvxj6FUbnxrgmqN3H1jTZA= -github.com/aws/aws-sdk-go-v2/config v1.27.23 h1:Cr/gJEa9NAS7CDAjbnB7tHYb3aLZI2gVggfmSAasDac= -github.com/aws/aws-sdk-go-v2/config v1.27.23/go.mod h1:WMMYHqLCFu5LH05mFOF5tsq1PGEMfKbu083VKqLCd0o= -github.com/aws/aws-sdk-go-v2/credentials v1.17.23 h1:G1CfmLVoO2TdQ8z9dW+JBc/r8+MqyPQhXCafNZcXVZo= -github.com/aws/aws-sdk-go-v2/credentials v1.17.23/go.mod h1:V/DvSURn6kKgcuKEk4qwSwb/fZ2d++FFARtWSbXnLqY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= +github.com/aws/aws-sdk-go-v2/config v1.28.1 h1:oxIvOUXy8x0U3fR//0eq+RdCKimWI900+SV+10xsCBw= +github.com/aws/aws-sdk-go-v2/config v1.28.1/go.mod h1:bRQcttQJiARbd5JZxw6wG0yIK3eLeSCPdg6uqmmlIiI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.42 h1:sBP0RPjBU4neGpIYyx8mkU2QqLPl5u9cmdTWVzIpHkM= +github.com/aws/aws-sdk-go-v2/credentials v1.17.42/go.mod h1:FwZBfU530dJ26rv9saAbxa9Ej3eF/AK0OAY86k13n4M= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 h1:68jFVtt3NulEzojFesM/WVarlFpCaXLKaBxDpzkQ9OQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18/go.mod h1:Fjnn5jQVIo6VyedMc0/EhPpfNlPl7dHV916O6B+49aE= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4 h1:6eKRM6fgeXG4krRO9XKz755vuRhT5UyB9M1W6vjA3JU= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.4/go.mod h1:h0TjcRi+nTob6fksqubKOe+Hra8uqfgmN+vuw4xRwWE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= -github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21 h1:7edmS3VOBDhK00b/MwGtGglCm7hhwNYnjJs/PgFdMQE= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.21/go.mod h1:Q9o5h4HoIWG8XfzxqiuK/CGUbepCJ8uTlaE3bAbxytQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 h1:Jw50LwEkVjuVzE1NzkhNKkBf9cRN7MtE1F/b2cOKTUM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22/go.mod h1:Y/SmAyPcOTmpeVaWSzSKiILfXTVJwrGmYZhcRbhWuEY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 h1:981MHwBaRZM7+9QSR6XamDzF/o7ouUGxFzr+nVSIhrs= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22/go.mod h1:1RA1+aBEfn+CAB/Mh0MB6LsdCYCnjZm7tKXtnk499ZQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22 h1:yV+hCAHZZYJQcwAaszoBNwLbPItHvApxT0kVIw6jRgs= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.22/go.mod h1:kbR1TL8llqB1eGnVbybcA4/wgScxdylOdyAd51yxPdw= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 h1:TToQNkvGguu209puTojY/ozlqy2d/SFNcoLIqTFi42g= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0/go.mod h1:0jp+ltwkf+SwG2fm/PKo8t4y8pJSgOCO4D8Lz3k0aHQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2 h1:4FMHqLfk0efmTqhXVRL5xYRqlEBNBiRI7N6w4jsEdd4= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.2/go.mod h1:LWoqeWlK9OZeJxsROW2RqrSPvQHKTpp69r/iDjwsSaw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2 h1:s7NA1SOw8q/5c0wr8477yOPp0z+uBaXBnLE0XYb0POA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.2/go.mod h1:fnjjWyAW/Pj5HYOxl9LJqWtEwS7W2qgcRLWP+uWbss0= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2 h1:t7iUP9+4wdc5lt3E41huP+GvQZJD38WLsgVp4iOtAjg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.2/go.mod h1:/niFCtmuQNxqx9v8WAPq5qh7EH25U4BF6tjoyq9bObM= -github.com/aws/aws-sdk-go-v2/service/s3 v1.66.0 h1:xA6XhTF7PE89BCNHJbQi8VvPzcgMtmGC5dr8S8N7lHk= -github.com/aws/aws-sdk-go-v2/service/s3 v1.66.0/go.mod h1:cB6oAuus7YXRZhWCc1wIwPywwZ1XwweNp2TVAEGYeB8= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc= -github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekLd/x5SAm96Cva+VbUdo8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ= -github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3 h1:kT6BcZsmMtNkP/iYMcRG+mIEA/IbeiUimXtGmqF39y0= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.3/go.mod h1:Z8uGua2k4PPaGOYn66pK02rhMrot3Xk3tpBuUFPomZU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 h1:qcxX0JYlgWH3hpPUnd6U0ikcl6LLA9sLkXE2w1fpMvY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3/go.mod h1:cLSNEmI45soc+Ef8K/L+8sEA3A3pYFEYf5B5UI+6bH4= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3 h1:ZC7Y/XgKUxwqcdhO5LE8P6oGP1eh6xlQReWNKfhvJno= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.3/go.mod h1:WqfO7M9l9yUAw0HcHaikwRd/H6gzYdz7vjejCA5e2oY= +github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2 h1:p9TNFL8bFUMd+38YIpTAXpoxyz0MxC7FlbFEH4P4E1U= +github.com/aws/aws-sdk-go-v2/service/s3 v1.66.2/go.mod h1:fNjyo0Coen9QTwQLWeV6WO2Nytwiu+cCcWaTdKCAqqE= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 h1:UTpsIf0loCIWEbrqdLb+0RxnTXfWh2vhw4nQmFi4nPc= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.3/go.mod h1:FZ9j3PFHHAR+w0BSEjK955w5YD2UwB/l/H0yAK3MJvI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 h1:2YCmIXv3tmiItw0LlYf6v7gEHebLY45kBEnPezbUKyU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3/go.mod h1:u19stRyNPxGhj6dRm+Cdgu6N75qnbW7+QN0q0dsAk58= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 h1:wVnQ6tigGsRqSWDEEyH6lSAJ9OyFUsSnbaUWChuSGzs= +github.com/aws/aws-sdk-go-v2/service/sts v1.32.3/go.mod h1:VZa9yTFyj4o10YGsmDO4gbQJUvvhY72fhumT8W4LqsE= github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= @@ -120,8 +120,8 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= -github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= +github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog= +github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -129,34 +129,34 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.8.0 h1:LdpZeXkZYMQhoKPCecJHlKvUkQFixN/nvyR1CdfOLjI= -github.com/hashicorp/hc-install v0.8.0/go.mod h1:+MwJYjDfCruSD/udvBmRB22Nlkwwkwf5sAB6uTIhSaU= -github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14= -github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= +github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= +github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= +github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= -github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec= -github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A= -github.com/hashicorp/terraform-plugin-framework v1.12.0 h1:7HKaueHPaikX5/7cbC1r9d1m12iYHY+FlNZEGxQ42CQ= -github.com/hashicorp/terraform-plugin-framework v1.12.0/go.mod h1:N/IOQ2uYjW60Jp39Cp3mw7I/OpC/GfZ0385R0YibmkE= +github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= +github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= +github.com/hashicorp/terraform-plugin-framework v1.13.0 h1:8OTG4+oZUfKgnfTdPTJwZ532Bh2BobF4H+yBiYJ/scw= +github.com/hashicorp/terraform-plugin-framework v1.13.0/go.mod h1:j64rwMGpgM3NYXTKuxrCnyubQb/4VKldEKlcG8cvmjU= github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0 h1:Zap24rkky7SvNGGNYHMKFhAriP6+6riI21BMYOYgLRE= github.com/hashicorp/terraform-plugin-framework-nettypes v0.2.0/go.mod h1:CYPq+I5bWsmI8021VJY85hAyOeiEEQpdGW+NapdQn7A= github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1 h1:gm5b1kHgFFhaKFhm4h2TgvMUlNzFAtUqlcOWnWPm+9E= github.com/hashicorp/terraform-plugin-framework-timeouts v0.4.1/go.mod h1:MsjL1sQ9L7wGwzJ5RjcI6FzEMdyoBnw+XK8ZnOvQOLY= github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0 h1:v3DapR8gsp3EM8fKMh6up9cJUFQ2iRaFsYLP8UJnCco= github.com/hashicorp/terraform-plugin-framework-timetypes v0.5.0/go.mod h1:c3PnGE9pHBDfdEVG9t1S1C9ia5LW+gkFR0CygXlM8ak= -github.com/hashicorp/terraform-plugin-framework-validators v0.14.0 h1:3PCn9iyzdVOgHYOBmncpSSOxjQhCTYmc+PGvbdlqSaI= -github.com/hashicorp/terraform-plugin-framework-validators v0.14.0/go.mod h1:LwDKNdzxrDY/mHBrlC6aYfE2fQ3Dk3gaJD64vNiXvo4= -github.com/hashicorp/terraform-plugin-go v0.24.0 h1:2WpHhginCdVhFIrWHxDEg6RBn3YaWzR2o6qUeIEat2U= -github.com/hashicorp/terraform-plugin-go v0.24.0/go.mod h1:tUQ53lAsOyYSckFGEefGC5C8BAaO0ENqzFd3bQeuYQg= +github.com/hashicorp/terraform-plugin-framework-validators v0.15.0 h1:RXMmu7JgpFjnI1a5QjMCBb11usrW2OtAG+iOTIj5c9Y= +github.com/hashicorp/terraform-plugin-framework-validators v0.15.0/go.mod h1:Bh89/hNmqsEWug4/XWKYBwtnw3tbz5BAy1L1OgvbIaY= +github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks= +github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-mux v0.16.0 h1:RCzXHGDYwUwwqfYYWJKBFaS3fQsWn/ZECEiW7p2023I= -github.com/hashicorp/terraform-plugin-mux v0.16.0/go.mod h1:PF79mAsPc8CpusXPfEVa4X8PtkB+ngWoiUClMrNZlYo= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 h1:kJiWGx2kiQVo97Y5IOGR4EMcZ8DtMswHhUuFibsCQQE= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0/go.mod h1:sl/UoabMc37HA6ICVMmGO+/0wofkVIRxf+BMb/dnoIg= +github.com/hashicorp/terraform-plugin-mux v0.17.0 h1:/J3vv3Ps2ISkbLPiZOLspFcIZ0v5ycUXCEQScudGCCw= +github.com/hashicorp/terraform-plugin-mux v0.17.0/go.mod h1:yWuM9U1Jg8DryNfvCp+lH70WcYv6D8aooQxxxIzFDsE= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 h1:wyKCCtn6pBBL46c1uIIBNUOWlNfYXfXpVo16iDyLp8Y= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= github.com/hashicorp/terraform-plugin-testing v1.10.0 h1:2+tmRNhvnfE4Bs8rB6v58S/VpqzGC6RCh9Y8ujdn+aw= github.com/hashicorp/terraform-plugin-testing v1.10.0/go.mod h1:iWRW3+loP33WMch2P/TEyCxxct/ZEcCGMquSLSCVsrc= github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= @@ -282,8 +282,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -375,14 +375,14 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.66.2 h1:3QdXkuq3Bkh7w+ywLdLvM56cmGvQHUMZpiCzt6Rqaoo= -google.golang.org/grpc v1.66.2/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/linode/acceptance/instance.go b/linode/acceptance/instance.go index 9047fc467..b32e0bd06 100644 --- a/linode/acceptance/instance.go +++ b/linode/acceptance/instance.go @@ -71,7 +71,7 @@ func CheckInstanceDestroy(s *terraform.State) error { return nil } -func AssertInstanceReboot(t *testing.T, shouldRestart bool, instance *linodego.Instance) func() { +func AssertInstanceReboot(t testing.TB, shouldRestart bool, instance *linodego.Instance) func() { t.Helper() return func() { diff --git a/linode/acceptance/test_retry.go b/linode/acceptance/test_retry.go index 65bf36293..91b28b3e4 100644 --- a/linode/acceptance/test_retry.go +++ b/linode/acceptance/test_retry.go @@ -1,136 +1,88 @@ package acceptance import ( - "errors" "fmt" - "runtime" + "sync/atomic" "testing" ) -// RunTestRetry attempts to retry the given test if an intermittent error occurs. +// RunTestWithRetries attempts to retry the given test if an intermittent error occurs. // This function wraps the given testing.T and handles errors accordingly. // This should only be used for flapping API tests. -func RunTestRetry(t *testing.T, maxAttempts int, f func(t *TRetry)) { +func RunTestWithRetries(t testing.TB, maxAttempts int, f func(t *WrappedT)) { for i := 0; i < maxAttempts; i++ { - newT := NewTRetry(t) - t.Cleanup(newT.Close) + wrappedT := &WrappedT{ + TB: t, + failed: atomic.Bool{}, + } + + closurePanic := false - go func() { - f(newT) + // Run the retryable test closure, + // capturing any test failures + func() { + defer func() { + if r := recover(); r != nil { + closurePanic = true + } + }() - newT.SuccessChannel <- true + f(wrappedT) }() - select { - case err := <-newT.ErrorChannel: - t.Logf("Retrying on test failure: %s\n", err) - case <-newT.SuccessChannel: + if !closurePanic && !t.Failed() { return } + + t.Logf("Retrying %s due to failure. (Attempt %d)", t.Name(), i+1) } t.Fatalf("Test failed after %d attempts", maxAttempts) } -// TRetry implements testing.T with additional retry logic -type TRetry struct { - t *testing.T - - ErrorChannel chan error - SuccessChannel chan bool -} - -func NewTRetry(t *testing.T) *TRetry { - return &TRetry{ - t: t, - ErrorChannel: make(chan error, 0), - SuccessChannel: make(chan bool, 0), - } -} - -func (t *TRetry) Close() { - close(t.ErrorChannel) - close(t.SuccessChannel) -} +// WrappedT implements testing.T with additional retry logic +type WrappedT struct { + testing.TB -func (t *TRetry) Cleanup(f func()) { - t.t.Cleanup(f) + failed atomic.Bool } -func (t *TRetry) Error(args ...any) { - t.ErrorChannel <- errors.New(fmt.Sprint(args...)) +func (t *WrappedT) Failed() bool { + return t.failed.Load() } -func (t *TRetry) Errorf(format string, args ...any) { - t.ErrorChannel <- fmt.Errorf(format, args...) +func (t *WrappedT) Fail() { + t.failed.Store(true) } -func (t *TRetry) Fail() { - runtime.Goexit() -} +func (t *WrappedT) FailNow() { + t.Fail() -func (t *TRetry) Failed() bool { - // We wrap this logic using channels - return false + // This is necessary to prevent further closure execution. + // lintignore: R009 + panic(nil) } -func (t *TRetry) Fatal(args ...any) { - t.ErrorChannel <- errors.New(fmt.Sprint(args...)) +func (t *WrappedT) Error(args ...any) { + t.TB.Log("ERROR:", fmt.Sprint(args...)) t.Fail() } -func (t *TRetry) Fatalf(format string, args ...any) { - t.ErrorChannel <- fmt.Errorf(format, args...) +func (t *WrappedT) Errorf(format string, args ...any) { + t.TB.Log("ERROR:", fmt.Sprintf(format, args...)) t.Fail() } -func (t *TRetry) Helper() { - t.t.Helper() -} - -func (t *TRetry) Log(args ...any) { - t.t.Log(args...) -} - -func (t *TRetry) Logf(format string, args ...any) { - t.t.Logf(format, args...) +func (t *WrappedT) Fatal(args ...any) { + t.TB.Log("FATAL:", fmt.Sprint(args...)) + t.FailNow() } -func (t *TRetry) Name() string { - return t.t.Name() +func (t *WrappedT) Fatalf(format string, args ...any) { + t.TB.Log("FATAL:", fmt.Sprintf(format, args...)) + t.FailNow() } -func (t *TRetry) Setenv(key, value string) { - t.t.Setenv(key, value) +func (t *WrappedT) Parallel() { + t.TB.Fatal("Parallel() cannot be called on instances of WrappedT") } - -func (t *TRetry) Skip(args ...any) { - t.t.Skip(args...) -} - -func (t *TRetry) SkipNow() { - t.t.SkipNow() -} - -func (t *TRetry) Skipf(format string, args ...any) { - t.t.Skipf(format, args...) -} - -func (t *TRetry) Skipped() bool { - return t.t.Skipped() -} - -func (t *TRetry) TempDir() string { - return t.t.TempDir() -} - -func (t *TRetry) FailNow() { - t.Fail() -} - -func (t *TRetry) Parallel() { - t.t.Parallel() -} - -//lint:ignore U1000 Ignore unused function -func (t *TRetry) private() {} diff --git a/linode/acceptance/tmpl/template.go b/linode/acceptance/tmpl/template.go index e7ffaa382..e5532d1fb 100644 --- a/linode/acceptance/tmpl/template.go +++ b/linode/acceptance/tmpl/template.go @@ -8,7 +8,7 @@ import ( // ProviderNoPoll is used to configure the provider to disable instance // polling. -func ProviderNoPoll(t *testing.T) string { +func ProviderNoPoll(t testing.TB) string { return acceptance.ExecuteTemplate(t, "provider_no_poll", nil, ) diff --git a/linode/acceptance/util.go b/linode/acceptance/util.go index 3a51d14cc..db15b89e7 100644 --- a/linode/acceptance/util.go +++ b/linode/acceptance/util.go @@ -149,7 +149,7 @@ func TestProvider(t *testing.T) { } } -func PreCheck(t *testing.T) { +func PreCheck(t testing.TB) { t.Helper() if v := os.Getenv("LINODE_TOKEN"); v == "" { @@ -157,7 +157,7 @@ func PreCheck(t *testing.T) { } } -func OptInTest(t *testing.T) { +func OptInTest(t testing.TB) { t.Helper() if _, ok := optInTests[t.Name()]; !ok { @@ -165,7 +165,7 @@ func OptInTest(t *testing.T) { } } -func LongRunningTest(t *testing.T) { +func LongRunningTest(t testing.TB) { t.Helper() shouldRunStr := os.Getenv(runLongTestsEnvVar) @@ -183,7 +183,7 @@ func LongRunningTest(t *testing.T) { } } -func GetSSHClient(t *testing.T, user, addr string) (client *ssh.Client) { +func GetSSHClient(t testing.TB, user, addr string) (client *ssh.Client) { t.Helper() signer, err := ssh.ParsePrivateKey([]byte(privateKeyMaterial)) @@ -526,7 +526,7 @@ func AnyOfTestCheckFunc(funcs ...resource.TestCheckFunc) resource.TestCheckFunc } } -func ExecuteTemplate(t *testing.T, templateName string, data interface{}) string { +func ExecuteTemplate(t testing.TB, templateName string, data interface{}) string { t.Helper() var b bytes.Buffer @@ -539,7 +539,7 @@ func ExecuteTemplate(t *testing.T, templateName string, data interface{}) string return b.String() } -func CreateTempFile(t *testing.T, name, content string) *os.File { +func CreateTempFile(t testing.TB, name, content string) *os.File { file, err := os.CreateTemp(os.TempDir(), name) if err != nil { t.Fatalf("failed to create temp file: %s", err) diff --git a/linode/account/tmpl/template.go b/linode/account/tmpl/template.go index e808d02f6..0d1c9c27d 100644 --- a/linode/account/tmpl/template.go +++ b/linode/account/tmpl/template.go @@ -8,7 +8,7 @@ import ( type TemplateData struct{} -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "account_data_basic", nil) } diff --git a/linode/accountavailabilities/tmpl/template.go b/linode/accountavailabilities/tmpl/template.go index 0a40af6ff..f15862df0 100644 --- a/linode/accountavailabilities/tmpl/template.go +++ b/linode/accountavailabilities/tmpl/template.go @@ -11,12 +11,12 @@ type TemplateData struct { Unavailable string } -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "account_availabilities_data_basic", nil) } -func DataFilterRegion(t *testing.T, region string) string { +func DataFilterRegion(t testing.TB, region string) string { return acceptance.ExecuteTemplate(t, "account_availabilities_data_by_region", TemplateData{ Region: region, diff --git a/linode/accountavailability/tmpl/template.go b/linode/accountavailability/tmpl/template.go index ff0d03641..92e387a39 100644 --- a/linode/accountavailability/tmpl/template.go +++ b/linode/accountavailability/tmpl/template.go @@ -10,7 +10,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, region string) string { +func DataBasic(t testing.TB, region string) string { return acceptance.ExecuteTemplate(t, "account_availability_data_basic", TemplateData{ Region: region, diff --git a/linode/accountlogin/tmpl/template.go b/linode/accountlogin/tmpl/template.go index f722c6bf6..8c6acc1ae 100644 --- a/linode/accountlogin/tmpl/template.go +++ b/linode/accountlogin/tmpl/template.go @@ -10,7 +10,7 @@ type TemplateData struct { ID int } -func DataBasic(t *testing.T, id int) string { +func DataBasic(t testing.TB, id int) string { return acceptance.ExecuteTemplate(t, "account_login_data_basic", TemplateData{ ID: id, diff --git a/linode/accountlogins/tmpl/template.go b/linode/accountlogins/tmpl/template.go index 25749acc4..d95842526 100644 --- a/linode/accountlogins/tmpl/template.go +++ b/linode/accountlogins/tmpl/template.go @@ -13,12 +13,12 @@ type TemplateData struct { Status string } -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "account_logins_data_basic", nil) } -func DataFilterRestricted(t *testing.T, username, ip, status string, restricted bool) string { +func DataFilterRestricted(t testing.TB, username, ip, status string, restricted bool) string { return acceptance.ExecuteTemplate(t, "account_logins_data_filter_by_restricted", TemplateData{ Username: username, @@ -28,7 +28,7 @@ func DataFilterRestricted(t *testing.T, username, ip, status string, restricted }) } -func DataFilterUsername(t *testing.T, username, ip, status string, restricted bool) string { +func DataFilterUsername(t testing.TB, username, ip, status string, restricted bool) string { return acceptance.ExecuteTemplate(t, "account_logins_data_filter_by_username", TemplateData{ Username: username, @@ -38,7 +38,7 @@ func DataFilterUsername(t *testing.T, username, ip, status string, restricted bo }) } -func DataFilterIP(t *testing.T, username, ip, status string, restricted bool) string { +func DataFilterIP(t testing.TB, username, ip, status string, restricted bool) string { return acceptance.ExecuteTemplate(t, "account_logins_data_filter_by_ip", TemplateData{ Username: username, @@ -48,7 +48,7 @@ func DataFilterIP(t *testing.T, username, ip, status string, restricted bool) st }) } -func DataFilterStatus(t *testing.T, username, ip, status string, restricted bool) string { +func DataFilterStatus(t testing.TB, username, ip, status string, restricted bool) string { return acceptance.ExecuteTemplate(t, "account_logins_data_filter_by_status", TemplateData{ Username: username, diff --git a/linode/accountsettings/tmpl/template.go b/linode/accountsettings/tmpl/template.go index 6ff1d209f..b4f40b572 100644 --- a/linode/accountsettings/tmpl/template.go +++ b/linode/accountsettings/tmpl/template.go @@ -12,17 +12,17 @@ type TemplateData struct { NetworkHelper bool } -func Basic(t *testing.T) string { +func Basic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "account_settings_basic", nil) } -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "account_settings_data_basic", nil) } -func Updates(t *testing.T, longviewSubscription string, backupsEnabled, networkHelper bool) string { +func Updates(t testing.TB, longviewSubscription string, backupsEnabled, networkHelper bool) string { return acceptance.ExecuteTemplate(t, "account_settings_updates", TemplateData{ LongviewSubscription: longviewSubscription, diff --git a/linode/childaccount/tmpl/template.go b/linode/childaccount/tmpl/template.go index fc9ce60ba..85cc8418d 100644 --- a/linode/childaccount/tmpl/template.go +++ b/linode/childaccount/tmpl/template.go @@ -8,7 +8,7 @@ import ( type TemplateData struct{} -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "child_account_data_basic", nil) } diff --git a/linode/childaccounts/tmpl/template.go b/linode/childaccounts/tmpl/template.go index 07aa2c1ed..dbe52381a 100644 --- a/linode/childaccounts/tmpl/template.go +++ b/linode/childaccounts/tmpl/template.go @@ -6,7 +6,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "child_accounts_data_basic", nil) } diff --git a/linode/databaseaccesscontrols/tmpl/template.go b/linode/databaseaccesscontrols/tmpl/template.go index f642ca9fb..968719d0a 100644 --- a/linode/databaseaccesscontrols/tmpl/template.go +++ b/linode/databaseaccesscontrols/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { AllowedIP string } -func MySQL(t *testing.T, label, engine, ip, region string) string { +func MySQL(t testing.TB, label, engine, ip, region string) string { return acceptance.ExecuteTemplate(t, "database_access_controls_mysql", TemplateData{ Engine: engine, @@ -23,7 +23,7 @@ func MySQL(t *testing.T, label, engine, ip, region string) string { }) } -func PostgreSQL(t *testing.T, label, engine, ip, region string) string { +func PostgreSQL(t testing.TB, label, engine, ip, region string) string { return acceptance.ExecuteTemplate(t, "database_access_controls_postgresql", TemplateData{ Engine: engine, diff --git a/linode/databasebackups/tmpl/template.go b/linode/databasebackups/tmpl/template.go index 810711d67..5e0e9c744 100644 --- a/linode/databasebackups/tmpl/template.go +++ b/linode/databasebackups/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, data TemplateData) string { +func DataBasic(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_backups_data_basic", data) } diff --git a/linode/databaseengines/tmpl/template.go b/linode/databaseengines/tmpl/template.go index 1a921975f..6c1766887 100644 --- a/linode/databaseengines/tmpl/template.go +++ b/linode/databaseengines/tmpl/template.go @@ -8,12 +8,12 @@ import ( type TemplateData struct{} -func DataAll(t *testing.T) string { +func DataAll(t testing.TB) string { return acceptance.ExecuteTemplate(t, "database_engines_data_all", nil) } -func DataByEngine(t *testing.T) string { +func DataByEngine(t testing.TB) string { return acceptance.ExecuteTemplate(t, "database_engines_data_by_engine", nil) } diff --git a/linode/databasemysql/tmpl/template.go b/linode/databasemysql/tmpl/template.go index c0b601350..fe8f436b0 100644 --- a/linode/databasemysql/tmpl/template.go +++ b/linode/databasemysql/tmpl/template.go @@ -17,7 +17,7 @@ type TemplateData struct { SSLConnection bool } -func Basic(t *testing.T, label, engine, region string) string { +func Basic(t testing.TB, label, engine, region string) string { return acceptance.ExecuteTemplate(t, "database_mysql_basic", TemplateData{ Engine: engine, @@ -26,17 +26,17 @@ func Basic(t *testing.T, label, engine, region string) string { }) } -func Complex(t *testing.T, data TemplateData) string { +func Complex(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_mysql_complex", data) } -func ComplexUpdates(t *testing.T, data TemplateData) string { +func ComplexUpdates(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_mysql_complex_updates", data) } -func DataBasic(t *testing.T, data TemplateData) string { +func DataBasic(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_mysql_data_basic", data) } diff --git a/linode/databasemysqlbackups/tmpl/template.go b/linode/databasemysqlbackups/tmpl/template.go index 96a4895e2..c527075be 100644 --- a/linode/databasemysqlbackups/tmpl/template.go +++ b/linode/databasemysqlbackups/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, data TemplateData) string { +func DataBasic(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_mysql_backups_data_basic", data) } diff --git a/linode/databasepostgresql/tmpl/template.go b/linode/databasepostgresql/tmpl/template.go index 6863befa7..131d9c371 100644 --- a/linode/databasepostgresql/tmpl/template.go +++ b/linode/databasepostgresql/tmpl/template.go @@ -18,7 +18,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label, engine, region string) string { +func Basic(t testing.TB, label, engine, region string) string { return acceptance.ExecuteTemplate(t, "database_postgresql_basic", TemplateData{ Engine: engine, @@ -27,17 +27,17 @@ func Basic(t *testing.T, label, engine, region string) string { }) } -func Complex(t *testing.T, data TemplateData) string { +func Complex(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_postgresql_complex", data) } -func ComplexUpdates(t *testing.T, data TemplateData) string { +func ComplexUpdates(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_postgresql_complex_updates", data) } -func DataBasic(t *testing.T, data TemplateData) string { +func DataBasic(t testing.TB, data TemplateData) string { return acceptance.ExecuteTemplate(t, "database_postgresql_data_basic", data) } diff --git a/linode/databases/tmpl/template.go b/linode/databases/tmpl/template.go index 5a46bdea3..6f78145d6 100644 --- a/linode/databases/tmpl/template.go +++ b/linode/databases/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { Label string } -func ByLabel(t *testing.T, engineVersion, instLabel, dsLabel, region string) string { +func ByLabel(t testing.TB, engineVersion, instLabel, dsLabel, region string) string { return acceptance.ExecuteTemplate(t, "databases_data_by_label", TemplateData{ DB: databasemysqltmpl.TemplateData{Engine: engineVersion, Label: instLabel, Region: region}, @@ -21,7 +21,7 @@ func ByLabel(t *testing.T, engineVersion, instLabel, dsLabel, region string) str }) } -func ByEngine(t *testing.T, engineVersion, label, engine, region string) string { +func ByEngine(t testing.TB, engineVersion, label, engine, region string) string { return acceptance.ExecuteTemplate(t, "databases_data_by_engine", TemplateData{ DB: databasemysqltmpl.TemplateData{Engine: engineVersion, Label: label, Region: region}, diff --git a/linode/domain/tmpl/template.go b/linode/domain/tmpl/template.go index 9691aac6f..f9f639640 100644 --- a/linode/domain/tmpl/template.go +++ b/linode/domain/tmpl/template.go @@ -10,42 +10,42 @@ type TemplateData struct { Domain string } -func Basic(t *testing.T, domain string) string { +func Basic(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_basic", TemplateData{Domain: domain}) } -func Updates(t *testing.T, domain string) string { +func Updates(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_updates", TemplateData{Domain: domain}) } -func RoundedSec(t *testing.T, domain string) string { +func RoundedSec(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_rounded_sec", TemplateData{Domain: domain}) } -func ZeroSec(t *testing.T, domain string) string { +func ZeroSec(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_zero_sec", TemplateData{Domain: domain}) } -func IPS(t *testing.T, domain string) string { +func IPS(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_ips", TemplateData{Domain: domain}) } -func IPSUpdates(t *testing.T, domain string) string { +func IPSUpdates(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_ips_updates", TemplateData{Domain: domain}) } -func DataBasic(t *testing.T, domain string) string { +func DataBasic(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_data_basic", TemplateData{Domain: domain}) } -func DataByID(t *testing.T, domain string) string { +func DataByID(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domain_data_byid", TemplateData{Domain: domain}) } diff --git a/linode/domainrecord/tmpl/template.go b/linode/domainrecord/tmpl/template.go index 93677023a..42445ea2a 100644 --- a/linode/domainrecord/tmpl/template.go +++ b/linode/domainrecord/tmpl/template.go @@ -16,7 +16,7 @@ type TemplateData struct { TTL int } -func Basic(t *testing.T, domainRecord string) string { +func Basic(t testing.TB, domainRecord string) string { return acceptance.ExecuteTemplate(t, "domain_record_basic", TemplateData{ Domain: domain.TemplateData{Domain: domainRecord + ".example"}, @@ -24,7 +24,7 @@ func Basic(t *testing.T, domainRecord string) string { }) } -func Updates(t *testing.T, domainRecord string) string { +func Updates(t testing.TB, domainRecord string) string { return acceptance.ExecuteTemplate(t, "domain_record_updates", TemplateData{ Domain: domain.TemplateData{Domain: domainRecord + ".example"}, @@ -32,21 +32,21 @@ func Updates(t *testing.T, domainRecord string) string { }) } -func ANoName(t *testing.T, d string) string { +func ANoName(t testing.TB, d string) string { return acceptance.ExecuteTemplate(t, "domain_record_a_noname", TemplateData{ Domain: domain.TemplateData{Domain: d}, }) } -func AAAANoName(t *testing.T, d string) string { +func AAAANoName(t testing.TB, d string) string { return acceptance.ExecuteTemplate(t, "domain_record_aaaa_noname", TemplateData{ Domain: domain.TemplateData{Domain: d}, }) } -func CAANoName(t *testing.T, d string) string { +func CAANoName(t testing.TB, d string) string { return acceptance.ExecuteTemplate(t, "domain_record_caa_noname", TemplateData{ Domain: domain.TemplateData{Domain: d}, @@ -54,7 +54,7 @@ func CAANoName(t *testing.T, d string) string { }) } -func TTL(t *testing.T, domainRecord string, ttlSec int) string { +func TTL(t testing.TB, domainRecord string, ttlSec int) string { return acceptance.ExecuteTemplate(t, "domain_record_ttl", TemplateData{ Domain: domain.TemplateData{Domain: domainRecord + ".example"}, @@ -63,7 +63,7 @@ func TTL(t *testing.T, domainRecord string, ttlSec int) string { }) } -func SRV(t *testing.T, domainName string, target string) string { +func SRV(t testing.TB, domainName string, target string) string { return acceptance.ExecuteTemplate(t, "domain_record_srv", TemplateData{ Domain: domain.TemplateData{Domain: domainName}, @@ -71,7 +71,7 @@ func SRV(t *testing.T, domainName string, target string) string { }) } -func WithDomain(t *testing.T, domainName, domainRecord string) string { +func WithDomain(t testing.TB, domainName, domainRecord string) string { return acceptance.ExecuteTemplate(t, "domain_record_with_domain", TemplateData{ Domain: domain.TemplateData{Domain: domainName}, @@ -79,28 +79,28 @@ func WithDomain(t *testing.T, domainName, domainRecord string) string { }) } -func DataBasic(t *testing.T, domainName string) string { +func DataBasic(t testing.TB, domainName string) string { return acceptance.ExecuteTemplate(t, "domain_record_data_basic", TemplateData{ Domain: domain.TemplateData{Domain: domainName}, }) } -func DataID(t *testing.T, domainName string) string { +func DataID(t testing.TB, domainName string) string { return acceptance.ExecuteTemplate(t, "domain_record_data_id", TemplateData{ Domain: domain.TemplateData{Domain: domainName}, }) } -func DataSRV(t *testing.T, domainName string) string { +func DataSRV(t testing.TB, domainName string) string { return acceptance.ExecuteTemplate(t, "domain_record_data_srv", TemplateData{ Domain: domain.TemplateData{Domain: domainName}, }) } -func DataCAA(t *testing.T, domainName string) string { +func DataCAA(t testing.TB, domainName string) string { return acceptance.ExecuteTemplate(t, "domain_record_data_caa", TemplateData{ Domain: domain.TemplateData{Domain: domainName}, diff --git a/linode/domains/datasource_test.go b/linode/domains/datasource_test.go index 232c99d79..43f0bb43d 100644 --- a/linode/domains/datasource_test.go +++ b/linode/domains/datasource_test.go @@ -18,7 +18,7 @@ func TestAccDataSourceDomains_basic(t *testing.T) { domainName := acctest.RandomWithPrefix("tf-test") + ".example" - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, diff --git a/linode/domains/tmpl/template.go b/linode/domains/tmpl/template.go index bbdf5f3f6..6afafd62d 100644 --- a/linode/domains/tmpl/template.go +++ b/linode/domains/tmpl/template.go @@ -10,17 +10,17 @@ type TemplateData struct { Domain string } -func DataBasic(t *testing.T, domain string) string { +func DataBasic(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domains_data_basic", TemplateData{Domain: domain}) } -func DataFilter(t *testing.T, domain string) string { +func DataFilter(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domains_data_filter", TemplateData{Domain: domain}) } -func DataAPIFilter(t *testing.T, domain string) string { +func DataAPIFilter(t testing.TB, domain string) string { return acceptance.ExecuteTemplate(t, "domains_data_api_filter", TemplateData{Domain: domain}) } diff --git a/linode/domainzonefile/tmpl/template.go b/linode/domainzonefile/tmpl/template.go index 2c95c7cf3..eb0ba03ec 100644 --- a/linode/domainzonefile/tmpl/template.go +++ b/linode/domainzonefile/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { Record string } -func Basic(t *testing.T, domainRecord string) string { +func Basic(t testing.TB, domainRecord string) string { return acceptance.ExecuteTemplate(t, "domain_zonefile_basic", TemplateData{ Domain: domain.TemplateData{Domain: domainRecord}, diff --git a/linode/firewall/tmpl/template.go b/linode/firewall/tmpl/template.go index 3bcf750e5..caeed45d5 100644 --- a/linode/firewall/tmpl/template.go +++ b/linode/firewall/tmpl/template.go @@ -22,7 +22,7 @@ type TemplateData struct { Label string } -func Basic(t *testing.T, label, devicePrefix, region string) string { +func Basic(t testing.TB, label, devicePrefix, region string) string { resources := []ResourceTemplateData{ { Prefix: devicePrefix, @@ -41,7 +41,7 @@ func Basic(t *testing.T, label, devicePrefix, region string) string { }) } -func Updates(t *testing.T, label, devicePrefix, region string) string { +func Updates(t testing.TB, label, devicePrefix, region string) string { resources := []ResourceTemplateData{ { Prefix: devicePrefix, @@ -67,14 +67,14 @@ func Updates(t *testing.T, label, devicePrefix, region string) string { }) } -func Minimum(t *testing.T, label string) string { +func Minimum(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "firewall_minimum", TemplateData{ Label: label, }) } -func MultipleRules(t *testing.T, label, devicePrefix, region string) string { +func MultipleRules(t testing.TB, label, devicePrefix, region string) string { return acceptance.ExecuteTemplate(t, "firewall_multiple_rules", TemplateData{ Label: label, @@ -90,28 +90,28 @@ func MultipleRules(t *testing.T, label, devicePrefix, region string) string { }) } -func NoDevice(t *testing.T, label string) string { +func NoDevice(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "firewall_no_device", TemplateData{ Label: label, }) } -func NoIPv6(t *testing.T, label string) string { +func NoIPv6(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "firewall_no_ipv6", TemplateData{ Label: label, }) } -func NoRules(t *testing.T, label string) string { +func NoRules(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "firewall_no_rules", TemplateData{ Label: label, }) } -func DataBasic(t *testing.T, label, devicePrefix, region string) string { +func DataBasic(t testing.TB, label, devicePrefix, region string) string { resources := []ResourceTemplateData{ { Prefix: devicePrefix, diff --git a/linode/firewalldevice/tmpl/template.go b/linode/firewalldevice/tmpl/template.go index 38fa4bbc2..78b503352 100644 --- a/linode/firewalldevice/tmpl/template.go +++ b/linode/firewalldevice/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label, region string) string { +func Basic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "firewall_device_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func Basic(t *testing.T, label, region string) string { }) } -func Detached(t *testing.T, label, region string) string { +func Detached(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "firewall_device_detached", TemplateData{ Label: label, @@ -27,7 +27,7 @@ func Detached(t *testing.T, label, region string) string { }) } -func WithNodeBalancer(t *testing.T, label, region string) string { +func WithNodeBalancer(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "firewall_device_with_nodebalancer", TemplateData{ Label: label, diff --git a/linode/firewalls/tmpl/template.go b/linode/firewalls/tmpl/template.go index 64040de8e..5a910e77f 100644 --- a/linode/firewalls/tmpl/template.go +++ b/linode/firewalls/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataAll(t *testing.T, label, region string) string { +func DataAll(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "data_linode_firewalls_all", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func DataAll(t *testing.T, label, region string) string { }) } -func DataFilter(t *testing.T, label, region string) string { +func DataFilter(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "data_linode_firewalls_filter", TemplateData{ Label: label, diff --git a/linode/framework_provider.go b/linode/framework_provider.go index 30d0c1810..3da7bdd5b 100644 --- a/linode/framework_provider.go +++ b/linode/framework_provider.go @@ -34,6 +34,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/instancedisk" "github.com/linode/terraform-provider-linode/v2/linode/instanceip" "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" + "github.com/linode/terraform-provider-linode/v2/linode/instancereservedipassignment" "github.com/linode/terraform-provider-linode/v2/linode/instancesharedips" "github.com/linode/terraform-provider-linode/v2/linode/instancetype" "github.com/linode/terraform-provider-linode/v2/linode/instancetypes" @@ -208,27 +209,29 @@ func (p *FrameworkProvider) Schema( func (p *FrameworkProvider) Resources(ctx context.Context) []func() resource.Resource { return []func() resource.Resource{ - token.NewResource, - stackscript.NewResource, - rdns.NewResource, - objkey.NewResource, - sshkey.NewResource, - ipv6range.NewResource, - nb.NewResource, accountsettings.NewResource, - vpcsubnet.NewResource, - vpc.NewResource, - instanceip.NewResource, + firewall.NewResource, firewalldevice.NewResource, - volume.NewResource, - instancesharedips.NewResource, + image.NewResource, instancedisk.NewResource, + instanceip.NewResource, + instancesharedips.NewResource, + ipv6range.NewResource, lkenodepool.NewResource, - image.NewResource, + nb.NewResource, nbconfig.NewResource, - firewall.NewResource, + nbnode.NewResource, + objkey.NewResource, placementgroup.NewResource, placementgroupassignment.NewResource, + instancereservedipassignment.NewResource, + rdns.NewResource, + sshkey.NewResource, + stackscript.NewResource, + token.NewResource, + volume.NewResource, + vpc.NewResource, + vpcsubnet.NewResource, } } diff --git a/linode/image/tmpl/template.go b/linode/image/tmpl/template.go index 7e4e5ae7d..573827011 100644 --- a/linode/image/tmpl/template.go +++ b/linode/image/tmpl/template.go @@ -16,7 +16,7 @@ type TemplateData struct { ReplicaRegion string } -func Basic(t *testing.T, image, region, label, tag string) string { +func Basic(t testing.TB, image, region, label, tag string) string { return acceptance.ExecuteTemplate(t, "image_basic", TemplateData{ Image: image, @@ -26,7 +26,7 @@ func Basic(t *testing.T, image, region, label, tag string) string { }) } -func Updates(t *testing.T, image, region, label, tag string) string { +func Updates(t testing.TB, image, region, label, tag string) string { return acceptance.ExecuteTemplate(t, "image_updates", TemplateData{ Image: image, @@ -36,7 +36,7 @@ func Updates(t *testing.T, image, region, label, tag string) string { }) } -func Upload(t *testing.T, image, upload, region, tag string) string { +func Upload(t testing.TB, image, upload, region, tag string) string { return acceptance.ExecuteTemplate(t, "image_upload", TemplateData{ Image: image, @@ -46,7 +46,7 @@ func Upload(t *testing.T, image, upload, region, tag string) string { }) } -func Replicate(t *testing.T, image, upload, region, replicaRegion string) string { +func Replicate(t testing.TB, image, upload, region, replicaRegion string) string { return acceptance.ExecuteTemplate(t, "image_replicate", TemplateData{ Image: image, @@ -56,7 +56,7 @@ func Replicate(t *testing.T, image, upload, region, replicaRegion string) string }) } -func NoReplicaRegions(t *testing.T, image, upload, region string) string { +func NoReplicaRegions(t testing.TB, image, upload, region string) string { return acceptance.ExecuteTemplate(t, "image_no_replica_regions", TemplateData{ Image: image, @@ -65,12 +65,12 @@ func NoReplicaRegions(t *testing.T, image, upload, region string) string { }) } -func DataBasic(t *testing.T, id string) string { +func DataBasic(t testing.TB, id string) string { return acceptance.ExecuteTemplate(t, "image_data_basic", TemplateData{ID: id}) } -func DataReplicate(t *testing.T, image, upload, region, replicaRegion string) string { +func DataReplicate(t testing.TB, image, upload, region, replicaRegion string) string { return acceptance.ExecuteTemplate(t, "image_data_replicate", TemplateData{ Image: image, diff --git a/linode/images/tmpl/template.go b/linode/images/tmpl/template.go index 921d9e103..06938f321 100644 --- a/linode/images/tmpl/template.go +++ b/linode/images/tmpl/template.go @@ -12,32 +12,32 @@ type TemplateData struct { Label string } -func DataBasic(t *testing.T, image, region, label string) string { +func DataBasic(t testing.TB, image, region, label string) string { return acceptance.ExecuteTemplate(t, "images_data_basic", TemplateData{Image: image, Region: region, Label: label}) } -func DataLatest(t *testing.T, image, region string) string { +func DataLatest(t testing.TB, image, region string) string { return acceptance.ExecuteTemplate(t, "images_data_latest", TemplateData{Image: image, Region: region}) } -func DataLatestEmpty(t *testing.T, image, region string) string { +func DataLatestEmpty(t testing.TB, image, region string) string { return acceptance.ExecuteTemplate(t, "images_data_latest_empty", TemplateData{Image: image, Region: region}) } -func DataOrder(t *testing.T, image, region string) string { +func DataOrder(t testing.TB, image, region string) string { return acceptance.ExecuteTemplate(t, "images_data_order", TemplateData{Image: image, Region: region}) } -func DataSubstring(t *testing.T, image, region string) string { +func DataSubstring(t testing.TB, image, region string) string { return acceptance.ExecuteTemplate(t, "images_data_substring", TemplateData{Image: image, Region: region}) } -func DataClientFilter(t *testing.T, image, region string) string { +func DataClientFilter(t testing.TB, image, region string) string { return acceptance.ExecuteTemplate(t, "images_data_clientfilter", TemplateData{Image: image, Region: region}) } diff --git a/linode/instance/resource.go b/linode/instance/resource.go index 3b688b2a0..f836f4f07 100644 --- a/linode/instance/resource.go +++ b/linode/instance/resource.go @@ -15,6 +15,8 @@ import ( linodediffs "github.com/linode/terraform-provider-linode/v2/linode/helper/customdiffs" ) +// Instance creation with reserved IPv4 is for internal use only : please refer to KB page for more information. + const ( LinodeInstanceCreateTimeout = 15 * time.Minute LinodeInstanceUpdateTimeout = time.Hour @@ -191,6 +193,13 @@ func createResource(ctx context.Context, d *schema.ResourceData, meta interface{ ), } + if ipv4Raw, ok := d.GetOk("ipv4"); ok { + ipv4Set := ipv4Raw.(*schema.Set) + for _, ip := range ipv4Set.List() { + createOpts.IPv4 = append(createOpts.IPv4, ip.(string)) + } + } + if tagsRaw, tagsOk := d.GetOk("tags"); tagsOk { for _, tag := range tagsRaw.(*schema.Set).List() { createOpts.Tags = append(createOpts.Tags, tag.(string)) diff --git a/linode/instance/resource_test.go b/linode/instance/resource_test.go index db0d77e16..4b98d895b 100644 --- a/linode/instance/resource_test.go +++ b/linode/instance/resource_test.go @@ -30,8 +30,9 @@ func init() { F: sweep, }) + // TODO:: Add linodego.CapabilityDiskEncryption back when it is enabled region, err := acceptance.GetRandomRegionWithCaps([]string{ - linodego.CapabilityVlans, linodego.CapabilityVPCs, linodego.CapabilityDiskEncryption, + linodego.CapabilityVlans, linodego.CapabilityVPCs, }, "core") if err != nil { log.Fatal(err) @@ -861,8 +862,8 @@ func TestAccResourceInstance_configUpdate(t *testing.T) { resName := "linode_instance.foobar" // This test can occasionally fail while running the entire test suite in parallel - acceptance.RunTestRetry(t, 3, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 3, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckInstanceDestroy, @@ -2526,7 +2527,10 @@ func TestAccResourceInstance_pgAssignment(t *testing.T) { }) } +// TODO:: Un-skip this test once diskencryption is enabled func TestAccResourceInstance_diskEncryption(t *testing.T) { + t.Skip("Skip disk encryption tests until it is enabled in region") + t.Parallel() resName := "linode_instance.foobar" @@ -2893,3 +2897,37 @@ func checkComputeInstanceDisk(instance *linodego.Instance, label string, size in return fmt.Errorf("Disk not found: %s", label) } } + +func TestAccResourceInstance_withReservedIP(t *testing.T) { + acceptance.OptInTest(t) + t.Parallel() + + var instance linodego.Instance + resourceName := "linode_instance.foobar" + instanceName := acctest.RandomWithPrefix("tf_test") + rootPass := acctest.RandString(16) + reservedIP := "50.116.51.242" // Use a test IP or fetch a real reserved IP + + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + CheckDestroy: acceptance.CheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: tmpl.WithReservedIP(t, instanceName, acceptance.PublicKeyMaterial, testRegion, rootPass, reservedIP), + Check: resource.ComposeTestCheckFunc( + acceptance.CheckInstanceExists(resourceName, &instance), + resource.TestCheckResourceAttr(resourceName, "label", instanceName), + resource.TestCheckResourceAttr(resourceName, "ipv4.#", "1"), + resource.TestCheckResourceAttr(resourceName, "ipv4.0", reservedIP), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"root_pass", "authorized_keys", "image", "migration_type", "resize_disk", "firewall_id"}, + }, + }, + }) +} diff --git a/linode/instance/schema_resource.go b/linode/instance/schema_resource.go index 70e12c386..fd678b227 100644 --- a/linode/instance/schema_resource.go +++ b/linode/instance/schema_resource.go @@ -331,9 +331,11 @@ var resourceSchema = map[string]*schema.Schema{ Type: schema.TypeSet, Elem: &schema.Schema{Type: schema.TypeString}, Description: "This Linode's IPv4 Addresses. Each Linode is assigned a single public IPv4 address upon " + - "creation, and may get a single private IPv4 address if needed. You may need to open a support ticket " + + "creation, and may get a single private IPv4 address if needed. You could pass a reserved IPv4 address here to create a linode with a particular reserved IP address. You may need to open a support ticket " + "to get additional IPv4 addresses.", + Optional: true, Computed: true, + ForceNew: true, }, "private_ip": { diff --git a/linode/instance/tmpl/template.go b/linode/instance/tmpl/template.go index ef236d0fb..f470470a2 100644 --- a/linode/instance/tmpl/template.go +++ b/linode/instance/tmpl/template.go @@ -28,9 +28,10 @@ type TemplateData struct { AssignedGroup string DiskEncryption *linodego.InstanceDiskEncryption + IPv4 []string } -func Basic(t *testing.T, label, pubKey, region string, rootPass string) string { +func Basic(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_basic", TemplateData{ Label: label, @@ -41,7 +42,7 @@ func Basic(t *testing.T, label, pubKey, region string, rootPass string) string { }) } -func Updates(t *testing.T, label, region string) string { +func Updates(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_updates", TemplateData{ Label: label, @@ -50,7 +51,7 @@ func Updates(t *testing.T, label, region string) string { }) } -func WatchdogDisabled(t *testing.T, label, region string, rootPass string) string { +func WatchdogDisabled(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_watchdog_disabled", TemplateData{ Label: label, @@ -60,7 +61,7 @@ func WatchdogDisabled(t *testing.T, label, region string, rootPass string) strin }) } -func WithType(t *testing.T, label, pubKey, typ, region string, rootPass string) string { +func WithType(t testing.TB, label, pubKey, typ, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_with_type", TemplateData{ Label: label, @@ -72,7 +73,7 @@ func WithType(t *testing.T, label, pubKey, typ, region string, rootPass string) }) } -func WithSwapSize(t *testing.T, label, pubKey, region string, swapSize int, rootPass string) string { +func WithSwapSize(t testing.TB, label, pubKey, region string, swapSize int, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_with_swap_size", TemplateData{ Label: label, @@ -84,7 +85,7 @@ func WithSwapSize(t *testing.T, label, pubKey, region string, swapSize int, root }) } -func FullDisk(t *testing.T, label, pubKey, stackScriptName, region string, swapSize int, rootPass string) string { +func FullDisk(t testing.TB, label, pubKey, stackScriptName, region string, swapSize int, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_full_disk", TemplateData{ Label: label, @@ -97,7 +98,7 @@ func FullDisk(t *testing.T, label, pubKey, stackScriptName, region string, swapS }) } -func WithConfig(t *testing.T, label, region string) string { +func WithConfig(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_with_config", TemplateData{ Label: label, @@ -106,7 +107,7 @@ func WithConfig(t *testing.T, label, region string) string { }) } -func MultipleConfigs(t *testing.T, label, region string) string { +func MultipleConfigs(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_multiple_configs", TemplateData{ Label: label, @@ -115,7 +116,7 @@ func MultipleConfigs(t *testing.T, label, region string) string { }) } -func Interfaces(t *testing.T, label, region string) string { +func Interfaces(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_interfaces", TemplateData{ Label: label, @@ -124,7 +125,7 @@ func Interfaces(t *testing.T, label, region string) string { }) } -func InterfacesUpdate(t *testing.T, label, region string) string { +func InterfacesUpdate(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_interfaces_update", TemplateData{ Label: label, @@ -133,7 +134,7 @@ func InterfacesUpdate(t *testing.T, label, region string) string { }) } -func InterfacesUpdateEmpty(t *testing.T, label, region string) string { +func InterfacesUpdateEmpty(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_interfaces_update_empty", TemplateData{ Label: label, @@ -142,7 +143,7 @@ func InterfacesUpdateEmpty(t *testing.T, label, region string) string { }) } -func ConfigInterfaces(t *testing.T, label, region string, rootPass string) string { +func ConfigInterfaces(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_interfaces", TemplateData{ Label: label, @@ -152,7 +153,7 @@ func ConfigInterfaces(t *testing.T, label, region string, rootPass string) strin }) } -func ConfigInterfacesMultiple(t *testing.T, label, region string, rootPass string) string { +func ConfigInterfacesMultiple(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_interfaces_multiple", TemplateData{ Label: label, @@ -162,7 +163,7 @@ func ConfigInterfacesMultiple(t *testing.T, label, region string, rootPass strin }) } -func ConfigInterfacesUpdate(t *testing.T, label, region string, rootPass string) string { +func ConfigInterfacesUpdate(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_interfaces_update", TemplateData{ Label: label, @@ -172,7 +173,7 @@ func ConfigInterfacesUpdate(t *testing.T, label, region string, rootPass string) }) } -func ConfigInterfacesUpdateNoReboot(t *testing.T, label, region string, rootPass string) string { +func ConfigInterfacesUpdateNoReboot(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_interfaces_update_no_reboot", TemplateData{ Label: label, @@ -182,7 +183,7 @@ func ConfigInterfacesUpdateNoReboot(t *testing.T, label, region string, rootPass }) } -func ConfigInterfacesUpdateEmpty(t *testing.T, label, region string, rootPass string) string { +func ConfigInterfacesUpdateEmpty(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_interfaces_update_empty", TemplateData{ Label: label, @@ -192,7 +193,7 @@ func ConfigInterfacesUpdateEmpty(t *testing.T, label, region string, rootPass st }) } -func ConfigUpdates(t *testing.T, label, region string) string { +func ConfigUpdates(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_config_updates", TemplateData{ Label: label, @@ -201,7 +202,7 @@ func ConfigUpdates(t *testing.T, label, region string) string { }) } -func ConfigsAllUpdated(t *testing.T, label, region string) string { +func ConfigsAllUpdated(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_configs_all_updated", TemplateData{ Label: label, @@ -210,7 +211,7 @@ func ConfigsAllUpdated(t *testing.T, label, region string) string { }) } -func RawDisk(t *testing.T, label, region string) string { +func RawDisk(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_raw_disk", TemplateData{ Label: label, @@ -219,7 +220,7 @@ func RawDisk(t *testing.T, label, region string) string { }) } -func RawDiskDeleted(t *testing.T, label, region string) string { +func RawDiskDeleted(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_raw_disk_deleted", TemplateData{ Label: label, @@ -228,7 +229,7 @@ func RawDiskDeleted(t *testing.T, label, region string) string { }) } -func Tag(t *testing.T, label, region string) string { +func Tag(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_tag", TemplateData{ Label: label, @@ -237,7 +238,7 @@ func Tag(t *testing.T, label, region string) string { }) } -func TagUpdate(t *testing.T, label, region string) string { +func TagUpdate(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_tag_update", TemplateData{ Label: label, @@ -246,7 +247,7 @@ func TagUpdate(t *testing.T, label, region string) string { }) } -func TagUpdateCaseChange(t *testing.T, label, region string) string { +func TagUpdateCaseChange(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_tag_update_case_change", TemplateData{ Label: label, @@ -255,7 +256,7 @@ func TagUpdateCaseChange(t *testing.T, label, region string) string { }) } -func TagVolume(t *testing.T, label, tag, region string) string { +func TagVolume(t testing.TB, label, tag, region string) string { return acceptance.ExecuteTemplate(t, "instance_tag_volume", TemplateData{ Label: label, @@ -265,7 +266,7 @@ func TagVolume(t *testing.T, label, tag, region string) string { }) } -func RawDiskExpanded(t *testing.T, label, region string) string { +func RawDiskExpanded(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_raw_disk_expanded", TemplateData{ Label: label, @@ -274,7 +275,7 @@ func RawDiskExpanded(t *testing.T, label, region string) string { }) } -func Disk(t *testing.T, label, pubKey, region string, rootPass string) string { +func Disk(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk", TemplateData{ Label: label, @@ -285,7 +286,7 @@ func Disk(t *testing.T, label, pubKey, region string, rootPass string) string { }) } -func DiskMultiple(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskMultiple(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_multiple", TemplateData{ Label: label, @@ -296,7 +297,7 @@ func DiskMultiple(t *testing.T, label, pubKey, region string, rootPass string) s }) } -func DiskConfig(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskConfig(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_config", TemplateData{ Label: label, @@ -307,7 +308,7 @@ func DiskConfig(t *testing.T, label, pubKey, region string, rootPass string) str }) } -func DiskConfigExpanded(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskConfigExpanded(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_config_expanded", TemplateData{ Label: label, @@ -318,7 +319,7 @@ func DiskConfigExpanded(t *testing.T, label, pubKey, region string, rootPass str }) } -func DiskConfigResized(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskConfigResized(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_config_resized", TemplateData{ Label: label, @@ -329,7 +330,7 @@ func DiskConfigResized(t *testing.T, label, pubKey, region string, rootPass stri }) } -func DiskConfigResizedExpanded(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskConfigResizedExpanded(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_config_resized_expanded", TemplateData{ Label: label, @@ -340,7 +341,7 @@ func DiskConfigResizedExpanded(t *testing.T, label, pubKey, region string, rootP }) } -func DiskConfigReordered(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskConfigReordered(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_config_reordered", TemplateData{ Label: label, @@ -351,7 +352,7 @@ func DiskConfigReordered(t *testing.T, label, pubKey, region string, rootPass st }) } -func DiskConfigMultiple(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskConfigMultiple(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_config_multiple", TemplateData{ Label: label, @@ -362,7 +363,7 @@ func DiskConfigMultiple(t *testing.T, label, pubKey, region string, rootPass str }) } -func DiskBootImage(t *testing.T, label, image, region string) string { +func DiskBootImage(t testing.TB, label, image, region string) string { return acceptance.ExecuteTemplate(t, "instance_disk_boot_image", TemplateData{ Label: label, @@ -371,7 +372,7 @@ func DiskBootImage(t *testing.T, label, image, region string) string { }) } -func VolumeConfig(t *testing.T, label, pubKey, region string, rootPass string) string { +func VolumeConfig(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_volume_config", TemplateData{ Label: label, @@ -382,7 +383,7 @@ func VolumeConfig(t *testing.T, label, pubKey, region string, rootPass string) s }) } -func PrivateImage(t *testing.T, label, region string) string { +func PrivateImage(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_private_image", TemplateData{ Label: label, @@ -391,7 +392,7 @@ func PrivateImage(t *testing.T, label, region string) string { }) } -func NoImage(t *testing.T, label, region string) string { +func NoImage(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_no_image", TemplateData{ Label: label, @@ -400,7 +401,7 @@ func NoImage(t *testing.T, label, region string) string { }) } -func PrivateNetworking(t *testing.T, label, pubKey, region string, rootPass string) string { +func PrivateNetworking(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_private_networking", TemplateData{ Label: label, @@ -411,7 +412,7 @@ func PrivateNetworking(t *testing.T, label, pubKey, region string, rootPass stri }) } -func AuthorizedUsers(t *testing.T, label, pubKey, region string, rootPass string) string { +func AuthorizedUsers(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_authorized_users", TemplateData{ Label: label, @@ -422,7 +423,7 @@ func AuthorizedUsers(t *testing.T, label, pubKey, region string, rootPass string }) } -func AuthorizedKeysEmpty(t *testing.T, label, region string) string { +func AuthorizedKeysEmpty(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_authorized_keys_empty", TemplateData{ Label: label, @@ -431,7 +432,7 @@ func AuthorizedKeysEmpty(t *testing.T, label, region string) string { }) } -func DiskAuthorizedKeysEmpty(t *testing.T, label, region string, rootPass string) string { +func DiskAuthorizedKeysEmpty(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_authorized_keys_empty", TemplateData{ Label: label, @@ -441,7 +442,7 @@ func DiskAuthorizedKeysEmpty(t *testing.T, label, region string, rootPass string }) } -func StackScript(t *testing.T, label, region string) string { +func StackScript(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_stackscript", TemplateData{ Label: label, @@ -450,7 +451,7 @@ func StackScript(t *testing.T, label, region string) string { }) } -func DiskStackScript(t *testing.T, label, pubKey, region string, rootPass string) string { +func DiskStackScript(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_stackscript", TemplateData{ Label: label, @@ -461,7 +462,7 @@ func DiskStackScript(t *testing.T, label, pubKey, region string, rootPass string }) } -func BootState(t *testing.T, label, region string, booted bool) string { +func BootState(t testing.TB, label, region string, booted bool) string { return acceptance.ExecuteTemplate(t, "instance_boot_state", TemplateData{ Label: label, @@ -471,7 +472,7 @@ func BootState(t *testing.T, label, region string, booted bool) string { }) } -func BootStateNoImage(t *testing.T, label, region string, booted bool) string { +func BootStateNoImage(t testing.TB, label, region string, booted bool) string { return acceptance.ExecuteTemplate(t, "instance_boot_state_noimage", TemplateData{ Label: label, @@ -480,7 +481,7 @@ func BootStateNoImage(t *testing.T, label, region string, booted bool) string { }) } -func BootStateInterface(t *testing.T, label, region string, booted bool) string { +func BootStateInterface(t testing.TB, label, region string, booted bool) string { return acceptance.ExecuteTemplate(t, "instance_boot_state_interface", TemplateData{ Label: label, @@ -490,7 +491,7 @@ func BootStateInterface(t *testing.T, label, region string, booted bool) string }) } -func BootStateConfig(t *testing.T, label, region string, booted bool, rootPass string) string { +func BootStateConfig(t testing.TB, label, region string, booted bool, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_boot_state_config", TemplateData{ Label: label, @@ -501,7 +502,7 @@ func BootStateConfig(t *testing.T, label, region string, booted bool, rootPass s }) } -func TypeChangeDisk(t *testing.T, label, instanceType, region string, resizeDisk bool) string { +func TypeChangeDisk(t testing.TB, label, instanceType, region string, resizeDisk bool) string { return acceptance.ExecuteTemplate(t, "instance_type_change_disk", TemplateData{ Label: label, @@ -512,7 +513,7 @@ func TypeChangeDisk(t *testing.T, label, instanceType, region string, resizeDisk }) } -func TypeChangeDiskExplicit(t *testing.T, label, instanceType, region string, resizeDisk bool) string { +func TypeChangeDiskExplicit(t testing.TB, label, instanceType, region string, resizeDisk bool) string { return acceptance.ExecuteTemplate(t, "instance_type_change_disk_explicit", TemplateData{ Label: label, @@ -522,7 +523,7 @@ func TypeChangeDiskExplicit(t *testing.T, label, instanceType, region string, re }) } -func TypeChangeDiskNone(t *testing.T, label, instanceType, region string, resizeDisk bool) string { +func TypeChangeDiskNone(t testing.TB, label, instanceType, region string, resizeDisk bool) string { return acceptance.ExecuteTemplate(t, "instance_type_change_disk_none", TemplateData{ Label: label, @@ -532,7 +533,7 @@ func TypeChangeDiskNone(t *testing.T, label, instanceType, region string, resize }) } -func TypeChangeWarm(t *testing.T, label, instanceType, region string, resizeDisk bool) string { +func TypeChangeWarm(t testing.TB, label, instanceType, region string, resizeDisk bool) string { return acceptance.ExecuteTemplate(t, "instance_type_change_warm", TemplateData{ Label: label, @@ -543,7 +544,7 @@ func TypeChangeWarm(t *testing.T, label, instanceType, region string, resizeDisk }) } -func IPv4Sharing(t *testing.T, label, region string) string { +func IPv4Sharing(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_ipv4_sharing", TemplateData{ Label: label, @@ -551,7 +552,7 @@ func IPv4Sharing(t *testing.T, label, region string) string { }) } -func IPv4SharingEmpty(t *testing.T, label, region string) string { +func IPv4SharingEmpty(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_ipv4_sharing_empty", TemplateData{ Label: label, @@ -559,7 +560,7 @@ func IPv4SharingEmpty(t *testing.T, label, region string) string { }) } -func IPv4SharingAllocation(t *testing.T, label, region string) string { +func IPv4SharingAllocation(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_ipv4_sharing_allocation", TemplateData{ Label: label, @@ -567,7 +568,7 @@ func IPv4SharingAllocation(t *testing.T, label, region string) string { }) } -func IPv4SharingBadInput(t *testing.T, label, region string) string { +func IPv4SharingBadInput(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_ipv4_sharing_bad_input", TemplateData{ Label: label, @@ -575,7 +576,7 @@ func IPv4SharingBadInput(t *testing.T, label, region string) string { }) } -func ManyLinodes(t *testing.T, label, pubKey, region string, rootPass string) string { +func ManyLinodes(t testing.TB, label, pubKey, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_many_linodes", TemplateData{ Label: label, @@ -586,7 +587,7 @@ func ManyLinodes(t *testing.T, label, pubKey, region string, rootPass string) st }) } -func UserData(t *testing.T, label, region string, rootPass string) string { +func UserData(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_userdata", TemplateData{ Label: label, @@ -597,7 +598,7 @@ func UserData(t *testing.T, label, region string, rootPass string) string { } func DiskEncryption( - t *testing.T, + t testing.TB, label, region, rootPass string, @@ -613,7 +614,7 @@ func DiskEncryption( }) } -func DataBasic(t *testing.T, label, region string, rootPass string) string { +func DataBasic(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_data_basic", TemplateData{ Label: label, @@ -623,7 +624,7 @@ func DataBasic(t *testing.T, label, region string, rootPass string) string { }) } -func DataWithBlockStorageEncryption(t *testing.T, label, region string, rootPass string) string { +func DataWithBlockStorageEncryption(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_data_with_block_storage_encryption", TemplateData{ Label: label, @@ -632,7 +633,7 @@ func DataWithBlockStorageEncryption(t *testing.T, label, region string, rootPass }) } -func DataWithPG(t *testing.T, label, region, assignedGroup string, groups []string) string { +func DataWithPG(t testing.TB, label, region, assignedGroup string, groups []string) string { return acceptance.ExecuteTemplate(t, "instance_data_with_pg", TemplateData{ Label: label, @@ -642,7 +643,7 @@ func DataWithPG(t *testing.T, label, region, assignedGroup string, groups []stri }) } -func DataMultiple(t *testing.T, label, tag, region string, rootPass string) string { +func DataMultiple(t testing.TB, label, tag, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_data_multiple", TemplateData{ Label: label, @@ -653,7 +654,7 @@ func DataMultiple(t *testing.T, label, tag, region string, rootPass string) stri }) } -func DataMultipleOrder(t *testing.T, label, tag, region string, rootPass string) string { +func DataMultipleOrder(t testing.TB, label, tag, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_data_multiple_order", TemplateData{ Label: label, @@ -664,7 +665,7 @@ func DataMultipleOrder(t *testing.T, label, tag, region string, rootPass string) }) } -func DataMultipleRegex(t *testing.T, label, tag, region string, rootPass string) string { +func DataMultipleRegex(t testing.TB, label, tag, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_data_multiple_regex", TemplateData{ Label: label, @@ -675,7 +676,7 @@ func DataMultipleRegex(t *testing.T, label, tag, region string, rootPass string) }) } -func DataClientFilter(t *testing.T, label, tag, region string, rootPass string) string { +func DataClientFilter(t testing.TB, label, tag, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_data_clientfilter", TemplateData{ Label: label, @@ -686,7 +687,7 @@ func DataClientFilter(t *testing.T, label, tag, region string, rootPass string) }) } -func FirewallOnCreation(t *testing.T, label, region string, rootPass string) string { +func FirewallOnCreation(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_firewall_on_creation", TemplateData{ Label: label, @@ -696,7 +697,7 @@ func FirewallOnCreation(t *testing.T, label, region string, rootPass string) str }) } -func VPCInterface(t *testing.T, label, region string) string { +func VPCInterface(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_vpc_interface", TemplateData{ Label: label, @@ -705,7 +706,7 @@ func VPCInterface(t *testing.T, label, region string) string { }) } -func VPCAndPublicInterfaces(t *testing.T, label, region string) string { +func VPCAndPublicInterfaces(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_vpc_public_interface", TemplateData{ Label: label, @@ -714,7 +715,7 @@ func VPCAndPublicInterfaces(t *testing.T, label, region string) string { }) } -func PublicAndVPCInterfaces(t *testing.T, label, region string) string { +func PublicAndVPCInterfaces(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_public_vpc_interface", TemplateData{ Label: label, @@ -723,7 +724,7 @@ func PublicAndVPCInterfaces(t *testing.T, label, region string) string { }) } -func PublicInterface(t *testing.T, label, region string) string { +func PublicInterface(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_public_interface", TemplateData{ Label: label, @@ -732,7 +733,7 @@ func PublicInterface(t *testing.T, label, region string) string { }) } -func WithPG(t *testing.T, label, region, assignedGroup string, groups []string) string { +func WithPG(t testing.TB, label, region, assignedGroup string, groups []string) string { return acceptance.ExecuteTemplate(t, "instance_with_pg", TemplateData{ Label: label, @@ -741,3 +742,16 @@ func WithPG(t *testing.T, label, region, assignedGroup string, groups []string) AssignedGroup: assignedGroup, }) } + +func WithReservedIP(t *testing.T, label, pubKey, region, rootPass string, reservedIP string) string { + generatedConfig := acceptance.ExecuteTemplate(t, + "instance_with_reserved_ip", TemplateData{ + Label: label, + PubKey: pubKey, + Image: acceptance.TestImageLatest, + Region: region, + RootPass: rootPass, + IPv4: []string{reservedIP}, + }) + return generatedConfig +} diff --git a/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf b/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf new file mode 100644 index 000000000..40331b2dc --- /dev/null +++ b/linode/instance/tmpl/templates/instance_with_reserved_ip.gotf @@ -0,0 +1,18 @@ +{{ define "instance_with_reserved_ip" }} + +{{ template "e2e_test_firewall" . }} + +resource "linode_instance" "foobar" { + label = "{{ .Label }}" + type = "g6-nanode-1" + region = "{{ .Region }}" + image = "{{ .Image }}" + firewall_id = linode_firewall.e2e_test_firewall.id + + root_pass = "{{ .RootPass }}" + authorized_keys = ["{{ .PubKey }}"] + + ipv4 = [{{ range $index, $ip := .IPv4 }}{{ if $index }}, {{ end }}"{{ $ip }}"{{ end }}] +} + +{{ end }} \ No newline at end of file diff --git a/linode/instanceconfig/resource_test.go b/linode/instanceconfig/resource_test.go index 442c3141f..2c176d0e6 100644 --- a/linode/instanceconfig/resource_test.go +++ b/linode/instanceconfig/resource_test.go @@ -266,7 +266,7 @@ func TestAccResourceInstanceConfig_booted(t *testing.T) { func TestAccResourceInstanceConfig_bootedSwap(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 3, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 3, func(t *acceptance.WrappedT) { var instance linodego.Instance config1Name := "linode_instance_config.foobar1" @@ -274,7 +274,7 @@ func TestAccResourceInstanceConfig_bootedSwap(t *testing.T) { instanceName := acctest.RandomWithPrefix("tf_test") rootPass := acctest.RandString(64) - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkDestroy, diff --git a/linode/instanceconfig/tmpl/template.go b/linode/instanceconfig/tmpl/template.go index 4ec930292..ef0476530 100644 --- a/linode/instanceconfig/tmpl/template.go +++ b/linode/instanceconfig/tmpl/template.go @@ -14,7 +14,7 @@ type TemplateData struct { RootPass string } -func Basic(t *testing.T, label, region string) string { +func Basic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "instance_config_basic", TemplateData{ Label: label, @@ -22,7 +22,7 @@ func Basic(t *testing.T, label, region string) string { }) } -func Complex(t *testing.T, label, region string, rootPass string) string { +func Complex(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_complex", TemplateData{ Label: label, @@ -31,7 +31,7 @@ func Complex(t *testing.T, label, region string, rootPass string) string { }) } -func ComplexUpdates(t *testing.T, label, region string, rootPass string, booted bool) string { +func ComplexUpdates(t testing.TB, label, region string, rootPass string, booted bool) string { return acceptance.ExecuteTemplate(t, "instance_config_complex_updates", TemplateData{ Label: label, @@ -41,7 +41,7 @@ func ComplexUpdates(t *testing.T, label, region string, rootPass string, booted }) } -func Booted(t *testing.T, label, region string, booted bool, rootPass string) string { +func Booted(t testing.TB, label, region string, booted bool, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_booted", TemplateData{ Label: label, @@ -51,7 +51,7 @@ func Booted(t *testing.T, label, region string, booted bool, rootPass string) st }) } -func BootedSwap(t *testing.T, label, region string, swap bool, rootPass string) string { +func BootedSwap(t testing.TB, label, region string, swap bool, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_booted_swap", TemplateData{ Label: label, @@ -61,7 +61,7 @@ func BootedSwap(t *testing.T, label, region string, swap bool, rootPass string) }) } -func Provisioner(t *testing.T, label, region string, rootPass string) string { +func Provisioner(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_config_provisioner", TemplateData{ Label: label, @@ -70,7 +70,7 @@ func Provisioner(t *testing.T, label, region string, rootPass string) string { }) } -func DeviceBlock(t *testing.T, label, region string, rootPass string) string { +func DeviceBlock(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "instance_config_device_block", TemplateData{ @@ -81,7 +81,7 @@ func DeviceBlock(t *testing.T, label, region string, rootPass string) string { ) } -func DeviceNamedBlock(t *testing.T, label, region string, rootPass string) string { +func DeviceNamedBlock(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "instance_config_device_named_block", TemplateData{ @@ -92,7 +92,7 @@ func DeviceNamedBlock(t *testing.T, label, region string, rootPass string) strin ) } -func VPCInterface(t *testing.T, label, region string, rootPass string) string { +func VPCInterface(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "vpc_interface", TemplateData{ @@ -103,7 +103,7 @@ func VPCInterface(t *testing.T, label, region string, rootPass string) string { ) } -func VPCInterfaceUpdated(t *testing.T, label, region string, rootPass string) string { +func VPCInterfaceUpdated(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "vpc_interface_update", TemplateData{ @@ -114,7 +114,7 @@ func VPCInterfaceUpdated(t *testing.T, label, region string, rootPass string) st ) } -func VPCInterfaceRemoved(t *testing.T, label, region string, rootPass string) string { +func VPCInterfaceRemoved(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "vpc_interface_remove", TemplateData{ @@ -125,7 +125,7 @@ func VPCInterfaceRemoved(t *testing.T, label, region string, rootPass string) st ) } -func VPCInterfaceSwapped(t *testing.T, label, region string, rootPass string) string { +func VPCInterfaceSwapped(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "vpc_interface_swap", TemplateData{ @@ -136,7 +136,7 @@ func VPCInterfaceSwapped(t *testing.T, label, region string, rootPass string) st ) } -func VPCInterfaceOnly(t *testing.T, label, region string, rootPass string) string { +func VPCInterfaceOnly(t testing.TB, label, region string, rootPass string) string { return acceptance.ExecuteTemplate( t, "vpc_interface_only", TemplateData{ diff --git a/linode/instancedisk/tmpl/template.go b/linode/instancedisk/tmpl/template.go index d76cd3536..21d4bf0dc 100644 --- a/linode/instancedisk/tmpl/template.go +++ b/linode/instancedisk/tmpl/template.go @@ -14,7 +14,7 @@ type TemplateData struct { RootPass string } -func Basic(t *testing.T, label, region string, size int) string { +func Basic(t testing.TB, label, region string, size int) string { return acceptance.ExecuteTemplate(t, "instance_disk_basic", TemplateData{ Label: label, @@ -23,7 +23,7 @@ func Basic(t *testing.T, label, region string, size int) string { }) } -func Complex(t *testing.T, label, region string, size int) string { +func Complex(t testing.TB, label, region string, size int) string { return acceptance.ExecuteTemplate(t, "instance_disk_basic", TemplateData{ Label: label, @@ -33,7 +33,7 @@ func Complex(t *testing.T, label, region string, size int) string { }) } -func BootedResize(t *testing.T, label, region string, size int, rootPass string) string { +func BootedResize(t testing.TB, label, region string, size int, rootPass string) string { return acceptance.ExecuteTemplate(t, "instance_disk_booted_resize", TemplateData{ Label: label, diff --git a/linode/instanceip/tmpl/template.go b/linode/instanceip/tmpl/template.go index c3ecfe8af..493e68c85 100644 --- a/linode/instanceip/tmpl/template.go +++ b/linode/instanceip/tmpl/template.go @@ -12,7 +12,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, instanceLabel, region string, applyImmediately bool) string { +func Basic(t testing.TB, instanceLabel, region string, applyImmediately bool) string { return acceptance.ExecuteTemplate(t, "instance_ip_basic", TemplateData{ Label: instanceLabel, @@ -21,7 +21,7 @@ func Basic(t *testing.T, instanceLabel, region string, applyImmediately bool) st }) } -func NoBoot(t *testing.T, instanceLabel, region string, applyImmediately bool) string { +func NoBoot(t testing.TB, instanceLabel, region string, applyImmediately bool) string { return acceptance.ExecuteTemplate(t, "instance_ip_no_boot", TemplateData{ Label: instanceLabel, diff --git a/linode/instancenetworking/tmpl/template.go b/linode/instancenetworking/tmpl/template.go index 73a46cd68..fdbaeda7c 100644 --- a/linode/instancenetworking/tmpl/template.go +++ b/linode/instancenetworking/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { InterfaceIPv4 string } -func DataBasic(t *testing.T, instanceLabel, region string) string { +func DataBasic(t testing.TB, instanceLabel, region string) string { return acceptance.ExecuteTemplate(t, "instance_networking_data_basic", TemplateData{ Label: instanceLabel, @@ -21,7 +21,7 @@ func DataBasic(t *testing.T, instanceLabel, region string) string { }) } -func DataVPC(t *testing.T, label, region, subnetIPv4, interfaceIPv4 string) string { +func DataVPC(t testing.TB, label, region, subnetIPv4, interfaceIPv4 string) string { return acceptance.ExecuteTemplate(t, "instance_networking_data_vpc", TemplateData{ Label: label, diff --git a/linode/instancereservedipassignment/framework_models.go b/linode/instancereservedipassignment/framework_models.go new file mode 100644 index 000000000..1dc73520a --- /dev/null +++ b/linode/instancereservedipassignment/framework_models.go @@ -0,0 +1,108 @@ +package instancereservedipassignment + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/linode/linodego" + + "github.com/linode/terraform-provider-linode/v2/linode/helper" + "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" +) + +type InstanceIPModel struct { + ID types.String `tfsdk:"id"` + LinodeID types.Int64 `tfsdk:"linode_id"` + Public types.Bool `tfsdk:"public"` + Address types.String `tfsdk:"address"` + Gateway types.String `tfsdk:"gateway"` + Prefix types.Int64 `tfsdk:"prefix"` + RDNS types.String `tfsdk:"rdns"` + Region types.String `tfsdk:"region"` + SubnetMask types.String `tfsdk:"subnet_mask"` + Type types.String `tfsdk:"type"` + ApplyImmediately types.Bool `tfsdk:"apply_immediately"` + IPVPCNAT1To1 types.List `tfsdk:"vpc_nat_1_1"` + Reserved types.Bool `tfsdk:"reserved"` +} + +func (m *InstanceIPModel) flattenInstanceIP( + ctx context.Context, + ip linodego.InstanceIP, + preserveKnown bool, +) diag.Diagnostics { + var diags diag.Diagnostics + + m.ID = helper.KeepOrUpdateString(m.ID, ip.Address, preserveKnown) + m.LinodeID = helper.KeepOrUpdateInt64(m.LinodeID, int64(ip.LinodeID), preserveKnown) + m.Public = helper.KeepOrUpdateBool(m.Public, ip.Public, preserveKnown) + m.Address = helper.KeepOrUpdateString(m.Address, ip.Address, preserveKnown) + m.Gateway = helper.KeepOrUpdateString(m.Gateway, ip.Gateway, preserveKnown) + m.Prefix = helper.KeepOrUpdateInt64(m.Prefix, int64(ip.Prefix), preserveKnown) + + m.RDNS = helper.KeepOrUpdateString(m.RDNS, ip.RDNS, preserveKnown) + m.Reserved = helper.KeepOrUpdateBool(m.Reserved, ip.Reserved, preserveKnown) + + m.Region = helper.KeepOrUpdateString(m.Region, ip.Region, preserveKnown) + m.SubnetMask = helper.KeepOrUpdateString(m.SubnetMask, ip.SubnetMask, preserveKnown) + m.Type = helper.KeepOrUpdateString(m.Type, string(ip.Type), preserveKnown) + + var resultList types.List + if ip.VPCNAT1To1 == nil { + resultList = types.ListNull(instancenetworking.VPCNAT1To1Type) + } else { + vpcNAT1To1, diags := instancenetworking.FlattenIPVPCNAT1To1(ip.VPCNAT1To1) + diags.Append(diags...) + if diags.HasError() { + return diags + } + + var listDiags diag.Diagnostics + resultList, listDiags = types.ListValue( + instancenetworking.VPCNAT1To1Type, + []attr.Value{vpcNAT1To1}, + ) + diags.Append(listDiags...) + if diags.HasError() { + return diags + } + } + m.IPVPCNAT1To1 = helper.KeepOrUpdateValue( + m.IPVPCNAT1To1, + resultList, + preserveKnown, + ) + + return diags +} + +func (m *InstanceIPModel) CopyFrom( + ctx context.Context, + other InstanceIPModel, + preserveKnown bool, +) diag.Diagnostics { + var diags diag.Diagnostics + + m.ID = helper.KeepOrUpdateValue(m.ID, other.Address, preserveKnown) + m.LinodeID = helper.KeepOrUpdateValue(m.LinodeID, other.LinodeID, preserveKnown) + m.Public = helper.KeepOrUpdateValue(m.Public, other.Public, preserveKnown) + m.Address = helper.KeepOrUpdateValue(m.Address, other.Address, preserveKnown) + m.Gateway = helper.KeepOrUpdateValue(m.Gateway, other.Gateway, preserveKnown) + m.Prefix = helper.KeepOrUpdateValue(m.Prefix, other.Prefix, preserveKnown) + + m.RDNS = helper.KeepOrUpdateValue(m.RDNS, other.RDNS, preserveKnown) + m.Reserved = helper.KeepOrUpdateValue(m.Reserved, other.Reserved, preserveKnown) + + m.Region = helper.KeepOrUpdateValue(m.Region, other.Region, preserveKnown) + m.SubnetMask = helper.KeepOrUpdateValue(m.SubnetMask, other.SubnetMask, preserveKnown) + m.Type = helper.KeepOrUpdateValue(m.Type, other.Type, preserveKnown) + m.IPVPCNAT1To1 = helper.KeepOrUpdateValue( + m.IPVPCNAT1To1, + other.IPVPCNAT1To1, + preserveKnown, + ) + + return diags +} diff --git a/linode/instancereservedipassignment/framework_resource.go b/linode/instancereservedipassignment/framework_resource.go new file mode 100644 index 000000000..c53de06c9 --- /dev/null +++ b/linode/instancereservedipassignment/framework_resource.go @@ -0,0 +1,294 @@ +package instancereservedipassignment + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" +) + +// For internal only: please refer to KB page for more information + +func NewResource() resource.Resource { + return &Resource{ + BaseResource: helper.NewBaseResource( + helper.BaseResourceConfig{ + Name: "linode_reserved_ip_assignment", + IDType: types.StringType, + Schema: &frameworkResourceSchema, + }, + ), + } +} + +type Resource struct { + helper.BaseResource +} + +func (r *Resource) Create( + ctx context.Context, + req resource.CreateRequest, + resp *resource.CreateResponse, +) { + tflog.Debug(ctx, "Create linode_reserved_ip_assignment") + var plan InstanceIPModel + + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + ctx = populateLogAttributes(ctx, &plan) + + linodeID := helper.FrameworkSafeInt64ToInt( + plan.LinodeID.ValueInt64(), + &resp.Diagnostics, + ) + if resp.Diagnostics.HasError() { + return + } + + isPublic := plan.Public.ValueBool() + + client := r.Meta.Client + var ip *linodego.InstanceIP + var err error + + if !plan.Address.IsNull() && !plan.Address.IsUnknown() { + // Assign a reserved IP + createOpts := linodego.InstanceReserveIPOptions{ + Type: "ipv4", + Public: isPublic, + Address: plan.Address.ValueString(), + } + ip, err = client.AssignInstanceReservedIP(ctx, linodeID, createOpts) + if err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf("Failed to assign reserved IP to instance (%d)", linodeID), + err.Error(), + ) + return + } + } + + if !plan.RDNS.IsNull() && !plan.RDNS.IsUnknown() { + rdns := plan.RDNS.ValueString() + + options := linodego.IPAddressUpdateOptions{ + RDNS: &rdns, + } + + tflog.Debug(ctx, "client.UpdateIPAddress(...)", map[string]any{ + "options": options, + }) + + if _, err := client.UpdateIPAddress(ctx, ip.Address, options); err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf( + "failed to set RDNS for instance (%d) ip (%s)", + linodeID, ip.Address, + ), + err.Error(), + ) + return + } + } + + resp.Diagnostics.Append(plan.flattenInstanceIP(ctx, *ip, true)...) + if resp.Diagnostics.HasError() { + return + } + + // IDs should always be overridden during creation (see #1085) + // TODO: Remove when Crossplane empty string ID issue is resolved + plan.ID = types.StringValue(ip.Address) + + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + if plan.ApplyImmediately.ValueBool() { + tflog.Debug(ctx, "Attempting apply_immediately") + + instance, err := client.GetInstance(ctx, linodeID) + if err != nil { + resp.Diagnostics.AddError("Failed to Get Linode Instance", err.Error()) + return + } + + if instance.Status == linodego.InstanceRunning { + tflog.Info(ctx, "detected instance in running status, rebooting instance") + ctx, cancel := context.WithTimeout(ctx, time.Duration(600)*time.Second) + resp.Diagnostics.Append(helper.FrameworkRebootInstance(ctx, linodeID, client, 0)...) + cancel() + } else { + tflog.Info(ctx, "Detected instance not in running status, can't perform a reboot.") + } + } +} + +func (r *Resource) Read( + ctx context.Context, + req resource.ReadRequest, + resp *resource.ReadResponse, +) { + tflog.Debug(ctx, "Read linode_instance_reserved_ip") + var state InstanceIPModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + // TODO: cleanup when Crossplane fixes it + if helper.FrameworkAttemptRemoveResourceForEmptyID(ctx, state.ID, resp) { + return + } + + ctx = populateLogAttributes(ctx, &state) + + client := r.Meta.Client + address := state.ID.ValueString() // Use ID as address + + ip, err := client.GetIPAddress(ctx, address) + if err != nil { + if lerr, ok := err.(*linodego.Error); ok && lerr.Code == 404 { + resp.Diagnostics.AddWarning( + "Reserved IP No Longer Exists", + fmt.Sprintf("Removing reserved IP %s from state because it no longer exists", state.ID.ValueString()), + ) + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError( + "Unable to Refresh Reserved IP", + fmt.Sprintf("Error finding the specified Reserved IP: %s", err.Error()), + ) + return + } + + if ip == nil { + resp.Diagnostics.AddError("nil Pointer", "received nil pointer for reserved IP") + return + } + + // Populate state with fetched data + resp.Diagnostics.Append(state.flattenInstanceIP(ctx, *ip, false)...) + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *Resource) Update( + ctx context.Context, + req resource.UpdateRequest, + resp *resource.UpdateResponse, +) { + var plan InstanceIPModel + var state InstanceIPModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + + if resp.Diagnostics.HasError() { + return + } + + if !plan.RDNS.Equal(state.RDNS) { + rdns := plan.RDNS.ValueStringPointer() + updateOptions := linodego.IPAddressUpdateOptions{ + RDNS: rdns, + } + + client := r.Meta.Client + address := plan.Address.ValueString() + linodeID := plan.LinodeID.ValueInt64() + + tflog.Debug(ctx, "client.UpdateIPAddress(...)", map[string]any{ + "options": updateOptions, + }) + + ip, err := client.UpdateIPAddress(ctx, address, updateOptions) + if err != nil { + resp.Diagnostics.AddError( + "Failed to Update RDNS", + fmt.Sprintf( + "failed to update RDNS for instance (%d) ip (%s): %s", + linodeID, address, err, + ), + ) + return + } + if ip == nil { + resp.Diagnostics.AddError( + "Failed to Get Updated IP", + fmt.Sprintf( + "ip is a nil pointer after update operation for instance (%d) ip (%s): %s", + linodeID, address, err, + ), + ) + return + } + resp.Diagnostics.Append(plan.flattenInstanceIP(ctx, *ip, true)...) + if resp.Diagnostics.HasError() { + return + } + } + plan.CopyFrom(ctx, state, true) + + // Workaround for Crossplane issue where ID is not + // properly populated in plan + // See TPT-2865 for more details + if plan.ID.ValueString() == "" { + plan.ID = state.ID + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *Resource) Delete( + ctx context.Context, + req resource.DeleteRequest, + resp *resource.DeleteResponse, +) { + var state InstanceIPModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + client := r.Meta.Client + address := state.Address.ValueString() + linodeID := helper.FrameworkSafeInt64ToInt( + state.LinodeID.ValueInt64(), + &resp.Diagnostics, + ) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, "client.DeleteInstanceIPAddress(...)") + if err := client.DeleteInstanceIPAddress(ctx, linodeID, address); err != nil { + if lErr, ok := err.(*linodego.Error); (ok && lErr.Code != 404) || !ok { + resp.Diagnostics.AddError( + "Failed to Delete IP", + fmt.Sprintf( + "failed to delete instance (%d) ip (%s): %s", + linodeID, address, err.Error(), + ), + ) + } + } +} + +func populateLogAttributes(ctx context.Context, data *InstanceIPModel) context.Context { + return helper.SetLogFieldBulk(ctx, map[string]any{ + "linode_id": data.LinodeID.ValueInt64(), + "address": data.ID.ValueString(), + }) +} diff --git a/linode/instancereservedipassignment/framework_schema.go b/linode/instancereservedipassignment/framework_schema.go new file mode 100644 index 000000000..511059651 --- /dev/null +++ b/linode/instancereservedipassignment/framework_schema.go @@ -0,0 +1,113 @@ +package instancereservedipassignment + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/linode/terraform-provider-linode/v2/linode/instancenetworking" +) + +var frameworkResourceSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The ID of the IPv4 address, which will be IPv4 address itself.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "linode_id": schema.Int64Attribute{ + Description: "The ID of the Linode to allocate an IPv4 address for.", + Required: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "public": schema.BoolAttribute{ + Description: "Whether the IPv4 address is public or private.", + Default: booldefault.StaticBool(true), + Computed: true, + Optional: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + }, + }, + + "address": schema.StringAttribute{ + Description: "The resulting IPv4 address.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "gateway": schema.StringAttribute{ + Description: "The default gateway for this address", + Computed: true, + }, + "prefix": schema.Int64Attribute{ + Description: "The number of bits set in the subnet mask.", + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, + }, + "rdns": schema.StringAttribute{ + Description: "The reverse DNS assigned to this address.", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "region": schema.StringAttribute{ + Description: "The region this IP resides in.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "subnet_mask": schema.StringAttribute{ + Description: "The mask that separates host bits from network bits for this address.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "type": schema.StringAttribute{ + Description: "The type of IP address.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "vpc_nat_1_1": schema.ListAttribute{ + Description: "Contains information about the NAT 1:1 mapping of a public IP address to a VPC subnet.", + Computed: true, + ElementType: instancenetworking.VPCNAT1To1Type, + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + }, + PlanModifiers: []planmodifier.List{ + listplanmodifier.UseStateForUnknown(), + }, + }, + + "apply_immediately": schema.BoolAttribute{ + Description: "If true, the instance will be rebooted to update network interfaces. " + + "This functionality is not affected by the `skip_implicit_reboots` provider argument.", + Optional: true, + Computed: true, + Default: booldefault.StaticBool(false), + }, + "reserved": schema.BoolAttribute{ + Description: "The reservation status of the IP address", + Computed: true, + }, + }, +} diff --git a/linode/instancereservedipassignment/resource_test.go b/linode/instancereservedipassignment/resource_test.go new file mode 100644 index 000000000..499b4bc28 --- /dev/null +++ b/linode/instancereservedipassignment/resource_test.go @@ -0,0 +1,58 @@ +//go:build integration || instancereservedipassignment + +package instancereservedipassignment_test + +import ( + "log" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" + "github.com/linode/terraform-provider-linode/v2/linode/instancereservedipassignment/tmpl" +) + +const testInstanceIPResName = "linode_reserved_ip_assignment.test" + +var testRegion string + +func init() { + region, err := acceptance.GetRandomRegionWithCaps(nil, "core") + if err != nil { + log.Fatal(err) + } + region = "us-east" + testRegion = region +} + +func TestAccInstanceIP_addReservedIP(t *testing.T) { + acceptance.OptInTest(t) + t.Parallel() + + var instance linodego.Instance + name := acctest.RandomWithPrefix("tf_test") + reservedIP := "50.116.48.7223" // Replace with your actual reserved IP address + resource.Test(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, + CheckDestroy: acceptance.CheckInstanceDestroy, + Steps: []resource.TestStep{ + { + Config: tmpl.AddReservedIP(t, name, testRegion, reservedIP), + Check: resource.ComposeTestCheckFunc( + acceptance.CheckInstanceExists("linode_instance.foobar", &instance), + resource.TestCheckResourceAttr(testInstanceIPResName, "address", reservedIP), + resource.TestCheckResourceAttr(testInstanceIPResName, "public", "true"), + resource.TestCheckResourceAttrSet(testInstanceIPResName, "linode_id"), + resource.TestCheckResourceAttrSet(testInstanceIPResName, "gateway"), + resource.TestCheckResourceAttrSet(testInstanceIPResName, "subnet_mask"), + resource.TestCheckResourceAttrSet(testInstanceIPResName, "prefix"), + resource.TestCheckResourceAttrSet(testInstanceIPResName, "rdns"), + resource.TestCheckResourceAttr(testInstanceIPResName, "region", testRegion), + resource.TestCheckResourceAttr(testInstanceIPResName, "type", "ipv4"), + ), + }, + }, + }) +} diff --git a/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf b/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf new file mode 100644 index 000000000..bf6ce2a9e --- /dev/null +++ b/linode/instancereservedipassignment/tmpl/AddReservedIPToInstance.gotf @@ -0,0 +1,20 @@ +{{ define "instance_ip_add_reservedIP" }} + +{{ template "e2e_test_firewall" . }} + +resource "linode_instance" "foobar" { + label = "{{.Label}}" + group = "tf_test" + type = "g6-nanode-1" + region = "{{ .Region }}" + image = "linode/debian12" + firewall_id = linode_firewall.e2e_test_firewall.id +} + +resource "linode_reserved_ip_assignment" "test" { + linode_id = linode_instance.foobar.id + public = true + address = "{{ .Address}}" +} + +{{ end }} \ No newline at end of file diff --git a/linode/instancereservedipassignment/tmpl/template.go b/linode/instancereservedipassignment/tmpl/template.go new file mode 100644 index 000000000..2746e7d05 --- /dev/null +++ b/linode/instancereservedipassignment/tmpl/template.go @@ -0,0 +1,23 @@ +package tmpl + +import ( + "testing" + + "github.com/linode/terraform-provider-linode/v2/linode/acceptance" +) + +type TemplateData struct { + Label string + ApplyImmediately bool + Region string + Address string +} + +func AddReservedIP(t *testing.T, instanceLabel, region string, address string) string { + return acceptance.ExecuteTemplate(t, + "instance_ip_add_reservedIP", TemplateData{ + Label: instanceLabel, + Region: region, + Address: address, + }) +} diff --git a/linode/instancesharedips/tmpl/template.go b/linode/instancesharedips/tmpl/template.go index b4060ac9a..470551bcc 100644 --- a/linode/instancesharedips/tmpl/template.go +++ b/linode/instancesharedips/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func SingleNode(t *testing.T, instanceLabel, region string) string { +func SingleNode(t testing.TB, instanceLabel, region string) string { return acceptance.ExecuteTemplate(t, "instance_shared_ips_single_node", TemplateData{ Label: instanceLabel, @@ -19,7 +19,7 @@ func SingleNode(t *testing.T, instanceLabel, region string) string { }) } -func DualNode(t *testing.T, instanceLabel, region string) string { +func DualNode(t testing.TB, instanceLabel, region string) string { return acceptance.ExecuteTemplate(t, "instance_shared_ips_dual_node", TemplateData{ Label: instanceLabel, diff --git a/linode/instancetype/tmpl/template.go b/linode/instancetype/tmpl/template.go index e58f7c322..2e1175116 100644 --- a/linode/instancetype/tmpl/template.go +++ b/linode/instancetype/tmpl/template.go @@ -10,7 +10,7 @@ type TemplateData struct { ID string } -func DataBasic(t *testing.T, id string) string { +func DataBasic(t testing.TB, id string) string { return acceptance.ExecuteTemplate(t, "instance_type_data_basic", TemplateData{ ID: id, diff --git a/linode/instancetypes/tmpl/template.go b/linode/instancetypes/tmpl/template.go index b58686152..65a715238 100644 --- a/linode/instancetypes/tmpl/template.go +++ b/linode/instancetypes/tmpl/template.go @@ -6,22 +6,22 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "instance_types_data_basic", nil) } -func DataSubstring(t *testing.T) string { +func DataSubstring(t testing.TB) string { return acceptance.ExecuteTemplate(t, "instance_types_data_substring", nil) } -func DataRegex(t *testing.T) string { +func DataRegex(t testing.TB) string { return acceptance.ExecuteTemplate(t, "instance_types_data_regex", nil) } -func DataByClass(t *testing.T) string { +func DataByClass(t testing.TB) string { return acceptance.ExecuteTemplate(t, "instance_types_data_by_class", nil) } diff --git a/linode/ipv6range/resource_test.go b/linode/ipv6range/resource_test.go index e44cf7e0c..1e4b4e3de 100644 --- a/linode/ipv6range/resource_test.go +++ b/linode/ipv6range/resource_test.go @@ -24,11 +24,11 @@ const testRegion = "eu-central" func TestAccIPv6Range_basic(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 3, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 3, func(t *acceptance.WrappedT) { resName := "linode_ipv6_range.foobar" instLabel := acctest.RandomWithPrefix("tf_test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkIPv6RangeDestroy, @@ -62,11 +62,11 @@ func TestAccIPv6Range_basic(t *testing.T) { func TestAccIPv6Range_routeTarget(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 3, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 3, func(t *acceptance.WrappedT) { resName := "linode_ipv6_range.foobar" instLabel := acctest.RandomWithPrefix("tf_test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkIPv6RangeDestroy, @@ -115,7 +115,7 @@ func TestAccIPv6Range_noID(t *testing.T) { func TestAccIPv6Range_reassignment(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 3, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 3, func(t *acceptance.WrappedT) { resName := "linode_ipv6_range.foobar" instance1ResName := "linode_instance.foobar" instance2ResName := "linode_instance.foobar2" @@ -125,7 +125,7 @@ func TestAccIPv6Range_reassignment(t *testing.T) { var instance1 linodego.Instance var instance2 linodego.Instance - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkIPv6RangeDestroy, @@ -180,7 +180,7 @@ func TestAccIPv6Range_raceCondition(t *testing.T) { t.Parallel() // Occasionally IPv6 range deletions take a bit to replicate - acceptance.RunTestRetry(t, 3, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 3, func(t *acceptance.WrappedT) { instLabel := acctest.RandomWithPrefix("tf_test") resource.Test(t, resource.TestCase{ @@ -273,7 +273,7 @@ func checkIPv6RangeNoDuplicates(s *terraform.State) error { return nil } -func validateInstanceIPv6Assignments(t *testing.T, assignedID, unassignedID int) { +func validateInstanceIPv6Assignments(t testing.TB, assignedID, unassignedID int) { client := acceptance.TestAccProvider.Meta().(*helper.ProviderMeta).Client assignedNetworking, err := client.GetInstanceIPAddresses(context.Background(), assignedID) diff --git a/linode/ipv6range/tmpl/template.go b/linode/ipv6range/tmpl/template.go index dc96e4fff..9d46dd006 100644 --- a/linode/ipv6range/tmpl/template.go +++ b/linode/ipv6range/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label, region string) string { +func Basic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6range_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func Basic(t *testing.T, label, region string) string { }) } -func RouteTarget(t *testing.T, label, region string) string { +func RouteTarget(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6range_route_target", TemplateData{ Label: label, @@ -27,12 +27,12 @@ func RouteTarget(t *testing.T, label, region string) string { }) } -func NoID(t *testing.T) string { +func NoID(t testing.TB) string { return acceptance.ExecuteTemplate(t, "ipv6range_no_id", nil) } -func ReassignmentStep1(t *testing.T, label, region string) string { +func ReassignmentStep1(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6range_reassign_step1", TemplateData{ Label: label, @@ -40,7 +40,7 @@ func ReassignmentStep1(t *testing.T, label, region string) string { }) } -func ReassignmentStep2(t *testing.T, label, region string) string { +func ReassignmentStep2(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6range_reassign_step2", TemplateData{ Label: label, @@ -48,7 +48,7 @@ func ReassignmentStep2(t *testing.T, label, region string) string { }) } -func RaceCondition(t *testing.T, label, region string) string { +func RaceCondition(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6range_race_condition", TemplateData{ Label: label, @@ -56,7 +56,7 @@ func RaceCondition(t *testing.T, label, region string) string { }) } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6range_data_basic", TemplateData{ Label: label, diff --git a/linode/ipv6ranges/tmpl/template.go b/linode/ipv6ranges/tmpl/template.go index 6d169943a..4e793b911 100644 --- a/linode/ipv6ranges/tmpl/template.go +++ b/linode/ipv6ranges/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "ipv6ranges_data_basic", TemplateData{ Label: label, diff --git a/linode/kernel/tmpl/template.go b/linode/kernel/tmpl/template.go index 8a8ea2843..e7ba7ddc3 100644 --- a/linode/kernel/tmpl/template.go +++ b/linode/kernel/tmpl/template.go @@ -10,7 +10,7 @@ type TemplateData struct { ID string } -func DataBasic(t *testing.T, kernelID string) string { +func DataBasic(t testing.TB, kernelID string) string { return acceptance.ExecuteTemplate(t, "kernel_data_basic", TemplateData{ID: kernelID}) } diff --git a/linode/kernels/tmpl/template.go b/linode/kernels/tmpl/template.go index 81bec797c..139b7c71e 100644 --- a/linode/kernels/tmpl/template.go +++ b/linode/kernels/tmpl/template.go @@ -10,21 +10,21 @@ type TemplateData struct { Id string } -func DataBasic(t *testing.T, id string) string { +func DataBasic(t testing.TB, id string) string { return acceptance.ExecuteTemplate(t, "kernels_data_basic", TemplateData{ Id: id, }) } -func DataFilter(t *testing.T, id string) string { +func DataFilter(t testing.TB, id string) string { return acceptance.ExecuteTemplate(t, "kernels_data_filter", TemplateData{ Id: id, }) } -func DataFilterEmpty(t *testing.T, id string) string { +func DataFilterEmpty(t testing.TB, id string) string { return acceptance.ExecuteTemplate(t, "kernels_data_filter_empty", TemplateData{ Id: id, diff --git a/linode/lke/framework_datasource_test.go b/linode/lke/framework_datasource_test.go index 962ffbaa9..577cf72b3 100644 --- a/linode/lke/framework_datasource_test.go +++ b/linode/lke/framework_datasource_test.go @@ -16,9 +16,9 @@ const dataSourceClusterName = "data.linode_lke_cluster.test" func TestAccDataSourceLKECluster_taints_labels(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -48,9 +48,9 @@ func TestAccDataSourceLKECluster_taints_labels(t *testing.T) { func TestAccDataSourceLKECluster_basic(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -83,9 +83,9 @@ func TestAccDataSourceLKECluster_basic(t *testing.T) { func TestAccDataSourceLKECluster_autoscaler(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -118,12 +118,12 @@ func TestAccDataSourceLKECluster_autoscaler(t *testing.T) { func TestAccDataSourceLKECluster_controlPlane(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") testIPv4 := "0.0.0.0/0" testIPv6 := "2001:db8::/32" - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, diff --git a/linode/lke/framework_resource_test.go b/linode/lke/framework_resource_test.go index 72218b1b5..cd15798a6 100644 --- a/linode/lke/framework_resource_test.go +++ b/linode/lke/framework_resource_test.go @@ -128,7 +128,7 @@ func checkLKEExists(cluster *linodego.LKECluster) resource.TestCheckFunc { // waitForAllNodesReady waits for every Node in every NodePool of the LKE Cluster to be in // a ready state. -func waitForAllNodesReady(t *testing.T, cluster *linodego.LKECluster, pollInterval, timeout time.Duration) { +func waitForAllNodesReady(t testing.TB, cluster *linodego.LKECluster, pollInterval, timeout time.Duration) { t.Helper() ctx := context.Background() @@ -180,9 +180,9 @@ func TestSmokeTests_lke(t *testing.T) { func TestAccResourceLKECluster_basic_smoke(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -229,9 +229,9 @@ func TestAccResourceLKECluster_k8sUpgrade(t *testing.T) { var cluster linodego.LKECluster - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -295,10 +295,10 @@ func TestAccResourceLKECluster_basicUpdates(t *testing.T) { return nil }) - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") newClusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: providerMap, Steps: []resource.TestStep{ @@ -332,10 +332,10 @@ func TestAccResourceLKECluster_basicUpdates(t *testing.T) { func TestAccResourceLKECluster_poolUpdates(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") newClusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -379,9 +379,9 @@ func TestAccResourceLKECluster_removeUnmanagedPool(t *testing.T) { var cluster linodego.LKECluster - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -425,10 +425,10 @@ func TestAccResourceLKECluster_removeUnmanagedPool(t *testing.T) { func TestAccResourceLKECluster_autoScaler(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") // newClusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -500,14 +500,14 @@ func TestAccResourceLKECluster_autoScaler(t *testing.T) { func TestAccResourceLKECluster_controlPlane(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") testIPv4 := "0.0.0.0/0" testIPv6 := "2001:db8::/32" testIPv4Updated := "203.0.113.1" testIPv6Updated := "2001:db8:1234:abcd::/64" - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, @@ -606,9 +606,9 @@ func TestAccResourceLKECluster_implicitCount(t *testing.T) { func TestAccResourceLKEClusterNodePoolTaintsLabels(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, diff --git a/linode/lke/tmpl/template.go b/linode/lke/tmpl/template.go index ee508f6f3..c7af81f94 100644 --- a/linode/lke/tmpl/template.go +++ b/linode/lke/tmpl/template.go @@ -24,17 +24,17 @@ type TemplateData struct { Labels map[string]string } -func Basic(t *testing.T, name, version, region string) string { +func Basic(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_basic", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func Updates(t *testing.T, name, version, region string) string { +func Updates(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_updates", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func ManyPools(t *testing.T, name, k8sVersion, region string) string { +func ManyPools(t testing.TB, name, k8sVersion, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_many_pools", TemplateData{ Label: name, @@ -43,27 +43,27 @@ func ManyPools(t *testing.T, name, k8sVersion, region string) string { }) } -func ComplexPools(t *testing.T, name, version, region string) string { +func ComplexPools(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_complex_pools", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func Autoscaler(t *testing.T, name, version, region string) string { +func Autoscaler(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_autoscaler", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func AutoscalerUpdates(t *testing.T, name, version, region string) string { +func AutoscalerUpdates(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_autoscaler_updates", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func AutoscalerManyPools(t *testing.T, name, version, region string) string { +func AutoscalerManyPools(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_autoscaler_many_pools", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func ControlPlane(t *testing.T, name, version, region, ipv4, ipv6 string, ha, enabled bool) string { +func ControlPlane(t testing.TB, name, version, region, ipv4, ipv6 string, ha, enabled bool) string { return acceptance.ExecuteTemplate(t, "lke_cluster_control_plane", TemplateData{ Label: name, @@ -76,7 +76,7 @@ func ControlPlane(t *testing.T, name, version, region, ipv4, ipv6 string, ha, en }) } -func NoCount(t *testing.T, name, version, region string) string { +func NoCount(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_no_count", TemplateData{ Label: name, @@ -85,7 +85,7 @@ func NoCount(t *testing.T, name, version, region string) string { }) } -func AutoscalerNoCount(t *testing.T, name, version, region string) string { +func AutoscalerNoCount(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_autoscaler_no_count", TemplateData{ Label: name, @@ -94,17 +94,17 @@ func AutoscalerNoCount(t *testing.T, name, version, region string) string { }) } -func DataBasic(t *testing.T, name, version, region string) string { +func DataBasic(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_data_basic", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func DataAutoscaler(t *testing.T, name, version, region string) string { +func DataAutoscaler(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_data_autoscaler", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func DataControlPlane(t *testing.T, name, version, region, ipv4, ipv6 string, ha, enabled bool) string { +func DataControlPlane(t testing.TB, name, version, region, ipv4, ipv6 string, ha, enabled bool) string { return acceptance.ExecuteTemplate(t, "lke_cluster_data_control_plane", TemplateData{ Label: name, @@ -117,7 +117,7 @@ func DataControlPlane(t *testing.T, name, version, region, ipv4, ipv6 string, ha }) } -func DataTaintsLabels(t *testing.T, name, version, region string, taints []TaintData, labels map[string]string) string { +func DataTaintsLabels(t testing.TB, name, version, region string, taints []TaintData, labels map[string]string) string { return acceptance.ExecuteTemplate(t, "lke_cluster_data_taints_labels", TemplateData{ Label: name, diff --git a/linode/lkeclusters/datasource_test.go b/linode/lkeclusters/datasource_test.go index ce4932463..31d89d583 100644 --- a/linode/lkeclusters/datasource_test.go +++ b/linode/lkeclusters/datasource_test.go @@ -57,9 +57,9 @@ func TestAccDataSourceLKEClusters_basic(t *testing.T) { dataSourceName := "data.linode_lke_clusters.test" - acceptance.RunTestRetry(t, 2, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 2, func(t *acceptance.WrappedT) { clusterName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: acceptance.CheckLKEClusterDestroy, diff --git a/linode/lkeclusters/tmpl/template.go b/linode/lkeclusters/tmpl/template.go index a0857e903..ff944f614 100644 --- a/linode/lkeclusters/tmpl/template.go +++ b/linode/lkeclusters/tmpl/template.go @@ -13,12 +13,12 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, name, version, region string) string { +func DataBasic(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_clusters_data_basic", TemplateData{Label: name, K8sVersion: version, Region: region}) } -func DataFilter(t *testing.T, name, version, region string) string { +func DataFilter(t testing.TB, name, version, region string) string { return acceptance.ExecuteTemplate(t, "lke_clusters_data_filter", TemplateData{Label: name, K8sVersion: version, Region: region}) } diff --git a/linode/lkenodepool/framework_resource_test.go b/linode/lkenodepool/framework_resource_test.go index fff996e91..e95a223ed 100644 --- a/linode/lkenodepool/framework_resource_test.go +++ b/linode/lkenodepool/framework_resource_test.go @@ -451,7 +451,7 @@ func containsTagWithPrefix(pool linodego.LKENodePool, prefix string) bool { return false } -func createResourceConfig(t *testing.T, data *tmpl.TemplateData) string { +func createResourceConfig(t testing.TB, data *tmpl.TemplateData) string { return acceptanceTmpl.ProviderNoPoll(t) + tmpl.Generate(t, data) } diff --git a/linode/lkenodepool/tmpl/template.go b/linode/lkenodepool/tmpl/template.go index c9f1d3679..6251d36a7 100644 --- a/linode/lkenodepool/tmpl/template.go +++ b/linode/lkenodepool/tmpl/template.go @@ -27,6 +27,6 @@ type TemplateData struct { Labels map[string]string } -func Generate(t *testing.T, data *TemplateData) string { +func Generate(t testing.TB, data *TemplateData) string { return acceptance.ExecuteTemplate(t, "nodepool_template", *data) } diff --git a/linode/lketypes/tmpl/template.go b/linode/lketypes/tmpl/template.go index 687ebbe6b..0bcd46d93 100644 --- a/linode/lketypes/tmpl/template.go +++ b/linode/lketypes/tmpl/template.go @@ -6,7 +6,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "lke_types_data_basic", nil) } diff --git a/linode/lkeversions/tmpl/template.go b/linode/lkeversions/tmpl/template.go index 3a9f98fcb..17b4869f1 100644 --- a/linode/lkeversions/tmpl/template.go +++ b/linode/lkeversions/tmpl/template.go @@ -6,7 +6,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "lke_versions_data_basic", nil) } diff --git a/linode/nb/tmpl/template.go b/linode/nb/tmpl/template.go index c98bd22fd..5800f1d13 100644 --- a/linode/nb/tmpl/template.go +++ b/linode/nb/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, nodebalancer, region string) string { +func Basic(t testing.TB, nodebalancer, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_basic", TemplateData{ Label: nodebalancer, @@ -19,7 +19,7 @@ func Basic(t *testing.T, nodebalancer, region string) string { }) } -func Updates(t *testing.T, nodebalancer, region string) string { +func Updates(t testing.TB, nodebalancer, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_updates", TemplateData{ Label: nodebalancer, @@ -27,7 +27,7 @@ func Updates(t *testing.T, nodebalancer, region string) string { }) } -func DataBasic(t *testing.T, nodebalancer, region string) string { +func DataBasic(t testing.TB, nodebalancer, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_data_basic", TemplateData{ Label: nodebalancer, @@ -35,7 +35,7 @@ func DataBasic(t *testing.T, nodebalancer, region string) string { }) } -func DataFirewalls(t *testing.T, nodebalancer, region string) string { +func DataFirewalls(t testing.TB, nodebalancer, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_data_firewalls", TemplateData{ Label: nodebalancer, @@ -43,7 +43,7 @@ func DataFirewalls(t *testing.T, nodebalancer, region string) string { }) } -func Firewall(t *testing.T, nodebalancer, region string) string { +func Firewall(t testing.TB, nodebalancer, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_firewall", TemplateData{ Label: nodebalancer, @@ -51,7 +51,7 @@ func Firewall(t *testing.T, nodebalancer, region string) string { }) } -func FirewallUpdate(t *testing.T, nodebalancer, region string) string { +func FirewallUpdate(t testing.TB, nodebalancer, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_firewall_updates", TemplateData{ Label: nodebalancer, diff --git a/linode/nbconfig/tmpl/template.go b/linode/nbconfig/tmpl/template.go index 3cd106276..cd3deab62 100644 --- a/linode/nbconfig/tmpl/template.go +++ b/linode/nbconfig/tmpl/template.go @@ -105,7 +105,7 @@ type TemplateData struct { SSLKey string } -func Basic(t *testing.T, nodebalancerName, region string) string { +func Basic(t testing.TB, nodebalancerName, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_config_basic", TemplateData{ NodeBalancer: nodebalancer.TemplateData{ @@ -115,7 +115,7 @@ func Basic(t *testing.T, nodebalancerName, region string) string { }) } -func Updates(t *testing.T, nodebalancerName, region string) string { +func Updates(t testing.TB, nodebalancerName, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_config_updates", TemplateData{ NodeBalancer: nodebalancer.TemplateData{ @@ -125,7 +125,7 @@ func Updates(t *testing.T, nodebalancerName, region string) string { }) } -func SSL(t *testing.T, nodebalancerName, region, cert, privKey string) string { +func SSL(t testing.TB, nodebalancerName, region, cert, privKey string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_config_ssl", TemplateData{ SSLCert: cert, @@ -137,7 +137,7 @@ func SSL(t *testing.T, nodebalancerName, region, cert, privKey string) string { }) } -func ProxyProtocol(t *testing.T, nodebalancerName, region string) string { +func ProxyProtocol(t testing.TB, nodebalancerName, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_config_proxy_protocol", TemplateData{ NodeBalancer: nodebalancer.TemplateData{ @@ -147,7 +147,7 @@ func ProxyProtocol(t *testing.T, nodebalancerName, region string) string { }) } -func DataBasic(t *testing.T, nodebalancerName, region string) string { +func DataBasic(t testing.TB, nodebalancerName, region string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_config_data_basic", TemplateData{ NodeBalancer: nodebalancer.TemplateData{ diff --git a/linode/nbconfigs/tmpl/template.go b/linode/nbconfigs/tmpl/template.go index 4acfe870c..4f40987ac 100644 --- a/linode/nbconfigs/tmpl/template.go +++ b/linode/nbconfigs/tmpl/template.go @@ -12,7 +12,7 @@ type TemplateData struct { Port int } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "nb_configs_data_basic", TemplateData{ Label: label, @@ -20,7 +20,7 @@ func DataBasic(t *testing.T, label, region string) string { }) } -func DataFilter(t *testing.T, label, region string, port int) string { +func DataFilter(t testing.TB, label, region string, port int) string { return acceptance.ExecuteTemplate(t, "nb_configs_data_filter", TemplateData{ Label: label, diff --git a/linode/nbnode/framework_models.go b/linode/nbnode/framework_models.go index f34f9c574..d45c0ad89 100644 --- a/linode/nbnode/framework_models.go +++ b/linode/nbnode/framework_models.go @@ -1,12 +1,15 @@ package nbnode import ( + "strconv" + + "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" ) -type DataSourceModel struct { - ID types.Int64 `tfsdk:"id"` +type BaseModel struct { NodeBalancerID types.Int64 `tfsdk:"nodebalancer_id"` ConfigID types.Int64 `tfsdk:"config_id"` Label types.String `tfsdk:"label"` @@ -16,6 +19,11 @@ type DataSourceModel struct { Status types.String `tfsdk:"status"` } +type DataSourceModel struct { + ID types.Int64 `tfsdk:"id"` + BaseModel +} + func (data *DataSourceModel) ParseNodeBalancerNode(nbnode *linodego.NodeBalancerNode) { data.ID = types.Int64Value(int64(nbnode.ID)) data.NodeBalancerID = types.Int64Value(int64(nbnode.NodeBalancerID)) @@ -26,3 +34,83 @@ func (data *DataSourceModel) ParseNodeBalancerNode(nbnode *linodego.NodeBalancer data.Address = types.StringValue(nbnode.Address) data.Status = types.StringValue(nbnode.Status) } + +// TODO: consider merging two models when resource's ID change to int type +type ResourceModel struct { + ID types.String `tfsdk:"id"` + BaseModel +} + +func (data *ResourceModel) FlattenNodeBalancerNode( + nbnode *linodego.NodeBalancerNode, preserveKnown bool, +) { + data.ID = helper.KeepOrUpdateString(data.ID, strconv.Itoa(nbnode.ID), preserveKnown) + data.NodeBalancerID = helper.KeepOrUpdateInt64(data.NodeBalancerID, int64(nbnode.NodeBalancerID), preserveKnown) + data.ConfigID = helper.KeepOrUpdateInt64(data.ConfigID, int64(nbnode.ConfigID), preserveKnown) + data.Label = helper.KeepOrUpdateString(data.Label, nbnode.Label, preserveKnown) + data.Weight = helper.KeepOrUpdateInt64(data.Weight, int64(nbnode.Weight), preserveKnown) + data.Mode = helper.KeepOrUpdateString(data.Mode, string(nbnode.Mode), preserveKnown) + data.Address = helper.KeepOrUpdateString(data.Address, nbnode.Address, preserveKnown) + data.Status = helper.KeepOrUpdateString(data.Status, nbnode.Status, preserveKnown) +} + +func (data *ResourceModel) GetIDs(diags *diag.Diagnostics) (int, int, int) { + id := helper.StringToInt(data.ID.ValueString(), diags) + nodeBalancerID := helper.FrameworkSafeInt64ToInt(data.NodeBalancerID.ValueInt64(), diags) + configID := helper.FrameworkSafeInt64ToInt(data.ConfigID.ValueInt64(), diags) + + return id, nodeBalancerID, configID +} + +func (data *ResourceModel) GetCreateParameters(diags *diag.Diagnostics) (int, int, linodego.NodeBalancerNodeCreateOptions) { + nodeBalancerID := helper.FrameworkSafeInt64ToInt(data.NodeBalancerID.ValueInt64(), diags) + configID := helper.FrameworkSafeInt64ToInt(data.ConfigID.ValueInt64(), diags) + return nodeBalancerID, configID, data.GetCreateOptions(diags) +} + +func (plan *ResourceModel) GetCreateOptions(diags *diag.Diagnostics) linodego.NodeBalancerNodeCreateOptions { + weight := helper.FrameworkSafeInt64ToInt(plan.Weight.ValueInt64(), diags) + return linodego.NodeBalancerNodeCreateOptions{ + Address: plan.Address.ValueString(), + Label: plan.Label.ValueString(), + Weight: weight, + Mode: linodego.NodeMode(plan.Mode.ValueString()), + } +} + +func (plan *ResourceModel) GetUpdateOptions( + state ResourceModel, diags *diag.Diagnostics, +) (result linodego.NodeBalancerNodeUpdateOptions) { + if !plan.Address.Equal(state.Address) { + result.Address = plan.Address.ValueString() + } + + if !plan.Label.Equal(state.Label) { + result.Label = plan.Label.ValueString() + } + + if !plan.Weight.Equal(state.Weight) { + weight := helper.FrameworkSafeInt64ToInt(plan.Weight.ValueInt64(), diags) + if diags.HasError() { + return + } + result.Weight = weight + } + + if !plan.Mode.Equal(state.Mode) { + result.Mode = linodego.NodeMode(plan.Mode.ValueString()) + } + + return +} + +func (plan *ResourceModel) CopyFrom(state ResourceModel, preserveKnown bool) { + plan.ID = helper.KeepOrUpdateValue(plan.ID, state.ID, preserveKnown) + plan.NodeBalancerID = helper.KeepOrUpdateValue(plan.NodeBalancerID, state.NodeBalancerID, preserveKnown) + plan.ConfigID = helper.KeepOrUpdateValue(plan.ConfigID, state.ConfigID, preserveKnown) + plan.Label = helper.KeepOrUpdateValue(plan.Label, state.Label, preserveKnown) + plan.Weight = helper.KeepOrUpdateValue(plan.Weight, state.Weight, preserveKnown) + plan.Mode = helper.KeepOrUpdateValue(plan.Mode, state.Mode, preserveKnown) + plan.Address = helper.KeepOrUpdateValue(plan.Address, state.Address, preserveKnown) + plan.Status = helper.KeepOrUpdateValue(plan.Status, state.Status, preserveKnown) +} diff --git a/linode/nbnode/framework_resource.go b/linode/nbnode/framework_resource.go new file mode 100644 index 000000000..1e9b58025 --- /dev/null +++ b/linode/nbnode/framework_resource.go @@ -0,0 +1,263 @@ +package nbnode + +import ( + "context" + "fmt" + "strconv" + + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/linode/linodego" + "github.com/linode/terraform-provider-linode/v2/linode/helper" +) + +func NewResource() resource.Resource { + return &Resource{ + BaseResource: helper.NewBaseResource( + helper.BaseResourceConfig{ + Name: "linode_nodebalancer_node", + IDType: types.StringType, + Schema: &frameworkResourceSchema, + }, + ), + } +} + +type Resource struct { + helper.BaseResource +} + +func AddNodeResource(ctx context.Context, node linodego.NodeBalancerNode, resp *resource.CreateResponse, plan ResourceModel) { + resp.State.SetAttribute(ctx, path.Root("id"), types.StringValue(strconv.Itoa(node.ID))) +} + +func (r *Resource) Create( + ctx context.Context, + req resource.CreateRequest, + resp *resource.CreateResponse, +) { + tflog.Debug(ctx, "Create "+r.Config.Name) + + var plan ResourceModel + client := r.Meta.Client + + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + nodeBalancerID, configID, createOpts := plan.GetCreateParameters(&resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, "client.CreateNodeBalancerNode(...)", map[string]any{ + "options": createOpts, + }) + node, err := client.CreateNodeBalancerNode(ctx, nodeBalancerID, configID, createOpts) + if err != nil { + resp.Diagnostics.AddError("Failed to Create a Linode NodeBalancerNode", err.Error()) + return + } + + // Add resource to TF states earlier to prevent + // dangling resources (resources created but not managed by TF) + AddNodeResource(ctx, *node, resp, plan) + + ctx = tflog.SetField(ctx, "node_id", node.ID) + + plan.FlattenNodeBalancerNode(node, true) + + // IDs should always be overridden during creation (see #1085) + // TODO: Remove when Crossplane empty string ID issue is resolved + plan.ID = types.StringValue(strconv.Itoa(node.ID)) + + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *Resource) Read( + ctx context.Context, + req resource.ReadRequest, + resp *resource.ReadResponse, +) { + tflog.Debug(ctx, "Read "+r.Config.Name) + + client := r.Meta.Client + + var state ResourceModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + ctx = populateLogAttributes(ctx, state) + + // TODO: cleanup when Crossplane fixes it + if helper.FrameworkAttemptRemoveResourceForEmptyID(ctx, state.ID, resp) { + return + } + + id, nodeBalancerID, configID := state.GetIDs(&resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + node, err := client.GetNodeBalancerNode(ctx, nodeBalancerID, configID, id) + if err != nil { + if linodego.IsNotFound(err) { + resp.Diagnostics.AddWarning( + "The NodeBalancer Node No Longer Exists", + fmt.Sprintf( + "Removing Linode Token with ID %v from state because it no longer exists", id, + ), + ) + resp.State.RemoveResource(ctx) + return + } + resp.Diagnostics.AddError( + "Unable to Refresh the NodeBalancer Node", + fmt.Sprintf( + "Error finding the specified Linode Token: %s", + err.Error(), + ), + ) + return + } + + state.FlattenNodeBalancerNode(node, false) + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *Resource) Update( + ctx context.Context, + req resource.UpdateRequest, + resp *resource.UpdateResponse, +) { + tflog.Debug(ctx, "Update "+r.Config.Name) + + var plan, state ResourceModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + ctx = populateLogAttributes(ctx, state) + client := r.Meta.Client + + id, nodeBalancerID, configID := plan.GetIDs(&resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + updateOpts := plan.GetUpdateOptions(state, &resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + tflog.Debug(ctx, "client.UpdateNodeBalancerNode(...)", map[string]any{ + "options": updateOpts, + }) + node, err := client.UpdateNodeBalancerNode(ctx, nodeBalancerID, configID, id, updateOpts) + if err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf( + "Failed to Update Linode NodeBalancer %d Config %d Node %d", + nodeBalancerID, configID, id, + ), + err.Error(), + ) + return + } + + plan.FlattenNodeBalancerNode(node, true) + + plan.CopyFrom(state, true) + + // Workaround for Crossplane issue where ID is not + // properly populated in plan + // See TPT-2865 for more details + if plan.ID.ValueString() == "" { + plan.ID = state.ID + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...) +} + +func (r *Resource) Delete( + ctx context.Context, + req resource.DeleteRequest, + resp *resource.DeleteResponse, +) { + tflog.Debug(ctx, "Delete "+r.Config.Name) + + var state ResourceModel + + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + ctx = populateLogAttributes(ctx, state) + + client := r.Meta.Client + + id, nodeBalancerID, configID := state.GetIDs(&resp.Diagnostics) + if resp.Diagnostics.HasError() { + return + } + + tflog.Trace(ctx, "client.DeleteNodeBalancerNode(...)") + err := client.DeleteNodeBalancerNode(ctx, nodeBalancerID, configID, id) + if err != nil { + resp.Diagnostics.AddError( + fmt.Sprintf( + "Failed to Delete Linode NodeBalancer %d Config %d Node %d", + nodeBalancerID, configID, id, + ), + err.Error(), + ) + return + } +} + +func populateLogAttributes(ctx context.Context, model ResourceModel) context.Context { + return helper.SetLogFieldBulk(ctx, map[string]any{ + "nodebalancer_id": model.NodeBalancerID.ValueInt64(), + "config_id": model.ConfigID.ValueInt64(), + "id": model.ID.ValueString(), + }) +} + +func (r *Resource) ImportState( + ctx context.Context, + req resource.ImportStateRequest, + resp *resource.ImportStateResponse, +) { + tflog.Debug(ctx, "Import "+r.Config.Name) + + helper.ImportStateWithMultipleIDs( + ctx, + req, + resp, + []helper.ImportableID{ + { + Name: "nodebalancer_id", + TypeConverter: helper.IDTypeConverterInt64, + }, + { + Name: "config_id", + TypeConverter: helper.IDTypeConverterInt64, + }, + { + Name: "id", + TypeConverter: helper.IDTypeConverterString, + }, + }, + ) +} diff --git a/linode/nbnode/framework_resource_schema.go b/linode/nbnode/framework_resource_schema.go new file mode 100644 index 000000000..dadf6bdd0 --- /dev/null +++ b/linode/nbnode/framework_resource_schema.go @@ -0,0 +1,78 @@ +package nbnode + +import ( + "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "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" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" +) + +var frameworkResourceSchema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + Description: "The ID of the NodeBalancer node resource.", + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + }, + "nodebalancer_id": schema.Int64Attribute{ + Description: "The ID of the NodeBalancer to access.", + Required: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "config_id": schema.Int64Attribute{ + Description: "The ID of the NodeBalancerConfig to access.", + Required: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.RequiresReplace(), + }, + }, + "label": schema.StringAttribute{ + Description: "The label for this node. This is for display purposes only.", + Required: true, + }, + "address": schema.StringAttribute{ + Description: "The private IP Address and port (IP:PORT) where this backend can be reached. " + + "This must be a private IP address.", + Required: true, + }, + "weight": schema.Int64Attribute{ + Description: "Used when picking a backend to serve a request and is not pinned to a single backend " + + "yet. Nodes with a higher weight will receive more traffic. (1-255)", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Int64{ + int64planmodifier.UseStateForUnknown(), + }, + Validators: []validator.Int64{ + int64validator.Between(1, 255), + }, + }, + "mode": schema.StringAttribute{ + Description: "The mode this NodeBalancer should use when sending traffic to this backend. If set to " + + "`accept` this backend is accepting traffic. If set to `reject` this backend will not receive traffic. " + + "If set to `drain` this backend will not receive new traffic, but connections already pinned to it will " + + "continue to be routed to it. If set to `backup` this backend will only accept traffic if all other " + + "nodes are down.", + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Validators: []validator.String{ + stringvalidator.OneOf("accept", "reject", "drain", "backup"), + }, + }, + "status": schema.StringAttribute{ + Description: "The current status of this node, based on the configured checks of its NodeBalancer " + + "Config. (unknown, UP, DOWN)", + Computed: true, + }, + }, +} diff --git a/linode/nbnode/resource.go b/linode/nbnode/resource.go deleted file mode 100644 index fdfab6cec..000000000 --- a/linode/nbnode/resource.go +++ /dev/null @@ -1,214 +0,0 @@ -package nbnode - -import ( - "context" - "fmt" - "log" - "strconv" - "strings" - - "github.com/hashicorp/terraform-plugin-log/tflog" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/linode/linodego" - "github.com/linode/terraform-provider-linode/v2/linode/helper" -) - -func Resource() *schema.Resource { - return &schema.Resource{ - Schema: resourceSchema, - ReadContext: readResource, - CreateContext: createResource, - UpdateContext: updateResource, - DeleteContext: deleteResource, - Importer: &schema.ResourceImporter{ - StateContext: importResource, - }, - } -} - -func readResource(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - ctx = populateLogAttributes(ctx, d) - tflog.Debug(ctx, "Read linode_nb_node") - - client := meta.(*helper.ProviderMeta).Client - id, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.Errorf("Error parsing Linode NodeBalancerNode ID %s as int: %s", d.Id(), err) - } - nodebalancerID, ok := d.Get("nodebalancer_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("nodebalancer_id")) - } - configID, ok := d.Get("config_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("config_id")) - } - - node, err := client.GetNodeBalancerNode(ctx, nodebalancerID, configID, id) - if err != nil { - if lerr, ok := err.(*linodego.Error); ok && lerr.Code == 404 { - log.Printf("[WARN] removing NodeBalancer Node ID %q from state because it no longer exists", d.Id()) - d.SetId("") - return nil - } - - return diag.Errorf("Error finding the specified Linode NodeBalancerNode: %s", err) - } - - d.Set("label", node.Label) - d.Set("weight", node.Weight) - d.Set("mode", node.Mode) - d.Set("address", node.Address) - d.Set("status", node.Status) - return nil -} - -func importResource(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - if strings.Contains(d.Id(), ",") { - s := strings.Split(d.Id(), ",") - // Validate that this is an ID by making sure it can be converted into an int - _, err := strconv.Atoi(s[2]) - if err != nil { - return nil, fmt.Errorf("invalid nodebalancer_node ID: %v", err) - } - - configID, err := strconv.Atoi(s[1]) - if err != nil { - return nil, fmt.Errorf("invalid config ID: %v", err) - } - - nodebalancerID, err := strconv.Atoi(s[0]) - if err != nil { - return nil, fmt.Errorf("invalid nodebalancer ID: %v", err) - } - - d.SetId(s[2]) - d.Set("nodebalancer_id", nodebalancerID) - d.Set("config_id", configID) - } - - err := readResource(ctx, d, meta) - if err != nil { - return nil, fmt.Errorf("unable to import %v as nodebalancer_node: %v", d.Id(), err) - } - - results := make([]*schema.ResourceData, 0) - results = append(results, d) - - return results, nil -} - -func createResource(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - ctx = populateLogAttributes(ctx, d) - tflog.Debug(ctx, "Create linode_nb_node") - - client := meta.(*helper.ProviderMeta).Client - - nodebalancerID, ok := d.Get("nodebalancer_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("nodebalancer_id")) - } - configID, ok := d.Get("config_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("config_id")) - } - - createOpts := linodego.NodeBalancerNodeCreateOptions{ - Address: d.Get("address").(string), - Label: d.Get("label").(string), - Mode: linodego.NodeMode(d.Get("mode").(string)), - Weight: d.Get("weight").(int), - } - - tflog.Debug(ctx, "client.CreateNodeBalancerNode(...)", map[string]any{ - "options": createOpts, - }) - - node, err := client.CreateNodeBalancerNode(ctx, nodebalancerID, configID, createOpts) - if err != nil { - return diag.Errorf("Error creating a Linode NodeBalancerNode: %s", err) - } - - ctx = tflog.SetField(ctx, "node_id", node.ID) - - d.SetId(fmt.Sprintf("%d", node.ID)) - d.Set("config_id", configID) - d.Set("nodebalancer_id", nodebalancerID) - - return readResource(ctx, d, meta) -} - -func updateResource(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - ctx = populateLogAttributes(ctx, d) - tflog.Debug(ctx, "Update linode_nb_node") - - client := meta.(*helper.ProviderMeta).Client - - id, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.Errorf("Error parsing Linode NodeBalancerConfig ID %v as int: %s", d.Id(), err) - } - nodebalancerID, ok := d.Get("nodebalancer_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("nodebalancer_id")) - } - configID, ok := d.Get("config_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("config_id")) - } - - updateOpts := linodego.NodeBalancerNodeUpdateOptions{ - Address: d.Get("address").(string), - Label: d.Get("label").(string), - Mode: linodego.NodeMode(d.Get("mode").(string)), - Weight: d.Get("weight").(int), - } - - tflog.Debug(ctx, "client.UpdateNodeBalancerNode(...)", map[string]any{ - "options": updateOpts, - }) - - if _, err = client.UpdateNodeBalancerNode(ctx, nodebalancerID, configID, id, updateOpts); err != nil { - return diag.Errorf("Error updating Linode Nodebalancer %d Config %d Node %d: %s", - nodebalancerID, configID, id, err) - } - - return readResource(ctx, d, meta) -} - -func deleteResource(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - ctx = populateLogAttributes(ctx, d) - tflog.Debug(ctx, "Update linode_nb_node") - - client := meta.(*helper.ProviderMeta).Client - id, err := strconv.Atoi(d.Id()) - if err != nil { - return diag.Errorf("Error parsing Linode NodeBalancerConfig ID %s as int: %s", d.Id(), err) - } - nodebalancerID, ok := d.Get("nodebalancer_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("nodebalancer_id")) - } - configID, ok := d.Get("config_id").(int) - if !ok { - return diag.Errorf("Error parsing Linode NodeBalancer ID %v as int", d.Get("config_id")) - } - - tflog.Trace(ctx, "client.DeleteNodeBalancerNode(...)") - - err = client.DeleteNodeBalancerNode(ctx, nodebalancerID, configID, id) - if err != nil { - return diag.Errorf("Error deleting Linode NodeBalancerNode %d: %s", id, err) - } - return nil -} - -func populateLogAttributes(ctx context.Context, d *schema.ResourceData) context.Context { - return helper.SetLogFieldBulk(ctx, map[string]any{ - "nodebalancer_id": d.Get("nodebalancer_id").(int), - "config_id": d.Get("config_id").(int), - "id": d.Id(), - }) -} diff --git a/linode/nbnode/schema_resource.go b/linode/nbnode/schema_resource.go deleted file mode 100644 index a07c73f9c..000000000 --- a/linode/nbnode/schema_resource.go +++ /dev/null @@ -1,57 +0,0 @@ -package nbnode - -import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" -) - -var resourceSchema = map[string]*schema.Schema{ - "nodebalancer_id": { - Type: schema.TypeInt, - Description: "The ID of the NodeBalancer to access.", - Required: true, - ForceNew: true, - }, - "config_id": { - Type: schema.TypeInt, - Description: "The ID of the NodeBalancerConfig to access.", - Required: true, - ForceNew: true, - }, - "label": { - Type: schema.TypeString, - Description: "The label for this node. This is for display purposes only.", - Required: true, - }, - "weight": { - Type: schema.TypeInt, - Description: "Used when picking a backend to serve a request and is not pinned to a single backend " + - "yet. Nodes with a higher weight will receive more traffic. (1-255)", - ValidateFunc: validation.IntBetween(1, 255), - Optional: true, - Computed: true, - }, - "mode": { - Type: schema.TypeString, - Description: "The mode this NodeBalancer should use when sending traffic to this backend. If set to " + - "`accept` this backend is accepting traffic. If set to `reject` this backend will not receive traffic. " + - "If set to `drain` this backend will not receive new traffic, but connections already pinned to it will " + - "continue to be routed to it. If set to `backup` this backend will only accept traffic if all other " + - "nodes are down.", - ValidateFunc: validation.StringInSlice([]string{"accept", "reject", "drain", "backup"}, false), - Optional: true, - Computed: true, - }, - "address": { - Type: schema.TypeString, - Description: "The private IP Address and port (IP:PORT) where this backend can be reached. " + - "This must be a private IP address.", - Required: true, - }, - "status": { - Type: schema.TypeString, - Description: "The current status of this node, based on the configured checks of its NodeBalancer " + - "Config. (unknown, UP, DOWN)", - Computed: true, - }, -} diff --git a/linode/nbnode/tmpl/template.go b/linode/nbnode/tmpl/template.go index 883f1fa50..ac07e68a1 100644 --- a/linode/nbnode/tmpl/template.go +++ b/linode/nbnode/tmpl/template.go @@ -21,7 +21,7 @@ type InstanceTemplateData struct { RootPass string } -func Basic(t *testing.T, nodebalancer, region string, rootPass string) string { +func Basic(t testing.TB, nodebalancer, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_node_basic", TemplateData{ @@ -41,7 +41,7 @@ func Basic(t *testing.T, nodebalancer, region string, rootPass string) string { }) } -func Updates(t *testing.T, nodebalancer, region string, rootPass string) string { +func Updates(t testing.TB, nodebalancer, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_node_updates", TemplateData{ @@ -61,7 +61,7 @@ func Updates(t *testing.T, nodebalancer, region string, rootPass string) string }) } -func DataBasic(t *testing.T, nodebalancer, region string, rootPass string) string { +func DataBasic(t testing.TB, nodebalancer, region string, rootPass string) string { return acceptance.ExecuteTemplate(t, "nodebalancer_node_data_basic", TemplateData{ diff --git a/linode/nbs/tmpl/template.go b/linode/nbs/tmpl/template.go index 2b94baa08..9b6b46b89 100644 --- a/linode/nbs/tmpl/template.go +++ b/linode/nbs/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "nbs_data_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func DataBasic(t *testing.T, label, region string) string { }) } -func DataFilterEmpty(t *testing.T, label, region string) string { +func DataFilterEmpty(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "nbs_data_filter_empty", TemplateData{ Label: label, @@ -27,7 +27,7 @@ func DataFilterEmpty(t *testing.T, label, region string) string { }) } -func DataFilter(t *testing.T, label, region string) string { +func DataFilter(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "nbs_data_filter", TemplateData{ Label: label, @@ -35,7 +35,7 @@ func DataFilter(t *testing.T, label, region string) string { }) } -func DataOrder(t *testing.T, label, region string) string { +func DataOrder(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "nbs_data_order", TemplateData{ Label: label, diff --git a/linode/nbtypes/tmpl/template.go b/linode/nbtypes/tmpl/template.go index b57ade428..eea47f665 100644 --- a/linode/nbtypes/tmpl/template.go +++ b/linode/nbtypes/tmpl/template.go @@ -6,7 +6,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "nb_types_data_basic", nil) } diff --git a/linode/networkingip/tmpl/template.go b/linode/networkingip/tmpl/template.go index b0e78e177..84f28951a 100644 --- a/linode/networkingip/tmpl/template.go +++ b/linode/networkingip/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "networking_ip_data_basic", TemplateData{Label: label, Region: region}) } diff --git a/linode/networktransferprices/tmpl/template.go b/linode/networktransferprices/tmpl/template.go index fe21d70d6..33e57f8b8 100644 --- a/linode/networktransferprices/tmpl/template.go +++ b/linode/networktransferprices/tmpl/template.go @@ -6,7 +6,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "network_transfer_prices_data_basic", nil) } diff --git a/linode/obj/resource_test.go b/linode/obj/resource_test.go index 95de2fa79..5a51a4f4c 100644 --- a/linode/obj/resource_test.go +++ b/linode/obj/resource_test.go @@ -60,11 +60,11 @@ func TestAccResourceObject_basic_cluster(t *testing.T) { contentSource := acceptance.CreateTempFile(t, "tf-test-obj-source", content) contentSourceUpdated := acceptance.CreateTempFile(t, "tf-test-obj-source-updated", contentUpdated) - acceptance.RunTestRetry(t, 6, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 6, func(t *acceptance.WrappedT) { bucketName := acctest.RandomWithPrefix("tf-test") keyName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkObjectDestroy, @@ -115,11 +115,11 @@ func TestAccResourceObject_basic(t *testing.T) { contentSource := acceptance.CreateTempFile(t, "tf-test-obj-source", content) contentSourceUpdated := acceptance.CreateTempFile(t, "tf-test-obj-source-updated", contentUpdated) - acceptance.RunTestRetry(t, 6, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 6, func(t *acceptance.WrappedT) { bucketName := acctest.RandomWithPrefix("tf-test") keyName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkObjectDestroy, @@ -150,11 +150,11 @@ func TestAccResourceObject_credsConfiged(t *testing.T) { content := "test_creds_configed" - acceptance.RunTestRetry(t, 6, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 6, func(t *acceptance.WrappedT) { bucketName := acctest.RandomWithPrefix("tf-test") keyName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkObjectDestroy, @@ -175,11 +175,11 @@ func TestAccResourceObject_tempKeys(t *testing.T) { content := "test_temp_keys" - acceptance.RunTestRetry(t, 6, func(tRetry *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 6, func(t *acceptance.WrappedT) { bucketName := acctest.RandomWithPrefix("tf-test") keyName := acctest.RandomWithPrefix("tf_test") - resource.Test(tRetry, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkObjectDestroy, diff --git a/linode/obj/tmpl/template.go b/linode/obj/tmpl/template.go index 18e7c5558..0a93e586c 100644 --- a/linode/obj/tmpl/template.go +++ b/linode/obj/tmpl/template.go @@ -18,7 +18,7 @@ type TemplateData struct { Source string } -func BasicWithCluster(t *testing.T, name, cluster, keyName, content, source string) string { +func BasicWithCluster(t testing.TB, name, cluster, keyName, content, source string) string { return acceptance.ExecuteTemplate(t, "object_object_basic", TemplateData{ Bucket: objectbucket.TemplateData{Label: name, Cluster: cluster}, @@ -29,7 +29,7 @@ func BasicWithCluster(t *testing.T, name, cluster, keyName, content, source stri }) } -func Basic(t *testing.T, name, region, keyName, content, source string) string { +func Basic(t testing.TB, name, region, keyName, content, source string) string { return acceptance.ExecuteTemplate(t, "object_object_basic", TemplateData{ Bucket: objectbucket.TemplateData{Label: name, Region: region}, @@ -40,7 +40,7 @@ func Basic(t *testing.T, name, region, keyName, content, source string) string { }) } -func Updates(t *testing.T, name, region, keyName, content, source string) string { +func Updates(t testing.TB, name, region, keyName, content, source string) string { return acceptance.ExecuteTemplate(t, "object_object_updates", TemplateData{ Bucket: objectbucket.TemplateData{Label: name, Region: region}, @@ -51,7 +51,7 @@ func Updates(t *testing.T, name, region, keyName, content, source string) string }) } -func CredsConfiged(t *testing.T, name, region, keyName, content string) string { +func CredsConfiged(t testing.TB, name, region, keyName, content string) string { return acceptance.ExecuteTemplate(t, "object_object_creds_configed", TemplateData{ Bucket: objectbucket.TemplateData{Label: name, Region: region}, @@ -61,7 +61,7 @@ func CredsConfiged(t *testing.T, name, region, keyName, content string) string { }) } -func TempKeys(t *testing.T, name, region, keyName, content string) string { +func TempKeys(t testing.TB, name, region, keyName, content string) string { return acceptance.ExecuteTemplate(t, "object_object_temp_keys", TemplateData{ Bucket: objectbucket.TemplateData{Label: name, Region: region}, diff --git a/linode/objbucket/datasource_test.go b/linode/objbucket/datasource_test.go index ac9d903ad..02003dd02 100644 --- a/linode/objbucket/datasource_test.go +++ b/linode/objbucket/datasource_test.go @@ -17,8 +17,8 @@ func TestAccDataSourceBucket_basic(t *testing.T) { resourceName := "data.linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -47,8 +47,8 @@ func TestAccDataSourceBucket_basic_cluster(t *testing.T) { resourceName := "data.linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, diff --git a/linode/objbucket/resource_test.go b/linode/objbucket/resource_test.go index 95c22d4f3..972245368 100644 --- a/linode/objbucket/resource_test.go +++ b/linode/objbucket/resource_test.go @@ -188,11 +188,11 @@ func TestSmokeTests_objbucket(t *testing.T) { func TestAccResourceBucket_basic_legacy_smoke(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { resName := "linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -218,11 +218,11 @@ func TestAccResourceBucket_basic_legacy_smoke(t *testing.T) { func TestAccResourceBucket_basic_smoke(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { resName := "linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -248,11 +248,11 @@ func TestAccResourceBucket_basic_smoke(t *testing.T) { func TestAccResourceBucket_access(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { resName := "linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -283,12 +283,12 @@ func TestAccResourceBucket_access(t *testing.T) { func TestAccResourceBucket_versioning(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { resName := "linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") objectStorageKeyName := acctest.RandomWithPrefix("tf-test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -317,12 +317,12 @@ func TestAccResourceBucket_versioning(t *testing.T) { func TestAccResourceBucket_lifecycle(t *testing.T) { t.Parallel() - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { resName := "linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") objectStorageKeyName := acctest.RandomWithPrefix("tf-test") - resource.Test(retryT, resource.TestCase{ + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -378,8 +378,8 @@ func TestAccResourceBucket_lifecycleNoID(t *testing.T) { objectStorageBucketName := acctest.RandomWithPrefix("tf-test") objectStorageKeyName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -424,8 +424,8 @@ func TestAccResourceBucket_cert(t *testing.T) { t.Fatal(err) } - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -469,8 +469,8 @@ func TestAccResourceBucket_dataSource(t *testing.T) { resName := "linode_object_storage_bucket.foobar" objectStorageBucketName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -498,8 +498,8 @@ func TestAccResourceBucket_update(t *testing.T) { objectStorageBucketName := acctest.RandomWithPrefix("tf-test") resName := "linode_object_storage_bucket.foobar" - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -530,8 +530,8 @@ func TestAccResourceBucket_credsConfiged(t *testing.T) { objectStorageBucketName := acctest.RandomWithPrefix("tf-test") objectStorageKeyName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -557,8 +557,8 @@ func TestAccResourceBucket_tempKeys(t *testing.T) { objectStorageBucketName := acctest.RandomWithPrefix("tf-test") objectStorageKeyName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -584,8 +584,8 @@ func TestAccResourceBucket_forceDelete(t *testing.T) { objectStorageBucketName := acctest.RandomWithPrefix("tf-test") objectStorageKeyName := acctest.RandomWithPrefix("tf-test") - acceptance.RunTestRetry(t, 5, func(retryT *acceptance.TRetry) { - resource.Test(retryT, resource.TestCase{ + acceptance.RunTestWithRetries(t, 5, func(t *acceptance.WrappedT) { + resource.Test(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, ProtoV5ProviderFactories: acceptance.ProtoV5ProviderFactories, CheckDestroy: checkBucketDestroy, @@ -612,19 +612,19 @@ func TestAccResourceBucket_forceDelete(t *testing.T) { keys, err := client.CreateObjectStorageKey(context.Background(), createOpts) if err != nil { - retryT.Errorf("error creating obj keys in PreConfig func: %v", err) + t.Errorf("error creating obj keys in PreConfig func: %v", err) } defer client.DeleteObjectStorageKey(context.Background(), keys.ID) bucket, err := client.GetObjectStorageBucket(context.Background(), testRegion, objectStorageBucketName) if err != nil { - retryT.Errorf("error getting obj bucket in PreConfig func: %v", err) + t.Errorf("error getting obj bucket in PreConfig func: %v", err) } endpoint := helper.ComputeS3EndpointFromBucket(context.Background(), *bucket) s3client, err := helper.S3Connection(context.Background(), endpoint, keys.AccessKey, keys.SecretKey) if err != nil { - retryT.Errorf("error connecting s3 in PreConfig func: %v", err) + t.Errorf("error connecting s3 in PreConfig func: %v", err) } contentBytes := []byte("delete test") diff --git a/linode/objbucket/tmpl/template.go b/linode/objbucket/tmpl/template.go index 5f86ef797..d92c4e48b 100644 --- a/linode/objbucket/tmpl/template.go +++ b/linode/objbucket/tmpl/template.go @@ -21,22 +21,22 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label, region string) string { +func Basic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "object_bucket_basic", TemplateData{Label: label, Region: region}) } -func BasicLegacy(t *testing.T, label, cluster string) string { +func BasicLegacy(t testing.TB, label, cluster string) string { return acceptance.ExecuteTemplate(t, "object_bucket_basic", TemplateData{Label: label, Cluster: cluster}) } -func Updates(t *testing.T, label, region string) string { +func Updates(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "object_bucket_updates", TemplateData{Label: label, Region: region}) } -func Access(t *testing.T, label, cluster, acl string, cors bool) string { +func Access(t testing.TB, label, cluster, acl string, cors bool) string { return acceptance.ExecuteTemplate(t, "object_bucket_access", TemplateData{ Label: label, @@ -46,7 +46,7 @@ func Access(t *testing.T, label, cluster, acl string, cors bool) string { }) } -func Cert(t *testing.T, label, region, cert, privKey string) string { +func Cert(t testing.TB, label, region, cert, privKey string) string { return acceptance.ExecuteTemplate(t, "object_bucket_cert", TemplateData{ Label: label, @@ -56,7 +56,7 @@ func Cert(t *testing.T, label, region, cert, privKey string) string { }) } -func Versioning(t *testing.T, label, cluster, keyName string, versioning bool) string { +func Versioning(t testing.TB, label, cluster, keyName string, versioning bool) string { return acceptance.ExecuteTemplate(t, "object_bucket_versioning", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -66,7 +66,7 @@ func Versioning(t *testing.T, label, cluster, keyName string, versioning bool) s }) } -func LifeCycle(t *testing.T, label, cluster, keyName string) string { +func LifeCycle(t testing.TB, label, cluster, keyName string) string { return acceptance.ExecuteTemplate(t, "object_bucket_lifecycle", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -75,7 +75,7 @@ func LifeCycle(t *testing.T, label, cluster, keyName string) string { }) } -func LifeCycleNoID(t *testing.T, label, cluster, keyName string) string { +func LifeCycleNoID(t testing.TB, label, cluster, keyName string) string { return acceptance.ExecuteTemplate(t, "object_bucket_lifecycle_no_id", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -84,7 +84,7 @@ func LifeCycleNoID(t *testing.T, label, cluster, keyName string) string { }) } -func LifeCycleUpdates(t *testing.T, label, cluster, keyName string) string { +func LifeCycleUpdates(t testing.TB, label, cluster, keyName string) string { return acceptance.ExecuteTemplate(t, "object_bucket_lifecycle_updates", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -93,7 +93,7 @@ func LifeCycleUpdates(t *testing.T, label, cluster, keyName string) string { }) } -func LifeCycleRemoved(t *testing.T, label, cluster, keyName string) string { +func LifeCycleRemoved(t testing.TB, label, cluster, keyName string) string { return acceptance.ExecuteTemplate(t, "object_bucket_lifecycle_removed", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -102,7 +102,7 @@ func LifeCycleRemoved(t *testing.T, label, cluster, keyName string) string { }) } -func TempKeys(t *testing.T, label, cluster, keyName string) string { +func TempKeys(t testing.TB, label, cluster, keyName string) string { return acceptance.ExecuteTemplate(t, "object_bucket_temp_keys", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -111,7 +111,7 @@ func TempKeys(t *testing.T, label, cluster, keyName string) string { }) } -func ForceDelete(t *testing.T, label, region string) string { +func ForceDelete(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "object_bucket_force_delete", TemplateData{ Label: label, @@ -119,11 +119,11 @@ func ForceDelete(t *testing.T, label, region string) string { }) } -func ForceDelete_Empty(t *testing.T) string { +func ForceDelete_Empty(t testing.TB) string { return acceptance.ExecuteTemplate(t, "object_bucket_force_delete_empty", nil) } -func ClusterDataBasic(t *testing.T, label, cluster string) string { +func ClusterDataBasic(t testing.TB, label, cluster string) string { return acceptance.ExecuteTemplate(t, "object_bucket_cluster_data_basic", TemplateData{ Label: label, @@ -131,7 +131,7 @@ func ClusterDataBasic(t *testing.T, label, cluster string) string { }) } -func CredsConfiged(t *testing.T, label, cluster, keyName string) string { +func CredsConfiged(t testing.TB, label, cluster, keyName string) string { return acceptance.ExecuteTemplate(t, "object_bucket_creds_configed", TemplateData{ Key: objkey.TemplateData{Label: keyName}, @@ -140,7 +140,7 @@ func CredsConfiged(t *testing.T, label, cluster, keyName string) string { }) } -func DataBasicWithCluster(t *testing.T, label, cluster string) string { +func DataBasicWithCluster(t testing.TB, label, cluster string) string { return acceptance.ExecuteTemplate(t, "object_bucket_data_basic", TemplateData{ Label: label, @@ -148,7 +148,7 @@ func DataBasicWithCluster(t *testing.T, label, cluster string) string { }) } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "object_bucket_data_basic", TemplateData{ Label: label, diff --git a/linode/objcluster/tmpl/template.go b/linode/objcluster/tmpl/template.go index 71c424343..402c1c852 100644 --- a/linode/objcluster/tmpl/template.go +++ b/linode/objcluster/tmpl/template.go @@ -10,7 +10,7 @@ type TemplateData struct { ID string } -func DataBasic(t *testing.T, id string) string { +func DataBasic(t testing.TB, id string) string { return acceptance.ExecuteTemplate(t, "obj_cluster_data_basic", TemplateData{ID: id}) } diff --git a/linode/objkey/tmpl/template.go b/linode/objkey/tmpl/template.go index 6d559027d..85b6dc531 100644 --- a/linode/objkey/tmpl/template.go +++ b/linode/objkey/tmpl/template.go @@ -12,22 +12,22 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label string) string { +func Basic(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "object_key_basic", TemplateData{Label: label}) } -func Updates(t *testing.T, label string) string { +func Updates(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "object_key_updates", TemplateData{Label: label}) } -func ClusterLimited(t *testing.T, label, cluster string) string { +func ClusterLimited(t testing.TB, label, cluster string) string { return acceptance.ExecuteTemplate(t, "object_key_limited", TemplateData{Label: label, Cluster: cluster}) } -func Limited(t *testing.T, label, region string) string { +func Limited(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "object_key_limited", TemplateData{Label: label, Region: region}) } diff --git a/linode/placementgroup/tmpl/template.go b/linode/placementgroup/tmpl/template.go index 90e779b1d..591ae1dbd 100644 --- a/linode/placementgroup/tmpl/template.go +++ b/linode/placementgroup/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { PlacementGroupPolicy string } -func DataBasic(t *testing.T, label, region, placementGroupType string, placementGroupPolicy string) string { +func DataBasic(t testing.TB, label, region, placementGroupType string, placementGroupPolicy string) string { return acceptance.ExecuteTemplate(t, "placement_group_data_basic", TemplateData{ Label: label, @@ -23,7 +23,7 @@ func DataBasic(t *testing.T, label, region, placementGroupType string, placement }) } -func Basic(t *testing.T, label, region, placementGroupType string, placementGroupPolicy string) string { +func Basic(t testing.TB, label, region, placementGroupType string, placementGroupPolicy string) string { return acceptance.ExecuteTemplate(t, "placement_group_basic", TemplateData{ Label: label, diff --git a/linode/placementgroupassignment/tmpl/template.go b/linode/placementgroupassignment/tmpl/template.go index 5c6db4dcd..9100adb2c 100644 --- a/linode/placementgroupassignment/tmpl/template.go +++ b/linode/placementgroupassignment/tmpl/template.go @@ -12,7 +12,7 @@ type TemplateData struct { AssignmentExists bool } -func Basic(t *testing.T, label, region string, assignmentExists bool) string { +func Basic(t testing.TB, label, region string, assignmentExists bool) string { return acceptance.ExecuteTemplate(t, "placement_group_assignment_basic", TemplateData{ Label: label, diff --git a/linode/placementgroups/tmpl/template.go b/linode/placementgroups/tmpl/template.go index 3850398fb..1dbf3a58a 100644 --- a/linode/placementgroups/tmpl/template.go +++ b/linode/placementgroups/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "placement_groups_data_basic", TemplateData{ Label: label, diff --git a/linode/profile/tmpl/template.go b/linode/profile/tmpl/template.go index 447257965..77fb7f656 100644 --- a/linode/profile/tmpl/template.go +++ b/linode/profile/tmpl/template.go @@ -8,7 +8,7 @@ import ( type TemplateData struct{} -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "profile_data_basic", nil) } diff --git a/linode/provider.go b/linode/provider.go index 8a9fcbf56..0bd899a11 100644 --- a/linode/provider.go +++ b/linode/provider.go @@ -20,7 +20,6 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/instance" "github.com/linode/terraform-provider-linode/v2/linode/instanceconfig" "github.com/linode/terraform-provider-linode/v2/linode/lke" - "github.com/linode/terraform-provider-linode/v2/linode/nbnode" "github.com/linode/terraform-provider-linode/v2/linode/obj" "github.com/linode/terraform-provider-linode/v2/linode/objbucket" "github.com/linode/terraform-provider-linode/v2/linode/user" @@ -155,7 +154,6 @@ func Provider() *schema.Provider { "linode_instance": instance.Resource(), "linode_instance_config": instanceconfig.Resource(), "linode_lke_cluster": lke.Resource(), - "linode_nodebalancer_node": nbnode.Resource(), "linode_object_storage_bucket": objbucket.Resource(), "linode_object_storage_object": obj.Resource(), "linode_user": user.Resource(), diff --git a/linode/provider_test.go b/linode/provider_test.go index f4d2ca739..d71282954 100644 --- a/linode/provider_test.go +++ b/linode/provider_test.go @@ -75,7 +75,7 @@ api_version = v4beta } } -func createTestConfig(t *testing.T, conf string) *os.File { +func createTestConfig(t testing.TB, conf string) *os.File { file, err := os.CreateTemp("", "linode") if err != nil { t.Fatal(err) @@ -91,7 +91,7 @@ func createTestConfig(t *testing.T, conf string) *os.File { return file } -func getEnvToken(t *testing.T) string { +func getEnvToken(t testing.TB) string { token, ok := os.LookupEnv("LINODE_TOKEN") if !ok { t.Fatal("LINODE_TOKEN must be specified") diff --git a/linode/rdns/tmpl/template.go b/linode/rdns/tmpl/template.go index 6e45066df..32d47bd42 100644 --- a/linode/rdns/tmpl/template.go +++ b/linode/rdns/tmpl/template.go @@ -14,7 +14,7 @@ type TemplateData struct { WaitForAvailable bool } -func Basic(t *testing.T, label, region string, waitForAvailable bool) string { +func Basic(t testing.TB, label, region string, waitForAvailable bool) string { return acceptance.ExecuteTemplate(t, "rdns_basic", TemplateData{ Label: label, @@ -23,7 +23,7 @@ func Basic(t *testing.T, label, region string, waitForAvailable bool) string { }) } -func Changed(t *testing.T, label, region string, waitForAvailable bool) string { +func Changed(t testing.TB, label, region string, waitForAvailable bool) string { return acceptance.ExecuteTemplate(t, "rdns_changed", TemplateData{ Label: label, @@ -32,7 +32,7 @@ func Changed(t *testing.T, label, region string, waitForAvailable bool) string { }) } -func Deleted(t *testing.T, label, region string) string { +func Deleted(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "rdns_deleted", TemplateData{ Label: label, @@ -40,7 +40,7 @@ func Deleted(t *testing.T, label, region string) string { }) } -func WithTimeout(t *testing.T, label, region, createTimeout, updateTimeout string) string { +func WithTimeout(t testing.TB, label, region, createTimeout, updateTimeout string) string { return acceptance.ExecuteTemplate(t, "rdns_with_timeout", TemplateData{ Label: label, @@ -50,7 +50,7 @@ func WithTimeout(t *testing.T, label, region, createTimeout, updateTimeout strin }) } -func WithTimeoutUpdated(t *testing.T, label, region, createTimeout, updateTimeout string) string { +func WithTimeoutUpdated(t testing.TB, label, region, createTimeout, updateTimeout string) string { return acceptance.ExecuteTemplate(t, "rdns_with_timeout_updated", TemplateData{ Label: label, diff --git a/linode/region/tmpl/template.go b/linode/region/tmpl/template.go index 1c4432ef1..f02b96290 100644 --- a/linode/region/tmpl/template.go +++ b/linode/region/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Label string } -func DataBasic(t *testing.T, id, label string) string { +func DataBasic(t testing.TB, id, label string) string { return acceptance.ExecuteTemplate(t, "region_data_basic", TemplateData{Region: id, Label: label}) } diff --git a/linode/regions/tmpl/template.go b/linode/regions/tmpl/template.go index 26673288a..807c9f41a 100644 --- a/linode/regions/tmpl/template.go +++ b/linode/regions/tmpl/template.go @@ -12,12 +12,12 @@ type TemplateData struct { Capabilities string } -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "regions_data_basic", nil) } -func DataFilterCountry(t *testing.T, country, status string, capabilities string) string { +func DataFilterCountry(t testing.TB, country, status string, capabilities string) string { return acceptance.ExecuteTemplate(t, "regions_data_filter_by_country", TemplateData{ Country: country, @@ -26,7 +26,7 @@ func DataFilterCountry(t *testing.T, country, status string, capabilities string }) } -func DataFilterStatus(t *testing.T, country, status string, capabilities string) string { +func DataFilterStatus(t testing.TB, country, status string, capabilities string) string { return acceptance.ExecuteTemplate(t, "regions_data_filter_by_status", TemplateData{ Country: country, @@ -35,7 +35,7 @@ func DataFilterStatus(t *testing.T, country, status string, capabilities string) }) } -func DataFilterCapabilities(t *testing.T, country, status string, capabilities string) string { +func DataFilterCapabilities(t testing.TB, country, status string, capabilities string) string { return acceptance.ExecuteTemplate(t, "regions_data_filter_by_capabilities", TemplateData{ Country: country, diff --git a/linode/sshkey/tmpl/template.go b/linode/sshkey/tmpl/template.go index 74a8984a7..e7170fee2 100644 --- a/linode/sshkey/tmpl/template.go +++ b/linode/sshkey/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { SSHKey string } -func Basic(t *testing.T, label, sshKey string) string { +func Basic(t testing.TB, label, sshKey string) string { return acceptance.ExecuteTemplate(t, "sshkey_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func Basic(t *testing.T, label, sshKey string) string { }) } -func Updates(t *testing.T, label, sshKey string) string { +func Updates(t testing.TB, label, sshKey string) string { return acceptance.ExecuteTemplate(t, "sshkey_updates", TemplateData{ Label: label, @@ -27,7 +27,7 @@ func Updates(t *testing.T, label, sshKey string) string { }) } -func DataBasic(t *testing.T, label string) string { +func DataBasic(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "sshkey_data_basic", TemplateData{Label: label}) } diff --git a/linode/sshkeys/tmpl/template.go b/linode/sshkeys/tmpl/template.go index c72e8536e..4feb75817 100644 --- a/linode/sshkeys/tmpl/template.go +++ b/linode/sshkeys/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { SSHKey string } -func DataBasic(t *testing.T, label, ssh_key string) string { +func DataBasic(t testing.TB, label, ssh_key string) string { return acceptance.ExecuteTemplate(t, "ssh_keys_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func DataBasic(t *testing.T, label, ssh_key string) string { }) } -func DataFilter(t *testing.T, label, ssh_key string) string { +func DataFilter(t testing.TB, label, ssh_key string) string { return acceptance.ExecuteTemplate(t, "ssh_keys_filter", TemplateData{ Label: label, @@ -27,7 +27,7 @@ func DataFilter(t *testing.T, label, ssh_key string) string { }) } -func DataFilterEmpty(t *testing.T, label, ssh_key string) string { +func DataFilterEmpty(t testing.TB, label, ssh_key string) string { return acceptance.ExecuteTemplate(t, "ssh_keys_filter_empty", TemplateData{ Label: label, @@ -35,7 +35,7 @@ func DataFilterEmpty(t *testing.T, label, ssh_key string) string { }) } -func DataAll(t *testing.T, label, ssh_key string) string { +func DataAll(t testing.TB, label, ssh_key string) string { return acceptance.ExecuteTemplate(t, "ssh_keys_all", TemplateData{ Label: label, diff --git a/linode/stackscript/tmpl/template.go b/linode/stackscript/tmpl/template.go index 9759c8790..04d9389b0 100644 --- a/linode/stackscript/tmpl/template.go +++ b/linode/stackscript/tmpl/template.go @@ -11,17 +11,17 @@ type TemplateData struct { Script string } -func Basic(t *testing.T, label string) string { +func Basic(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "stackscript_basic", TemplateData{Label: label}) } -func CodeChange(t *testing.T, label string) string { +func CodeChange(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "stackscript_code_change", TemplateData{Label: label}) } -func DataBasic(t *testing.T, script string) string { +func DataBasic(t testing.TB, script string) string { return acceptance.ExecuteTemplate(t, "stackscript_data_basic", TemplateData{ Script: script, diff --git a/linode/stackscripts/tmpl/template.go b/linode/stackscripts/tmpl/template.go index de24e507b..5531e5a09 100644 --- a/linode/stackscripts/tmpl/template.go +++ b/linode/stackscripts/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Script string } -func DataBasic(t *testing.T, label, script string) string { +func DataBasic(t testing.TB, label, script string) string { return acceptance.ExecuteTemplate(t, "stackscripts_data_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func DataBasic(t *testing.T, label, script string) string { }) } -func DataSubString(t *testing.T, label, script string) string { +func DataSubString(t testing.TB, label, script string) string { return acceptance.ExecuteTemplate(t, "stackscripts_data_substring", TemplateData{ Label: label, @@ -27,7 +27,7 @@ func DataSubString(t *testing.T, label, script string) string { }) } -func DataLatest(t *testing.T, label, script string) string { +func DataLatest(t testing.TB, label, script string) string { return acceptance.ExecuteTemplate(t, "stackscripts_data_latest", TemplateData{ Label: label, @@ -35,7 +35,7 @@ func DataLatest(t *testing.T, label, script string) string { }) } -func DataClientFilter(t *testing.T, label, script string) string { +func DataClientFilter(t testing.TB, label, script string) string { return acceptance.ExecuteTemplate(t, "stackscripts_data_clientfilter", TemplateData{ Label: label, diff --git a/linode/token/tmpl/template.go b/linode/token/tmpl/template.go index 8ee94a30a..72079100a 100644 --- a/linode/token/tmpl/template.go +++ b/linode/token/tmpl/template.go @@ -20,17 +20,17 @@ type TemplateNewScopesData struct { Scopes string } -func Basic(t *testing.T, label string) string { +func Basic(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "token_basic", TemplateData{Label: label}) } -func Updates(t *testing.T, label string) string { +func Updates(t testing.TB, label string) string { return acceptance.ExecuteTemplate(t, "token_updates", TemplateData{Label: label}) } -func RecreateNewScopes(t *testing.T, label, scopes string) string { +func RecreateNewScopes(t testing.TB, label, scopes string) string { return acceptance.ExecuteTemplate(t, "token_recreate_new_scopes", TemplateNewScopesData{ TemplateData: TemplateData{Label: label}, @@ -38,7 +38,7 @@ func RecreateNewScopes(t *testing.T, label, scopes string) string { }) } -func RecreateNewExpiryDate(t *testing.T, label, expiry string) string { +func RecreateNewExpiryDate(t testing.TB, label, expiry string) string { return acceptance.ExecuteTemplate(t, "token_recreate_new_expiry_date", TemplateNewExpiryData{ TemplateData: TemplateData{Label: label}, diff --git a/linode/user/tmpl/template.go b/linode/user/tmpl/template.go index ce51c5d15..d992ebf5d 100644 --- a/linode/user/tmpl/template.go +++ b/linode/user/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { InstLabel string } -func Basic(t *testing.T, username, email string, restricted bool) string { +func Basic(t testing.TB, username, email string, restricted bool) string { return acceptance.ExecuteTemplate(t, "user_basic", TemplateData{ Username: username, @@ -22,7 +22,7 @@ func Basic(t *testing.T, username, email string, restricted bool) string { }) } -func Grants(t *testing.T, username, email string) string { +func Grants(t testing.TB, username, email string) string { return acceptance.ExecuteTemplate(t, "user_grants", TemplateData{ Username: username, @@ -30,7 +30,7 @@ func Grants(t *testing.T, username, email string) string { }) } -func GrantsUpdate(t *testing.T, username, email, instance string) string { +func GrantsUpdate(t testing.TB, username, email, instance string) string { return acceptance.ExecuteTemplate(t, "user_grants_update", TemplateData{ Username: username, @@ -39,17 +39,17 @@ func GrantsUpdate(t *testing.T, username, email, instance string) string { }) } -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "user_data_basic", nil) } -func DataNoUser(t *testing.T) string { +func DataNoUser(t testing.TB) string { return acceptance.ExecuteTemplate(t, "user_data_nouser", nil) } -func DataGrants(t *testing.T, username, email string) string { +func DataGrants(t testing.TB, username, email string) string { return acceptance.ExecuteTemplate(t, "data_grants", TemplateData{ Username: username, diff --git a/linode/users/tmpl/template.go b/linode/users/tmpl/template.go index 67848ce8a..073ef7e26 100644 --- a/linode/users/tmpl/template.go +++ b/linode/users/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { InstLabel string } -func DataBasic(t *testing.T, username, email string) string { +func DataBasic(t testing.TB, username, email string) string { return acceptance.ExecuteTemplate(t, "users_data_basic", TemplateData{ Username: username, @@ -21,7 +21,7 @@ func DataBasic(t *testing.T, username, email string) string { }) } -func DataClientFilter(t *testing.T, username, email string) string { +func DataClientFilter(t testing.TB, username, email string) string { return acceptance.ExecuteTemplate(t, "users_data_clientfilter", TemplateData{ Username: username, @@ -29,7 +29,7 @@ func DataClientFilter(t *testing.T, username, email string) string { }) } -func DataSubstring(t *testing.T, username, email string) string { +func DataSubstring(t testing.TB, username, email string) string { return acceptance.ExecuteTemplate(t, "users_data_substring", TemplateData{ Username: username, diff --git a/linode/vlan/datasource_test.go b/linode/vlan/datasource_test.go index 0143fd516..e35802813 100644 --- a/linode/vlan/datasource_test.go +++ b/linode/vlan/datasource_test.go @@ -28,7 +28,7 @@ func init() { testRegion = region } -func preConfigVLANPoll(t *testing.T, vlanName string) func() { +func preConfigVLANPoll(t testing.TB, vlanName string) func() { return func() { client := acceptance.TestAccProvider.Meta().(*helper.ProviderMeta).Client if _, err := waitForVLANWithLabel(client, vlanName, 30); err != nil { diff --git a/linode/vlan/tmpl/template.go b/linode/vlan/tmpl/template.go index bf8bd71c4..ca9cf8ab2 100644 --- a/linode/vlan/tmpl/template.go +++ b/linode/vlan/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateData struct { Label string } -func DataBasic(t *testing.T, instLabel, region, vlanLabel, label string) string { +func DataBasic(t testing.TB, instLabel, region, vlanLabel, label string) string { return acceptance.ExecuteTemplate(t, "vlan_data_basic", TemplateData{ InstLabel: instLabel, @@ -23,7 +23,7 @@ func DataBasic(t *testing.T, instLabel, region, vlanLabel, label string) string }) } -func DataRegex(t *testing.T, instLabel, region, vlanLabel, label string) string { +func DataRegex(t testing.TB, instLabel, region, vlanLabel, label string) string { return acceptance.ExecuteTemplate(t, "vlan_data_regex", TemplateData{ InstLabel: instLabel, @@ -33,7 +33,7 @@ func DataRegex(t *testing.T, instLabel, region, vlanLabel, label string) string }) } -func DataCheckDuplicate(t *testing.T, instLabel, region, vlanLabel, label string) string { +func DataCheckDuplicate(t testing.TB, instLabel, region, vlanLabel, label string) string { return acceptance.ExecuteTemplate(t, "vlan_data_check_duplicate", TemplateData{ InstLabel: instLabel, diff --git a/linode/volume/tmpl/template.go b/linode/volume/tmpl/template.go index accda98a7..c86a33d0c 100644 --- a/linode/volume/tmpl/template.go +++ b/linode/volume/tmpl/template.go @@ -12,37 +12,37 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, volume, region string) string { +func Basic(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_basic", TemplateData{Label: volume, Region: region}) } -func Updates(t *testing.T, volume, region string) string { +func Updates(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_updates", TemplateData{Label: volume, Region: region}) } -func UpdatesTagsCaseChange(t *testing.T, volume, region string) string { +func UpdatesTagsCaseChange(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_updates_tags_case_change", TemplateData{Label: volume, Region: region}) } -func Resized(t *testing.T, volume, region string) string { +func Resized(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_resized", TemplateData{Label: volume, Region: region}) } -func Attached(t *testing.T, volume, region string) string { +func Attached(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_attached", TemplateData{Label: volume, Region: region}) } -func ReAttached(t *testing.T, volume, region string) string { +func ReAttached(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_reattached", TemplateData{Label: volume, Region: region}) } -func ClonedStep1(t *testing.T, volume, region, pubKey string) string { +func ClonedStep1(t testing.TB, volume, region, pubKey string) string { return acceptance.ExecuteTemplate(t, "volume_cloned_step1", TemplateData{ Label: volume, @@ -51,7 +51,7 @@ func ClonedStep1(t *testing.T, volume, region, pubKey string) string { }) } -func ClonedStep2(t *testing.T, volume, region, pubKey string) string { +func ClonedStep2(t testing.TB, volume, region, pubKey string) string { return acceptance.ExecuteTemplate(t, "volume_cloned_step2", TemplateData{ Label: volume, @@ -60,7 +60,7 @@ func ClonedStep2(t *testing.T, volume, region, pubKey string) string { }) } -func DataBasic(t *testing.T, volume, region string) string { +func DataBasic(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volume_data_basic", TemplateData{Label: volume, Region: region}) } diff --git a/linode/volumes/tmpl/template.go b/linode/volumes/tmpl/template.go index b08e6e718..c0361b383 100644 --- a/linode/volumes/tmpl/template.go +++ b/linode/volumes/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, volume, region string) string { +func DataBasic(t testing.TB, volume, region string) string { return acceptance.ExecuteTemplate(t, "volumes_data_basic", TemplateData{Label: volume, Region: region}) } diff --git a/linode/volumetypes/tmpl/template.go b/linode/volumetypes/tmpl/template.go index 2ff0f75fe..4bbfc35d3 100644 --- a/linode/volumetypes/tmpl/template.go +++ b/linode/volumetypes/tmpl/template.go @@ -6,7 +6,7 @@ import ( "github.com/linode/terraform-provider-linode/v2/linode/acceptance" ) -func DataBasic(t *testing.T) string { +func DataBasic(t testing.TB) string { return acceptance.ExecuteTemplate(t, "volume_types_data_basic", nil) } diff --git a/linode/vpc/tmpl/template.go b/linode/vpc/tmpl/template.go index a5ad0b538..62d00a554 100644 --- a/linode/vpc/tmpl/template.go +++ b/linode/vpc/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label, region string) string { +func Basic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "vpc_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func Basic(t *testing.T, label, region string) string { }) } -func Updates(t *testing.T, label, region string) string { +func Updates(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "vpc_updates", TemplateData{ Label: label, @@ -27,7 +27,7 @@ func Updates(t *testing.T, label, region string) string { }) } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "vpc_data_basic", TemplateData{ Label: label, diff --git a/linode/vpcips/tmpl/template.go b/linode/vpcips/tmpl/template.go index eb639e2e3..686b2bbfb 100644 --- a/linode/vpcips/tmpl/template.go +++ b/linode/vpcips/tmpl/template.go @@ -13,7 +13,7 @@ type TemplateDataBasic struct { IPv4_2 string } -func DataBasic(t *testing.T, label, region, ipv4_1, ipv4_2 string) string { +func DataBasic(t testing.TB, label, region, ipv4_1, ipv4_2 string) string { return acceptance.ExecuteTemplate(t, "vpc_ips_data_basic", TemplateDataBasic{ Label: label, diff --git a/linode/vpcs/tmpl/template.go b/linode/vpcs/tmpl/template.go index 7229cc149..be2ff6948 100644 --- a/linode/vpcs/tmpl/template.go +++ b/linode/vpcs/tmpl/template.go @@ -11,7 +11,7 @@ type TemplateData struct { Region string } -func DataBasic(t *testing.T, label, region string) string { +func DataBasic(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "vpcs_data_basic", TemplateData{ Label: label, @@ -19,7 +19,7 @@ func DataBasic(t *testing.T, label, region string) string { }) } -func DataFilterLabel(t *testing.T, label, region string) string { +func DataFilterLabel(t testing.TB, label, region string) string { return acceptance.ExecuteTemplate(t, "vpcs_data_filter_label", TemplateData{ Label: label, diff --git a/linode/vpcsubnet/tmpl/template.go b/linode/vpcsubnet/tmpl/template.go index 2f8d595ff..c157b1c8a 100644 --- a/linode/vpcsubnet/tmpl/template.go +++ b/linode/vpcsubnet/tmpl/template.go @@ -12,7 +12,7 @@ type TemplateData struct { Region string } -func Basic(t *testing.T, label, ipv4, region string) string { +func Basic(t testing.TB, label, ipv4, region string) string { return acceptance.ExecuteTemplate(t, "vpc_subnet_basic", TemplateData{ Label: label, @@ -21,7 +21,7 @@ func Basic(t *testing.T, label, ipv4, region string) string { }) } -func Updates(t *testing.T, label, ipv4, region string) string { +func Updates(t testing.TB, label, ipv4, region string) string { return acceptance.ExecuteTemplate(t, "vpc_subnet_updates", TemplateData{ Label: label, @@ -30,7 +30,7 @@ func Updates(t *testing.T, label, ipv4, region string) string { }) } -func DataBasic(t *testing.T, label, ipv4, region string) string { +func DataBasic(t testing.TB, label, ipv4, region string) string { return acceptance.ExecuteTemplate(t, "vpc_subnet_data_basic", TemplateData{ Label: label, @@ -39,7 +39,7 @@ func DataBasic(t *testing.T, label, ipv4, region string) string { }) } -func Attached(t *testing.T, label, ipv4, region string) string { +func Attached(t testing.TB, label, ipv4, region string) string { return acceptance.ExecuteTemplate(t, "vpc_subnet_attached", TemplateData{ Label: label, diff --git a/linode/vpcsubnets/tmpl/template.go b/linode/vpcsubnets/tmpl/template.go index 25fb34b8e..e70aa4227 100644 --- a/linode/vpcsubnets/tmpl/template.go +++ b/linode/vpcsubnets/tmpl/template.go @@ -12,7 +12,7 @@ type TemplateData struct { IPv4 string } -func DataBasic(t *testing.T, label, region, ipv4 string) string { +func DataBasic(t testing.TB, label, region, ipv4 string) string { return acceptance.ExecuteTemplate(t, "vpc_subnets_data_basic", TemplateData{ Label: label, @@ -21,7 +21,7 @@ func DataBasic(t *testing.T, label, region, ipv4 string) string { }) } -func DataFilterLabel(t *testing.T, label, region, ipv4 string) string { +func DataFilterLabel(t testing.TB, label, region, ipv4 string) string { return acceptance.ExecuteTemplate(t, "vpc_subnets_data_filter_label", TemplateData{ Label: label,