New docker_stack_module with tests (#576)

* First docker stack info approach without tests

Fixes results when no stack availabl

Fixes sanity test

Fixing links

Fixes tabs

Fixes long line

Improving Json Output

Changes arguments

Lint with autopep8

Moves imports

Adds extra line

Adds Tests

Adds pip and fixes return empty

Fixes silly missing else

* Adds Tests and Fixes comments

* Removes tasks option

* Removes arguments

* Changes error message

* Changes Tests

* Add proposals f

* Improve output

* Change test for output change

* Add debug
This commit is contained in:
Jose Angel Munoz 2020-07-29 14:56:49 +02:00 committed by GitHub
parent 233617fdfa
commit bc5dde0e25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 201 additions and 0 deletions

View file

@ -0,0 +1,84 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Jose Angel Munoz (@imjoseangel)
# 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 = '''
---
module: docker_stack_info
author: "Jose Angel Munoz (@imjoseangel)"
short_description: Return information on a docker stack
description:
- Retrieve information on docker stacks using the C(docker stack) command
on the target node (see examples).
version_added: "1.0.0"
'''
RETURN = '''
results:
description: |
List of dictionaries containing the list of stacks or tasks associated
to a stack name.
sample: >
"results": [{"name":"grafana","namespace":"default","orchestrator":"Kubernetes","services":"2"}]
returned: always
type: list
'''
EXAMPLES = '''
- name: Shows stack info
community.general.docker_stack_info:
register: result
- name: Show results
ansible.builtin.debug:
var: result.results
'''
import json
from ansible.module_utils.basic import AnsibleModule
def docker_stack_list(module):
docker_bin = module.get_bin_path('docker', required=True)
rc, out, err = module.run_command(
[docker_bin, "stack", "ls", "--format={{json .}}"])
return rc, out.strip(), err.strip()
def main():
module = AnsibleModule(
argument_spec={
},
supports_check_mode=False
)
rc, out, err = docker_stack_list(module)
if rc != 0:
module.fail_json(msg="Error running docker stack. {0}".format(err),
rc=rc, stdout=out, stderr=err)
else:
if out:
ret = list(
json.loads(outitem)
for outitem in out.splitlines())
else:
ret = []
module.exit_json(changed=False,
rc=rc,
stdout=out,
stderr=err,
results=ret)
if __name__ == "__main__":
main()

View file

@ -0,0 +1 @@
./cloud/docker/docker_stack_info.py

View file

@ -0,0 +1,8 @@
shippable/posix/group1
skip/aix
skip/osx
skip/freebsd
destructive
skip/docker # The tests sometimes make docker daemon unstable; hence,
# we skip all docker-based CI runs to avoid disrupting
# the whole CI system.

View file

@ -0,0 +1,5 @@
version: '3'
services:
busybox:
image: busybox:latest
command: sleep 3600

View file

@ -0,0 +1,5 @@
version: '3'
services:
busybox:
environment:
envvar: value

View file

@ -0,0 +1,3 @@
---
dependencies:
- setup_docker

View file

@ -0,0 +1,5 @@
- include_tasks: test_stack_info.yml
when: docker_api_version is version('1.25', '>=')
- fail: msg="Too old docker / docker-py version to run docker_stack tests!"
when: not(docker_api_version is version('1.25', '>=')) and (ansible_distribution != 'CentOS' or ansible_distribution_major_version|int > 6)

View file

@ -0,0 +1,75 @@
---
- block:
- name: Make sure we're not already using Docker swarm
docker_swarm:
state: absent
force: true
- name: Get docker_stack_info when docker is not running in swarm mode
docker_stack_info:
ignore_errors: true
register: output
- name: Assert failure when called when swarm is not running
assert:
that:
- 'output is failed'
- '"Error running docker stack" in output.msg'
- name: Create a swarm cluster
docker_swarm:
state: present
advertise_addr: "{{ansible_default_ipv4.address}}"
- name: Get docker_stack_info when docker is running and not stack available
docker_stack_info:
register: output
- name: Assert stack facts
assert:
that:
- 'output.results | type_debug == "list"'
- 'output.results | length == 0'
- name: Copy compose files
copy:
src: "{{ item }}"
dest: "{{ output_dir }}/"
with_items:
- stack_compose_base.yml
- stack_compose_overrides.yml
- name: Install docker_stack python requirements
pip:
name: jsondiff,pyyaml
- name: Create stack with compose file
register: output
docker_stack:
state: present
name: test_stack
compose:
- "{{ output_dir }}/stack_compose_base.yml"
- name: Assert test_stack changed on stack creation with compose file
assert:
that:
- output is changed
- name: Get docker_stack_info when docker is running
docker_stack_info:
register: output
- name: assert stack facts
assert:
that:
- 'output.results | type_debug == "list"'
- 'output.results[0].Name == "test_stack"'
- 'output.results[0].Orchestrator == "Swarm"'
- 'output.results[0].Services == "1"'
always:
- name: Cleanup
docker_swarm:
state: absent
force: true

View file

@ -0,0 +1,15 @@
stack_compose_base:
version: '3'
services:
busybox:
image: busybox:latest
command: sleep 3600
stack_compose_overrides:
version: '3'
services:
busybox:
environment:
envvar: value
stack_update_expected_diff: '{"test_stack_busybox": {"TaskTemplate": {"ContainerSpec": {"Env": ["envvar=value"]}}}}'