F5Networks / f5-declarative-onboarding

F5 BIG-IP Declarative Onboarding
Apache License 2.0
58 stars 22 forks source link

Adding route class with IPv6 link local address requires target - should match exactly one schema in oneOf #274

Open JeffGiroux opened 2 years ago

JeffGiroux commented 2 years ago

Environment

Summary

Trying to add IPv6 next hop default routes on the BIG-IP. In cloud, there is no default IPv6 traditional gateway and instead uses the link local RA...in which BIG-IP does not participate unfortunately. As a workaround, you must find the link local address in each cloud provider network and use that value as your IPv6 next hop gateway. When creating a route with 'gw' of next hop link local address, the BIG-IP route requires 'target' and to choose interface/vlan too.

Steps To Reproduce

Steps to reproduce the behavior:

  1. Submit a DO declaration with IPv6 self IP and the following declaration:

    {
    "schemaVersion": "1.0.0",
    "class": "Device",
    "async": true,
    "label": "Onboard BIG-IP",
    "Common": {
        "class": "Tenant",
        "dbVars": {
            "class": "DbVariables",
            "restjavad.useextramb": true,
            "provision.extramb": "1000",
            "config.allow.rfc3927": "enable",
            "ui.advisory.enabled": true,
            "ui.advisory.color": "blue",
            "ui.advisory.text": "bigip.f5demo.com"
        },
        "mySystem": {
            "class": "System",
            "autoPhonehome": true,
            "hostname": "bigip.f5demo.com"
        },
        "myDns": {
            "class": "DNS",
            "nameServers": [
                "8.8.8.8",
                "2001:4860:4860::8844"
            ],
            "search": [
                "f5.com"
            ]
        },
        "myNtp": {
            "class": "NTP",
            "servers": [
                "0.us.pool.ntp.org",
                "1.pool.ntp.org",
                "2.pool.ntp.org"
            ],
            "timezone": "UTC"
        },
        "myProvisioning": {
            "class": "Provision",
            "ltm": "nominal"
        },
        "external": {
            "class": "VLAN",
            "tag": 4094,
            "mtu": 1500,
            "interfaces": [
                {
                    "name": "1.1",
                    "tagged": false
                }
            ]
        },
        "internal": {
            "class": "VLAN",
            "tag": 4093,
            "mtu": 1500,
            "interfaces": [
                {
                    "name": "1.2",
                    "tagged": false
                }
            ]
        },
        "external-localself": {
            "class": "SelfIp",
            "address": "10.0.10.10/24",
            "vlan": "external",
            "allowService": "default",
            "trafficGroup": "traffic-group-local-only"
        },
        "external-localself-v6": {
            "class": "SelfIp",
            "address": "fd00:db8:deca:deed::10/64",
            "vlan": "external",
            "allowService": "default",
            "trafficGroup": "traffic-group-local-only"
        },
        "internal-localself": {
            "class": "SelfIp",
            "address": "10.0.20.10/24",
            "vlan": "internal",
            "allowService": "default",
            "trafficGroup": "traffic-group-local-only"
        },
        "internal-localself-v6": {
            "class": "SelfIp",
            "address": "fd00:db8:deca:dcba::10/64",
            "vlan": "internal",
            "allowService": "default",
            "trafficGroup": "traffic-group-local-only"
        },
        "default": {
            "class": "Route",
            "gw": "10.0.10.1",
            "network": "default",
            "mtu": 1500
        },
        "default-v6": {
            "class": "Route",
            "gw": "fe80::1234:5678:9abc",
            "target": "external",
            "network": "default-inet6",
            "mtu": 1500
        }
    }
    }
  2. See this behavior Error when only gw with link local is used (no interace)

        "errors": [
            "transaction failed:a link local gateway requires an interface to be specified",
            "transaction failed:a link local gateway requires an interface to be specified"
        ],

When trying to satisfy this requirement in DO however (link local gw + interrace), you receive error and you cannot add an IPv6 route using link local address as next hop.

                "keyword": "oneOf",
                "dataPath": ".declaration.Common['default-v6']",
                "schemaPath": "#/allOf/7/then/oneOf",
                "params": {
                    "passingSchemas": null
                },
                "message": "should match exactly one schema in oneOf"
            }

Expected Behavior

DO needs to match what TMSH supports. The expected output that does indeed work with tmsh looks like this in bigip.conf

tmsh create net route default-v6 network default-inet6 gw fe80::1234:5678:9abc interface external mtu 1500
tmsh list net route
net route default-v6 {
    gw fe80::1234:5678:9abc
    interface /Common/external
    mtu 1500
    network default-inet6
}

Both 'gw' and 'interface' can be used. You can also perform this action in the UI too.

Actual Behavior

DO errors if you use gw and link local address without interface. However, you cannot use both with DO, so you get an error there too.

JeffGiroux commented 2 years ago

If doing DO in runtime init, then here's the equivalent yaml variabilized

    - extensionType: do
      type: inline
      value:
        schemaVersion: 1.0.0
        class: Device
        async: true
        label: Onboard BIG-IP
        Common:
          class: Tenant
          dbVars:
            class: DbVariables
            restjavad.useextramb: true
            provision.extramb: 1000
            config.allow.rfc3927: enable
            ui.advisory.enabled: true
            ui.advisory.color: blue
            ui.advisory.text: '{{{ HOST_NAME }}}.example.com'
          mySystem:
            autoPhonehome: true
            class: System
            hostname: '{{{ HOST_NAME }}}.example.com'
          '{{{ USER_NAME }}}':
            class: User
            partitionAccess:
              all-partitions:
                role: admin
            password: '{{{ ADMIN_PASS }}}'
            shell: bash
            userType: regular
            keys:
              - '{{{ SSH_KEYS }}}'
          myDns:
            class: DNS
            nameServers:
              - '{{{ DNS_SERVER }}}'
              - 2001:4860:4860::8844
            search:
              - f5.com
          myNtp:
            class: NTP
            servers:
              - '{{{ NTP_SERVER }}}'
              - 1.pool.ntp.org
              - 2.pool.ntp.org
            timezone: '{{{ TIMEZONE }}}'
          myProvisioning:
            class: Provision
            ltm: nominal
          external:
            class: VLAN
            tag: 4094
            mtu: 1500
            interfaces:
              - name: 1.1
                tagged: false
          external-localself:
            class: SelfIp
            address: '{{{ SELF_IP_EXTERNAL }}}/24'
            vlan: external
            allowService: default
            trafficGroup: traffic-group-local-only
          external-localself-v6:
            class: SelfIp
            address: '{{{ SELF_IP_EXTERNAL_V6 }}}/64'
            vlan: external
            allowService: default
            trafficGroup: traffic-group-local-only
          internal:
            class: VLAN
            tag: 4093
            mtu: 1500
            interfaces:
              - name: 1.2
                tagged: false
          internal-localself:
            class: SelfIp
            address: '{{{ SELF_IP_INTERNAL }}}/24'
            vlan: internal
            allowService: default
            trafficGroup: traffic-group-local-only
          internal-localself-v6:
            class: SelfIp
            address: '{{{ SELF_IP_INTERNAL_V6 }}}/64'
            vlan: internal
            allowService: default
            trafficGroup: traffic-group-local-only
          default:
            class: Route
            gw: '{{{ GATEWAY_EXTERNAL }}}'
            network: default
            mtu: 1500
          default-v6:
            class: Route
            gw: '{{{ GATEWAY_EXTERNAL_V6 }}}'
            target: external
            network: default-inet6
            mtu: 1500
JeffGiroux commented 2 years ago

Workaround

Will require tmsh commands. If using runtime init, you can use the DO stuff within runtime init minus the route for v6. Then...add the v6 route with tmsh commands in the post_onboard section like this.

post_onboard_enabled:
  - name: misc_commands
    type: inline
    commands:
    - tmsh create net route default-v6 network default-inet6 gw '{{{ GATEWAY_EXTERNAL_V6 }}}' interface external mtu 1500
    - tmsh save sys config
dstokesf5 commented 2 years ago

Thank you for your feedback. I have added this issue to our internal product backlog as AUTOTOOL-2823.