boto / boto3

AWS SDK for Python
https://aws.amazon.com/sdk-for-python/
Apache License 2.0
8.87k stars 1.85k forks source link

IAM policy documentation wrong about return type #229

Open wt opened 8 years ago

wt commented 8 years ago

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.

kyleknap commented 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.

wt commented 8 years ago

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?

kpfleming commented 8 years ago

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?

JordonPhillips commented 8 years ago

@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.

kpfleming commented 8 years ago

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.

xysr89 commented 6 years ago

any updates?

prufrax commented 6 years ago

Yeah, the documentation still doesn't match the behaviour.

castaway2000 commented 6 years ago

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.

LHCGreg commented 3 years ago

This is still an issue, the documentation does not match the behavior.

kpfleming commented 3 years ago

This issue is old enough to have entered primary school by now...