171 lines
4.0 KiB
Python
171 lines
4.0 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
# Copyright: (c) 2021, Yanick Champoux <yanick@babyl.ca>
|
||
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||
|
|
||
|
from __future__ import absolute_import, division, print_function
|
||
|
|
||
|
__metaclass__ = type
|
||
|
|
||
|
DOCUMENTATION = r"""
|
||
|
---
|
||
|
module: command_info
|
||
|
|
||
|
short_description: Retrieves information about a given command.
|
||
|
|
||
|
version_added: "1.0.0"
|
||
|
|
||
|
description: Retrieves the location and version of a command on the remote machine.
|
||
|
|
||
|
options:
|
||
|
command_name:
|
||
|
description: Target command.
|
||
|
required: true
|
||
|
type: str
|
||
|
|
||
|
version_args:
|
||
|
description: Arguments passed to the command to print the version string.
|
||
|
required: false
|
||
|
default: --version
|
||
|
type: str
|
||
|
|
||
|
version_regex:
|
||
|
description: Regular expression to capture the version from the command output.
|
||
|
default: v?(\d+\.\d+\.\d+[^\n ]*)
|
||
|
required: false
|
||
|
type: str
|
||
|
|
||
|
target_version:
|
||
|
description: Target version to compare against.
|
||
|
required: false
|
||
|
type: str
|
||
|
|
||
|
author:
|
||
|
- Yanick Champoux (@yanick)
|
||
|
"""
|
||
|
|
||
|
EXAMPLES = r"""
|
||
|
- name: perl info
|
||
|
command_info:
|
||
|
command_name: perl
|
||
|
target_version: 5.32.0
|
||
|
|
||
|
# get the info on ls
|
||
|
- name: ls info
|
||
|
command_info:
|
||
|
command_name: ls
|
||
|
version_regex: '(\d+\.d+)'
|
||
|
target_version: 8.30
|
||
|
"""
|
||
|
|
||
|
RETURN = r"""
|
||
|
needs_upgrade:
|
||
|
description: Wether the new version of the command needs to be installed.
|
||
|
type: bool
|
||
|
sample: True
|
||
|
|
||
|
installed_version:
|
||
|
description: Version string of the currently installed command.
|
||
|
type: str
|
||
|
sample: '1.2.3'
|
||
|
|
||
|
target_version:
|
||
|
description: Version string of the targetted version.
|
||
|
type: str
|
||
|
sample: '1.2.3'
|
||
|
|
||
|
location:
|
||
|
description: Path where the command was found.
|
||
|
type: str
|
||
|
sample: '/usr/local/bin/ls'
|
||
|
"""
|
||
|
|
||
|
from ansible.module_utils.basic import AnsibleModule
|
||
|
import subprocess
|
||
|
import re
|
||
|
|
||
|
def strip_zeros(version):
|
||
|
return re.sub( '^0+', '', version )
|
||
|
|
||
|
def needs_upgrade(version, target):
|
||
|
if not version:
|
||
|
return True
|
||
|
|
||
|
version = list(map( strip_zeros, version.split('.') ))
|
||
|
target = list(map( strip_zeros, target.split('.') ))
|
||
|
for v in version:
|
||
|
t = target.pop(0)
|
||
|
if v < t:
|
||
|
return True
|
||
|
if v > t:
|
||
|
return False
|
||
|
return False
|
||
|
|
||
|
def run_module():
|
||
|
module_args = dict(
|
||
|
command_name=dict(type="str", required=True),
|
||
|
version_args=dict(default="--version"),
|
||
|
version_regex=dict(default=r"v?(\d+\.\d+\.\d+[^\n ]*)"),
|
||
|
target_version=dict(default=None, type="str"),
|
||
|
)
|
||
|
|
||
|
result = dict(
|
||
|
changed=False,
|
||
|
needs_upgrade=False,
|
||
|
installed_version=None,
|
||
|
location=None,
|
||
|
)
|
||
|
|
||
|
module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)
|
||
|
|
||
|
command_name = module.params["command_name"]
|
||
|
|
||
|
if command_name[0] == '/':
|
||
|
result["location"] = command_name
|
||
|
else:
|
||
|
cmd_location = subprocess.run(
|
||
|
[
|
||
|
"which",
|
||
|
command_name,
|
||
|
],
|
||
|
text=True,
|
||
|
capture_output=True,
|
||
|
)
|
||
|
|
||
|
result["location"] = cmd_location.stdout.rstrip()
|
||
|
|
||
|
if result["location"]:
|
||
|
cmd_output = subprocess.run(
|
||
|
[module.params["command_name"], module.params["version_args"]],
|
||
|
capture_output=True,
|
||
|
text=True,
|
||
|
)
|
||
|
|
||
|
result["command_stdout"] = cmd_output.stdout
|
||
|
result["command_stderr"] = cmd_output.stderr
|
||
|
|
||
|
m = re.search(
|
||
|
module.params["version_regex"],
|
||
|
result["command_stdout"] + result["command_stderr"],
|
||
|
)
|
||
|
|
||
|
if m:
|
||
|
result["installed_version"] = m.group(1)
|
||
|
|
||
|
if "target_version" in module.params:
|
||
|
result["target_version"] = module.params["target_version"]
|
||
|
result["needs_upgrade"] = 1 == needs_upgrade(
|
||
|
result["installed_version"],
|
||
|
module.params["target_version"]
|
||
|
)
|
||
|
|
||
|
module.exit_json(**result)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
run_module()
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|