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

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

Open
kaiseranton opened this issue Aug 1, 2022 · 9 comments
Open

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

kaiseranton opened this issue Aug 1, 2022 · 9 comments
Assignees

Comments

@kaiseranton
Copy link

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
  • Bug Report
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:

  • name: Gather listed OGs with provided configurations
    cisco.asa.asa_ogs:
    config:
    state: gathered

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
Copy link
Member

@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
Copy link
Author

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
Copy link
Author

Another way to Test it without 2 ASAs is:
0. Configure the BGroup & AGroup on your ASA by Hand

  1. Run a play with state "gathered" and save the output
  2. Delete by hand the 2 groups from the ASA
  3. Run a play with state "replaced" and your saved output
  • You will get an error because of the sorted groups

@justjais
Copy link
Member

@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:
  - object_groups:
    - group_object:
      - BGroup
      name: AGroup
    - name: BGroup
      network_object:
        host:
        - 192.168.1.1
    object_type: network
  invocation:
    module_args:
      config: null
      running_config: null
      state: gathered

PLAY RECAP ***********************************************************************************************************************************************************************
44.235.77.146              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  1. Delete the 2 groups from the ASA manually
    ASA device config:
ciscoasa# sh object-group
ciscoasa#
  1. Run a play with the state "replaced" and your saved output
    Ansible play:
- name: Run gathered result using Replaced
      cisco.asa.asa_ogs:
        config:
        - object_groups:
          - group_object:
            - BGroup
            name: AGroup
          - name: BGroup
            network_object:
              host:
              - 192.168.1.1
          object_type: network
        state: replaced

Play run:

➜  security_collections ansible-playbook -i inventory asa_og.yaml

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:
  - object_groups:
    - name: AGroup
    - name: BGroup
      network_object:
        host:
        - 192.168.1.1
    object_type: network
  before: {}
  commands:
  - object-group network AGroup
  - group-object BGroup
  - object-group network BGroup
  - network-object host 192.168.1.1
  invocation:
    module_args:
      config:
      - object_groups:
        - description: null
          group_object:
          - BGroup
          icmp_type: null
          name: AGroup
          network_object: null
          port_object: null
          protocol: null
          protocol_object: null
          security_group: null
          service_object: null
          services_object: null
          user_object: null
        - description: null
          group_object: null
          icmp_type: null
          name: BGroup
          network_object:
            address: null
            host:
            - 192.168.1.1
            ipv6_address: null
            object: null
          port_object: null
          protocol: null
          protocol_object: null
          security_group: null
          service_object: null
          services_object: null
          user_object: null
        object_type: network
      running_config: null
      state: replaced
META: ran handlers
META: ran handlers

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:
  - object_groups:
    - group_object:
      - BGroup
      name: AGroup
    - name: BGroup
      network_object:
        host:
        - 192.168.1.1
    object_type: network
  before:
  - object_groups:
    - name: AGroup
    - name: BGroup
      network_object:
        host:
        - 192.168.1.1
    object_type: network
  commands:
  - object-group network AGroup
  - group-object BGroup
  invocation:
    module_args:
      config:
      - object_groups:
        - description: null
          group_object:
          - BGroup
          icmp_type: null
          name: AGroup
          network_object: null
          port_object: null
          protocol: null
          protocol_object: null
          security_group: null
          service_object: null
          services_object: null
          user_object: null
        - description: null
          group_object: null
          icmp_type: null
          name: BGroup
          network_object:
            address: null
            host:
            - 192.168.1.1
            ipv6_address: null
            object: null
          port_object: null
          protocol: null
          protocol_object: null
          security_group: null
          service_object: null
          services_object: null
          user_object: null
        object_type: network
      running_config: null
      state: replaced

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:
  - object_groups:
    - group_object:
      - BGroup
      name: AGroup
    - name: BGroup
      network_object:
        host:
        - 192.168.1.1
    object_type: network
  commands: []
  invocation:
    module_args:
      config:
      - object_groups:
        - description: null
          group_object:
          - BGroup
          icmp_type: null
          name: AGroup
          network_object: null
          port_object: null
          protocol: null
          protocol_object: null
          security_group: null
          service_object: null
          services_object: null
          user_object: null
        - description: null
          group_object: null
          icmp_type: null
          name: BGroup
          network_object:
            address: null
            host:
            - 192.168.1.1
            ipv6_address: null
            object: null
          port_object: null
          protocol: null
          protocol_object: null
          security_group: null
          service_object: null
          services_object: null
          user_object: null
        object_type: network
      running_config: null
      state: replaced

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
Copy link
Author

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
Copy link
Member

@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
Copy link
Author

Thank you!

@kaiseranton
Copy link
Author

@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
Copy link
Author

I just created a pull request to add a toggle switch. That would be a great solution for me :) #189

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

2 participants