Skip to content

Instantly share code, notes, and snippets.

@pixie79
Created July 7, 2014 06:06
Show Gist options
  • Save pixie79/ef20c9c7be88a745d53c to your computer and use it in GitHub Desktop.
Save pixie79/ef20c9c7be88a745d53c to your computer and use it in GitHub Desktop.
Consul Service module for Ansible
# -*- coding: utf-8 -*-
# -*- mode: python -*-
DOCUMENTATION = '''
---
module: consul
short_description: Consul Agent API interaction with Docker
description:
- This module wraps the Consul API making calls to the Agent end points
to register and unregister services.
options:
docker_name:
description:
- The name of the docker file the service relates to.
required: True
default: None
docker_id:
description:
- The ID that relates to this service, e.g HTTP
required: False
default: {{ docker_name }}
port:
description:
- The port which the service to be registered runs on.
required: True
default: None
tags:
description:
- Any tags as a list that should be registered for the service.
required: False
default: None
check:
description:
- The path to a script which can check the service is working
required: False
default: None
check_args:
description:
- Any arguments to be passed on to the check as a string
required: False
default: None
docker_remove:
description:
- Should we remove or leave a failed docker container from the system
required: False
default: True
author: Mark Olliver
'''
EXAMPLES = '''
# Example that checks if Sentinel docker is running, if it is and the service
# is not registered then we register the service. If the docker is not running
# then we deregister the service if it was registered. If the remove flag is
# set then we remove the docker container if it is not running to tidy up the
# system.
- consul:
docker_name: "sentinel{{ env_suffix }}"
docker_id: "sentinel{{ env_suffix }}"
port: 26379
tags: "{{ env_suffix }}"
check: redis_check.py
check_args: "--docker_name sentinel{{ env_suffix }} --docker_id
sentinel{{ env_suffix }} --port 26379"
'''
'''
TODO(Mark): Extend to use check mode which will allow for reporting if
# a service is registered
'''
import urllib2
import json
def register_service(module, docker_name, docker_id, port,
tags, check, check_args):
url = "http://localhost:8500/v1/agent/service/register"
if (check):
data = {'ID': docker_id,
'Name': docker_name,
'Port': port,
'Tags': [tags],
'Check': {'Script': "/checks/" + check + " " + check_args,
'Interval': "60s"
}
}
else:
data = {'ID': docker_id,
'Name': docker_name,
'Port': port,
'Tags': [tags]
}
req = urllib2.Request(url, json.dumps(data))
try:
response = urllib2.urlopen(req)
content = (response.read())
except urllib2.HTTPError, e:
module.fail_json(msg="Consul Registration Error")
module.exit_json(changed=True, msg=" Registered Service: " + docker_id)
def deregister_service(module, docker_id, docker_name, docker_remove):
url = "http://localhost:8500/v1/agent/service/deregister/"
req = urllib2.Request(url + docker_id)
try:
content = urllib2.urlopen(req)
except urllib2.HTTPError, e:
module.fail_json(msg="Could not deregister service: " + docker_id)
if (docker_remove):
import docker
try:
docker.remove_container(docker_name)
module.exit_json(changed=True,
msg="Deregistered Service and removed Container: \
" + docker_id)
except:
pass
module.exit_json(changed=True, msg="Deregistered Service: " + docker_id)
def check_docker_running(docker_name):
import docker
c = docker.Client(base_url='unix://var/run/docker.sock',
version='1.11',
timeout=10)
containers = c.containers(quiet=False, all=False, trunc=True, latest=False,
since=None, before=None, limit=-1)
for x in range(len(containers)):
if docker_name in containers[x]["Names"][0]:
print containers[x]["Names"][0]
if "Up" in containers[x]["Status"]:
return True
def check_service_registered(module, docker_name, docker_id):
url = "http://localhost:8500/v1/agent/services"
req = urllib2.Request(url)
try:
content = json.load(urllib2.urlopen(req))
except urllib2.HTTPError, e:
module.fail_json(msg="Could not check service: " + docker_id)
try:
if docker_name == content[docker_id]["Service"]:
return True
else:
return False
except KeyError, e:
return False
def main():
module = AnsibleModule(
argument_spec=dict(
docker_name=dict(required=True),
docker_id=dict(required=False),
port=dict(required=True),
tags=dict(required=False),
check=dict(require=False),
check_args=dict(required=False),
docker_remove=dict(required=False)
),
supports_check_mode=False
)
docker_name = module.params.get('docker_name')
docker_id = module.params.get('docker_id') or docker_name
port = module.params.get('port')
tags = module.params.get('tags') or None
check = module.params.get('check') or None
check_args = module.params.get('check_args') or ""
docker_remove = module.params.get('docker_remove') or True
docker_running = check_docker_running(docker_name)
service_registered = check_service_registered(module,
docker_name,
docker_id)
if docker_running:
if service_registered:
module.exit_json(changed=False,
msg="Docker running and service registered")
else:
register_service(module, docker_name, docker_id, port,
tags, check, check_args)
else:
deregister_service(module, docker_id, docker_name, docker_remove)
# import module snippets
from ansible.module_utils.basic import *
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment