Merge "Migrate back haproxy validation to tripleo-validations" into stable/train
This commit is contained in:
commit
0b380a7deb
|
@ -0,0 +1,14 @@
|
|||
=============================
|
||||
Module - tripleo_haproxy_conf
|
||||
=============================
|
||||
|
||||
|
||||
This module provides for the following ansible plugin:
|
||||
|
||||
* tripleo_haproxy_conf
|
||||
|
||||
|
||||
.. ansibleautoplugin::
|
||||
:module: library/tripleo_haproxy_conf.py
|
||||
:documentation: true
|
||||
:examples: true
|
|
@ -0,0 +1,46 @@
|
|||
===============
|
||||
tripleo_haproxy
|
||||
===============
|
||||
|
||||
--------------
|
||||
About The Role
|
||||
--------------
|
||||
|
||||
An Ansible role to check if the ``HAProxy`` configuration has recommended
|
||||
values.
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
This role requires and Up and Running Overcloud.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
None.
|
||||
|
||||
Example Playbook
|
||||
================
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- hosts: undercloud
|
||||
roles:
|
||||
- { role: tripleo_haproxy }
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
Apache
|
||||
|
||||
Author Information
|
||||
==================
|
||||
|
||||
**Red Hat Tripleo DFG:PIDONE**
|
||||
|
||||
----------------
|
||||
Full Description
|
||||
----------------
|
||||
|
||||
.. ansibleautoplugin::
|
||||
:role: roles/tripleo_haproxy
|
|
@ -0,0 +1,108 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import re
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from yaml import safe_load as yaml_safe_load
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tripleo_haproxy_conf
|
||||
short_description: Gather the HAProxy config
|
||||
description:
|
||||
- Gather the HAProxy config
|
||||
- Owned by DFG:PIDONE
|
||||
options:
|
||||
path:
|
||||
required: true
|
||||
description:
|
||||
- file path to the config file
|
||||
type: str
|
||||
author: "Tomas Sedovic"
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- hosts: webservers
|
||||
tasks:
|
||||
- name: Gather the HAProxy config
|
||||
tripleo_haproxy_conf: path=/etc/haproxy/haproxy.cfg
|
||||
'''
|
||||
|
||||
|
||||
def generic_ini_style_conf_parser(file_path, section_regex, option_regex):
|
||||
"""
|
||||
ConfigParser chokes on both mariadb and haproxy files. Luckily, they have
|
||||
a syntax approaching ini config file so they are relatively easy to parse.
|
||||
This generic ini style config parser is not perfect, as it can ignore some
|
||||
valid options, but it is good enough for our use case.
|
||||
|
||||
:return: parsed haproxy configuration
|
||||
:rtype: dict
|
||||
"""
|
||||
config = {}
|
||||
current_section = None
|
||||
with open(file_path) as config_file:
|
||||
for line in config_file:
|
||||
match_section = re.match(section_regex, line)
|
||||
if match_section:
|
||||
current_section = match_section.group(1)
|
||||
config[current_section] = {}
|
||||
match_option = re.match(option_regex, line)
|
||||
if match_option and current_section:
|
||||
option = re.sub(r'\s+', ' ', match_option.group(1))
|
||||
config[current_section][option] = match_option.group(2)
|
||||
return config
|
||||
|
||||
|
||||
def parse_haproxy_conf(file_path):
|
||||
"""
|
||||
Provides section and option regex to the parser.
|
||||
Essentially a wrapper for generic_ini_style_conf_parser.
|
||||
Provides no extra functionality but simplifies the call, somewhat.
|
||||
|
||||
:return: parsed haproxy configuration
|
||||
:rtype: dict
|
||||
|
||||
..note::
|
||||
|
||||
Both regular expressions bellow are used for parsing haproxy.cfg,
|
||||
which has a rather vague syntax. The regexes are supposed to match all
|
||||
possibilities described here, and some more:
|
||||
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/load_balancer_administration/ch-haproxy-setup-vsa
|
||||
"""
|
||||
section_regex = r'^(\w+)'
|
||||
option_regex = r'^(?:\s+)(\w+(?:\s+\w+)*?)\s+([\w/]*)$'
|
||||
return generic_ini_style_conf_parser(file_path, section_regex,
|
||||
option_regex)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=yaml_safe_load(DOCUMENTATION)['options']
|
||||
)
|
||||
|
||||
haproxy_conf_path = module.params.get('path')
|
||||
|
||||
try:
|
||||
config = parse_haproxy_conf(haproxy_conf_path)
|
||||
except IOError:
|
||||
module.fail_json(msg="Could not open the haproxy conf file at: '%s'" %
|
||||
haproxy_conf_path)
|
||||
|
||||
module.exit_json(changed=False, ansible_facts={u'haproxy_conf': config})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
- hosts: haproxy
|
||||
vars:
|
||||
metadata:
|
||||
name: TripleO HAProxy configuration
|
||||
description: Verify the HAProxy configuration has recommended values.
|
||||
groups:
|
||||
- post-deployment
|
||||
categories:
|
||||
- os
|
||||
- system
|
||||
- ha
|
||||
- loadbalancing
|
||||
- proxy
|
||||
products:
|
||||
- tripleo
|
||||
- haproxy
|
||||
config_file: '/var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg'
|
||||
global_maxconn_min: 20480
|
||||
defaults_maxconn_min: 4096
|
||||
defaults_timeout_queue: '2m'
|
||||
defaults_timeout_client: '2m'
|
||||
defaults_timeout_server: '2m'
|
||||
defaults_timeout_check: '10s'
|
||||
roles:
|
||||
- tripleo_haproxy
|
|
@ -0,0 +1,21 @@
|
|||
---
|
||||
# Path to the haproxy.cfg file
|
||||
haproxy_config_file: '/var/lib/config-data/puppet-generated/haproxy/etc/haproxy/haproxy.cfg'
|
||||
|
||||
# Global mininum per-process number of concurrent connections
|
||||
global_maxconn_min: 20480
|
||||
|
||||
# Defaults mininum per-process number of concurrent connections
|
||||
defaults_maxconn_min: 4096
|
||||
|
||||
# Time to wait in the queue for a connection slot to be free
|
||||
defaults_timeout_queue: '2m'
|
||||
|
||||
# Inactivity time on the client side
|
||||
defaults_timeout_client: '2m'
|
||||
|
||||
# Inactivity time on the server side
|
||||
defaults_timeout_server: '2m'
|
||||
|
||||
# Additional check timeout
|
||||
defaults_timeout_check: '10s'
|
|
@ -0,0 +1,71 @@
|
|||
---
|
||||
# Copyright 2021 Red Hat, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
- name: Converge
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
haproxy_config_file: /haproxy.cfg
|
||||
|
||||
tasks:
|
||||
- name: create haproxy config file
|
||||
copy:
|
||||
dest: /haproxy.cfg
|
||||
content: |
|
||||
# This file managed by Puppet
|
||||
global
|
||||
daemon
|
||||
group haproxy
|
||||
log /dev/log local0
|
||||
maxconn 100
|
||||
pidfile /var/run/haproxy.pid
|
||||
ssl-default-bind-ciphers !SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES
|
||||
ssl-default-bind-options no-sslv3 no-tlsv10
|
||||
stats socket /var/lib/haproxy/stats mode 600 level user
|
||||
stats timeout 1s
|
||||
user haproxy
|
||||
|
||||
defaults
|
||||
log global
|
||||
maxconn 100
|
||||
mode tcp
|
||||
retries 1
|
||||
timeout http-request 1s
|
||||
timeout queue 1s
|
||||
timeout connect 1s
|
||||
timeout client 1s
|
||||
timeout server 2m
|
||||
timeout check 10s
|
||||
- block:
|
||||
- include_role:
|
||||
name: tripleo_haproxy
|
||||
rescue:
|
||||
- name: Clear host errors
|
||||
meta: clear_host_errors
|
||||
|
||||
- debug:
|
||||
msg: The validation works! End the playbook run
|
||||
|
||||
- name: End play
|
||||
meta: end_play
|
||||
|
||||
- name: Fail the test
|
||||
fail:
|
||||
msg: |
|
||||
The haproxy role should have detected issues within haproxy
|
||||
configuration file!
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
# inherits tripleo-validations/.config/molecule/config.yml
|
||||
# To override default values, please take a look at the config.yml.
|
|
@ -0,0 +1,56 @@
|
|||
---
|
||||
- name: Gather the HAProxy configuration
|
||||
become: true
|
||||
tripleo_haproxy_conf:
|
||||
path: "{{ haproxy_config_file }}"
|
||||
|
||||
- name: Check the HAProxy configuration
|
||||
fail:
|
||||
msg: >-
|
||||
{% if haproxy_conf.global.maxconn|int < global_maxconn_min %}
|
||||
- [FAILED] 'global maxconn' value check
|
||||
* Current value: {{ haproxy_conf.global.maxconn }}, Recommended value: > {{ global_maxconn_min }}
|
||||
{% else %}
|
||||
- [PASSED] 'global maxconn' value check
|
||||
{% endif %}
|
||||
{% if haproxy_conf.defaults.maxconn|int < defaults_maxconn_min %}
|
||||
- [FAILED] 'defaults maxconn' value check
|
||||
* Current value: {{ haproxy_conf.defaults.maxconn }}, Recommended Value: > {{ defaults_maxconn_min }}
|
||||
{% else %}
|
||||
- [PASSED] 'defaults maxconn' value check
|
||||
{% endif %}
|
||||
{% if haproxy_conf.defaults['timeout queue'] != defaults_timeout_queue %}
|
||||
- [FAILED] 'timeout queue' option in 'defaults' check
|
||||
* Current value: {{ haproxy_conf.defaults['timeout queue'] }}
|
||||
* Recommended value: {{ defaults_timeout_queue }}
|
||||
{% else %}
|
||||
- [PASSED] 'timeout queue' option in 'defaults' check
|
||||
{% endif %}
|
||||
{% if haproxy_conf.defaults['timeout client'] != defaults_timeout_client %}
|
||||
- [FAILED] 'timeout client' option in 'defaults' check
|
||||
* Current value: {{ haproxy_conf.defaults['timeout client'] }}
|
||||
* Recommended value: {{ defaults_timeout_client }}
|
||||
{% else %}
|
||||
- [PASSED] 'timeout client' option in 'defaults' check
|
||||
{% endif %}
|
||||
{% if haproxy_conf.defaults['timeout server'] != defaults_timeout_server %}
|
||||
- [FAILED] 'timeout server' option in 'defaults' check
|
||||
* Current value: {{ haproxy_conf.defaults['timeout server'] }}
|
||||
* Recommended value: {{ defaults_timeout_server }}
|
||||
{% else %}
|
||||
- [PASSED] 'timeout server' option in 'defaults' check
|
||||
{% endif %}
|
||||
{% if haproxy_conf.defaults['timeout check'] != defaults_timeout_check %}
|
||||
- [FAILED] 'timeout check' option in 'defaults' check
|
||||
* Current value: {{ haproxy_conf.defaults['timeout check'] }}
|
||||
* Recommended value: {{ defaults_timeout_check }}
|
||||
{% else %}
|
||||
- [PASSED] 'timeout check' option in 'defaults' check
|
||||
{% endif %}
|
||||
failed_when: >
|
||||
(haproxy_conf.global.maxconn|int < global_maxconn_min) or
|
||||
(haproxy_conf.defaults.maxconn|int < defaults_maxconn_min) or
|
||||
(haproxy_conf.defaults['timeout queue'] != defaults_timeout_queue) or
|
||||
(haproxy_conf.defaults['timeout client'] != defaults_timeout_client) or
|
||||
(haproxy_conf.defaults['timeout server'] != defaults_timeout_server) or
|
||||
(haproxy_conf.defaults['timeout check'] != defaults_timeout_check)
|
|
@ -0,0 +1,56 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
from tripleo_validations.tests import base
|
||||
|
||||
from library import tripleo_haproxy_conf
|
||||
|
||||
|
||||
class TestHaproxyConf(base.TestCase):
|
||||
def setUp(self):
|
||||
super(TestHaproxyConf, self).setUp()
|
||||
self.h_conf = tripleo_haproxy_conf
|
||||
|
||||
@mock.patch('library.tripleo_haproxy_conf.generic_ini_style_conf_parser')
|
||||
def test_parse_haproxy_conf(self, mock_generic_ini_style_conf_parser):
|
||||
""" Despite the appearences this test is not using regex at all.
|
||||
These are merely raw strings, that it asserts are passed to the `generic_ini_style_conf_parser`.
|
||||
From the pov of the test it is irrelevant what form they have.
|
||||
It's the `generic_ini_style_conf_parser` function that is supposed to receive these strings as arguments.
|
||||
Test is merely checking that the code immediately preceding it's call does what it should do.
|
||||
The regexes are finally used for parsing haproxy.cfg, which has a rather vague syntax.
|
||||
In short: The regexes are supposed to match all possibilities described here, and some more:
|
||||
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/load_balancer_administration/ch-haproxy-setup-vsa
|
||||
"""
|
||||
|
||||
file_path = './foo/bar'
|
||||
|
||||
args = {
|
||||
'file_path': file_path,
|
||||
'section_regex': r'^(\w+)',
|
||||
'option_regex': r'^(?:\s+)(\w+(?:\s+\w+)*?)\s+([\w/]*)$'
|
||||
}
|
||||
|
||||
self.h_conf.parse_haproxy_conf(file_path)
|
||||
mock_generic_ini_style_conf_parser.assert_called_once_with(
|
||||
args['file_path'],
|
||||
args['section_regex'],
|
||||
args['option_regex']
|
||||
)
|
|
@ -20,6 +20,7 @@
|
|||
- tripleo-validations-centos-8-molecule-stonith_exists
|
||||
- tripleo-validations-centos-8-molecule-system_encoding
|
||||
- tripleo-validations-centos-8-molecule-tls_everywhere
|
||||
- tripleo-validations-centos-8-molecule-tripleo_haproxy
|
||||
- tripleo-validations-centos-8-molecule-undercloud_debug
|
||||
- tripleo-validations-centos-8-molecule-undercloud_heat_purge_deleted
|
||||
- tripleo-validations-centos-8-molecule-undercloud_tokenflush
|
||||
|
@ -44,6 +45,7 @@
|
|||
- tripleo-validations-centos-8-molecule-stonith_exists
|
||||
- tripleo-validations-centos-8-molecule-system_encoding
|
||||
- tripleo-validations-centos-8-molecule-tls_everywhere
|
||||
- tripleo-validations-centos-8-molecule-tripleo_haproxy
|
||||
- tripleo-validations-centos-8-molecule-undercloud_debug
|
||||
- tripleo-validations-centos-8-molecule-undercloud_heat_purge_deleted
|
||||
- tripleo-validations-centos-8-molecule-undercloud_tokenflush
|
||||
|
@ -491,3 +493,13 @@
|
|||
parent: tripleo-validations-centos-8-base
|
||||
vars:
|
||||
tripleo_validations_role_name: compute_tsx
|
||||
- job:
|
||||
files:
|
||||
- ^roles/tripleo_haproxy/.*
|
||||
- ^tests/prepare-test-host.yml
|
||||
- ^ci/playbooks/pre.yml
|
||||
- ^ci/playbooks/run.yml
|
||||
name: tripleo-validations-centos-8-molecule-tripleo_haproxy
|
||||
parent: tripleo-validations-centos-8-base
|
||||
vars:
|
||||
tripleo_validations_role_name: tripleo_haproxy
|
||||
|
|
Loading…
Reference in New Issue