boto/boto — pull request #2512 by victortrac (2014-08-10 05:18:49+00:00)
Title: cloudsearch2 errors with updating access policies

I was trying to programmatically allow my IP access to my cloudsearch instance like this:
```
from boto import cloudsearch2
from boto.cloudsearch2.domain import Domain

connection = cloudsearch2.connect_to_region(region)
domain = Domain(connection, "my_domain_arn")
ip = requests.get('http://jsonip.com').json()['ip']
service_policy = domain.get_access_policies()
service_policy.allow_doc_ip(ip + '/32')
service_policy.allow_search_ip(ip + '/32')
service_policy.save()
```

On Python 2.7.5 and boto 2.32.1, I ran into this error:

```
...
service_policy = domain.get_access_policies()
File "/lib/python2.7/site-packages/boto/cloudsearch2/domain.py", line 228, in get_access_policies
save_fn=self.layer1.update_service_access_policies)
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 59, in __init__
self.refresh(data)
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 87, in refresh
self._update_options(data['Options'])
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 69, in _update_options
self.update(options)
ValueError: dictionary update sequence element #0 has length 1; 2 is required
```

It appears that ```options``` is a JSON string while the ```ServicePoliciesStatus``` object expects a python dict. After fixing that, I then ran into this error:

```
...
service_policy.allow_doc_ip(ip + '/32')
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 197, in allow_doc_ip
self._allow_ip(arn, ip)
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 168, in _allow_ip
condition['aws:SourceIp'].append(ip)
AttributeError: 'unicode' object has no attribute 'append'
```

This was caused by the API returning a unicode string for an existing IP instead of a list for the existing statement:
```python
{u'Statement': [{u'Action': u'cloudsearch:*',
u'Condition': {u'IpAddress': {u'aws:SourceIp': u'1.2.3.4/32'}},
u'Effect': u'Allow',
u'Principal': {u'AWS': u'*'},
u'Resource': u'arn:aws:cloudsearch:us-west-1:1234567890:domain/test',
u'Sid': u''}],
u'Version': u'2012-10-17'}
```

After making sure that the value is in a list, I then ran into this problem:
```
File "/app/api/search/__init__.py", line 35, in _setup_policy
service_policy.allow_doc_ip(ip + '/32')
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 197, in allow_doc_ip
self._allow_ip(arn, ip)
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 160, in _allow_ip
for condition_name in statement['Condition']:
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 102, in save
self.refresh(data)
File "/lib/python2.7/site-packages/boto/cloudsearch2/optionstatus.py", line 86, in refresh
self._update_status(data['Status'])
KeyError: 'Status'
```

The data dict coming back from the API had a `UpdateServiceAccessPoliciesResponse` key after making policy changes instead of a flat ```Status``` key.

After fixing these issues, I'm able to successfully update my access policies.