Browse Source

Add common Ansible roles and libraries

Signed-off-by: Gael Chamoulaud (Strider) <gchamoul@redhat.com>
changes/52/712252/1
Gael Chamoulaud (Strider) 2 years ago
parent
commit
eb35089c1c
No known key found for this signature in database GPG Key ID: 4119D0305C651D66
  1. 89
      library/haproxy_conf.py
  2. 64
      library/hiera.py
  3. 166
      library/validations_read_ini.py
  4. 55
      library/warn.py
  5. 37
      roles/advanced_format_512e_support/molecule/default/Dockerfile.j2
  6. 47
      roles/advanced_format_512e_support/molecule/default/molecule.yml
  7. 26
      roles/advanced_format_512e_support/molecule/default/playbook.yml
  8. 10
      roles/advanced_format_512e_support/tasks/main.yml
  9. 9
      roles/advanced_format_512e_support/vars/main.yml
  10. 10
      roles/check_latest_packages_version/defaults/main.yml
  11. 37
      roles/check_latest_packages_version/molecule/default/Dockerfile.j2
  12. 47
      roles/check_latest_packages_version/molecule/default/molecule.yml
  13. 51
      roles/check_latest_packages_version/molecule/default/playbook.yml
  14. 25
      roles/check_latest_packages_version/molecule/default/prepare.yml
  15. 16
      roles/check_latest_packages_version/tasks/main.yml
  16. 8
      roles/check_latest_packages_version/vars/main.yml
  17. 2
      roles/dns/defaults/main.yml
  18. 37
      roles/dns/molecule/default/Dockerfile.j2
  19. 46
      roles/dns/molecule/default/molecule.yml
  20. 47
      roles/dns/molecule/default/playbook.yml
  21. 4
      roles/dns/tasks/main.yml
  22. 7
      roles/dns/vars/main.yml
  23. 42
      roles/haproxy/README.md
  24. 8
      roles/haproxy/defaults/main.yml
  25. 36
      roles/haproxy/molecule/default/Dockerfile.j2
  26. 47
      roles/haproxy/molecule/default/molecule.yml
  27. 71
      roles/haproxy/molecule/default/playbook.yml
  28. 51
      roles/haproxy/tasks/main.yml
  29. 6
      roles/haproxy/vars/main.yml
  30. 4
      roles/no_op/tasks/main.yml
  31. 8
      roles/no_op/vars/main.yml
  32. 37
      roles/ntp/molecule/default/Dockerfile.j2
  33. 47
      roles/ntp/molecule/default/molecule.yml
  34. 26
      roles/ntp/molecule/default/playbook.yml
  35. 26
      roles/ntp/tasks/main.yml
  36. 10
      roles/ntp/vars/main.yml
  37. 2
      roles/service_status/defaults/main.yaml
  38. 37
      roles/service_status/molecule/default/Dockerfile.j2
  39. 49
      roles/service_status/molecule/default/molecule.yml
  40. 25
      roles/service_status/molecule/default/playbook.yml
  41. 37
      roles/service_status/molecule/docker/Dockerfile.j2
  42. 61
      roles/service_status/molecule/docker/molecule.yml
  43. 59
      roles/service_status/molecule/docker/playbook.yml
  44. 65
      roles/service_status/molecule/docker/prepare.yml
  45. 37
      roles/service_status/molecule/podman/Dockerfile.j2
  46. BIN
      roles/service_status/molecule/podman/bolt_state.db
  47. 49
      roles/service_status/molecule/podman/molecule.yml
  48. 46
      roles/service_status/molecule/podman/playbook.yml
  49. 39
      roles/service_status/molecule/podman/prepare.yml
  50. 37
      roles/service_status/molecule/systemd/Dockerfile.j2
  51. 49
      roles/service_status/molecule/systemd/molecule.yml
  52. 44
      roles/service_status/molecule/systemd/playbook.yml
  53. 39
      roles/service_status/molecule/systemd/prepare.yml
  54. 59
      roles/service_status/tasks/containers.yaml
  55. 3
      roles/service_status/tasks/main.yaml
  56. 13
      roles/service_status/tasks/systemd.yaml
  57. 37
      roles/stonith_exists/molecule/default/Dockerfile.j2
  58. 46
      roles/stonith_exists/molecule/default/molecule.yml
  59. 56
      roles/stonith_exists/molecule/default/playbook.yml
  60. 30
      roles/stonith_exists/molecule/default/prepare.yml
  61. 22
      roles/stonith_exists/tasks/main.yml
  62. 11
      roles/stonith_exists/vars/main.yml
  63. 36
      roles/undercloud_cpu/README.md
  64. 3
      roles/undercloud_cpu/defaults/main.yml
  65. 37
      roles/undercloud_cpu/molecule/default/Dockerfile.j2
  66. 46
      roles/undercloud_cpu/molecule/default/molecule.yml
  67. 42
      roles/undercloud_cpu/molecule/default/playbook.yml
  68. 7
      roles/undercloud_cpu/tasks/main.yml
  69. 10
      roles/undercloud_cpu/vars/main.yaml
  70. 36
      roles/undercloud_disk_space/README.md
  71. 8
      roles/undercloud_disk_space/defaults/main.yml
  72. 37
      roles/undercloud_disk_space/molecule/default/Dockerfile.j2
  73. 46
      roles/undercloud_disk_space/molecule/default/molecule.yml
  74. 44
      roles/undercloud_disk_space/molecule/default/playbook.yml
  75. 39
      roles/undercloud_disk_space/tasks/main.yml
  76. 11
      roles/undercloud_disk_space/vars/main.yaml
  77. 36
      roles/undercloud_ram/README.md
  78. 3
      roles/undercloud_ram/defaults/main.yml
  79. 37
      roles/undercloud_ram/molecule/default/Dockerfile.j2
  80. 46
      roles/undercloud_ram/molecule/default/molecule.yml
  81. 42
      roles/undercloud_ram/molecule/default/playbook.yml
  82. 9
      roles/undercloud_ram/tasks/main.yml
  83. 11
      roles/undercloud_ram/vars/main.yaml
  84. 37
      roles/undercloud_selinux_mode/README.md
  85. 37
      roles/undercloud_selinux_mode/molecule/default/Dockerfile.j2
  86. 47
      roles/undercloud_selinux_mode/molecule/default/molecule.yml
  87. 26
      roles/undercloud_selinux_mode/molecule/default/playbook.yml
  88. 24
      roles/undercloud_selinux_mode/tasks/main.yml
  89. 8
      roles/undercloud_selinux_mode/vars/main.yml
  90. 38
      roles/undercloud_service_status/README.md
  91. 8
      roles/undercloud_service_status/defaults/main.yml
  92. 18
      roles/undercloud_service_status/tasks/main.yml
  93. 8
      roles/undercloud_service_status/vars/main.yaml
  94. 27
      roles/validate_selinux/defaults/main.yml
  95. 15
      roles/validate_selinux/handlers/main.yml
  96. 37
      roles/validate_selinux/molecule/default/Dockerfile
  97. 49
      roles/validate_selinux/molecule/default/molecule.yml
  98. 63
      roles/validate_selinux/molecule/default/playbook.yml
  99. 60
      roles/validate_selinux/molecule/default/prepare.yml
  100. 15
      roles/validate_selinux/molecule/default/verify.yml

89
library/haproxy_conf.py

@ -0,0 +1,89 @@
#!/usr/bin/env python
# -*- 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: haproxy_conf
short_description: Gather the HAProxy config
description:
- Gather the HAProxy config
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
haproxy_conf: path=/etc/haproxy/haproxy.cfg
'''
# 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 -- it can ignore some
# valid options -- but good enough for our use case.
def generic_ini_style_conf_parser(file_path, section_regex, option_regex):
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):
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()

64
library/hiera.py

@ -0,0 +1,64 @@
#!/usr/bin/env python
# Copyright 2016 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.
import subprocess
from ansible.module_utils.basic import AnsibleModule
from yaml import safe_load as yaml_safe_load
DOCUMENTATION = '''
---
module: hiera
short_description: Get data from hiera
description:
- Get data from hiera
options:
name:
required: true
description:
- Name to lookup
type: str
author: "Martin Andre (@mandre)"
'''
EXAMPLES = '''
- hosts: webservers
tasks:
- name: Lookup foo
hiera: name=foo
'''
def main():
module = AnsibleModule(
argument_spec=yaml_safe_load(DOCUMENTATION)['options']
)
name = module.params.get('name')
cmd = ['/usr/bin/hiera', '-c', '/etc/puppet/hiera.yaml', name]
result = subprocess.check_output(cmd, universal_newlines=True).rstrip()
if result == 'nil':
module.fail_json(msg="Failed to retrieve hiera data for {}"
.format(name))
module.exit_json(changed=False,
ansible_facts={name: result})
if __name__ == '__main__':
main()

166
library/validations_read_ini.py

@ -0,0 +1,166 @@
#!/usr/bin/env python
# -*- 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.
# Ansible module to read a value from an Ini file.
# Usage:
# - validations_read_ini: path=/path/to/file.ini section=default key=something
# register: my_ini
#
# This will read the `path/to/file.ini` file and read the `Hello!` value under:
# [default]
# something = Hello!
#
# You can register the result and use it later with `{{ my_ini.value }}`
try:
import configparser as ConfigParser
except ImportError:
import ConfigParser
from enum import Enum
import os
from ansible.module_utils.basic import AnsibleModule
from yaml import safe_load as yaml_safe_load
# Possible return values
class ReturnValue(Enum):
OK = 0
INVALID_FORMAT = 1
KEY_NOT_FOUND = 2
def check_file(path, ignore_missing):
'''Validate entered path'''
if not (os.path.exists(path) and os.path.isfile(path)):
return "Could not open the ini file: '{}'".format(path)
else:
return ''
def get_result(path, section, key, default=None):
'''Get value based on section and key'''
msg = ''
value = None
config = ConfigParser.SafeConfigParser()
try:
config.read(path)
except Exception:
msg = "The file '{}' is not in a valid INI format.".format(path)
ret = ReturnValue.INVALID_FORMAT
return (ret, msg, value)
try:
value = config.get(section, key)
msg = ("The key '{}' under the section '{}' in file {} "
"has the value: '{}'").format(key, section, path, value)
ret = ReturnValue.OK
return (ret, msg, value)
except ConfigParser.Error:
if default:
msg = ("There is no key '{}' under section '{}' in file {}. Using"
" default value '{}'".format(key, section, path, default))
ret = ReturnValue.OK
value = default
else:
value = None
msg = "There is no key '{}' under the section '{}' in file {}.".format(
key, section, path)
ret = ReturnValue.KEY_NOT_FOUND
return (ret, msg, value)
DOCUMENTATION = '''
---
module: validations_read_ini
short_description: Get data from an ini file
description:
- Get data from an ini file
options:
path:
required: true
description:
- File path
type: str
section:
required: true
description:
- Section to look up
type: str
key:
required: true
description:
- Section key to look up
type: str
default:
required: false
description:
- Default value if key isn't found
ignore_missing_file:
required: false
description:
- Flag if a missing file should be ignored
type: bool
author: "Tomas Sedovic"
'''
EXAMPLES = '''
- hosts: webservers
tasks:
- name: Lookup bar value
validations_read_ini: path=config.ini section=foo key=bar ignore_missing_file=True
'''
def main():
module = AnsibleModule(
argument_spec=yaml_safe_load(DOCUMENTATION)['options']
)
ini_file_path = module.params.get('path')
ignore_missing = module.params.get('ignore_missing_file')
# Check that file exists
msg = check_file(ini_file_path, ignore_missing)
if msg != '':
# Opening file failed
if ignore_missing:
module.exit_json(msg=msg, changed=False, value=None)
else:
module.fail_json(msg=msg)
else:
# Try to parse the result from ini file
section = module.params.get('section')
key = module.params.get('key')
default = module.params.get('default')
ret, msg, value = get_result(ini_file_path, section, key, default)
if ret == ReturnValue.INVALID_FORMAT:
module.fail_json(msg=msg)
elif ret == ReturnValue.KEY_NOT_FOUND:
module.exit_json(msg=msg, changed=False, value=None)
elif ret == ReturnValue.OK:
module.exit_json(msg=msg, changed=False, value=value)
if __name__ == '__main__':
main()

55
library/warn.py

@ -0,0 +1,55 @@
#!/usr/bin/env python
# Copyright 2017 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.
from ansible.module_utils.basic import AnsibleModule
from yaml import safe_load as yaml_safe_load
DOCUMENTATION = '''
---
module: warn
short_description: Add warning to playbook output
description:
- Add warning to playbook output
options:
msg:
required: true
description:
- The warning text
type: str
author: "Martin Andre (@mandre)"
'''
EXAMPLES = '''
- hosts: webservers
tasks:
- name: Output warning message
warn: msg="Warning!"
'''
def main():
module = AnsibleModule(
argument_spec=yaml_safe_load(DOCUMENTATION)['options']
)
msg = module.params.get('msg')
module.exit_json(changed=False,
warnings=[msg])
if __name__ == '__main__':
main()

37
roles/advanced_format_512e_support/molecule/default/Dockerfile.j2

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

47
roles/advanced_format_512e_support/molecule/default/molecule.yml

@ -0,0 +1,47 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools python-enum34 python-netaddr ruby epel-release PyYAML
easy_install:
- pip
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
pkg_extras: python*-setuptools python*-enum python*-netaddr ruby PyYAML
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_LIBRARY: "../../../../library"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: false
verifier:
name: testinfra
lint:
name: flake8

26
roles/advanced_format_512e_support/molecule/default/playbook.yml

@ -0,0 +1,26 @@
---
# Copyright 2019 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
tasks:
- name: Warn developers about the lack of molecule testing
fail:
msg: >-
This role needs molecule tests!

10
roles/advanced_format_512e_support/tasks/main.yml

@ -0,0 +1,10 @@
---
- name: List the available drives
register: drive_list
command: "ls /sys/class/block/"
changed_when: false
- name: Detect whether the drive uses Advanced Format
advanced_format: drive={{ item }}
when: item is match("^sd.$")
with_items: "{{ drive_list.stdout_lines }}"

9
roles/advanced_format_512e_support/vars/main.yml

@ -0,0 +1,9 @@
---
metadata:
name: Advanced Format 512e Support
description: >
Detect whether the undercloud disks use Advanced Format. If they do,
the overcloud images may fail to upload to Glance.
groups:
- prep
- pre-deployment

10
roles/check_latest_packages_version/defaults/main.yml

@ -0,0 +1,10 @@
---
tripleoclient: >-
{%- if ansible_distribution == 'RedHat' and ansible_distribution_major_version == '8' -%}
python3-tripleoclient
{%- else -%}
python2-tripleoclient
{%- endif -%}
packages:
- "{{ tripleoclient }}"

37
roles/check_latest_packages_version/molecule/default/Dockerfile.j2

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

47
roles/check_latest_packages_version/molecule/default/molecule.yml

@ -0,0 +1,47 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools PyYAML
easy_install:
- pip
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
pkg_extras: python*-setuptools PyYAML
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_LIBRARY: "../../../../library"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: false
verifier:
name: testinfra
lint:
name: flake8

51
roles/check_latest_packages_version/molecule/default/playbook.yml

@ -0,0 +1,51 @@
---
# Copyright 2019 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
tasks:
- name: Validate No Available Update for patch rpm
include_role:
name: check_latest_packages_version
vars:
packages:
- patch
- name: Working Detection of Update for Pam package
block:
- include_role:
name: check_latest_packages_version
vars:
packages:
- pam
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 check_latest_packages_version role should have detected
that packages have available updates.

25
roles/check_latest_packages_version/molecule/default/prepare.yml

@ -0,0 +1,25 @@
---
# Copyright 2019 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: Prepare
hosts: all
gather_facts: false
tasks:
- name: install patch rpm
package:
name: patch

16
roles/check_latest_packages_version/tasks/main.yml

@ -0,0 +1,16 @@
---
- name: Get available updates for packages
check_package_update:
package: "{{ item }}"
pkg_mgr: "{{ ansible_pkg_mgr }}"
with_items: "{{ packages }}"
register: updates
- name: Check if current version is the latest one
fail:
msg: >-
A newer version of the {{ item.name }} package is
available: {{ item.new_version }}-{{ item.new_release }}
(currently {{ item.current_version }}-{{ item.current_release }})
with_items: "{{ updates.results }}"
when: item.new_version

8
roles/check_latest_packages_version/vars/main.yml

@ -0,0 +1,8 @@
---
metadata:
name: Check if latest version of packages is installed
description: >
Makes sure python-tripleoclient is at its latest version
before starting an upgrade.
groups:
- pre-upgrade

2
roles/dns/defaults/main.yml

@ -0,0 +1,2 @@
---
server_to_lookup: example.com

37
roles/dns/molecule/default/Dockerfile.j2

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

46
roles/dns/molecule/default/molecule.yml

@ -0,0 +1,46 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools
easy_install:
- pip
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
pkg_extras: python*-setuptools
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: false
verifier:
name: testinfra
lint:
name: flake8

47
roles/dns/molecule/default/playbook.yml

@ -0,0 +1,47 @@
---
# Copyright 2019 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
tasks:
- name: Should get a success
include_role:
name: dns
vars:
server_to_lookup: www.redhat.com
- name: Should properly fail
block:
- include_role:
name: dns
vars:
server_to_lookup: role.dns.domain.do-not.exists
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 dns role should have detected a faulty DNS configuration

4
roles/dns/tasks/main.yml

@ -0,0 +1,4 @@
---
- name: Ensure DNS resolution works
command: "getent hosts {{ server_to_lookup }}"
changed_when: false

7
roles/dns/vars/main.yml

@ -0,0 +1,7 @@
---
metadata:
name: Verify DNS
description: >
Verify that the DNS resolution works
groups:
- pre-deployment

42
roles/haproxy/README.md

@ -0,0 +1,42 @@
haproxy
=======
An Ansible role to check if the HAProxy configuration has recommended values.
Requirements
------------
This role requires an Up and Running Overcloud
Role Variables
--------------
- 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'
Dependencies
------------
No dependencies
Example Playbook
----------------
- hosts: undercloud
roles:
- { role: haproxy }
License
-------
Apache
Author Information
------------------
Red Hat TripleO Validations Team.

8
roles/haproxy/defaults/main.yml

@ -0,0 +1,8 @@
---
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'

36
roles/haproxy/molecule/default/Dockerfile.j2

@ -0,0 +1,36 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

47
roles/haproxy/molecule/default/molecule.yml

@ -0,0 +1,47 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools haproxy PyYAML
easy_install:
- pip
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
pkg_extras: python*-setuptools haproxy PyYAML
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_LIBRARY: "../../../../library"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: true
verifier:
name: testinfra
lint:
name: flake8

71
roles/haproxy/molecule/default/playbook.yml

@ -0,0 +1,71 @@
---
# Copyright 2019 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 1s
timeout check 1s
- block:
- include_role:
name: 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!

51
roles/haproxy/tasks/main.yml

@ -0,0 +1,51 @@
---
- name: Gather the HAProxy config
become: true
haproxy_conf:
path: "{{ haproxy_config_file }}"
- name: Verify global maxconn
fail:
msg: >-
The 'global maxconn' value '{{ haproxy_conf.global.maxconn }}'
must be greater than {{ global_maxconn_min }}
failed_when: haproxy_conf.global.maxconn|int < global_maxconn_min
- name: Verify defaults maxconn
fail:
msg: >-
The 'defaults maxconn' value '{{ haproxy_conf.defaults.maxconn }}'
must be greater than {{ defaults_maxconn_min }}
failed_when: haproxy_conf.defaults.maxconn|int < defaults_maxconn_min
- name: Verify defaults timeout queue
fail:
msg: >-
The 'timeout queue' option in 'defaults' is
'{{ haproxy_conf.defaults['timeout queue'] }}',
but must be set to {{ defaults_timeout_queue }}
failed_when: "haproxy_conf.defaults['timeout queue'] != defaults_timeout_queue"
- name: Verify defaults timeout client
fail:
msg: >-
The 'timeout client' option in 'defaults' is
'{{ haproxy_conf.defaults['timeout client'] }}',
but must be set to {{ defaults_timeout_client }}
failed_when: "haproxy_conf.defaults['timeout client'] != defaults_timeout_client"
- name: Verify defaults timeout server
fail:
msg: >-
The 'timeout server' option in 'defaults' is
'{{ haproxy_conf.defaults['timeout server'] }}',
but must be set to {{ defaults_timeout_server }}
failed_when: "haproxy_conf.defaults['timeout server'] != defaults_timeout_server"
- name: Verify defaults timeout check
fail:
msg: >-
The 'timeout check' option in 'defaults' is
'{{ haproxy_conf.defaults['timeout check'] }}',
but must be set to {{ defaults_timeout_check }}
failed_when: "haproxy_conf.defaults['timeout check'] != defaults_timeout_check"

6
roles/haproxy/vars/main.yml

@ -0,0 +1,6 @@
---
metadata:
name: HAProxy configuration
description: Verify the HAProxy configuration has recommended values.
groups:
- post-deployment

4
roles/no_op/tasks/main.yml

@ -0,0 +1,4 @@
---
- name: Run a no-op validation everywhere
debug:
msg: "This is a no-op action for testing that the validations framework runs"

8
roles/no_op/vars/main.yml

@ -0,0 +1,8 @@
---
metadata:
name: NO-OP validation
description: >
A simple validation doing nothing in order to test that
the validations framework works.
groups:
- no-op

37
roles/ntp/molecule/default/Dockerfile.j2

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

47
roles/ntp/molecule/default/molecule.yml

@ -0,0 +1,47 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools python-enum34 python-netaddr ruby epel-release PyYAML
easy_install:
- pip
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
pkg_extras: python*-setuptools python*-enum python*-netaddr ruby PyYAML
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_LIBRARY: "../../../../library"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: false
verifier:
name: testinfra
lint:
name: flake8

26
roles/ntp/molecule/default/playbook.yml

@ -0,0 +1,26 @@
---
# Copyright 2019 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
tasks:
- name: Warn developers about the lack of molecule testing
fail:
msg: >-
This role needs molecule tests!

26
roles/ntp/tasks/main.yml

@ -0,0 +1,26 @@
---
- name: Get if chrony is enabled
become: true
hiera:
name: "chrony_enabled"
- when: chrony_enabled|bool
block:
- name: Populate service facts
service_facts: # needed to make yaml happy
- name: Fail if chronyd service is not running
fail:
msg: "Chronyd service is not running"
when: "ansible_facts.services['chronyd.service'].state != 'running'"
- name: Run chronyc
become: true
command: chronyc -a 'burst 4/4'
changed_when: false
# ntpstat returns 0 if synchronised and non-zero otherwise:
- name: Run ntpstat
command: ntpstat
changed_when: false
when: not chrony_enabled|bool

10
roles/ntp/vars/main.yml

@ -0,0 +1,10 @@
---
metadata:
name: Verify all deployed nodes have their clock synchronised
description: >
Each overcloud node should have their clocks synchronised.
The deployment should configure and run chronyd. This validation verifies
that it is indeed running and connected to an NTP server on all nodes.
groups:
- post-deployment

2
roles/service_status/defaults/main.yaml

@ -0,0 +1,2 @@
---
service_status_podman_opt: ''

37
roles/service_status/molecule/default/Dockerfile.j2

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

49
roles/service_status/molecule/default/molecule.yml

@ -0,0 +1,49 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools python-enum34 python-netaddr ruby epel-release PyYAML
easy_install:
- pip
command: /sbin/init
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
command: /sbin/init
pkg_extras: python*-setuptools python*-enum python*-netaddr ruby PyYAML
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_LIBRARY: "../../../../library"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: false
verifier:
name: testinfra
lint:
name: flake8

25
roles/service_status/molecule/default/playbook.yml

@ -0,0 +1,25 @@
---
# Copyright 2019 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
tasks:
- name: Full check with defaults
include_role:
name: service_status

37
roles/service_status/molecule/docker/Dockerfile.j2

@ -0,0 +1,37 @@
# Molecule managed
# Copyright 2019 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.
{% if item.registry is defined %}
FROM {{ item.registry.url }}/{{ item.image }}
{% else %}
FROM {{ item.image }}
{% endif %}
RUN if [ $(command -v apt-get) ]; then apt-get update && apt-get install -y python sudo bash ca-certificates && apt-get clean; \
elif [ $(command -v dnf) ]; then dnf makecache && dnf --assumeyes install python sudo python-devel python*-dnf bash {{ item.pkg_extras | default('') }} && dnf clean all; \
elif [ $(command -v yum) ]; then yum makecache fast && yum install -y python sudo yum-plugin-ovl python-setuptools bash {{ item.pkg_extras | default('') }} && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf && yum clean all; \
elif [ $(command -v zypper) ]; then zypper refresh && zypper install -y python sudo bash python-xml {{ item.pkg_extras | default('') }} && zypper clean -a; \
elif [ $(command -v apk) ]; then apk update && apk add --no-cache python sudo bash ca-certificates {{ item.pkg_extras | default('') }}; \
elif [ $(command -v xbps-install) ]; then xbps-install -Syu && xbps-install -y python sudo bash ca-certificates {{ item.pkg_extras | default('') }} && xbps-remove -O; fi
{% for pkg in item.easy_install | default([]) %}
# install pip for centos where there is no python-pip rpm in default repos
RUN easy_install {{ pkg }}
{% endfor %}
CMD ["sh", "-c", "while true; do sleep 10000; done"]

61
roles/service_status/molecule/docker/molecule.yml

@ -0,0 +1,61 @@
---
driver:
name: docker
log: true
platforms:
- name: centos7
hostname: centos7
image: centos:7
pkg_extras: python-setuptools python-enum34 python-netaddr ruby epel-release PyYAML
easy_install:
- pip
command: /sbin/init
capabilities:
- SYS_ADMIN
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /sys/fs/cgroup:/sys/fs/cgroup:ro
environment: &env
http_proxy: "{{ lookup('env', 'http_proxy') }}"
https_proxy: "{{ lookup('env', 'https_proxy') }}"
- name: fedora28
hostname: fedora28
image: fedora:28
command: /sbin/init
capabilities:
- SYS_ADMIN
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /sys/fs/cgroup:/sys/fs/cgroup:ro
pkg_extras: python*-setuptools python*-enum python*-netaddr ruby PyYAML python*-libselinux
environment:
<<: *env
provisioner:
name: ansible
log: true
env:
ANSIBLE_STDOUT_CALLBACK: yaml
ANSIBLE_LIBRARY: "../../../../library"
scenario:
test_sequence:
- destroy
- create
- prepare
- converge
- verify
- destroy
lint:
enabled: false
verifier:
name: testinfra
lint:
name: flake8

59
roles/service_status/molecule/docker/playbook.yml

@ -0,0 +1,59 @@
---
# Copyright 2019 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
become: true
tasks:
- name: "Check containers - docker version, no service"
include_role:
name: service_status
tasks_from: containers.yaml
- name: "Check containers - docker version, with service"
block:
- name: Activate docker service
service:
name: docker
state: started
enabled: true
- name: Catch failure
block:
- name: Run check
include_role:
name: service_status
tasks_from: containers.yaml
rescue:
- name: Clear host errors
meta: clear_host_errors
- name: Test output
debug:
msg: |
Success finding broken containers
- name: End play
meta: end_play
- name: Fail if this point is reached
fail:
msg: |
Did not find broken containers

65
roles/service_status/molecule/docker/prepare.yml

@ -0,0 +1,65 @@
---
# Copyright 2019 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: Prepare
hosts: all
gather_facts: false
tasks:
- name: install docker
package:
name: docker
- name: fake docker exe
copy:
dest: /usr/bin/docker
mode: 0755
content: |
#!/bin/sh
echo 'thirsty_goldwasser Exited (0) 12 seconds ago'
echo 'fedora28 Exited (255) 7 hours ago'
echo 'centos7 Exited (255) 7 hours ago'
- name: docker unit override basedir
file:
path: /etc/systemd/system/docker.service.d
state: directory
- name: fake docker unit
copy:
dest: /etc/systemd/system/docker.service.d/override.conf
content: |
[Unit]
After=network.target
Wants=
Requires=
[Service]
Type=simple
ExecStart=
ExecStart=/usr/bin/fake
Restart=
- name: fake docker exec for unit
copy: