Repository: ansible/ansible

Issue:
Add a way to make boto not verify SSL certs
Starting a year ago with version 2.6.0, boto began verifying servers' SSL certificates by default.  Since most Eucalyptus and Nova installs have self-signed certs, this breaks Ansible's AWS-related modules when they're pointed at one of those clouds using a relatively current version of boto.

They added a `validate_certs=False` arg to calls like `boto.connect_ec2_endpoint` one can use to disable this behavior, but right now Ansible doesn't have a way to trigger that.  Modules like ec2, ec2_elb, and so on would benefit from a parameter that lets one turn cert verification off when they need to talk to services with self-signed certs.

EPEL bug that triggered this report:  https://bugzilla.redhat.com/show_bug.cgi?id=1003105



Discussion:
@lwade -- this doesn't seem quite correct, right?

I know you guys were using a recent boto with the Eucalyptus stuff.

Let me know.

Interesting, I'm using boto 2.9.6 and these modules work fine with Eucalyptus (3.3.0 and 3.3.1).  Example of using the ec2 module (just tested):

```
   - name: euca provision
     local_action: ec2 keypair=admin group=default instance_type=m1.small image=emi-A48F39EB wait=yes ec2_access_key=XXX ec2_secret_key=YYY ec2_url=http://mycloud:8773/services/Eucalyptus
```

```
< TASK: euca provision >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||


changed: [localhost] => {"changed": true, "instance_ids": ["i-BA7E4442"], "instances": [{"ami_launch_index": "0", "architecture": null, "dns_name": "euca-78-152-43-12.eucalyptus.emea.eucalyptus.com", "hypervisor": null, "id": "i-BA7E4442", "image_id": "emi-A48F39EB", "instance_type": "m1.small", "kernel": "eki-3F6E3890", "key_name": "admin", "launch_time": "2013-08-31T09:39:23.770Z", "placement": "cluster01", "private_dns_name": "euca-172-30-53-96.eucalyptus.internal", "private_ip": "172.30.53.96", "public_dns_name": "euca-78-152-43-12.eucalyptus.emea.eucalyptus.com", "public_ip": "78.152.43.12", "ramdisk": "eri-DD9E36B1", "root_device_name": "/dev/sda1", "root_device_type": "instance-store", "state": "running", "state_code": 16, "virtualization_type": null}]}
```

Since boto 2.9.9 is now the version in EPEL(6), we should test with that in future.  Most of the time we've tested against this version (i.e. required 2.5.2 and upwards prior to the change in EPEL). Anyhow, that is an aside.

Oh sorry, just noticed.  Yes, so this would be an issue.  I'm not using SSL for tests at the moment, so a patch for this would be welcome, adding a parameter like ssl_cert_check=disabled/enabled perhaps...

I'm not going to get a chance to look at this until week after next (holiday) but PR welcome in the meantime :D


Resolving patch:
diff --git a/lib/ansible/module_utils/ec2.py b/lib/ansible/module_utils/ec2.py
--- a/lib/ansible/module_utils/ec2.py
+++ b/lib/ansible/module_utils/ec2.py
@@ -1,3 +1,9 @@
+try:
+    from distutils.version import LooseVersion
+    HAS_LOOSE_VERSION = True
+except:
+    HAS_LOOSE_VERSION = False
+
 AWS_REGIONS = ['ap-northeast-1',
                'ap-southeast-1',
                'ap-southeast-2',
@@ -14,6 +20,7 @@ def ec2_argument_spec():
         ec2_url=dict(),
         ec2_secret_key=dict(aliases=['aws_secret_key', 'secret_key'], no_log=True),
         ec2_access_key=dict(aliases=['aws_access_key', 'access_key']),
+        validate_certs=dict(default=True, type='bool'),
     )
 
 
@@ -62,17 +69,24 @@ def ec2_connect(module):
     """ Return an ec2 connection"""
 
     ec2_url, aws_access_key, aws_secret_key, region = get_ec2_creds(module)
+    validate_certs = module.get('validate_certs', True)
 
     # If we have a region specified, connect to its endpoint.
     if region:
         try:
-            ec2 = boto.ec2.connect_to_region(region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key)
+            if HAS_LOOSE_VERSION and LooseVersion(boto.Version) >= LooseVersion("2.6.0"):
+                ec2 = boto.ec2.connect_to_region(region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key, validate_certs=validate_certs)
+            else:
+                ec2 = boto.ec2.connect_to_region(region, aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key)
         except boto.exception.NoAuthHandlerFound, e:
             module.fail_json(msg = str(e))
     # Otherwise, no region so we fallback to the old connection method
     elif ec2_url:
         try:
-            ec2 = boto.connect_ec2_endpoint(ec2_url, aws_access_key, aws_secret_key)
+            if HAS_LOOSE_VERSION and LooseVersion(boto.Version) >= LooseVersion("2.6.0"):
+                ec2 = boto.connect_ec2_endpoint(ec2_url, aws_access_key, aws_secret_key, validate_certs=validate_certs)
+            else:
+                ec2 = boto.connect_ec2_endpoint(ec2_url, aws_access_key, aws_secret_key)
         except boto.exception.NoAuthHandlerFound, e:
             module.fail_json(msg = str(e))
     else:


Test patch: