Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unifi_network invalid payload #196

Open
kurtmc opened this issue Oct 11, 2021 · 10 comments
Open

unifi_network invalid payload #196

kurtmc opened this issue Oct 11, 2021 · 10 comments

Comments

@kurtmc
Copy link
Contributor

kurtmc commented Oct 11, 2021

Recently I have noticed that we are getting the following error quite a lot:

╷
│ Error: api.err.InvalidPayload (400 ) for POST https://xxxxxxxxxxxxxxxxxxxxx/api/s/1ugonv7v/rest/networkconf
│ 
│   with unifi_network.management["f2da017a-cf58-4ff6-943a-ae71eba1981b"],
│   on unifi_customer_networks.tf line 74, in resource "unifi_network" "management":
│   74: resource "unifi_network" "management" {
│ 
╵

I turned on trace to see if unifi gives me a better error:

---[ REQUEST ]---------------------------------------
POST /api/s/1ugonv7v/rest/networkconf HTTP/1.1
Host: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
User-Agent: terraform-provider-unifi/0.1
Content-Length: 1606
Content-Type: application/json; charset=utf-8
Cookie: unifises=gdaBAdkkmjwmNgGI24scY5AbZjzAnFKM; csrf_token=gdSuAP01vQHV7S2Fl36TOd0p8GlOpfKu
Accept-Encoding: gzip

{
 "auto_scale_enabled": false,
 "dhcpd_boot_enabled": false,
 "dhcpd_boot_server": "",
 "dhcpd_dns_1": "",
 "dhcpd_dns_2": "",
 "dhcpd_dns_3": "",
 "dhcpd_dns_4": "",
 "dhcpd_dns_enabled": false,
 "dhcpd_enabled": false,
 "dhcpd_gateway": "",
 "dhcpd_gateway_enabled": false,
 "dhcpd_ip_1": "",
 "dhcpd_ip_2": "",
 "dhcpd_ip_3": "",
 "dhcpd_leasetime": 86400,
 "dhcpd_mac_1": "",
 "dhcpd_mac_2": "",
 "dhcpd_mac_3": "",
 "dhcpd_ntp_1": "",
 "dhcpd_ntp_2": "",
 "dhcpd_ntp_enabled": false,
 "dhcpd_start": "",
 "dhcpd_stop": "",
 "dhcpd_time_offset_enabled": false,
 "dhcpd_unifi_controller": "",
 "dhcpdv6_dns_auto": false,
 "dhcpdv6_enabled": false,
 "dhcpd_wins_1": "",
 "dhcpd_wins_2": "",
 "dhcpd_wins_enabled": false,
 "dhcp_relay_enabled": false,
 "dhcpguard_enabled": false,
 "dpi_enabled": false,
 "dpigroup_id": "",
 "domain_name": "",
 "enabled": true,
 "exposed_to_site_vpn": false,
 "gateway_device": "",
 "igmp_fastleave": false,
 "igmp_querier": "",
 "igmp_snooping": false,
 "igmp_supression": false,
 "ipsec_dynamic_routing": false,
 "ipsec_pfs": false,
 "ipv6_interface_type": "none",
 "ipv6_pd_prefixid": "",
 "ipv6_ra_enabled": false,
 "is_nat": false,
 "lte_lan_enabled": false,
 "mac_override": "",
 "mac_override_enabled": false,
 "name": "management",
 "networkgroup": "LAN",
 "pptpc_require_mppe": false,
 "purpose": "vlan-only",
 "radiusprofile_id": "",
 "remote_site_id": "",
 "report_wan_event": false,
 "require_mschapv2": false,
 "upnp_lan_enabled": false,
 "usergroup_id": "",
 "vlan": 101,
 "vlan_enabled": true,
 "vpn_client_default_route": false,
 "vpn_client_pull_dns": false,
 "wan_dns1": "",
 "wan_dns2": "",
 "wan_dns3": "",
 "wan_dns4": "",
 "wan_gateway": "",
 "wan_gateway_v6": "",
 "wan_ipv6": "",
 "wan_provider_capabilities": {},
 "wan_smartq_enabled": false,
 "wan_vlan_enabled": false
}
-----------------------------------------------------: timestamp=2021-10-11T16:13:09.257+1300
2021-10-11T16:13:09.324+1300 [INFO]  provider.terraform-provider-unifi_v0.30.0: 2021/10/11 16:13:09 [DEBUG] Unifi API Response Details:
---[ RESPONSE ]--------------------------------------
HTTP/1.1 400
Content-Length: 225
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Access-Control-Allow-Origin,Access-Control-Allow-Credentials
Connection: keep-alive
Content-Type: application/json;charset=UTF-8
Date: Mon, 11 Oct 2021 03:13:09 GMT
Server: nginx/1.15.12
Vary: Origin
X-Frame-Options: DENY

{
 "meta": {
  "rc": "error",
  "validationError": {
   "field": "wan_gateway",
   "pattern": "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
  },
  "msg": "api.err.InvalidPayload"
 },
 "data": []
}
-----------------------------------------------------: timestamp=2021-10-11T16:13:09.323+1300

Should we make wan_gateway a string pointer so that it's not marshalled to an empty string when this request is made?

@kurtmc
Copy link
Contributor Author

kurtmc commented Oct 12, 2021

Adding some more context. I am running this against version 6.4.54

And here is a terraform snippet that can reproduce the error:

resource "unifi_site" "customer" {
  description = "to_delete"
}

resource "unifi_network" "management" {
  site        = unifi_site.customer.name
  name        = "management"
  purpose     = "vlan-only"
  vlan_id     = 101
}

Adding in a dummy value for wan_gateway is the workaround I am currently using. My workaround in production looks like this:

resource "unifi_network" "management" {
  site        = unifi_site.customer.name
  name        = "management"
  purpose     = "vlan-only"
  vlan_id     = 101
  wan_gateway = "0.0.0.0" 

  lifecycle {
    ignore_changes = [
      wan_gateway,
    ]
  }
}

@j33pguy
Copy link

j33pguy commented Oct 13, 2021

Can confirm getting same POST Message (400) on apply.....using provider = 0.34.0 and unifi os 1.11.0-16 (EA) for UDM Pro...can provide screenshots logs if needed...thanks

@kurtmc
Copy link
Contributor Author

kurtmc commented Oct 13, 2021

I added a test for this, but I suspect I need to upgrade the unifi version that it's run against: https://github.com/paultyng/terraform-provider-unifi/pull/197/checks?check_run_id=3887403832

@joshuaspence
Copy link
Collaborator

Hmm, the tests should already be running against the latest versions

@j33pguy
Copy link

j33pguy commented Oct 13, 2021

Good stuff....still super new to terraform, today was the first day I could actually even get any response, I am a software dev, but very green....Thank you guys for your work!!!

@joshuaspence
Copy link
Collaborator

I think this is the same issue as #107, but I may not be able to investigate further for another few weeks. In the mean time, if anyone can produce a reproduction case (ideally an acceptance test in the repo), that should help a lot.

@lloydoliver
Copy link

lloydoliver commented Oct 19, 2021

I'm running into the same issue at present, however the workaround mentioned above doesn't always work.

adding

  lifecycle {
    ignore_changes = [
      wan_gateway,
    ]
  }

still results in a 400 InvalidPayload error when a change to the network needs to be applied

removing this and having just a dummy "wan_gateway" results in a successful run when another change is needing to be applied (ie IP Range change), but without the lifecycle block it results in wanting to apply the wan_gateway on every run but results in a very misleading "Not Found" error. All API calls return 200 so not sure where that particular error is coming from.

Also on 6.4.54 (Cloud Key)
TF snippet that I'm seeing the error with

resource "unifi_network" "Main" {
  dhcp_dns      = ["172.16.12.102"]
  dhcp_enabled  = true
  dhcp_lease    = "3600"
  dhcp_start    = "172.16.10.6"
  dhcp_stop     = "172.16.10.254"
  name	        = "Main"
  purpose	= "corporate"
  site          = var.site
  subnet        = "172.16.10.1/24"
  vlan_id       = 10
  wan_gateway   = "0.0.0.0" 
  
  lifecycle {
    ignore_changes = [
      wan_gateway,
    ]
  }
}

@jonwilliams84
Copy link

I have the same issue...
Unifi: 6.4.54

Any changes to a network, be it a dhcp scope or a name or other parameter results in:

╷
│ Error: api.err.InvalidPayload (400 ) for PUT https://x.x.x.x:8443/api/s/default/rest/networkconf/6194484b5764540124b3c76e
│ 
│   with unifi_network.network["iot"],
│   on testing.tf line 49, in resource "unifi_network" "network":
│   49: resource "unifi_network" "network" {
│ 
╵

network.tf:

output "network" {
  value = local.network
}

locals {
  network = defaults(var.network, {
    site                = "default"
    dhcp_dns            = ""
    dhcp_enabled        = true
    dhcp_lease          = 86400
    dhcp_relay_enabled  = false
    dhcpd_boot_enabled  = false
    domain_name         = "mydomain.com"
    igmp_snooping       = false
    ipv6_interface_type = "none"
    ipv6_ra_enable      = false
    network_group       = "LAN"
    wan_dns             = ""
    wan_egress_qos      = 0
    wan_gateway         = "0.0.0.0"
    purpose             = "corporate"
  })
}

resource "unifi_network" "network" {
  for_each            = { for i, v in local.network : i => v }
  name                = each.value.name
  dhcp_enabled        = each.value.dhcp_enabled
  dhcp_lease          = each.value.dhcp_lease
  dhcp_relay_enabled  = each.value.dhcp_relay_enabled
  dhcp_start          = each.value.dhcp_start
  dhcp_stop           = each.value.dhcp_stop
  dhcpd_boot_enabled  = each.value.dhcpd_boot_enabled
  domain_name         = each.value.domain_name
  igmp_snooping       = each.value.igmp_snooping
  ipv6_interface_type = each.value.ipv6_interface_type
  ipv6_ra_enable      = each.value.ipv6_ra_enable
  network_group       = each.value.network_group
  purpose             = each.value.purpose
  site                = unifi_site.sirfragalot.name
  subnet              = each.value.subnet
  vlan_id             = each.value.vlan_id
  wan_egress_qos      = each.value.wan_egress_qos
  wan_gateway         = each.value.wan_gateway
  wan_dns             = each.value.wan_dns
  dhcp_dns            = each.value.dhcp_dns

  lifecycle {
    ignore_changes = [
      wan_gateway,
    ]
  }
}

network-variables.tf:

variable "network" {
  type = map(object({
    name                = string
    site                = optional(string)
    dhcp_dns            = optional(list(string))
    dhcp_enabled        = optional(bool)
    dhcp_lease          = optional(number)
    dhcp_relay_enabled  = optional(bool)
    dhcpd_boot_enabled  = optional(bool)
    domain_name         = optional(string)
    igmp_snooping       = optional(bool)
    ipv6_interface_type = optional(string)
    ipv6_ra_enable      = optional(bool)
    network_group       = optional(string)
    wan_dns             = optional(list(string))
    wan_egress_qos      = optional(number)
    wan_gateway         = optional(string)
    purpose             = optional(string)
    dhcp_start          = string
    dhcp_stop           = string
    subnet              = string
    vlan_id             = number
  }))
}

network.auto.tfvars:

network = {
  main = {
    name       = "LAN"
    dhcp_start = "192.168.1.6"
    dhcp_stop  = "192.168.1.254"
    subnet     = "192.168.1.0/24"
    vlan_id    = 0
  }
  iot = {
    name       = "IoT"
    dhcp_start = "10.32.12.10"
    dhcp_stop  = "10.32.12.100"
    subnet     = "10.32.12.0/24"
    vlan_id    = 107
    dhcp_dns   = ["192.168.1.53", "192.168.1.153"]
    wan_dns    = []
  }
  cctv = {
    name       = "CCTV"
    dhcp_start = "10.32.13.10"
    dhcp_stop  = "10.32.13.100"
    subnet     = "10.32.13.0/24"
    vlan_id    = 999
    dhcp_dns   = []
    wan_dns    = []
  }
}

@paultyng
Copy link
Owner

paultyng commented Nov 21, 2021

Did some more investigation here, most of these are already omitempty. I think explicit null should probably be used instead of 0.0.0.0 or empty strings. I couldn't get it to fail with exactly the same issues in my testing though, but working on it here: #203

My guess though is this has to do with how certain fields are only roundtripped if the purpose is WAN, but its having issues with the validation. My understanding was the validation should allow for empty, but I guess its explicitly looking for null / unset.

@evenh
Copy link

evenh commented Jan 25, 2022

I'm encountering this specific issue as well, in the same way that @kurtmc reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants