ansible-collections / cisco.asa

Ansible Security Collection for Cisco ASA
GNU General Public License v3.0
61 stars 46 forks source link

[cisco.asa.asa_ogs] Sorting objects groups lead to problems #176

Open kaiseranton opened 2 years ago

kaiseranton commented 2 years ago
SUMMARY

When the objcet_groups are getting sorted while parsing the running configuration into a json, then it will lead to problems. While trying to use the parsed json to configure a device then it will lead to a problem, that subgroups might be needed but will be configured later because of the sorted names. Example: on ASA: object-group network BGroup network-object host 192.168.1.1 object-group network AGroup group-object BGroup

in parsed JSON: object-group network AGroup group-object BGroup object-group network BGroup network-object host 192.168.1.1

The Module will crash because he is trying to configure something not existing. A simple fix would be, to remove the sort function or make the sort function a boolean to toggle off.

ISSUE TYPE
COMPONENT NAME

cisco.asa.asa_ogs

ANSIBLE VERSION
ansible 2.9.27
python version = 3.6.8 
COLLECTION VERSION
3.1.0
CONFIGURATION
3.1.0
OS / ENVIRONMENT

Redhat Linux

STEPS TO REPRODUCE

Configure a Cisco ASA with: object-group network BGroup network-object host 192.168.1.1 object-group network AGroup group-object BGroup

Afterwards run a play:

Take the output JSON and put it into the same Module with the state "replaced", then it will crash because of the sorted groups.

EXPECTED RESULTS

to configure object-group network BGroup network-object host 192.168.1.1 object-group network AGroup group-object BGroup

ACTUAL RESULTS

it will try to configure object-group network AGroup group-object BGroup object-group network BGroup network-object host 192.168.1.1

justjais commented 2 years ago

@kaiseranton Thanks for raising the issue, but I am unable to reproduce the mentioned bug scenario with the following ASA config and Ansible play.

OG config:

ciscoasa# sh object-group
object-group network BGroup
 network-object host 192.168.1.1
object-group network AGroup
 group-object BGroup

Ansible play:

- name: Gather listed OGs with provided configurations
  cisco.asa.asa_ogs:
    config:
    state: gathered
  register: result
- name: Run gathered result using Replaced
  cisco.asa.asa_ogs:
    config: "{{ result['gathered'] }}"
    state: replaced
  register: replaced_result
- debug:
     msg: "{{ replaced_result }}"

Ansible ply run output:

➜  security_collections ansible-playbook -i inventory asa_og.yaml
PLAY [asa] ***********************************************************************************************************************************************************************

TASK [Gather listed OGs with provided configurations] ****************************************************************************************************************************
ok: [35.88.3.128]

TASK [Run gathered result using Replaced] ****************************************************************************************************************************************
ok: [35.88.3.128]

TASK [debug] *********************************************************************************************************************************************************************
ok: [35.88.3.128] =>
  msg:
    before:
    - object_groups:
      - group_object:
        - BGroup
        name: AGroup
      - name: BGroup
        network_object:
          host:
          - 192.168.1.1
      object_type: network
    changed: false
    commands: []
    failed: false

PLAY RECAP ***********************************************************************************************************************************************************************
35.88.3.128                : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Above, is the expected output for the respective scenario. Let me know if you still have the issue with all of the required details.

kaiseranton commented 2 years ago

Hello @justjais This output is kinda incorrect, If you try to use this output for configuring a different ASA then you will get a problem because of the sorted groups. He will try to configure AGroup with with subgroup BGroup - BGroup dosent exist on a new ASA. This could be fixed if the output woudln't be sorted, then he would configure first BGroup with the IP and afterwards the AGroup with the subgroup BGroup.

Your case only works because you try this on a ASA where BGroup already exists.

Try: ASA 1: You configure BGroup and AGroup by Hand, then you run a play with the state "gathered" - save this output

ASA 2: The ASA has NO groups configured, then try to fill it with the state "replaced" and the data you saved before.

kaiseranton commented 2 years ago

Another way to Test it without 2 ASAs is:

  1. Configure the BGroup & AGroup on your ASA by Hand
  2. Run a play with state "gathered" and save the output
  3. Delete by hand the 2 groups from the ASA
  4. Run a play with state "replaced" and your saved output
    • You will get an error because of the sorted groups
justjais commented 2 years ago

@kaiseranton Thanks for sharing the steps to reproduce. I've used the steps to reproduce with 1 ASA, and below is the observation I've made.

  1. Run a play with state "gathered" and save the output: ASA device config:
    ciscoasa# sh object-group
    object-group network BGroup
    network-object host 192.168.1.1
    object-group network AGroup
    group-object BGroup

    Gather Play run:

    
    ➜  security_collections ansible-playbook -i inventory asa_og.yaml -vvvv
    PLAYBOOK: asa_og.yaml ************************************************************************************************************************************************************
    Positional arguments: asa_og.yaml
    verbosity: 4
    connection: smart
    timeout: 60
    become_method: sudo
    tags: ('all',)
    inventory: ('/Users/sjaiswal/Sumit/ansible_fork/collections/security_collections/inventory',)
    forks: 5
    1 plays in asa_og.yaml

PLAY [asa] ***

TASK [Gather listed OGs with provided configurations] **** ok: [44.235.77.146] => changed=false gathered:

PLAY RECAP *** 44.235.77.146 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0


2. Delete the 2 groups from the ASA manually
ASA device config:

ciscoasa# sh object-group ciscoasa#


3. Run a play with the state "replaced" and your saved output
Ansible play:

PLAYBOOK: asa_og.yaml **** Positional arguments: asa_og.yaml verbosity: 4 connection: smart timeout: 60 become_method: sudo tags: ('all',) inventory: ('/Users/sjaiswal/Sumit/ansible_fork/collections/security_collections/inventory',) forks: 5 1 plays in asa_og.yaml

PLAY [asa] *** META: ran handlers redirecting (type: action) cisco.asa.asa_ogs to cisco.asa.asa Loading collection ansible.netcommon from /Users/sjaiswal/Sumit/ansible_fork/collections/security_collections/collections/ansible_collections/ansible/netcommon

TASK [Run gathered result using Replaced] **** changed: [44.235.77.146] => changed=true after:

PLAY RECAP *** 44.235.77.146 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0


This is the expected output but it doesn’t error out/cause the failure of the play run, which imitates Cisco ASA where it throws a warning that `Specified group object (BGroup) does not exist` but doesn’t error out.

If I run the play again with a similar replace play ideally, the play should be idempotent and show no change but as the `group-object BGroup` config cmd was not executed the last time there would be a config diff and play would apply the respective change again and as this time `BGroup` exists, config change would be made as expected.

ref play run:

➜ security_collections ansible-playbook -i inventory asa_og.yaml

PLAYBOOK: asa_og.yaml ****

PLAY [asa] *** META: ran handlers redirecting (type: action) cisco.asa.asa_ogs to cisco.asa.asa Loading collection ansible.netcommon from /Users/sjaiswal/Sumit/ansible_fork/collections/security_collections/collections/ansible_collections/ansible/netcommon

TASK [Run gathered result using Replaced] **** changed: [44.235.77.146] => changed=true after:

PLAY RECAP *** 44.235.77.146 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0


Now, if I run the play again, the play run will be idempotent and with no change, ref play run:

➜ security_collections ansible-playbook -i inventory asa_og.yaml PLAYBOOK: asa_og.yaml ****

PLAY [asa] ***

TASK [Run gathered result using Replaced] **** ok: [44.235.77.146] => changed=false before:

PLAY RECAP *** 44.235.77.146 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0



Can you plz share the play run error that you've mentioned in the issue.
kaiseranton commented 2 years ago

Hi @justjais, thank you for you quick response! then I ment the warning from cisco Specified group object (BGroup) does not exist The problem is, that we use one firewall as "template" and we try to mirror the configuration to many other ASA Firewalls. So that's why we called it a bug, because in the state gathered there is no need for sorting. OGs module does not consider order of creation of dependant subgroups Would it be possible to create a boolean which makes the sorting toggleable?

justjais commented 2 years ago

@kaiseranton sure, let me check with the team and I'll update the thread ASAP. That said I wanted to check if there's any particular issue that you cannot run the same play again twice, as running the play twice would configure the box as expected in this scenario.

kaiseranton commented 2 years ago

Thank you!

kaiseranton commented 2 years ago

@kaiseranton sure, let me check with the team and I'll update the thread ASAP. That said I wanted to check if there's any particular issue that you cannot run the same play again twice, as running the play twice would configure the box as expected in this scenario.

Hello, do you have any News?

kaiseranton commented 2 years ago

I just created a pull request to add a toggle switch. That would be a great solution for me :) https://github.com/ansible-collections/cisco.asa/pull/189