cisco-open / terraform-provider-meraki

A Terraform Provider for Cisco Meraki
Mozilla Public License 2.0
15 stars 6 forks source link

resource `meraki_devices_appliance_uplinks_settings` dynamic error #50

Closed finkjordanj closed 3 months ago

finkjordanj commented 3 months ago

Prerequisites

Describe the bug When trying to apply dynamic ipv4 interface getting value conversion Error on what appears to be a non dynamic dependency on the nameservers like the address and gateway fields do.

Expected behavior

When building an interface as a dynamic IP expect to be able to leave address/gateway/name servers blank since that is how the dashboard behavior allows for.

resource "meraki_devices_appliance_uplinks_settings" "this" {

  serial = "<-blanked->"
  interfaces = {
    wan1 = {
      enabled = true
      svis = {
        ipv4 = {
          assignment_mode = "dynamic"
        }
      }
      vlan_tagging = {
        enabled = false
      }
    }
  }
}

Error on apply

fink@LTWXCGVT333:~/dev/meraki-terraform-test $ terraform apply
Acquiring state lock. This may take a few moments...
meraki_devices.this_mx: Refreshing state... [name=750-comm-meraki-lab-mx1]
data.meraki_networks.dev_networks: Reading...
data.meraki_networks.dev_networks: Read complete after 2s
meraki_networks_appliance_firewall_firewalled_services.this_web: Refreshing state...
meraki_networks_appliance_firewall_firewalled_services.this_icmp: Refreshing state...
meraki_networks_appliance_firewall_firewalled_services.this_snmp: Refreshing state...
meraki_networks_appliance_vlans_settings.this_vlans: Refreshing state...
meraki_networks_appliance_settings.this: Refreshing state...
meraki_networks_syslog_servers.this_spoke: Refreshing state...
meraki_networks_group_policies.group_policy_byod: Refreshing state... [name=BYOD]
meraki_networks_group_policies.group_policy_guest: Refreshing state... [name=GUEST]
meraki_networks_group_policies.group_policy_pan: Refreshing state... [name=PAN]
meraki_networks_group_policies.group_policy_internal: Refreshing state... [name=INTERNAL]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  ~ update in-place

Terraform will perform the following actions:

  # meraki_devices.this_mx will be updated in-place
  ~ resource "meraki_devices" "this_mx" {
      ~ details           = [] -> (known after apply)
      ~ firmware          = "wired-18-1-07" -> (known after apply)
      + floor_plan_id     = (known after apply)
      ~ imei              = null -> (known after apply)
      ~ lan_ip            = null -> (known after apply)
      ~ mac               = "2c:3f:0b:b4:9b:61" -> (known after apply)
      ~ model             = "MX67" -> (known after apply)
      + move_map_marker   = true
        name              = "750-comm-meraki-lab-mx1"
      ~ network_id        = "L_783626335162467749" -> (known after apply)
      ~ product_type      = null -> (known after apply)
      + switch_profile_id = (known after apply)
      + tags              = (known after apply)
        # (5 unchanged attributes hidden)
    }

  # meraki_devices_appliance_uplinks_settings.this will be created
  + resource "meraki_devices_appliance_uplinks_settings" "this" {
      + interfaces = {
          + wan1 = {
              + enabled      = true
              + pppoe        = (known after apply)
              + svis         = {
                  + ipv4 = {
                      + address         = (known after apply)
                      + assignment_mode = "dynamic"
                      + gateway         = (known after apply)
                      + nameservers     = (known after apply)
                    }
                  + ipv6 = (known after apply)
                }
              + vlan_tagging = {
                  + enabled = false
                  + vlan_id = (known after apply)
                }
            }
          + wan2 = (known after apply)
        }
      + serial     = "<-blanked->"
    }

Plan: 1 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

meraki_devices_appliance_uplinks_settings.this: Creating...
meraki_devices.this_mx: Modifying... [name=750-comm-meraki-lab-mx1]
meraki_devices.this_mx: Modifications complete after 2s [name=750-comm-meraki-lab-mx1]
╷
│ Error: Plugin did not respond
│ 
│ The plugin encountered an error, and failed to respond to the plugin6.(*GRPCProvider).ApplyResourceChange call. The plugin logs may contain more details.
╵

Stack trace from the terraform-provider-meraki_v0.2.1-alpha plugin:

panic: reflect: call of reflect.Value.Type on zero Value

goroutine 15 [running]:
reflect.Value.typeSlow({0x0?, 0x0?, 0xc0002cbff0?})
        reflect/value.go:2634 +0x113
reflect.Value.Type(...)
        reflect/value.go:2629
terraform-provider-meraki/internal/provider.changeStructUnknowns({0x11f7300, 0x0?}, {0x13e93c0?, 0xc00049a4e0?})
        terraform-provider-meraki/internal/provider/utils.go:761 +0x245
terraform-provider-meraki/internal/provider.changeStructUnknowns({0x14a8000, 0xc00031a4a0?}, {0x14a8000?, 0xc00031a4c0?})
        terraform-provider-meraki/internal/provider/utils.go:807 +0xbe5
terraform-provider-meraki/internal/provider.changeStructUnknowns({0x13e9780, 0xc00049a470?}, {0x13e9780?, 0xc00049a480?})
        terraform-provider-meraki/internal/provider/utils.go:807 +0xbe5
terraform-provider-meraki/internal/provider.mergeInterfaces({0x13e9820, 0xc00031a420}, {0x13e9820, 0xc00031a440}, 0x1)
        terraform-provider-meraki/internal/provider/utils.go:694 +0x14b2
terraform-provider-meraki/internal/provider.ResponseApplianceGetDeviceApplianceUplinksSettingsItemToBodyRs({{0x2, {0xc0003c5130, 0xe}}, 0xc000672b10}, 0xc0000e2e70?, 0x0)
        terraform-provider-meraki/internal/provider/resource_meraki_devices_appliance_uplinks_settings.go:1284 +0x107
terraform-provider-meraki/internal/provider.(*DevicesApplianceUplinksSettingsResource).Create(0xc000340348, {0x189d928, 0xc0000e2e70}, {{{{0x18a55b0, 0xc0000e0300}, {0x133d360, 0xc000174570}}, {0x18b7880, 0xc0000aaf50}}, {{{0x18a55b0, ...}, ...}, ...}, ...}, ...)
        terraform-provider-meraki/internal/provider/resource_meraki_devices_appliance_uplinks_settings.go:616 +0x59a
github.com/hashicorp/terraform-plugin-framework/internal/fwserver.(*Server).CreateResource(0xc0001611e0, {0x189d928, 0xc0000e2e70}, 0xc0002cd580, 0xc0002cd520)
        github.com/hashicorp/terraform-plugin-framework@v1.7.0/internal/fwserver/server_createresource.go:101 +0x578
github.com/hashicorp/terraform-plugin-framework/internal/fwserver.(*Server).ApplyResourceChange(0xc0006ff6d8?, {0x189d928, 0xc0000e2e70}, 0xc0003482d0, 0xc0002cd6d8)
        github.com/hashicorp/terraform-plugin-framework@v1.7.0/internal/fwserver/server_applyresourcechange.go:57 +0x4a5
github.com/hashicorp/terraform-plugin-framework/internal/proto6server.(*Server).ApplyResourceChange(0xc0001611e0, {0x189d928?, 0xc0000e2d50?}, 0xc0005f1f40)
        github.com/hashicorp/terraform-plugin-framework@v1.7.0/internal/proto6server/server_applyresourcechange.go:55 +0x3e5
github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server.(*server).ApplyResourceChange(0xc00018a820, {0x189d928?, 0xc0000e2510?}, 0xc000181110)
        github.com/hashicorp/terraform-plugin-go@v0.22.2/tfprotov6/tf6server/server.go:846 +0x3d0
github.com/hashicorp/terraform-plugin-go/tfprotov6/internal/tfplugin6._Provider_ApplyResourceChange_Handler({0x1564480?, 0xc00018a820}, {0x189d928, 0xc0000e2510}, 0xc00013fc00, 0x0)
        github.com/hashicorp/terraform-plugin-go@v0.22.2/tfprotov6/internal/tfplugin6/tfplugin6_grpc.pb.go:518 +0x169
google.golang.org/grpc.(*Server).processUnaryRPC(0xc00013b000, {0x189d928, 0xc0000e2450}, {0x18b5cf8, 0xc000374000}, 0xc000558480, 0xc000291620, 0x20eca38, 0x0)
        google.golang.org/grpc@v1.63.2/server.go:1369 +0xe23
google.golang.org/grpc.(*Server).handleStream(0xc00013b000, {0x18b5cf8, 0xc000374000}, 0xc000558480)
        google.golang.org/grpc@v1.63.2/server.go:1780 +0x1016
google.golang.org/grpc.(*Server).serveStreams.func2.1()
        google.golang.org/grpc@v1.63.2/server.go:1019 +0x8b
created by google.golang.org/grpc.(*Server).serveStreams.func2 in goroutine 22
        google.golang.org/grpc@v1.63.2/server.go:1030 +0x135

Error: The terraform-provider-meraki_v0.2.1-alpha plugin crashed!

This is always indicative of a bug within the plugin. It would be immensely
helpful if you could report the crash with the plugin's maintainers so that it
can be fixed. The output above should help diagnose the issue.

If i try to do direct import of the dynamic configured object it errors on the name servers so would assume import/update would be related.

~/dev/meraki-terraform-test $ terraform import meraki_devices_appliance_uplinks_settings.this "<-blanked->"
Acquiring state lock. This may take a few moments...
meraki_devices_appliance_uplinks_settings.this: Importing from ID "<-blanked->"...
data.meraki_networks.dev_networks: Reading...
meraki_devices_appliance_uplinks_settings.this: Import prepared!
  Prepared meraki_devices_appliance_uplinks_settings for import
meraki_devices_appliance_uplinks_settings.this: Refreshing state...
data.meraki_networks.dev_networks: Read complete after 0s
╷
│ Error: Value Conversion Error
│ 
│ An unexpected error was encountered while verifying an attribute value matched its expected type to prevent unexpected behavior or panics. This is always an error in the provider. Please report the following to
│ the provider developer:
│ 
│ Expected framework type from provider logic: types.SetType[basetypes.StringType] / underlying type: tftypes.Set[tftypes.String]
│ Received framework type from provider logic: types.SetType[!!! MISSING TYPE !!!] / underlying type: tftypes.Set[tftypes.DynamicPseudoType]
│ Path: interfaces.wan1.svis.ipv4.nameservers.addresses
╵

Would expect this to just leave and make sure interface for a site stays configured as dynamic IP. Assuming there is a check on whether the address and gateway fields have a expected data entry only if the assign_mode = "static" Would like to see name servers also have this validate check applied as we are unable to assign a DNS name server when interface is set to dynamic in the dashboard.

Direct API call via Python library confirmed responds like expected.

Screenshots API call/response

Python api call

import common.dashboard_init
import json
import os
import sys

current = os.path.dirname(os.path.realpath(__file__))
parent = os.path.dirname(current)
sys.path.append(parent)

dashboard = common.dashboard_init.dashboard

def printj(ugly_json_object: list):
    # The json.dumps() method converts a JSON object into human-friendly formatted text
    pretty_json_string = json.dumps(ugly_json_object, indent=4, sort_keys=False)
    print(pretty_json_string)

interfaces = {
    "wan1": {
        "enabled": True,
        "vlanTagging": {"enabled": False},
        "svis": {"ipv4": {"assignmentMode": "dynamic"}},
    },
    "pppoe": {"enabled": False},
    "wan2": {
        "enabled": False,
    },
}

data = dashboard.appliance.updateDeviceApplianceUplinksSettings(
    "<-blanked->", interfaces
)
printj(data)
response

{
    "interfaces": {
        "wan1": {
            "enabled": true,
            "vlanTagging": {
                "enabled": false
            },
            "svis": {
                "ipv4": {
                    "assignmentMode": "dynamic"
                },
                "ipv6": {
                    "assignmentMode": "dynamic"
                }
            },
            "pppoe": {
                "enabled": false
            }
        },
        "wan2": {
            "enabled": false,
            "vlanTagging": {
                "enabled": false
            },
            "svis": {
                "ipv4": {
                    "assignmentMode": "dynamic"
                },
                "ipv6": {
                    "assignmentMode": "dynamic"
                }
            },
            "pppoe": {
                "enabled": false
            }
        }
    }
}

Environment (please complete the following information):

Additional context

fmunozmiranda commented 3 months ago

Hi @finkjordanj could you please try it again with v0.2.2-apha and update if it works now?

finkjordanj commented 3 months ago

Confirmed issue with Dynamic ipv4 assignment resolved.