F5Networks / f5-ansible

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

bigip_command giving dependency error under ansible 2.6.2 #829

Closed Rotorouter closed 6 years ago

Rotorouter commented 6 years ago
ISSUE TYPE
COMPONENT NAME

bigip_command.py

ANSIBLE VERSION
ansible 2.6.2
  config file = /home/routing-buckets/ansible.cfg
  configured module search path = [u'/export/home/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, May  3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]
PYTHON VERSION
Python 2.7.5
BIGIP VERSION
Sys::Version
Main Package
  Product     BIG-IP
  Version     12.1.3.3
  Build       0.0.1
  Edition     Point Release 3
  Date        Fri Mar  9 14:11:15 PST 2018
LIBRARY VERSIONS
bigsuds==1.0.6
f5-sdk==3.0.18
CONFIGURATION
OS / ENVIRONMENT
SUMMARY

Any playbooks I run containing bigip_command tasks give the below error. Ansible, f5-sdk, and bigsuds were all installed via pip. "fatal: [lab-gtm.com]: FAILED! => {"msg": "Could not find imported module support code for bigip_command. Looked for either FailedConditionsError.py or netcli.py"}"

STEPS TO REPRODUCE
- name: Modify GSLB Pools.
  hosts: [lab-gtm]
  connection: local
  gather_facts: no
  vars_files:
    - vars/creds.yaml
  tasks:
    - name: List the Current Members of Pool
      bigip_command:
        provider: "{{ ssh_server }}"
        commands: list gtm pool prod-pool
      delegate_to: localhost
      register: gtm_pool_config

    - debug:
        var: gtm_pool_config.stdout_lines

### The vars/creds.yaml file contains the "{{ ssh_server }}" dict with the provider info; see below. (The same dict works as expected with the bigip_gtm_pool_member module.)
ssh_server:
  ssh_keyfile: vars/id_rsa_f5
  timeout: 20
  server: "{{ inventory_hostname }}"
  user: "{{ un }}"
  password: "{{ pw }}"
  validate_certs: no
  transport: cli
EXPECTED RESULTS

to get the output from the bigip_command module

ACTUAL RESULTS
TASK [List the Current Members of Pool] ***********************************************************************************************************
task path: /home/routing-buckets/tst2.yaml:52
<lab-gtm.com> using connection plugin network_cli
<localhost> ESTABLISH LOCAL CONNECTION FOR USER:
<localhost> EXEC /bin/sh -c 'echo && sleep 0'
<localhost> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /export/home/.ansible/tmp/ansible-tmp-1533163499.46-128415975224046 `" && echo ansible-tmp-1533163499.46-128415975224046="` echo /export/home/.ansible/tmp/ansible-tmp-1533163499.46-128415975224046 `" ) && sleep 0'
fatal: [lab-gtm.com]: FAILED! => {
    "msg": "Could not find imported module support code for bigip_command.  Looked for either FailedConditionsError.py or netcli.py"
Rotorouter commented 6 years ago

FYI, I tried removing the ssh_keyfile from the ssh_server dict and just using username/password. Same results.

Rotorouter commented 6 years ago

Problem also seems to affect the task when it uses rest; here's the relevant task (gives the same error):

- name: List the Current Members of Pool
  bigip_command:
    server: "{{ inventory_hostname }}"
    user: "{{ eiusername }}"
    password: "{{ eipassword }}"
    transport: rest
    warn: no
    validate_certs: no
    commands: list gtm pool a istcalp01-prod-pool
  delegate_to: localhost
  register: gtm_pool_config

We're using this to get snapshots of the config before/after we make the changes so that it shows up in the ansible output logs. If there's another way to get that info let me know (otherwise it's a blocker for using ansible 2.6, which we want to do in order to use the new gtm modules you guys have developed).

caphrim007 commented 6 years ago

@Rotorouter is this a fresh install of ansible? or an upgrade from a previous version? If an upgrade, was the upgrade from an earlier release like 2.5?

Rotorouter commented 6 years ago

Hi Tim, it's an upgrade. The server where I'm running it has been part of a Tower cluster which had had 2.4.4 installed via pip previously. When I upgraded to 2.6.2 I uninstalled 2.4.4 via pip then installed 2.6.2.

caphrim007 commented 6 years ago

@Rotorouter ok, this is becoming more clear.

Here's my W.A.G. In ansible 2.4, the thing that is being raised in the error (FailedConditionsError) did not exist because the file that it needed to exist in, (module_utils/network/common/parsing.py) did not exist.

So, my guess is that during the upgrade, you somehow got the modules for 2.6, but you didnt get (somehow) the module utils for 2.6. I don't really know how that's possible, but it might be the case that you have a custom ansible.cfg that is referring to outdated module utils?

I haven't done a Tower upgrade to be able to best answer this, so we'll need to walk through it a bit to get to the bottom of the issue.

In your ansible installation, do you have a module_utils/network/common/parsing.py file? In fact, does parsing.py exist anywhere on the tower system?

Rotorouter commented 6 years ago

@caphrim007 yea...parsing.py does exist, and looks like it's in the right spot (though maybe not the right version?) $ find / -name parsing.py /usr/lib/python2.7/site-packages/ansible/module_utils/network/common/parsing.py

Do you know what pip package would include that and either FailedConditionsError.py or netcli.py? I'm thinking if I did a force update on whatever that package is it might resolve the dependency issue.

caphrim007 commented 6 years ago

both FailedConditionsError.py and netcli.py are provided by Ansible (in pip). does netcli.py exist anywhere?

Rotorouter commented 6 years ago

netcli.py doesn't exist no. So I did a force reinstall of ansible:

pip install --ignore-installed ansible

netcli.py still wasn't present on the system, so I copied it from another server. After that the playbook complained about other missing modules:

fatal: [lab-gtm.com]: FAILED! => {"msg": "Could not find imported module support code for bigip_command. Looked for either to_list.py or network_common.py"}

So I copied network_common.py over from another server as well. That sort of worked, but it looks like there must be a version difference between what bigip_command.py needs and the version I have, since it barks about not recognizing the "provider" parameter in my task (which isn't even explicitly provided in the task, which is weird. I guess you must route user & password parameters through the provider dict).

"msg": "Unsupported parameters for (bigip_command) module: provider Supported parameters include: commands, interval, match, partition, password, retries, server, server_port, state, user, validate_certs, wait_for"

This is the task:

I guess the ansible package in pypy isn't pulling in its dependencies properly?

caphrim007 commented 6 years ago

@Rotorouter I don't think you're actually using Ansible 2.6. What I mean by that, is that I think Tower might be trying to use it, but it is using the 2.4 binaries or virtualenv instead.

The reason I say that is because netcli.py was in Ansible 2.4, but was removed in 2.5 and hasn't been back since. Also, provider is something that we added to our modules in the 2.5 timeframe.

So I believe you have something wrong with your Tower installation.

Rotorouter commented 6 years ago

So this testing has actually been all from the CLI, not from tower. I'd expect that the bigip_command module wouldn't look for FailedConditionsError.py or netcli.py if ansible 2.6.2 doesn't use them.

$ ansible --version ansible 2.6.2 config file = /home/routing-buckets/ansible.cfg configured module search path = [u'/export/home/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, May 3 2017, 07:55:04) [GCC 4.8.5 20150623 (Red Hat 4.8.5-14)]

caphrim007 commented 6 years ago

@Rotorouter are you running ansible from inside a virtualenv?

Rotorouter commented 6 years ago

Hi Tim, so it looks like it was a stupid environment error after all: Using module file /home/routing-buckets/library/bigip_command.py

That's not the system bigip_command.py, but the one in library/ where I'm running the job, and it's an old module version. My ansible.cfg wasn't pointed to that directory, so this shouldn't have happened, but maybe Ansible changed a compiled in default to look in ./library/

Anyway, your code is innocent. Once I removed those old modules all was sound. Thanks for all your help.

caphrim007 commented 6 years ago

@Rotorouter if you want, PM me (my email address is in my github profile) and we can take this offline. I'm a bit unsure how you got into this situation

Rotorouter commented 6 years ago

@caphrim007 see above, we're copacetic. Thanks for your help and have a good weekend.