Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MinioAdmin: allow specifying policies as dict besides file #1480

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Alveel
Copy link
Contributor

@Alveel Alveel commented Jan 31, 2025

It would be nice to be able to add/update IAM/service account policies through Python dict objects as well as what's currently available through JSON files.

This PR tries to accomplish this.

Feedback/questions welcome.

Depends on #1483

@darix
Copy link

darix commented Feb 4, 2025

i wonder if it makes sense to refactor out something like

def _load_policy(policy_file, policy):
        if policy and policy_file:
            raise ValueError(
                "only one of policy or policy_file may be specified")
        if not policy or not policy_file:
            raise ValueError("either policy or policy_file must be specified")
        body = ''
        if policy:
            body = json.dumps(policy)
        elif policy_file:
            with open(policy_file, encoding='utf-8') as file:
                body = file.read()
       return body

given in how many places we basically have the same code now.

@Alveel
Copy link
Contributor Author

Alveel commented Feb 4, 2025

Sounds fairly sensible actually. I'll wait for feedback from a member and see what they think.

@Alveel
Copy link
Contributor Author

Alveel commented Feb 11, 2025

@balamurugana please review

@Alveel
Copy link
Contributor Author

Alveel commented Feb 13, 2025

I'd love to hear some feedback on the current state.

@Alveel Alveel requested a review from balamurugana February 13, 2025 21:01
@harshavardhana harshavardhana requested review from balamurugana and removed request for balamurugana February 14, 2025 10:35
@harshavardhana
Copy link
Member

I'd love to hear some feedback on the current state.

Please fix the CI tests

@Alveel
Copy link
Contributor Author

Alveel commented Feb 14, 2025

Fixed. Moved the .open() for Path to its own line so I can put the mypy comment on the same line while keeping it within 80 characters to keep autopep8 happy.

Copy link
Member

@balamurugana balamurugana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below is the exact diff, I am referring

diff --git a/minio/minioadmin.py b/minio/minioadmin.py
index d62ac21..0fd2979 100644
--- a/minio/minioadmin.py
+++ b/minio/minioadmin.py
@@ -452,16 +452,24 @@ class MinioAdmin:
         response = self._url_open("GET", _COMMAND.LIST_GROUPS)
         return response.data.decode()
 
-    def policy_add(self, policy_name: str, policy_file: str) -> str:
+    def policy_add(self,
+                   policy_name: str,
+                   policy_file: str | None = None,
+                   policy: bytes | None = None) -> str:
         """Add new policy."""
-        with open(policy_file, encoding='utf-8') as file:
-            response = self._url_open(
-                "PUT",
-                _COMMAND.ADD_CANNED_POLICY,
-                query_params={"name": policy_name},
-                body=file.read().encode(),
-            )
-            return response.data.decode()
+        if not (policy_file is not None) ^ (policy is not None):
+            raise ValueError("either policy_file or policy must be provided")
+        body = policy
+        if policy_file:
+            with open(policy_file, encoding='utf-8') as file:
+                body = file.read().encode()
+        response = self._url_open(
+            "PUT",
+            _COMMAND.ADD_CANNED_POLICY,
+            query_params={"name": policy_name},
+            body=body,
+        )
+        return response.data.decode()
 
     def policy_remove(self, policy_name: str) -> str:
         """Remove policy."""
@@ -754,6 +762,7 @@ class MinioAdmin:
                             name: str | None = None,
                             description: str | None = None,
                             policy_file: str | None = None,
+                            policy: dict | None = None,
                             expiration: str | None = None,
                             status: str | None = None) -> str:
         """
@@ -763,7 +772,9 @@ class MinioAdmin:
             raise ValueError("both access key and secret key must be provided")
         if access_key == "" or secret_key == "":
             raise ValueError("access key or secret key must not be empty")
-        data = {
+        if policy_file is not None and policy is not None:
+            raise ValueError("either policy_file or policy must be provided")
+        data: dict[str, Any] = {
             "status": "enabled",
             "accessKey": access_key,
             "secretKey": secret_key,
@@ -775,6 +786,8 @@ class MinioAdmin:
         if policy_file:
             with open(policy_file, encoding="utf-8") as file:
                 data["policy"] = json.load(file)
+        if policy:
+            data["policy"] = policy
         if expiration:
             data["expiration"] = expiration
         if status:
@@ -798,15 +811,19 @@ class MinioAdmin:
                                name: str | None = None,
                                description: str | None = None,
                                policy_file: str | None = None,
+                               policy: dict | None = None,
                                expiration: str | None = None,
                                status: str | None = None) -> str:
         """Update an existing service account"""
-        args = [secret_key, name, description, policy_file, expiration, status]
+        args = [secret_key, name, description,
+                policy_file, policy, expiration, status]
         if not any(arg for arg in args):
             raise ValueError("at least one of secret_key, name, description, "
                              "policy_file, expiration or status must be "
                              "specified")
-        data = {}
+        if policy_file is not None and policy is not None:
+            raise ValueError("either policy_file or policy must be provided")
+        data: dict[str, Any] = {}
         if secret_key:
             data["newSecretKey"] = secret_key
         if name:
@@ -816,6 +833,8 @@ class MinioAdmin:
         if policy_file:
             with open(policy_file, encoding="utf-8") as file:
                 data["newPolicy"] = json.load(file)
+        if policy:
+            data["newPolicy"] = policy
         if expiration:
             data["newExpiration"] = expiration
         if status:

@Alveel
Copy link
Contributor Author

Alveel commented Feb 18, 2025

I think that's it? I still see "1 requested change" but I don't see where or what it is.

Do you want me to squash my commits?

@Alveel
Copy link
Contributor Author

Alveel commented Feb 20, 2025

@balamurugana can you take a look? 🙂

@Alveel
Copy link
Contributor Author

Alveel commented Feb 25, 2025

Apologies, that was a dumb error I introduced and insufficiently tested. Tested properly now and passing all tests.

@Alveel Alveel force-pushed the allow-specifying-policy-as-dict branch from 62bb83b to 98b71fa Compare February 26, 2025 15:04
@Alveel
Copy link
Contributor Author

Alveel commented Feb 26, 2025

Squashed commits, should be all clean now. Can you please take a look?

If needed, I still have the original commits in a separate branch locally.

balamurugana
balamurugana previously approved these changes Feb 27, 2025
Copy link
Member

@balamurugana balamurugana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Depends on #1483

@balamurugana balamurugana marked this pull request as draft February 27, 2025 04:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants