@ -63,8 +63,43 @@ options:
description :
- URL of docker host to issue commands to
required : false
default : unix : / / var / run / docker . sock
default : $ { DOCKER_HOST } or unix : / / var / run / docker . sock
aliases : [ ]
use_tls :
description :
- Whether to use tls to connect to the docker server . " no " means not to
use tls ( and ignore any other tls related parameters ) . " encrypt " means
to use tls to encrypt the connection to the server . " verify " means to
also verify that the server ' s certificate is valid for the server
( this both verifies the certificate against the CA and that the
certificate was issued for that host . If this is unspecified , tls will
only be used if one of the other tls options require it .
choices : [ " no " , " encrypt " , " verify " ]
version_added : " 2.0 "
tls_client_cert :
description :
- Path to the PEM - encoded certificate used to authenticate docker client .
If specified tls_client_key must be valid
default : $ { DOCKER_CERT_PATH } / cert . pem
version_added : " 2.0 "
tls_client_key :
description :
- Path to the PEM - encoded key used to authenticate docker client . If
specified tls_client_cert must be valid
default : $ { DOCKER_CERT_PATH } / key . pem
version_added : " 2.0 "
tls_ca_cert :
description :
- Path to a PEM - encoded certificate authority to secure the Docker connection .
This has no effect if use_tls is encrypt .
default : $ { DOCKER_CERT_PATH } / ca . pem
version_added : " 2.0 "
tls_hostname :
description :
- A hostname to check matches what ' s supplied in the docker server ' s
certificate . If unspecified , the hostname is taken from the docker_url .
default : Taken from docker_url
version_added : " 2.0 "
docker_api_version :
description :
- Remote API version to use . This defaults to the current default as
@ -118,6 +153,7 @@ Remove image from local docker storage:
'''
import re
import os
from urlparse import urlparse
try :
@ -161,11 +197,90 @@ class DockerImageManager:
self . name = self . module . params . get ( ' name ' )
self . tag = self . module . params . get ( ' tag ' )
self . nocache = self . module . params . get ( ' nocache ' )
docker_url = urlparse ( module . params . get ( ' docker_url ' ) )
# Connect to the docker server using any configured host and TLS settings.
env_host = os . getenv ( ' DOCKER_HOST ' )
env_docker_verify = os . getenv ( ' DOCKER_TLS_VERIFY ' )
env_cert_path = os . getenv ( ' DOCKER_CERT_PATH ' )
env_docker_hostname = os . getenv ( ' DOCKER_TLS_HOSTNAME ' )
docker_url = module . params . get ( ' docker_url ' )
if not docker_url :
if env_host :
docker_url = env_host
else :
docker_url = ' unix://var/run/docker.sock '
docker_api_version = module . params . get ( ' docker_api_version ' )
tls_client_cert = module . params . get ( ' tls_client_cert ' , None )
if not tls_client_cert and env_cert_path :
tls_client_cert = os . path . join ( env_cert_path , ' cert.pem ' )
tls_client_key = module . params . get ( ' tls_client_key ' , None )
if not tls_client_key and env_cert_path :
tls_client_key = os . path . join ( env_cert_path , ' key.pem ' )
tls_ca_cert = module . params . get ( ' tls_ca_cert ' )
if not tls_ca_cert and env_cert_path :
tls_ca_cert = os . path . join ( env_cert_path , ' ca.pem ' )
tls_hostname = module . params . get ( ' tls_hostname ' )
if tls_hostname is None :
if env_docker_hostname :
tls_hostname = env_docker_hostname
else :
parsed_url = urlparse ( docker_url )
if ' : ' in parsed_url . netloc :
tls_hostname = parsed_url . netloc [ : parsed_url . netloc . rindex ( ' : ' ) ]
else :
tls_hostname = parsed_url
if not tls_hostname :
tls_hostname = True
# use_tls can be one of four values:
# no: Do not use tls
# encrypt: Use tls. We may do client auth. We will not verify the server
# verify: Use tls. We may do client auth. We will verify the server
# None: Only use tls if the parameters for client auth were specified
# or tls_ca_cert (which requests verifying the server with
# a specific ca certificate)
use_tls = module . params . get ( ' use_tls ' )
if use_tls is None and env_docker_verify is not None :
use_tls = ' verify '
tls_config = None
if use_tls != ' no ' :
params = { }
# Setup client auth
if tls_client_cert and tls_client_key :
params [ ' client_cert ' ] = ( tls_client_cert , tls_client_key )
# We're allowed to verify the connection to the server
if use_tls == ' verify ' or ( use_tls is None and tls_ca_cert ) :
if tls_ca_cert :
params [ ' ca_cert ' ] = tls_ca_cert
params [ ' verify ' ] = True
params [ ' assert_hostname ' ] = tls_hostname
else :
params [ ' verify ' ] = True
params [ ' assert_hostname ' ] = tls_hostname
elif use_tls == ' encrypt ' :
params [ ' verify ' ] = False
if params :
# See https://github.com/docker/docker-py/blob/d39da11/docker/utils/utils.py#L279-L296
docker_url = docker_url . replace ( ' tcp:// ' , ' https:// ' )
tls_config = docker . tls . TLSConfig ( * * params )
self . client = docker . Client (
base_url = docker_url . geturl ( ) ,
base_url = docker_url ,
version = module . params . get ( ' docker_api_version ' ) ,
timeout = module . params . get ( ' timeout ' ) )
timeout = module . params . get ( ' timeout ' ) ,
tls = tls_config )
self . changed = False
self . log = [ ]
self . error_msg = None
@ -244,7 +359,12 @@ def main():
tag = dict ( required = False , default = " latest " ) ,
nocache = dict ( default = False , type = ' bool ' ) ,
state = dict ( default = ' present ' , choices = [ ' absent ' , ' present ' , ' build ' ] ) ,
docker_url = dict ( default = ' unix://var/run/docker.sock ' ) ,
use_tls = dict ( default = None , choices = [ ' no ' , ' encrypt ' , ' verify ' ] ) ,
tls_client_cert = dict ( required = False , default = None , type = ' str ' ) ,
tls_client_key = dict ( required = False , default = None , type = ' str ' ) ,
tls_ca_cert = dict ( required = False , default = None , type = ' str ' ) ,
tls_hostname = dict ( required = False , type = ' str ' , default = None ) ,
docker_url = dict ( ) ,
docker_api_version = dict ( required = False ,
default = DEFAULT_DOCKER_API_VERSION ,
type = ' str ' ) ,
@ -286,6 +406,45 @@ def main():
module . exit_json ( failed = failed , changed = manager . has_changed ( ) , msg = msg , image_id = image_id )
except SSLError as e :
if get_platform ( ) == " Darwin " :
# Ensure that the environment variables has been set
if " DOCKER_HOST " not in os . environ :
environment_error = '''
It looks like you have not set your docker environment
variables . Please ensure that you have set the requested
variables as instructed when running boot2docker up . If
they are set in . bash_profile you will need to symlink
it to . bashrc .
'''
module . exit_json ( failed = True , changed = manager . has_changed ( ) , msg = " SSLError: " + str ( e ) + environment_error )
# If the above is true it's likely the hostname does not match
else :
environment_error = '''
You may need to ignore hostname missmatches by setting
tls_hostname = boot2docker in your role . If this does not
resolve the issue please open an issue at
ansible / ansible - modules - core and ping michaeljs1990
'''
module . exit_json ( failed = True , changed = manager . has_changed ( ) , msg = " SSLError: " + str ( e ) + environment_error )
# General error for non darwin users
else :
module . exit_json ( failed = True , changed = manager . has_changed ( ) , msg = " SSLError: " + str ( e ) )
except ConnectionError as e :
if get_platform ( ) == " Darwin " and " DOCKER_HOST " not in os . environ :
# Ensure that the environment variables has been set
environment_error = '''
It looks like you have not set your docker environment
variables . Please ensure that you have set the requested
variables as instructed when running boot2docker up . If
they are set in . bash_profile you will need to symlink
it to . bashrc .
'''
module . exit_json ( failed = True , changed = manager . has_changed ( ) , msg = " ConnectionError: " + str ( e ) + environment_error )
module . exit_json ( failed = True , changed = manager . has_changed ( ) , msg = " ConnectionError: " + str ( e ) )
except DockerAPIError as e :
module . exit_json ( failed = True , changed = manager . has_changed ( ) , msg = " Docker API error: " + e . explanation )