Open wt opened 8 years ago
Making sure that the attribute is a JSON string would difficult to do because that is represented as a dictionary in IAM's API, and it also would be a breaking change if we did change it to a string.
As to the documentation, it is incorrectly labeled a string. We will look into updating it.
Is there any way to get at that string so that I can pass it to the IAM.RolePolicy.puIs method without having to re-encode it in json?
This automatic parsing is kinda terrible for any use case that can treat the string as a opaque value.
Maybe it would make more sense to turn the policy_document into an object that has methods for getting the string or the dict depending on whats appropriate?
I just ran into this as well, after fighting with PutGroupPolicy complaining about syntax errors; I know the string I'm passing is a valid policy document, because I copied it directly from the IAM policy in the AWS console. Is it also possible that the PolicyDocument parameter to PutGroupPolicy expects a dict, and not a string?
@kpfleming No, as of right now policy documents as input parameters expect and only accept strings. You probably copied in some extra bits from the console formatting.
I have pull requests up to fix the documentation to refer to policy documents as dicts instead of strings and to accept dicts as policy document inputs. Sorry for the delay.
Well, since I commented here I've successfully run my Python script dozens of times, and it put inline policies into groups without any trouble; it supplies the policy to the create_policy() function on the Group as a 'dict'. Presumably this gets automatically converted to a string somewhere in the process.
any updates?
Yeah, the documentation still doesn't match the behaviour.
I have also encountered a few discrepancies in the api implementation as well. With regards to the string vs dict issue i have found occurrences of both in my calls to aws boto3. strings and dicts in the same call.
This can be tested and validated with the following code.
from collections import defaultdict
import boto3
try:
basestring
except NameError:
basestring = (str, bytes)
managed_role_policies = defaultdict(list)
for arp in iam.list_attached_role_policies(RoleName=role['RoleName'])['AttachedPolicies']:
managed_role_policies[role['RoleName']].append(arp['PolicyArn'])
for role, policy in managed_role_policies.items():
for p in policy:
versions = iam.list_policy_versions(PolicyArn=p)
for ver in versions['Versions']:
for action in iam.get_policy_version(PolicyArn=p, VersionId=ver['VersionId'])['PolicyVersion']['Document']['Statement']:
if isinstance(action, basestring):
print('{} {}'.format(type(action), action))
else:
try:
print('{} {}'.format(type(action), action['Action']))
except:
print('{} {}'.format(type(action), action['NotAction']))
secondly is the lack of documentation to the NotAction Key and when the NotAction Key is present the Action Key is not. This particular API call is seriously inconsistent.
please update the docs to reflect the implementation.
This is still an issue, the documentation does not match the behavior.
This issue is old enough to have entered primary school by now...
Here's one example of the error:
http://boto3.readthedocs.org/en/latest/reference/services/iam.html#IAM.RolePolicy.policy_document
The documentation says a string is returned. Actually, a dict is returned. It's okay to have a dict created from the json, I guess. However, I also cannot use that dict directly with the following API:
http://boto3.readthedocs.org/en/latest/reference/services/iam.html#IAM.RolePolicy.put
I have to wrap the dict with json.dumps() to get it to be the string that the put() method wants for the PolicyDocument arg.
This is confusing, and it would be nice if I could just pass the dict or if the return of the policy_document attribute were actually a string.