conversion from netplan (network v2) YAML to ENI format fails for 'default' routes

Bug #2046490 reported by David Torrey
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
cloud-init (Ubuntu)
Invalid
Undecided
Unassigned

Bug Description

As reported by a customer, when cloud-init converts netplan YAML to ENI format for older distros, it does not handle the new "default" route syntax. This is somewhat reproducible via the command line.

My test platform: 22.04.3 with cloud-init 23.3.3-0ubuntu0~22.04.1

For example, with this input YAML:

network:
  ethernets:
    eno1:
      addresses:
      - 10.0.0.1/24
      match:
        macaddress: 11:22:33:44:55:66;
      routes:
        - to: default
          via: 10.0.0.254
      mtu: 1500
      nameservers:
        addresses:
        - 10.0.0.254
        search:
        - example.com
  version: 2

$ cloud-init devel net-convert -p test.yaml -k yaml -d ./test -D debian -O eni
2023-12-14 20:10:27,181 - network_state.py[ERROR]: Address default is not a valid ip network
Traceback (most recent call last):
  File "/usr/bin/cloud-init", line 33, in <module>
    sys.exit(load_entry_point('cloud-init==23.3.3', 'console_scripts', 'cloud-init')())
  File "/usr/lib/python3/dist-packages/cloudinit/cmd/main.py", line 1080, in main
    retval = util.log_time(
  File "/usr/lib/python3/dist-packages/cloudinit/util.py", line 2833, in log_time
    ret = func(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/cloudinit/cmd/devel/net_convert.py", line 167, in handle_args
    ns = network_state.parse_net_config_data(pre_ns, renderer=r)
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 1111, in parse_net_config_data
    nsi.parse_config(skip_broken=skip_broken)
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 309, in parse_config
    self.parse_config_v2(skip_broken=skip_broken)
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 364, in parse_config_v2
    handler(self, command)
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 757, in handle_ethernets
    subnets = self._v2_to_v1_ipcfg(cfg)
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 928, in _v2_to_v1_ipcfg
    _normalize_route(
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 1068, in _normalize_route
    _normalize_net_keys(
  File "/usr/lib/python3/dist-packages/cloudinit/net/network_state.py", line 1002, in _normalize_net_keys
    raise ValueError(f"Address {addr} is not a valid ip address")
ValueError: Address default is not a valid ip address

The expectation is of course a working default route in the files in ENI format. The deprecated "gateway4" syntax does work, as does modifying the input YAML to use "0.0.0.0/0" instead of "default". The latter substitution results, ironically, in an ENI file that uses "default":

$ cat ./test/etc/network/interfaces.d/50-cloud-init
# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
auto lo
iface lo inet loopback
    dns-nameservers 10.0.0.254
    dns-search example.com

auto eno1
iface eno1 inet static
    address 10.0.0.1/24
    dns-nameservers 10.0.0.254
    dns-search example.com
    dns {'nameservers': ['10.0.0.254'], 'search': ['example.com']}
    mtu 1500
    post-up route add default gw 10.0.0.254 || true
    pre-down route del default gw 10.0.0.254 || true

I was able to reproduce this scenario, but the customer reports an additional behavior, possibly with older versions of cloud-init, where instead of failing entirely, the use of "default" resulted in an ENI file that had "default/0" instead of simply "default". This may have been fixed in more recent cloud-init versions, and the equivalent "gateway4" syntax also produces the correct result here.

In any event, the customer is also wondering whether or not the fix may be backported to older versions, as well as when support for the "gateway4" syntax will be entirely removed, since that is the workaround at the moment.

Thanks,
Dave
Canonical Support

David Torrey (dotj)
summary: - conversion from netplan YAML to ENI format fails for 'default' routes
+ conversion from netplan (network v2) YAML to ENI format fails for
+ 'default' routes
Revision history for this message
James Falcon (falcojr) wrote :

While the supplied config is valid netplan, it is not valid network v2 configuration:
https://cloudinit.readthedocs.io/en/latest/reference/network-config-format-v2.html

In order to render to ENI, valid v1 or v2 configuration must be used.

There are plans to add `to: default` v2 configuration syntax in the future. When that change happens, it will be backported to currently supported Ubuntu releases. Additionally, if the `gateway4` syntax is removed, it will only happen in a newer development release once `to: default` is supported, and that change will not be backported as it could break currently deployed installations.

Since the behavior is working as intended, I'm going to change the status to invalid, but if there are additional questions or concerns I didn't cover, we can discuss it here and I can reopen the issue if needed.

Changed in cloud-init (Ubuntu):
status: New → Invalid
Revision history for this message
David Torrey (dotj) wrote :

I concur that the underlying issue is subtle differences between netplan and network v2 syntaxes, and appreciate that updates are the works. Thank you also for the clarification on deprecation and backporting schedules.

However, from a customer perspective, is this difference called out explicitly anywhere in our documentation? The appearance is so similar, right down to the resulting netplan YAML files containing

```
network:
  version: 2
```

as to be indistinguishable unless an incompatible keyword is invoked.

Can this be filed as a documentation bug? Happy to do that if I knew where.

Revision history for this message
James Falcon (falcojr) wrote :

I agree that it is confusing, but it is spelled out in the top two sections of https://cloudinit.readthedocs.io/en/latest/reference/network-config-format-v2.html .

In particular:
"Cloud-init’s support for Version 2 network config is a subset of the Version 2 format defined for the Netplan tool."

and

"If you are writing or generating network configuration that may be used on non-netplan systems, you must limit yourself to the subset described in this document, or you will see network configuration failures on non-netplan systems."

We're open to suggestions that could make it more clear though. The 'Give feedback' button at the top of that page would be the easiest way to file a documentation issue.

Revision history for this message
David Torrey (dotj) wrote :

Thank you for that link. I must not have run across it in my searches because I didn't understand the difference to begin with (like using a dictionary to find a spelling), but it's quite clear as-is. I'll have to think about any suggestions for where/whether to link it elsewhere for visibility -- it might come down to particular use cases. That, plus networking is just a small subset of full cloud-init functionality.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.