@ -12,8 +12,7 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
' status ' : [ ' stableinterface ' ] ,
' supported_by ' : ' core ' }
DOCUMENTATION = '''
DOCUMENTATION = r '''
- - -
module : uri
short_description : Interacts with webservices
@ -27,44 +26,33 @@ options:
description :
- HTTP or HTTPS URL in the form ( http | https ) : / / host . domain [ : port ] / path
required : true
default : null
dest :
description :
- path of where to download the file to ( if desired ) . If I ( dest ) is a
directory , the basename of the file on the remote server will be used .
required : false
default : null
user :
description :
- username for the module to use for Digest , Basic or WSSE authentication .
required : false
default : null
password :
description :
- password for the module to use for Digest , Basic or WSSE authentication .
required : false
default : null
body :
description :
- The body of the http request / response to the web service . If C ( body_format ) is set
to ' json ' it will take an already formatted JSON string or convert a data structure
into JSON .
required : false
default : null
body_format :
description :
- The serialization format of the body . When set to json , encodes the
body argument , if needed , and automatically sets the Content - Type header accordingly .
As of C ( 2.3 ) it is possible to override the ` Content - Type ` header , when
set to json via the I ( headers ) option .
required : false
choices : [ " raw " , " json " ]
default : raw
version_added : " 2.0 "
method :
description :
- The HTTP method of the request or response . It MUST be uppercase .
required : false
choices : [ " GET " , " POST " , " PUT " , " HEAD " , " DELETE " , " OPTIONS " , " PATCH " , " TRACE " , " CONNECT " , " REFRESH " ]
default : " GET "
return_content :
@ -73,18 +61,16 @@ options:
the dictionary result . If the reported Content - type is
" application/json " , then the JSON is additionally loaded into a key
called C ( json ) in the dictionary results .
required : false
choices : [ " yes " , " no " ]
default : " no "
type : bool
default : ' no '
force_basic_auth :
description :
- The library used by the uri module only sends authentication information when a webservice
responds to an initial request with a 401 status . Since some basic auth services do not properly
send a 401 , logins will fail . This option forces the sending of the Basic authentication header
upon initial request .
required : false
choices : [ " yes " , " no " ]
default : " no "
type : bool
default : ' no '
follow_redirects :
description :
- Whether or not the URI module should follow redirects . C ( all ) will follow all redirects .
@ -93,27 +79,22 @@ options:
any redirects . Note that C ( yes ) and C ( no ) choices are accepted for backwards compatibility ,
where C ( yes ) is the equivalent of C ( all ) and C ( no ) is the equivalent of C ( safe ) . C ( yes ) and C ( no )
are deprecated and will be removed in some future version of Ansible .
required : false
choices : [ " all " , " safe " , " none " ]
default : " safe "
creates :
description :
- a filename , when it already exists , this step will not be run .
required : false
removes :
description :
- a filename , when it does not exist , this step will not be run .
required : false
status_code :
description :
- A valid , numeric , HTTP status code that signifies success of the
request . Can also be comma separated list of status codes .
required : false
default : 200
timeout :
description :
- The socket level timeout in seconds
required : false
default : 30
HEADER_ :
description :
@ -122,52 +103,44 @@ options:
" Content-Type " along with your request with a value of " application/json " .
This option is deprecated as of C ( 2.1 ) and may be removed in a future
release . Use I ( headers ) instead .
required : false
default : null
headers :
description :
- Add custom HTTP headers to a request in the format of a YAML hash . As
of C ( 2.3 ) supplying C ( Content - Type ) here will override the header
generated by supplying C ( json ) for I ( body_format ) .
required : false
default : null
version_added : ' 2.1 '
others :
description :
- all arguments accepted by the M ( file ) module also work here
required : false
validate_certs :
description :
- If C ( no ) , SSL certificates will not be validated . This should only
set to C ( no ) used on personally controlled sites using self - signed
certificates . Prior to 1.9 .2 the code defaulted to C ( no ) .
required : false
type : bool
default : ' yes '
choices : [ ' yes ' , ' no ' ]
version_added : ' 1.9.2 '
client_cert :
required : false
default : null
description :
- PEM formatted certificate chain file to be used for SSL client
authentication . This file can also include the key as well , and if
the key is included , I ( client_key ) is not required
version_added : 2.4
version_added : ' 2.4 '
client_key :
required : false
default : null
description :
- PEM formatted file that contains your private key to be used for SSL
client authentication . If I ( client_cert ) contains both the certificate
and key , this option is not required .
version_added : 2.4
version_added : ' 2.4 '
notes :
- The dependency on httplib2 was removed in Ansible 2.1
- The dependency on httplib2 was removed in Ansible 2.1 .
- The module returns all the HTTP headers in lower - case .
- For Windows targets , use the M ( win_uri ) module instead .
author : " Romeo Theriault (@romeotheriault) "
author :
- Romeo Theriault ( @romeotheriault )
'''
EXAMPLES = '''
EXAMPLES = r '''
- name : Check that you can connect ( GET ) to a page and it returns a status 200
uri :
url : http : / / www . example . com
@ -225,6 +198,30 @@ EXAMPLES = '''
'''
RETURN = r '''
# The return information includes all the HTTP headers in lower-case.
msg :
description : The HTTP message from the request
returned : always
type : string
sample : OK ( unknown bytes )
redirected :
description : Whether the request was redirected
returned : always
type : bool
sample : false
status :
description : The HTTP status code from the request
returned : always
type : int
sample : 200
url :
description : The actual URL used for the request
returned : always
type : string
sample : https : / / www . ansible . com /
'''
import cgi
import datetime
import json
@ -258,10 +255,10 @@ def write_file(module, url, dest, content):
# raise an error if there is no tmpsrc file
if not os . path . exists ( tmpsrc ) :
os . remove ( tmpsrc )
module . fail_json ( msg = " Source %s does not exist " % ( tmpsrc ) )
module . fail_json ( msg = " Source ' %s ' does not exist " % tmpsrc )
if not os . access ( tmpsrc , os . R_OK ) :
os . remove ( tmpsrc )
module . fail_json ( msg = " Source %s not readable " % ( tmpsrc ) )
module . fail_json ( msg = " Source ' %s ' not readable " % tmpsrc )
checksum_src = module . sha1 ( tmpsrc )
# check if there is no dest file
@ -269,15 +266,15 @@ def write_file(module, url, dest, content):
# raise an error if copy has no permission on dest
if not os . access ( dest , os . W_OK ) :
os . remove ( tmpsrc )
module . fail_json ( msg = " Destination %s not writable " % ( dest ) )
module . fail_json ( msg = " Destination ' %s ' not writable " % dest )
if not os . access ( dest , os . R_OK ) :
os . remove ( tmpsrc )
module . fail_json ( msg = " Destination %s not readable " % ( dest ) )
module . fail_json ( msg = " Destination ' %s ' not readable " % dest )
checksum_dest = module . sha1 ( dest )
else :
if not os . access ( os . path . dirname ( dest ) , os . W_OK ) :
os . remove ( tmpsrc )
module . fail_json ( msg = " Destination dir %s not writable " % ( os . path . dirname ( dest ) ) )
module . fail_json ( msg = " Destination dir ' %s ' not writable " % os . path . dirname ( dest ) )
if checksum_src != checksum_dest :
try :
@ -371,19 +368,19 @@ def uri(module, url, dest, body, body_format, method, headers, socket_timeout):
def main ( ) :
argument_spec = url_argument_spec ( )
argument_spec . update ( dict (
dest = dict ( required = False , default = None , type = ' path ' ) ,
url_username = dict ( required = False , default = None , aliases = [ ' user ' ] ) ,
url_password = dict ( required = False , default = None , aliases = [ ' password ' ] , no_log = True ) ,
body = dict ( required = False , default = None , type = ' raw ' ) ,
body_format = dict ( required = False , default = ' raw ' , choices = [ ' raw ' , ' json ' ] ) ,
method = dict ( required = False , default = ' GET ' , choices = [ ' GET ' , ' POST ' , ' PUT ' , ' HEAD ' , ' DELETE ' , ' OPTIONS ' , ' PATCH ' , ' TRACE ' , ' CONNECT ' , ' REFRESH ' ] ) ,
return_content = dict ( required = False , default = ' no ' , type = ' bool ' ) ,
follow_redirects = dict ( required = False , default = ' safe ' , choices = [ ' all ' , ' safe ' , ' none ' , ' yes ' , ' no ' ] ) ,
creates = dict ( required = False , default = None , type = ' path ' ) ,
removes = dict ( required = False , default = None , type = ' path ' ) ,
status_code = dict ( required = False , default = [ 200 ] , type = ' list ' ) ,
timeout = dict ( required = False , default = 30 , type = ' int ' ) ,
headers = dict ( required = False , type = ' dict ' , default = { } )
dest = dict ( type = ' path ' ) ,
url_username = dict ( type = ' str ' , aliases = [ ' user ' ] ) ,
url_password = dict ( type = ' str ' , aliases = [ ' password ' ] , no_log = True ) ,
body = dict ( type = ' raw ' ) ,
body_format = dict ( type = ' str ' , default = ' raw ' , choices = [ ' raw ' , ' json ' ] ) ,
method = dict ( type = ' str ' , default = ' GET ' , choices = [ ' GET ' , ' POST ' , ' PUT ' , ' HEAD ' , ' DELETE ' , ' OPTIONS ' , ' PATCH ' , ' TRACE ' , ' CONNECT ' , ' REFRESH ' ] ) ,
return_content = dict ( type = ' bool ' , default = ' no ' ) ,
follow_redirects = dict ( type = ' str ' , default = ' safe ' , choices = [ ' all ' , ' safe ' , ' none ' , ' yes ' , ' no ' ] ) ,
creates = dict ( type = ' path ' ) ,
removes = dict ( type = ' path ' ) ,
status_code = dict ( type = ' list ' , default = [ 200 ] ) ,
timeout = dict ( type = ' int ' , default = 30 ) ,
headers = dict ( type = ' dict ' , default = { } )
) )
module = AnsibleModule (
@ -428,14 +425,14 @@ def main():
# and the filename already exists. This allows idempotence
# of uri executions.
if os . path . exists ( creates ) :
module . exit_json ( stdout = " skipped, since %s exists " % creates , changed = False , rc = 0 )
module . exit_json ( stdout = " skipped, since ' %s ' exists " % creates , changed = False , rc = 0 )
if removes is not None :
# do not run the command if the line contains removes=filename
# and the filename do not exists. This allows idempotence
# of uri executions.
if not os . path . exists ( removes ) :
module . exit_json ( stdout = " skipped, since %s does not exist " % removes , changed = False , rc = 0 )
module . exit_json ( stdout = " skipped, since ' %s ' does not exist " % removes , changed = False , rc = 0 )
# Make the request
resp , content , dest = uri ( module , url , dest , body , body_format , method ,