CiscoDevNet / ansible-dcnm

Apache License 2.0
47 stars 37 forks source link

Policy delete deploying pending configs for switch in the fabric as opposed to only declared policy. #179

Open samurato opened 2 years ago

samurato commented 2 years ago

Community Note

Ansible Version and collection version

DCNM version

Affected module(s)

Ansible Playbook

- name: Delete no password strength policy
  cisco.dcnm.dcnm_service_policy:
    fabric: "{{ targeted_fabric }}"
    state: deleted 
    config:
      - name: CUSTOM_TEMPLATE_v1_1  # name is mandatory
      - switch:
          - ip: "{{ targeted_ip }}"

Debug Output

(automation-env) : ~/code/to-git/cisco-dcnm-module-playbooks$ ansible-playbook -i inventory policy.yml -vvv
ansible-playbook 2.10.5
config file = /home/code/to-git/cisco-dcnm-module-playbooks/ansible.cfg
configured module search path = ['/home/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /var/venv/automation-env/lib/python3.8/site-packages/ansible
executable location = /var/venv/automation-env/bin/ansible-playbook
python version = 3.8.10 (default, Jun 22 2022, 20:18:18) [GCC 9.4.0]
Using /home/code/to-git/cisco-dcnm-module-playbooks/ansible.cfg as config file
host_list declined parsing /home/code/to-git/cisco-dcnm-module-playbooks/inventory as it did not pass its verify_file() method
script declined parsing /home/code/to-git/cisco-dcnm-module-playbooks/inventory as it did not pass its verify_file() method
auto declined parsing /home/code/to-git/cisco-dcnm-module-playbooks/inventory as it did not pass its verify_file() method
Parsed /home/code/to-git/cisco-dcnm-module-playbooks/inventory inventory source with ini plugin
[WARNING]: While constructing a mapping from /home/code/to-git/cisco-dcnm-module-playbooks/policy.yml, line 7, column 5, found a duplicate dict key (targeted_fabric). Using last defined value only.
Skipping callback 'default', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.

PLAYBOOK: policy.yml *****************************************************************************************************************************************************************************************
1 plays in policy.yml

PLAY [dcnm_controllers] **************************************************************************************************************************************************************************************
META: ran handlers

TASK [leaf-switch-deploy : DCNM Delete no password strength-check Policy] ************************************************************************************************************************************
task path: /home/code/to-git/cisco-dcnm-module-playbooks/roles/leaf-switch-deploy/tasks/main.yml:3
included: /home/code/to-git/cisco-dcnm-module-playbooks/roles/leaf-switch-deploy/tasks/custom-delete-password-policy.yml for 10.10.10.10 => (item={'targeted_ip': '10.10.20.10', 'leaf': True, 'tcam_model_leaf': True})

TASK [leaf-switch-deploy : Delete no password strength policy] ***********************************************************************************************************************************************
task path: /home/code/to-git/cisco-dcnm-module-playbooks/roles/leaf-switch-deploy/tasks/custom-delete-password-policy.yml:1
<10.10.10.10> ESTABLISH LOCAL CONNECTION FOR USER: sam
<10.10.10.10> EXEC /bin/sh -c '( umask 77 && mkdir -p "echo /home/.ansible/tmp/ansible-local-728699ci1g9qf4"&& mkdir "echo /home/.ansible/tmp/ansible-local-728699ci1g9qf4/ansible-tmp-1661914438.7802823-728714-49864876881276" && echo ansible-tmp-1661914438.7802823-728714-49864876881276="echo /home/.ansible/tmp/ansible-local-728699ci1g9qf4/ansible-tmp-1661914438.7802823-728714-49864876881276" ) && sleep 0'
<10.10.10.10> Attempting python interpreter discovery
<10.10.10.10> EXEC /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'/usr/bin/python'"'"'; command -v '"'"'python3.7'"'"'; command -v '"'"'python3.6'"'"'; command -v '"'"'python3.5'"'"'; command -v '"'"'python2.7'"'"'; command -v '"'"'python2.6'"'"'; command -v '"'"'/usr/libexec/platform-python'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python'"'"'; echo ENDFOUND && sleep 0'
<10.10.10.10> EXEC /bin/sh -c '/usr/bin/python && sleep 0'
Using module file /var/venv/automation-env/lib/python3.8/site-packages/ansible_collections/cisco/dcnm/plugins/modules/dcnm_policy.py
<10.10.10.10> PUT /home/.ansible/tmp/ansible-local-728699ci1g9qf4/tmpyqaq7sg5 TO /home/.ansible/tmp/ansible-local-728699ci1g9qf4/ansible-tmp-1661914438.7802823-728714-49864876881276/AnsiballZ_dcnm_policy.py
<10.10.10.10> EXEC /bin/sh -c 'chmod u+x /home/.ansible/tmp/ansible-local-728699ci1g9qf4/ansible-tmp-1661914438.7802823-728714-49864876881276/ /home/.ansible/tmp/ansible-local-728699ci1g9qf4/ansible-tmp-1661914438.7802823-728714-49864876881276/AnsiballZ_dcnm_policy.py && sleep 0'
<10.10.10.10> EXEC /bin/sh -c '/usr/bin/python3 /home/.ansible/tmp/ansible-local-728699ci1g9qf4/ansible-tmp-1661914438.7802823-728714-49864876881276/AnsiballZ_dcnm_policy.py && sleep 0'

changed: [10 .2.2.2] => changed=true 
  diff:
  - deleted:
    - policy: POLICY-6089180
      templateName: CUSTOM_TEMPLATE_v1_1
    deploy: []
    merged: []
    query: []
    skipped: []
  invocation:
    module_args:
      config:
      - name: CUSTOM_TEMPLATE_v1_1
      - switch:
        - ip: 10.1.1.1
      deploy: false
      fabric: SAM-Fabric
      state: deleted
  response:
  - DATA:
      autoGenerated: false
      createdOn: 1668125287452
      deleted: true
      description: ''
      entityName: SWITCH
      entityType: SWITCH
      generatedConfig: |-
        username admin password password
      id: 6089180
      modifiedOn: 1668125287452
      nvPairs:
        FABRIC_NAME: SAM-Password
        PASSWORD: password
        USERNAME: admin
      policyId: POLICY-6089180
      priority: -101
      serialNumber: XXXXXXX
      source: ''
      status: NA
      statusOn: 1668125287452
      templateContentType: TEMPLATE_CLI
      templateName: CUSTOM_TEMPLATE_v1_1
    MESSAGE: OK
    METHOD: PUT
    REQUEST_PATH: https://10.2.2.2:443/rest/control/policies/POLICY-12345/mark-delete
    RETURN_CODE: 200
  - DATA:
      status: Config deployment has been triggered
    MESSAGE: OK
    METHOD: POST
    REQUEST_PATH: https://10.2.2.2:443/rest/control/fabrics/SAM-Fabric/config-deploy/xxxxxxx
    RETURN_CODE: 200

Expected Behavior

This should only push the policy that we are targeting all the policies that has been in pending. Example in the Gui Rest API tool A put request is sent when I delete a policy

PUT /rest/control/policies/POLICY-12345

{
    "id": 12345,
    "source": "",
    "serialNumber": "xxxxxxxxx",
    "policyId": "POLICY-12345",
    "entityType": "SWITCH",
    "entityName": "SWITCH",
    "templateName": "CUSTOM_TEMPLATE_v1_1",
    "priority": -101,
    "nvPairs": {
        "USERNAME": "username",
        "FABRIC_NAME": "sam-fabric",
        "PASSWORD": "password"
    },
    "deleted": true
}
Status 200 - Took 429ms

Actual Behavior

This playbook is marking a policy to be deleted and dpeloying all the pending configs. So all the configs that are staged (not deployed) will also be deployed. This behavious is due to two rest call being made

METHOD: PUT
    REQUEST_PATH: https://10.2.2.2:443/rest/control/policies/POLICY-12345/mark-delete

METHOD: POST
    REQUEST_PATH: https://10.2.2.2:443/rest/control/fabrics/SAM-Fabric/config-deploy/xxxxxxx

Steps to Reproduce

Setup 2-3 policies via GUI but do not deploy them. Use the playbook and try to delete one policy. We can see the fabric goes in sync due to the

    REQUEST_PATH: https://10.2.2.2:443/rest/control/fabrics/SAM-Fabric/config-deploy/xxxxxxx

This should not happen as other policies are not supposed to be touched by this module as we are targeting per policy

References

I think by invoking just the rest call below we can achieve https://github.com/CiscoDevNet/ansible-dcnm/issues/164 However, this needs to be tested

METHOD: PUT
    REQUEST_PATH: https://10.2.2.2:443/rest/control/policies/POLICY-12345/mark-delete

https://github.com/CiscoDevNet/ansible-dcnm/issues/163 :- This bug blast radius has narrowed down to switch as opposed to fabric level. Also, I have replaced my values with dummy values for config data.

dsx1123 commented 2 years ago

@samurato mark-delete will only mark the policy as deleted so the next recalculation of the entire configuration of the switch will generate "no xxxx" to remove the configuration from the switch.

NDFC can't just simply delete the command in policy by appending no in the front, your example is simple as there is no context. Let's take a look below example if you configure a bgp neighbor:

router bgp 65001
  neighbor 192.10.0.1
   remote-as 65001

NDFC can't just add no command on each line of the config as it will be valid:

  1. there might be still other neighbors configured under BGP
  2. remove neighbor 192.10.0.1 will also remove and context under it, so no remote-as 65001 will be an invalid command line

In a nutshell, in order to remove the configuration that is deployed from policy, NDFC has to recalculate the entire configuration of the given switch and deploy it. The behavior of the module is expected.