Appending a role binding does not work as per the docs
Summary
As per documented in https://cloud.google.com/iam/docs/write-policy-client-libraries, adding a new role binding is shown to be accomplished by the following
binding = {"role": "foo", "members": ["bar"]} policy["bindings"].append(binding)
Expected behaviour
Successfully adding the binding
Observed behaviour
TypeError: Expected a message object, but got {'role': 'foo', 'members': ['bar']}.
Background info
python-version: 3.11.9
Pip freeze:
Arpeggio==2.0.2 asttokens==2.4.1 attrs==23.2.0 black==24.4.2 cachetools==5.3.3 certifi==2024.2.2 cffi==1.16.0 charset-normalizer==3.3.2 click==8.1.7 cryptography==42.0.7 decorator==5.1.1 Deprecated==1.2.14 dill==0.3.8 executing==2.0.1 gitdb==4.0.11 GitPython==3.1.41 google-api-core==2.19.0 google-auth==2.29.0 google-cloud-core==2.4.1 google-cloud-firestore==2.15.0 google-cloud-resource-manager==1.12.3 googleapis-common-protos==1.63.0 grpc-google-iam-v1==0.13.0 grpcio==1.60.1 grpcio-status==1.60.1 idna==3.7 iniconfig==2.0.0 ipython==8.24.0 isort==5.13.2 jedi==0.19.1 Jinja2==3.1.3 MarkupSafe==2.1.5 matplotlib-inline==0.1.7 mypy-extensions==1.0.0 packaging==24.0 parso==0.8.4 parver==0.5 pathspec==0.12.1 pexpect==4.9.0 platformdirs==4.2.1 pluggy==1.5.0 prompt-toolkit==3.0.43 proto-plus==1.23.0 protobuf==4.25.3 ptyprocess==0.7.0 pulumi==3.114.0 pulumi_gcp==7.20.0 pure-eval==0.2.2 pyasn1==0.6.0 pyasn1_modules==0.4.0 pycparser==2.22 PyGithub==2.2.0 Pygments==2.18.0 PyJWT==2.8.0 PyNaCl==1.5.0 pytest==8.2.0 pytest-order==1.2.1 PyYAML==6.0.1 requests==2.31.0 rsa==4.9 semver==2.13.0 six==1.16.0 smmap==5.0.1 stack-data==0.6.3 toml==0.10.2 traitlets==5.14.3 typing_extensions==4.11.0 urllib3==2.2.1 wcwidth==0.2.13 wrapt==1.16.0
@aaron-tillekeratne Thanks for reporting this. It's unclear how you've defined policy.
For the quickest resolution to this issue, kindly provide a complete code snippet to reproduce this issue. We can then identify if it's a problem with the sample docs or the api / client.
Reproducible code example.
from google.cloud import resourcemanager_v3
PROJECT_ID = "YOUR_PROJECT_GOES_HERE"
ROLE = f"projects/{PROJECT_ID}/roles/YOUR_ROLE_ID_HERE"
MEMBER = "user:[email protected]"
client = resourcemanager_v3.ProjectsClient()
policy = client.get_iam_policy(request={"resource":f"projects/{PROJECT_ID}"})
policy.bindings.append({"role":ROLE, "members":[MEMBER]})
# TypeError: Expected a message object, but got {'role': 'projects/YOUR_PROJECT_GOES_HERE/roles/YOUR_ROLE_ID_HERE', 'members': ['user:[email protected]']}.
Any updates on this one?
@aaron-tillekeratne — ran into the same problem as you.
Had a dig around, and tried this out on a dev GCP project (I'm in no way an expert on Protobuf, etc. so YMMV), but putting in the new binding into a Binding class seemed to work.
Can't provide my example, but editing from your reproducible code example:
from google.cloud import resourcemanager_v3
from google.iam.v1.policy_pb2 import Binding
PROJECT_ID = "YOUR_PROJECT_GOES_HERE"
ROLE = f"projects/{PROJECT_ID}/roles/YOUR_ROLE_ID_HERE"
MEMBER = "user:[email protected]"
client = resourcemanager_v3.ProjectsClient()
policy = client.get_iam_policy(request={"resource":f"projects/{PROJECT_ID}"})
policy.bindings.append(Binding(role=ROLE, members=[MEMBER]))
Note I'm not using your exact Python env; relevant Google-related packages:
google-cloud-resource-manager 1.12.5
grpc-google-iam-v1 0.12.7
protobuf 4.25.4
@ohmayr — grateful for confirmation that this is correct!
nice one, i'm on a different project at the moment, but I trust this would work. I'll close this.