apache2_mod_proxy: big revamp (#9457)
* apache2_mod_proxy: big revamp * fix case when state=null * fix logic for change detectionpull/9766/merge
parent
4867eb4140
commit
98b328c539
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- apache2_mod_proxy - code simplification, no change in functionality (https://github.com/ansible-collections/community.general/pull/9457).
|
|
@ -206,10 +206,11 @@ members:
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from ansible_collections.community.general.plugins.module_utils import deps
|
from ansible_collections.community.general.plugins.module_utils import deps
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper, ModuleHelperException
|
||||||
|
|
||||||
from ansible.module_utils.common.text.converters import to_text
|
from ansible.module_utils.common.text.converters import to_text
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.urls import fetch_url
|
||||||
from ansible.module_utils.six import iteritems, PY2
|
from ansible.module_utils.six import raise_from, PY2
|
||||||
|
|
||||||
if PY2:
|
if PY2:
|
||||||
with deps.declare("BeautifulSoup"):
|
with deps.declare("BeautifulSoup"):
|
||||||
|
@ -270,19 +271,19 @@ class BalancerMember(object):
|
||||||
resp, info = fetch_url(self.module, self.management_url, headers={'Referer': self.management_url})
|
resp, info = fetch_url(self.module, self.management_url, headers={'Referer': self.management_url})
|
||||||
|
|
||||||
if info['status'] != 200:
|
if info['status'] != 200:
|
||||||
self.module.fail_json(msg="Could not get balancer_member_page, check for connectivity! {0}".format(info))
|
raise ModuleHelperException("Could not get balancer_member_page, check for connectivity! {0}".format(info))
|
||||||
else:
|
|
||||||
try:
|
try:
|
||||||
soup = BeautifulSoup(resp)
|
soup = BeautifulSoup(resp)
|
||||||
except TypeError as exc:
|
except TypeError as exc:
|
||||||
self.module.fail_json(msg="Cannot parse balancer_member_page HTML! {0}".format(exc))
|
raise_from(ModuleHelperException("Cannot parse balancer_member_page HTML! {0}".format(exc)), exc)
|
||||||
else:
|
|
||||||
subsoup = find_all(find_all(soup, 'table')[1], 'tr')
|
subsoup = find_all(find_all(soup, 'table')[1], 'tr')
|
||||||
keys = find_all(subsoup[0], 'th')
|
keys = find_all(subsoup[0], 'th')
|
||||||
for valuesset in subsoup[1::1]:
|
for valuesset in subsoup[1::1]:
|
||||||
if re.search(pattern=self.host, string=str(valuesset)):
|
if re.search(pattern=self.host, string=str(valuesset)):
|
||||||
values = find_all(valuesset, 'td')
|
values = find_all(valuesset, 'td')
|
||||||
return {keys[x].string: values[x].string for x in range(0, len(keys))}
|
return {keys[x].string: values[x].string for x in range(0, len(keys))}
|
||||||
|
|
||||||
def get_member_status(self):
|
def get_member_status(self):
|
||||||
""" Returns a dictionary of a balancer member's status attributes."""
|
""" Returns a dictionary of a balancer member's status attributes."""
|
||||||
|
@ -291,7 +292,7 @@ class BalancerMember(object):
|
||||||
'hot_standby': 'Stby',
|
'hot_standby': 'Stby',
|
||||||
'ignore_errors': 'Ign'}
|
'ignore_errors': 'Ign'}
|
||||||
actual_status = self.attributes['Status']
|
actual_status = self.attributes['Status']
|
||||||
status = {mode: patt in actual_status for mode, patt in iteritems(status_mapping)}
|
status = {mode: patt in actual_status for mode, patt in status_mapping.items()}
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def set_member_status(self, values):
|
def set_member_status(self, values):
|
||||||
|
@ -307,7 +308,7 @@ class BalancerMember(object):
|
||||||
|
|
||||||
response, info = fetch_url(self.module, self.management_url, data=request_body, headers={'Referer': self.management_url})
|
response, info = fetch_url(self.module, self.management_url, data=request_body, headers={'Referer': self.management_url})
|
||||||
if info['status'] != 200:
|
if info['status'] != 200:
|
||||||
self.module.fail_json(msg="Could not set the member status! {host} {status}".format(host=self.host, status=info['status']))
|
raise ModuleHelperException("Could not set the member status! {0} {1}".format(self.host, info['status']))
|
||||||
|
|
||||||
attributes = property(get_member_attributes)
|
attributes = property(get_member_attributes)
|
||||||
status = property(get_member_status, set_member_status)
|
status = property(get_member_status, set_member_status)
|
||||||
|
@ -328,13 +329,10 @@ class BalancerMember(object):
|
||||||
class Balancer(object):
|
class Balancer(object):
|
||||||
""" Apache httpd 2.4 mod_proxy balancer object"""
|
""" Apache httpd 2.4 mod_proxy balancer object"""
|
||||||
|
|
||||||
def __init__(self, host, suffix, module, tls=False):
|
def __init__(self, module, host, suffix, tls=False):
|
||||||
if tls:
|
proto = "https" if tls else "http"
|
||||||
self.base_url = 'https://{0}'.format(host)
|
self.base_url = '{0}://{1}'.format(proto, host)
|
||||||
self.url = 'https://{0}{1}'.format(host, suffix)
|
self.url = '{0}://{1}{2}'.format(proto, host, suffix)
|
||||||
else:
|
|
||||||
self.base_url = 'http://{0}'.format(host)
|
|
||||||
self.url = 'http://{0}{1}'.format(host, suffix)
|
|
||||||
self.module = module
|
self.module = module
|
||||||
self.page = self.fetch_balancer_page()
|
self.page = self.fetch_balancer_page()
|
||||||
|
|
||||||
|
@ -342,42 +340,38 @@ class Balancer(object):
|
||||||
""" Returns the balancer management html page as a string for later parsing."""
|
""" Returns the balancer management html page as a string for later parsing."""
|
||||||
resp, info = fetch_url(self.module, self.url)
|
resp, info = fetch_url(self.module, self.url)
|
||||||
if info['status'] != 200:
|
if info['status'] != 200:
|
||||||
self.module.fail_json(msg="Could not get balancer page! HTTP status response: {0}".format(info['status']))
|
raise ModuleHelperException("Could not get balancer page! HTTP status response: {0}".format(info['status']))
|
||||||
else:
|
|
||||||
content = to_text(resp.read())
|
|
||||||
apache_version = regexp_extraction(content.upper(), APACHE_VERSION_EXPRESSION, 1)
|
|
||||||
if apache_version:
|
|
||||||
if not re.search(pattern=r"2\.4\.[\d]*", string=apache_version):
|
|
||||||
self.module.fail_json(
|
|
||||||
msg="This module only acts on an Apache2 2.4+ instance, current Apache2 version: {version}".format(
|
|
||||||
version=apache_version
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return content
|
|
||||||
|
|
||||||
self.module.fail_json(msg="Could not get the Apache server version from the balancer-manager")
|
content = to_text(resp.read())
|
||||||
|
apache_version = regexp_extraction(content.upper(), APACHE_VERSION_EXPRESSION, 1)
|
||||||
|
if not apache_version:
|
||||||
|
raise ModuleHelperException("Could not get the Apache server version from the balancer-manager")
|
||||||
|
|
||||||
|
if not re.search(pattern=r"2\.4\.[\d]*", string=apache_version):
|
||||||
|
raise ModuleHelperException("This module only acts on an Apache2 2.4+ instance, current Apache2 version: {0}".format(apache_version))
|
||||||
|
return content
|
||||||
|
|
||||||
def get_balancer_members(self):
|
def get_balancer_members(self):
|
||||||
""" Returns members of the balancer as a generator object for later iteration."""
|
""" Returns members of the balancer as a generator object for later iteration."""
|
||||||
try:
|
try:
|
||||||
soup = BeautifulSoup(self.page)
|
soup = BeautifulSoup(self.page)
|
||||||
except TypeError:
|
except TypeError as e:
|
||||||
self.module.fail_json(msg="Cannot parse balancer page HTML! {0}".format(self.page))
|
raise_from(ModuleHelperException("Cannot parse balancer page HTML! {0}".format(self.page)), e)
|
||||||
else:
|
|
||||||
elements = find_all(soup, 'a')
|
elements = find_all(soup, 'a')
|
||||||
for element in elements[1::1]:
|
for element in elements[1::1]:
|
||||||
balancer_member_suffix = str(element.get('href'))
|
balancer_member_suffix = element.get('href')
|
||||||
if not balancer_member_suffix:
|
if not balancer_member_suffix:
|
||||||
self.module.fail_json(msg="Argument 'balancer_member_suffix' is empty!")
|
raise ModuleHelperException("Argument 'balancer_member_suffix' is empty!")
|
||||||
else:
|
|
||||||
yield BalancerMember(self.base_url + balancer_member_suffix, self.url, self.module)
|
yield BalancerMember(self.base_url + balancer_member_suffix, self.url, self.module)
|
||||||
|
|
||||||
members = property(get_balancer_members)
|
members = property(get_balancer_members)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
class ApacheModProxy(ModuleHelper):
|
||||||
""" Initiates module."""
|
""" Initiates module."""
|
||||||
module = AnsibleModule(
|
module = dict(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
balancer_vhost=dict(required=True, type='str'),
|
balancer_vhost=dict(required=True, type='str'),
|
||||||
balancer_url_suffix=dict(default="/balancer-manager/", type='str'),
|
balancer_url_suffix=dict(default="/balancer-manager/", type='str'),
|
||||||
|
@ -388,64 +382,47 @@ def main():
|
||||||
),
|
),
|
||||||
supports_check_mode=True
|
supports_check_mode=True
|
||||||
)
|
)
|
||||||
|
use_old_vardict = False
|
||||||
|
|
||||||
deps.validate(module)
|
def __init_module__(self):
|
||||||
|
deps.validate(self.module)
|
||||||
|
|
||||||
if module.params['state'] is not None:
|
if len(self.vars.state or []) > 1 and ("present" in self.vars.state or "enabled" in self.vars.state):
|
||||||
states = module.params['state']
|
self.do_raise(msg="states present/enabled are mutually exclusive with other states!")
|
||||||
if (len(states) > 1) and (("present" in states) or ("enabled" in states)):
|
|
||||||
module.fail_json(msg="state present/enabled is mutually exclusive with other states!")
|
|
||||||
else:
|
|
||||||
states = ['None']
|
|
||||||
|
|
||||||
mybalancer = Balancer(module.params['balancer_vhost'],
|
self.mybalancer = Balancer(self.module, self.vars.balancer_vhost, self.vars.balancer_url_suffix, tls=self.vars.tls)
|
||||||
module.params['balancer_url_suffix'],
|
|
||||||
module=module,
|
|
||||||
tls=module.params['tls'])
|
|
||||||
|
|
||||||
if module.params['member_host'] is None:
|
def __run__(self):
|
||||||
json_output_list = []
|
if self.vars.member_host is None:
|
||||||
for member in mybalancer.members:
|
self.vars.members = [member.as_dict() for member in self.mybalancer.members]
|
||||||
json_output_list.append(member.as_dict())
|
|
||||||
module.exit_json(
|
|
||||||
changed=False,
|
|
||||||
members=json_output_list
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
changed = False
|
|
||||||
member_exists = False
|
|
||||||
member_status = {'disabled': False, 'drained': False, 'hot_standby': False, 'ignore_errors': False}
|
|
||||||
for mode in member_status:
|
|
||||||
for state in states:
|
|
||||||
if mode == state:
|
|
||||||
member_status[mode] = True
|
|
||||||
elif mode == 'disabled' and state == 'absent':
|
|
||||||
member_status[mode] = True
|
|
||||||
|
|
||||||
for member in mybalancer.members:
|
|
||||||
if str(member.host) == module.params['member_host']:
|
|
||||||
member_exists = True
|
|
||||||
if module.params['state'] is not None:
|
|
||||||
member_status_before = member.status
|
|
||||||
if not module.check_mode:
|
|
||||||
member_status_after = member.status = member_status
|
|
||||||
else:
|
|
||||||
member_status_after = member_status
|
|
||||||
if member_status_before != member_status_after:
|
|
||||||
changed = True
|
|
||||||
json_output = member.as_dict()
|
|
||||||
if member_exists:
|
|
||||||
module.exit_json(
|
|
||||||
changed=changed,
|
|
||||||
member=json_output
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
module.fail_json(
|
member_exists = False
|
||||||
msg='{member_host} is not a member of the balancer {balancer_vhost}!'.format(
|
member_status = {'disabled': False, 'drained': False, 'hot_standby': False, 'ignore_errors': False}
|
||||||
member_host=module.params['member_host'],
|
for mode in member_status:
|
||||||
balancer_vhost=module.params['balancer_vhost'],
|
for state in self.vars.state or []:
|
||||||
)
|
if mode == state:
|
||||||
)
|
member_status[mode] = True
|
||||||
|
elif mode == 'disabled' and state == 'absent':
|
||||||
|
member_status[mode] = True
|
||||||
|
|
||||||
|
for member in self.mybalancer.members:
|
||||||
|
if str(member.host) == self.vars.member_host:
|
||||||
|
member_exists = True
|
||||||
|
if self.vars.state is not None:
|
||||||
|
member_status_before = member.status
|
||||||
|
if not self.check_mode:
|
||||||
|
member_status_after = member.status = member_status
|
||||||
|
else:
|
||||||
|
member_status_after = member_status
|
||||||
|
self.changed |= (member_status_before != member_status_after)
|
||||||
|
self.vars.member = member.as_dict()
|
||||||
|
|
||||||
|
if not member_exists:
|
||||||
|
self.do_raise(msg='{0} is not a member of the balancer {1}!'.format(self.vars.member_host, self.vars.balancer_vhost))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ApacheModProxy.execute()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in New Issue