F5Networks / f5-ansible

Imperative Ansible modules for F5 BIG-IP products
GNU General Public License v3.0
375 stars 231 forks source link

bigip_policy - httplib.InvalidURL when rule name contains control characters (eg: space) #1650

Closed BapRx closed 3 years ago

BapRx commented 4 years ago
ISSUE TYPE
COMPONENT NAME

bigip_policy

ANSIBLE VERSION
ansible 2.9.0
  config file = /home/baptiste/ansible-for-f5/ansible.cfg
  configured module search path = ['/home/baptiste/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.7/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]
PYTHON VERSION

Tried python version 3.7.3 and 2.7.16

BIGIP VERSION

Version: 14.1.2 Build 0.0.37

SUMMARY

When a policy rule name contains control characters, 'Drop All' for example, the module would raise the following exception : httplib.InvalidURL: URL can't contain control characters. '/mgmt/tm/ltm/policy/~Common~Drafts~policy_name/rules/Drop All' (found at least ' ')

STEPS TO REPRODUCE

For example :

EXPECTED RESULTS
TASK [policy : Re-ordering Policy Rules.] ***************************************************
changed: [10.33.49.75]
ACTUAL RESULTS
TASK [policy : Re-ordering Policy Rules.] ***************************************************
The full traceback is:
Traceback (most recent call last):
  File "/home/baptiste/.ansible/tmp/ansible-tmp-1581595307.5431423-263906382893521/AnsiballZ_bigip_policy.py", line 102, in <module>
    _ansiballz_main()
  File "/home/baptiste/.ansible/tmp/ansible-tmp-1581595307.5431423-263906382893521/AnsiballZ_bigip_policy.py", line 94, in _ansiballz_main
    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)
  File "/home/baptiste/.ansible/tmp/ansible-tmp-1581595307.5431423-263906382893521/AnsiballZ_bigip_policy.py", line 40, in invoke_module
    runpy.run_module(mod_name='ansible.modules.network.f5.bigip_policy', init_globals=None, run_name='__main__', alter_sys=False)
  File "/usr/lib/python2.7/runpy.py", line 192, in run_module
    fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 1128, in <module>
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 1121, in main
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 1069, in exec_module
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 763, in exec_module
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 790, in present
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 838, in update
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 940, in update_on_device
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 527, in _upsert_policy_rules_on_device
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py", line 493, in _rule_exists_on_device
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/network/f5/icontrol.py", line 232, in get
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/network/f5/icontrol.py", line 193, in send
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/urls.py", line 1294, in open
  File "/usr/lib/python2.7/urllib2.py", line 154, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib/python2.7/urllib2.py", line 429, in open
    response = self._open(req, data)
  File "/usr/lib/python2.7/urllib2.py", line 447, in _open
    '_open', req)
  File "/usr/lib/python2.7/urllib2.py", line 407, in _call_chain
    result = func(*args)
  File "/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/urls.py", line 467, in https_open
  File "/usr/lib/python2.7/urllib2.py", line 1195, in do_open
    h.request(req.get_method(), req.get_selector(), req.data, headers)
  File "/usr/lib/python2.7/httplib.py", line 1058, in request
    self._send_request(method, url, body, headers)
  File "/usr/lib/python2.7/httplib.py", line 1092, in _send_request
    self.putrequest(method, url, **skips)
  File "/usr/lib/python2.7/httplib.py", line 945, in putrequest
    % (url, match.group()))
httplib.InvalidURL: URL can't contain control characters. '/mgmt/tm/ltm/policy/~Common~Drafts~policy_name/rules/Drop All' (found at least ' ')

fatal: [10.33.49.75]: FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "module_stderr": "Traceback (most recent call last):\n  File \"/home/baptiste/.ansible/tmp/ansible-tmp-1581595307.5431423-263906382893521/AnsiballZ_bigip_policy.py\", line 102, in <module>\n    _ansiballz_main()\n  File \"/home/baptiste/.ansible/tmp/ansible-tmp-1581595307.5431423-263906382893521/AnsiballZ_bigip_policy.py\", line 94, in _ansiballz_main\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\n  File \"/home/baptiste/.ansible/tmp/ansible-tmp-1581595307.5431423-263906382893521/AnsiballZ_bigip_policy.py\", line 40, in invoke_module\n    runpy.run_module(mod_name='ansible.modules.network.f5.bigip_policy', init_globals=None, run_name='__main__', alter_sys=False)\n  File \"/usr/lib/python2.7/runpy.py\", line 192, in run_module\n    fname, loader, pkg_name)\n  File \"/usr/lib/python2.7/runpy.py\", line 72, in _run_code\n    exec code in run_globals\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 1128, in <module>\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 1121, in main\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 1069, in exec_module\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 763, in exec_module\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 790, in present\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 838, in update\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 940, in update_on_device\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 527, in _upsert_policy_rules_on_device\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/modules/network/f5/bigip_policy.py\", line 493, in _rule_exists_on_device\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/network/f5/icontrol.py\", line 232, in get\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/network/f5/icontrol.py\", line 193, in send\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/urls.py\", line 1294, in open\n  File \"/usr/lib/python2.7/urllib2.py\", line 154, in urlopen\n    return opener.open(url, data, timeout)\n  File \"/usr/lib/python2.7/urllib2.py\", line 429, in open\n    response = self._open(req, data)\n  File \"/usr/lib/python2.7/urllib2.py\", line 447, in _open\n    '_open', req)\n  File \"/usr/lib/python2.7/urllib2.py\", line 407, in _call_chain\n    result = func(*args)\n  File \"/tmp/ansible_bigip_policy_payload_1Yh5RH/ansible_bigip_policy_payload.zip/ansible/module_utils/urls.py\", line 467, in https_open\n  File \"/usr/lib/python2.7/urllib2.py\", line 1195, in do_open\n    h.request(req.get_method(), req.get_selector(), req.data, headers)\n  File \"/usr/lib/python2.7/httplib.py\", line 1058, in request\n    self._send_request(method, url, body, headers)\n  File \"/usr/lib/python2.7/httplib.py\", line 1092, in _send_request\n    self.putrequest(method, url, **skips)\n  File \"/usr/lib/python2.7/httplib.py\", line 945, in putrequest\n    % (url, match.group()))\nhttplib.InvalidURL: URL can't contain control characters. '/mgmt/tm/ltm/policy/~Common~Drafts~policy_name/rules/Drop All' (found at least ' ')\n",
    "module_stdout": "",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}
FIX

Escaping rule names with the urllib module.

+ import urllib
-            if self._rule_exists_on_device(rule, draft):
+            if self._rule_exists_on_device(urllib.quote_plus(rule), draft):
-                ordinal = self._read_rule_from_device(rule, draft)
+                ordinal = self._read_rule_from_device(urllib.quote_plus(rule), draft)
-                    self._modify_rule_on_device(rule, idx, draft)
+                    self._modify_rule_on_device(urllib.quote_plus(rule), idx, draft)
-                self._create_rule_on_device(rule, idx, draft)
+                self._create_rule_on_device(urllib.quote_plus(rule), idx, draft)
focrensh commented 4 years ago

Tracking with FMFA-481