mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-07 13:52:54 +00:00
Validate SSL certs accessed through urllib*
* Adds another module utility file which generalizes the access of urls via the urllib* libraries. * Adds a new spec generator for common arguments. * Makes the user-agent string configurable. Fixes #6211
This commit is contained in:
@@ -52,6 +52,13 @@ options:
|
||||
- Optional URL to submit the notification to. Use to send notifications to Airbrake-compliant tools like Errbit.
|
||||
required: false
|
||||
default: https://airbrake.io/deploys
|
||||
validate_certs:
|
||||
description:
|
||||
- If C(no), SSL certificates for the target url will not be validated. This should only be used
|
||||
on personally controlled sites using self-signed certificates.
|
||||
required: false
|
||||
default: 'yes'
|
||||
choices: ['yes', 'no']
|
||||
|
||||
# informational: requirements for nodes
|
||||
requirements: [ urllib, urllib2 ]
|
||||
@@ -64,29 +71,12 @@ EXAMPLES = '''
|
||||
revision=4.2
|
||||
'''
|
||||
|
||||
HAS_URLLIB = True
|
||||
try:
|
||||
import urllib
|
||||
except ImportError:
|
||||
HAS_URLLIB = False
|
||||
|
||||
HAS_URLLIB2 = True
|
||||
try:
|
||||
import urllib2
|
||||
except ImportError:
|
||||
HAS_URLLIB2 = False
|
||||
|
||||
# ===========================================
|
||||
# Module execution.
|
||||
#
|
||||
|
||||
def main():
|
||||
|
||||
if not HAS_URLLIB:
|
||||
module.fail_json(msg="urllib is not installed")
|
||||
if not HAS_URLLIB2:
|
||||
module.fail_json(msg="urllib2 is not installed")
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
token=dict(required=True),
|
||||
@@ -95,6 +85,7 @@ def main():
|
||||
repo=dict(required=False),
|
||||
revision=dict(required=False),
|
||||
url=dict(required=False, default='https://api.airbrake.io/deploys.txt')
|
||||
validate_certs=dict(default='yes', type='bool'),
|
||||
),
|
||||
supports_check_mode=True
|
||||
)
|
||||
@@ -123,18 +114,16 @@ def main():
|
||||
module.exit_json(changed=True)
|
||||
|
||||
# Send the data to airbrake
|
||||
try:
|
||||
req = urllib2.Request(url, urllib.urlencode(params))
|
||||
result=urllib2.urlopen(req)
|
||||
except Exception, e:
|
||||
module.fail_json(msg="unable to update airbrake via %s?%s : %s" % (url, urllib.urlencode(params), e))
|
||||
data = urllib.urlencode(params)
|
||||
response, info = fetch_url(module, url, data=data, validate_certs=module.params['validate_certs'])
|
||||
if info['status'] == 200:
|
||||
module.exit_json(changed=True)
|
||||
else:
|
||||
if result.code == 200:
|
||||
module.exit_json(changed=True)
|
||||
else:
|
||||
module.fail_json(msg="HTTP result code: %d connecting to %s" % (result.code, url))
|
||||
module.fail_json(msg="HTTP result code: %d connecting to %s" % (info['status'], url))
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.urls import *
|
||||
|
||||
main()
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
import datetime
|
||||
import urllib2
|
||||
import base64
|
||||
import os
|
||||
|
||||
@@ -74,12 +73,6 @@ EXAMPLES='''
|
||||
|
||||
'''
|
||||
|
||||
try:
|
||||
import urllib2
|
||||
HAS_URLLIB2 = True
|
||||
except ImportError:
|
||||
HAS_URLLIB2 = False
|
||||
|
||||
api_host = "api.boundary.com"
|
||||
config_directory = "/etc/bprobe"
|
||||
|
||||
@@ -101,7 +94,7 @@ def build_url(name, apiid, action, meter_id=None, cert_type=None):
|
||||
elif action == "delete":
|
||||
return "https://%s/%s/meters/%s" % (api_host, apiid, meter_id)
|
||||
|
||||
def http_request(name, apiid, apikey, action, meter_id=None, cert_type=None):
|
||||
def http_request(module, name, apiid, apikey, action, data=None, meter_id=None, cert_type=None):
|
||||
|
||||
if meter_id is None:
|
||||
url = build_url(name, apiid, action)
|
||||
@@ -111,11 +104,11 @@ def http_request(name, apiid, apikey, action, meter_id=None, cert_type=None):
|
||||
else:
|
||||
url = build_url(name, apiid, action, meter_id, cert_type)
|
||||
|
||||
auth = auth_encode(apikey)
|
||||
request = urllib2.Request(url)
|
||||
request.add_header("Authorization", "Basic %s" % (auth))
|
||||
request.add_header("Content-Type", "application/json")
|
||||
return request
|
||||
headers = dict()
|
||||
headers["Authorization"] = "Basic %s" % auth_encode(apikey)
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
return fetch_url(module, url, data=data, headers=headers)
|
||||
|
||||
def create_meter(module, name, apiid, apikey):
|
||||
|
||||
@@ -126,14 +119,10 @@ def create_meter(module, name, apiid, apikey):
|
||||
module.exit_json(status="Meter " + name + " already exists",changed=False)
|
||||
else:
|
||||
# If it doesn't exist, create it
|
||||
request = http_request(name, apiid, apikey, action="create")
|
||||
# A create request seems to need a json body with the name of the meter in it
|
||||
body = '{"name":"' + name + '"}'
|
||||
request.add_data(body)
|
||||
response, info = http_request(module, name, apiid, apikey, data=body, action="create")
|
||||
|
||||
try:
|
||||
result = urllib2.urlopen(request)
|
||||
except urllib2.URLError, e:
|
||||
if info['status'] != 200:
|
||||
module.fail_json(msg="Failed to connect to api host to create meter")
|
||||
|
||||
# If the config directory doesn't exist, create it
|
||||
@@ -160,15 +149,13 @@ def create_meter(module, name, apiid, apikey):
|
||||
|
||||
def search_meter(module, name, apiid, apikey):
|
||||
|
||||
request = http_request(name, apiid, apikey, action="search")
|
||||
response, info = http_request(module, name, apiid, apikey, action="search")
|
||||
|
||||
try:
|
||||
result = urllib2.urlopen(request)
|
||||
except urllib2.URLError, e:
|
||||
if info['status'] != 200:
|
||||
module.fail_json("Failed to connect to api host to search for meter")
|
||||
|
||||
# Return meters
|
||||
return json.loads(result.read())
|
||||
return json.loads(response.read())
|
||||
|
||||
def get_meter_id(module, name, apiid, apikey):
|
||||
# In order to delete the meter we need its id
|
||||
@@ -186,16 +173,9 @@ def delete_meter(module, name, apiid, apikey):
|
||||
if meter_id is None:
|
||||
return 1, "Meter does not exist, so can't delete it"
|
||||
else:
|
||||
action = "delete"
|
||||
request = http_request(name, apiid, apikey, action, meter_id)
|
||||
# See http://stackoverflow.com/questions/4511598/how-to-make-http-delete-method-using-urllib2
|
||||
# urllib2 only does GET or POST I believe, but here we need delete
|
||||
request.get_method = lambda: 'DELETE'
|
||||
|
||||
try:
|
||||
result = urllib2.urlopen(request)
|
||||
except urllib2.URLError, e:
|
||||
module.fail_json("Failed to connect to api host to delete meter")
|
||||
response, info = http_request(module, name, apiid, apikey, action, meter_id)
|
||||
if info['status'] != 200:
|
||||
module.fail_json("Failed to delete meter")
|
||||
|
||||
# Each new meter gets a new key.pem and ca.pem file, so they should be deleted
|
||||
types = ['cert', 'key']
|
||||
@@ -214,17 +194,14 @@ def download_request(module, name, apiid, apikey, cert_type):
|
||||
|
||||
if meter_id is not None:
|
||||
action = "certificates"
|
||||
request = http_request(name, apiid, apikey, action, meter_id, cert_type)
|
||||
|
||||
try:
|
||||
result = urllib2.urlopen(request)
|
||||
except urllib2.URLError, e:
|
||||
response, info = http_request(module, name, apiid, apikey, action, meter_id, cert_type)
|
||||
if info['status'] != 200:
|
||||
module.fail_json("Failed to connect to api host to download certificate")
|
||||
|
||||
if result:
|
||||
try:
|
||||
cert_file_path = '%s/%s.pem' % (config_directory,cert_type)
|
||||
body = result.read()
|
||||
body = response.read()
|
||||
cert_file = open(cert_file_path, 'w')
|
||||
cert_file.write(body)
|
||||
cert_file.close
|
||||
@@ -238,9 +215,6 @@ def download_request(module, name, apiid, apikey, cert_type):
|
||||
|
||||
def main():
|
||||
|
||||
if not HAS_URLLIB2:
|
||||
module.fail_json(msg="urllib2 is not installed")
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
state=dict(required=True, choices=['present', 'absent']),
|
||||
@@ -268,5 +242,6 @@ def main():
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.urls import *
|
||||
main()
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ datadog_event: title="Testing from ansible" text="Test!"
|
||||
'''
|
||||
|
||||
import socket
|
||||
from urllib2 import urlopen, Request, URLError
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
@@ -97,8 +96,7 @@ def main():
|
||||
post_event(module)
|
||||
|
||||
def post_event(module):
|
||||
uri = "https://app.datadoghq.com/api/v1/events?api_key=" + \
|
||||
module.params['api_key']
|
||||
uri = "https://app.datadoghq.com/api/v1/events?api_key=%s" % module.params['api_key']
|
||||
|
||||
body = dict(
|
||||
title=module.params['title'],
|
||||
@@ -117,22 +115,20 @@ def post_event(module):
|
||||
|
||||
json_body = module.jsonify(body)
|
||||
headers = {"Content-Type": "application/json"}
|
||||
request = Request(uri, json_body, headers, unverifiable=True)
|
||||
|
||||
try:
|
||||
response = urlopen(request)
|
||||
(response, info) = fetch_url(module, uri, data=json_body, headers=headers)
|
||||
if info['status'] == 200:
|
||||
response_body = response.read()
|
||||
response_json = module.from_json(response_body)
|
||||
if response_json['status'] == 'ok':
|
||||
module.exit_json(changed=True)
|
||||
else:
|
||||
module.fail_json(msg=response)
|
||||
|
||||
except URLError, e:
|
||||
module.fail_json(msg="URL error: %s." % e)
|
||||
except socket.error, e:
|
||||
module.fail_json(msg="Socket error: %s to %s" % (e, uri))
|
||||
else:
|
||||
module.fail_json(**info)
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.urls import *
|
||||
|
||||
main()
|
||||
|
||||
@@ -75,29 +75,12 @@ EXAMPLES = '''
|
||||
revision=1.0
|
||||
'''
|
||||
|
||||
HAS_URLLIB = True
|
||||
try:
|
||||
import urllib
|
||||
except ImportError:
|
||||
HAS_URLLIB = False
|
||||
|
||||
HAS_URLLIB2 = True
|
||||
try:
|
||||
import urllib2
|
||||
except ImportError:
|
||||
HAS_URLLIB2 = False
|
||||
|
||||
# ===========================================
|
||||
# Module execution.
|
||||
#
|
||||
|
||||
def main():
|
||||
|
||||
if not HAS_URLLIB:
|
||||
module.fail_json(msg="urllib is not installed")
|
||||
if not HAS_URLLIB2:
|
||||
module.fail_json(msg="urllib2 is not installed")
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
token=dict(required=True),
|
||||
@@ -134,29 +117,20 @@ def main():
|
||||
module.exit_json(changed=True)
|
||||
|
||||
# Send the data to NewRelic
|
||||
try:
|
||||
req = urllib2.Request("https://rpm.newrelic.com/deployments.xml", urllib.urlencode(params))
|
||||
req.add_header('x-api-key',module.params["token"])
|
||||
result=urllib2.urlopen(req)
|
||||
# urlopen behaves differently in python 2.4 and 2.6 so we handle
|
||||
# both cases here. In python 2.4 it throws an exception if the
|
||||
# return code is anything other than a 200. In python 2.6 it
|
||||
# doesn't throw an exception for any 2xx return codes. In both
|
||||
# cases we expect newrelic should return a 201 on success. So
|
||||
# to handle both cases, both the except & else cases below are
|
||||
# effectively identical.
|
||||
except Exception, e:
|
||||
if e.code == 201:
|
||||
module.exit_json(changed=True)
|
||||
else:
|
||||
module.fail_json(msg="unable to update newrelic: %s" % e)
|
||||
url = "https://rpm.newrelic.com/deployments.xml"
|
||||
data = urllib.urlencode(params)
|
||||
headers = {
|
||||
'x-api-key': module.params["token"],
|
||||
}
|
||||
response, info = fetch_url(module, url, data=data, headers=headers)
|
||||
if info['status'] in (200, 201):
|
||||
module.exit_json(changed=True)
|
||||
else:
|
||||
if result.code == 201:
|
||||
module.exit_json(changed=True)
|
||||
else:
|
||||
module.fail_json(msg="result code: %d" % result.code)
|
||||
module.fail_json(msg="unable to update newrelic: %s" % info['msg'])
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.urls import *
|
||||
|
||||
main()
|
||||
|
||||
|
||||
@@ -87,24 +87,23 @@ EXAMPLES='''
|
||||
|
||||
import json
|
||||
import datetime
|
||||
import urllib2
|
||||
import base64
|
||||
|
||||
|
||||
def ongoing(name, user, passwd):
|
||||
def ongoing(module, name, user, passwd):
|
||||
|
||||
url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows/ongoing"
|
||||
auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
|
||||
headers = {"Authorization": "Basic %s" % auth}
|
||||
|
||||
req = urllib2.Request(url)
|
||||
req.add_header("Authorization", "Basic %s" % auth)
|
||||
res = urllib2.urlopen(req)
|
||||
out = res.read()
|
||||
response, info = fetch_url(module, url, headers=headers)
|
||||
if info['status'] != 200:
|
||||
module.fail_json(msg="failed to lookup the ongoing window: %s" % info['msg'])
|
||||
|
||||
return False, out
|
||||
return False, response.read()
|
||||
|
||||
|
||||
def create(name, user, passwd, service, hours, desc):
|
||||
def create(module, name, user, passwd, service, hours, desc):
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
later = now + datetime.timedelta(hours=int(hours))
|
||||
@@ -113,15 +112,17 @@ def create(name, user, passwd, service, hours, desc):
|
||||
|
||||
url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows"
|
||||
auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
|
||||
headers = {
|
||||
'Authorization': 'Basic %s' % auth,
|
||||
'Content-Type' : 'application/json',
|
||||
}
|
||||
data = json.dumps({'maintenance_window': {'start_time': start, 'end_time': end, 'description': desc, 'service_ids': [service]}})
|
||||
|
||||
req = urllib2.Request(url, data)
|
||||
req.add_header("Authorization", "Basic %s" % auth)
|
||||
req.add_header('Content-Type', 'application/json')
|
||||
res = urllib2.urlopen(req)
|
||||
out = res.read()
|
||||
response, info = fetch_url(module, url, data=data, headers=headers, method='POST')
|
||||
if info['status'] != 200:
|
||||
module.fail_json(msg="failed to create the window: %s" % info['msg'])
|
||||
|
||||
return False, out
|
||||
return False, response.read()
|
||||
|
||||
|
||||
def main():
|
||||
@@ -149,10 +150,10 @@ def main():
|
||||
if state == "running" or state == "started":
|
||||
if not service:
|
||||
module.fail_json(msg="service not specified")
|
||||
(rc, out) = create(name, user, passwd, service, hours, desc)
|
||||
(rc, out) = create(module, name, user, passwd, service, hours, desc)
|
||||
|
||||
if state == "ongoing":
|
||||
(rc, out) = ongoing(name, user, passwd)
|
||||
(rc, out) = ongoing(module, name, user, passwd)
|
||||
|
||||
if rc != 0:
|
||||
module.fail_json(msg="failed", result=out)
|
||||
@@ -161,4 +162,6 @@ def main():
|
||||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.urls import *
|
||||
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user