Forcepoint / fp-NGFW-SMC-ansible

Apache License 2.0
6 stars 5 forks source link

Incorrect engine yaml exports and dual stack configuration issues #6

Open pfromme25 opened 1 month ago

pfromme25 commented 1 month ago

Hi,

some general information first:

We are experiencing issues with both the engine and engine_facts module in conjunction with dual stack interfaces.

For the engine_facts module, exporting our current configuration in yaml format omits one address family of two configured CVIs for an interface, while the NDIs are present. Fixing this export manually does not seem to garner any results, as no changes in our yaml configuration get applied in the SMC.

E.g. an interface on an engine with the following configuration:

exports as follows:

                        "cvi_mode": "packetdispatch",
                        "interface_id": "0",
                        "interfaces": [
                            {
                                "cluster_virtual": "2001::1",
                                "network_value": "2001::/64",
                                "nodes": [
                                    {
                                        "address": "10.100.100.3",
                                        "network_value": "10.100.100.0/24",
                                        "nodeid": 2
                                    },
                                    {
                                        "address": "10.100.100.2",
                                        "network_value": "10.100.100.0/24",
                                        "nodeid": 1
                                    },
                                    {
                                        "address": "2001::2",
                                        "network_value": "2001::/64",
                                        "nodeid": 1
                                    },
                                    {
                                        "address": "2001::3",
                                        "network_value": "2001::/64",
                                        "nodeid": 2
                                    }
                                ]
                            }
                        ],

With one CVI clearly missing and the NDIs of the other address family being lumped together with the one it actually exported.

We tried fixing this export by manually splitting the interface configuration into two CVIs with their respective NDIs:

interfaces:
      - cluster_virtual: 10.100.100.1
        network_value: 10.100.100.0/24
        nodes:
        - address: 10.100.100.3
          network_value: 10.100.100.0/24
          nodeid: 2
        - address: 10.100.100.2
          network_value: 10.100.100.0/24
          nodeid: 1
      - cluster_virtual: 2001::1
        network_value: 2001::/64
        nodes:
        - address: 2001::2
          network_value: 2001::/64
          nodeid: 1
        - address: 2001::3
          network_value: 2001::/64
          nodeid: 2

However, no matter if we keep the original export mentioned above nor using our fixed version, no changes in the yaml configuration (e.g. changing an address from 2001::2 to 2001::50) for these interfaces get applied on the SMC side. The ansible run simply states "ok" as in no changes were made and this is correctly reported. Checking in the SMC, these interfaces stay unaltered no matter if we change a CVI or NDI of this dual stack interface. Looking at the code, we assume it goes wrong somewhere between the hand-off point of the ansible module and the smc-python library as the ansible module simply calls the smc-python library with the interfaces in its yaml definition and states changes made only if the smc-python library reports so.

This only affects dual stack interfaces, as interfaces with a single CVI have a working export and can be changed later by altering the yaml definition.

We noticed that the engine_facts module seems to omit one CVI as soon as we export it as yaml. However, the original json export has a slightly different format and shows both CVIs:

"interfaces": [
                                {
                                    "node_interface": {
                                        "address": "10.100.100.3",
                                        "auth_request": false,
                                        "auth_request_source": false,
                                        "automatic_default_route": false,
                                        "backup_heartbeat": false,
                                        "backup_mgt": false,
                                        "domain_specific_dns_queries_source": false,
                                        "dynamic": false,
                                        "igmp_mode": "none",
                                        "key": 147,
                                        "network_value": "10.100.100.0/24",
                                        "nicid": "0",
                                        "nodeid": 2,
                                        "outgoing": true,
                                        "pppoa": false,
                                        "pppoe": false,
                                        "primary_heartbeat": true,
                                        "primary_mgt": true,
                                        "reverse_connection": false,
                                        "vrrp": false,
                                        "vrrp_id": -1,
                                        "vrrp_priority": -1
                                    }
                                },
                                {
                                    "cluster_virtual_interface": {
                                        "address": "10.100.100.1",
                                        "auth_request": true,
                                        "igmp_mode": "none",
                                        "key": 145,
                                        "network_value": "10.100.100.0/24",
                                        "nicid": "0",
                                        "relayed_by_dhcp": false
                                    }
                                },
                                {
                                    "node_interface": {
                                        "address": "10.100.100.2",
                                        "auth_request": false,
                                        "auth_request_source": false,
                                        "automatic_default_route": false,
                                        "backup_heartbeat": false,
                                        "backup_mgt": false,
                                        "domain_specific_dns_queries_source": false,
                                        "dynamic": false,
                                        "igmp_mode": "none",
                                        "key": 146,
                                        "network_value": "10.100.100.0/24",
                                        "nicid": "0",
                                        "nodeid": 1,
                                        "outgoing": true,
                                        "pppoa": false,
                                        "pppoe": false,
                                        "primary_heartbeat": true,
                                        "primary_mgt": true,
                                        "reverse_connection": false,
                                        "vrrp": false,
                                        "vrrp_id": -1,
                                        "vrrp_priority": -1
                                    }
                                },
                                {
                                    "cluster_virtual_interface": {
                                        "address": "2001::1",
                                        "auth_request": false,
                                        "igmp_mode": "none",
                                        "key": 151,
                                        "network_value": "2001::/64",
                                        "nicid": "0",
                                        "relayed_by_dhcp": false
                                    }
                                },
                                {
                                    "node_interface": {
                                        "address": "2001::2",
                                        "auth_request": false,
                                        "auth_request_source": false,
                                        "automatic_default_route": false,
                                        "backup_heartbeat": false,
                                        "backup_mgt": false,
                                        "domain_specific_dns_queries_source": false,
                                        "dynamic": false,
                                        "igmp_mode": "none",
                                        "key": 152,
                                        "network_value": "2001::/64",
                                        "nicid": "0",
                                        "nodeid": 1,
                                        "outgoing": false,
                                        "pppoa": false,
                                        "pppoe": false,
                                        "primary_heartbeat": false,
                                        "primary_mgt": false,
                                        "reverse_connection": false,
                                        "vrrp": false,
                                        "vrrp_id": -1,
                                        "vrrp_priority": -1
                                    }
                                },
                                {
                                    "node_interface": {
                                        "address": "2001::3",
                                        "auth_request": false,
                                        "auth_request_source": false,
                                        "automatic_default_route": false,
                                        "backup_heartbeat": false,
                                        "backup_mgt": false,
                                        "domain_specific_dns_queries_source": false,
                                        "dynamic": false,
                                        "igmp_mode": "none",
                                        "key": 153,
                                        "network_value": "2001::/64",
                                        "nicid": "0",
                                        "nodeid": 2,
                                        "outgoing": false,
                                        "pppoa": false,
                                        "pppoe": false,
                                        "primary_heartbeat": false,
                                        "primary_mgt": false,
                                        "reverse_connection": false,
                                        "vrrp": false,
                                        "vrrp_id": -1,
                                        "vrrp_priority": -1
                                    }
                                }
],

We used the example templates provided in this repository, exporting our engine config with the following:

{% if results.ansible_facts.engines %}
- name: Firewall template
  engine:
{% for engine in results.ansible_facts.engines %}
{{- engine | to_nice_yaml(indent=2) | indent(4, True) }}
{% endfor %}
{% endif %}

And using this in our tasks:

- name: Write the yaml using a jinja template
  template: src=templates/engine_yaml.j2 dest=testcluster-export.yml

For checking the module output in both yaml and json, we used:

- name: Get engine details for 'testcluster' as yaml
  register: results
  engine_facts:
    filter: AnsibleTestCluster
    as_yaml: true

- name: Get engine details for 'testcluster' as json
  register: results
  engine_facts:
    filter: AnsibleTestCluster

In this regard, we also noticed the yaml export missing any information about configured DHCP relays or other adjacent information. Is it possible to configure these settings through the ansible module?

Thank you very much in advance.

amol-suruse commented 1 month ago

where did you get this export? from api response of smc or some thing else?

"cvi_mode": "packetdispatch", "interface_id": "0", "interfaces": [ { "cluster_virtual": "2001::1", "network_value": "2001::/64", "nodes": [ { "address": "10.100.100.3", "network_value": "10.100.100.0/24", "nodeid": 2 }, { "address": "10.100.100.2", "network_value": "10.100.100.0/24", "nodeid": 1 }, { "address": "2001::2", "network_value": "2001::/64", "nodeid": 1 }, { "address": "2001::3", "network_value": "2001::/64", "nodeid": 2 } ] } ],

pfromme25 commented 1 month ago

where did you get this export? from api response of smc or some thing else?

This was the output of an ansible playbook debug run (with -vvv) outputting the ansible_facts of the engine.

If it is of any help, here is the complete yaml output of the template for a test engine we created:

- name: Firewall template
  engine:
    antivirus: false
    bgp:
      enabled: false
      router_id: null
    cluster_mode: balancing
    default_nat: automatic
    file_reputation: false
    interfaces:
    - cvi_mode: packetdispatch
      interface_id: '1'
      interfaces:
      - cluster_virtual: 2002::9
        network_value: 2002::/64
        nodes:
        - address: 2002::6
          network_value: 2002::/64
          nodeid: 1
        - address: 2002::8
          network_value: 2002::/64
          nodeid: 2
      macaddress: REDACTED
      zone_ref: REDACTED
    - cvi_mode: packetdispatch
      interface_id: '0'
      interfaces:
      - cluster_virtual: 2001::1
        network_value: 2001::/64
        nodes:
        - address: 10.100.100.3
          network_value: 10.100.100.0/24
          nodeid: 2
        - address: 10.100.100.2
          network_value: 10.100.100.0/24
          nodeid: 1
        - address: 2001::2
          network_value: 2001::/64
          nodeid: 1
        - address: 2001::3
          network_value: 2001::/64
          nodeid: 2
      macaddress: REDACTED
      zone_ref: REDACTED
    log_server: REDACTED
    name: AnsibleTestCluster
    ospf:
      enabled: false
      router_id: null
    primary_heartbeat: '0'
    primary_mgt: '0'
    type: fw_cluster

And here is the corresponding screenshot of the interface configuration in SMC: ansible-test-cluster

amol-suruse commented 1 month ago

Hi, We have created an internal ticket to fix this issue. We will fix it in the upcoming release.

Thanks