From 98b71faf7dd0c82fd6a8c4d85396f484b42bbaf1 Mon Sep 17 00:00:00 2001 From: Alwyn Kik Date: Thu, 30 Jan 2025 15:08:10 +0100 Subject: [PATCH 1/4] MinioAdmin: allow specifying policies as dict besides file --- minio/minioadmin.py | 58 +++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/minio/minioadmin.py b/minio/minioadmin.py index d62ac21d..7ca090c7 100644 --- a/minio/minioadmin.py +++ b/minio/minioadmin.py @@ -24,6 +24,7 @@ import os from datetime import timedelta from enum import Enum, unique +from pathlib import Path from typing import Any, TextIO, Tuple, cast from urllib.parse import urlunsplit @@ -452,16 +453,26 @@ def group_list(self) -> str: 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 | os.PathLike | None = None, + policy: dict | 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 policy_file: + with Path(policy_file).open(encoding='utf-8') as file: + body = file.read().encode() + elif policy: + body = json.dumps(policy).encode() + else: + raise ValueError("either policy or policy_file must be specified") + + 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.""" @@ -753,7 +764,8 @@ def add_service_account(self, secret_key: str | None = None, name: str | None = None, description: str | None = None, - policy_file: str | None = None, + policy: dict | None = None, + policy_file: str | os.PathLike | None = None, expiration: str | None = None, status: str | None = None) -> str: """ @@ -763,7 +775,9 @@ def add_service_account(self, 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 and policy: + raise ValueError("specify either policy_file or policy, not both") + data: dict[str, Any] = { "status": "enabled", "accessKey": access_key, "secretKey": secret_key, @@ -773,8 +787,10 @@ def add_service_account(self, if description: data["description"] = description if policy_file: - with open(policy_file, encoding="utf-8") as file: + with Path(policy_file).open(encoding="utf-8") as file: data["policy"] = json.load(file) + if policy: + data["policy"] = policy if expiration: data["expiration"] = expiration if status: @@ -797,16 +813,20 @@ def update_service_account(self, secret_key: str | None = None, name: str | None = None, description: str | None = None, - policy_file: str | None = None, + policy_file: str | os.PathLike | 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 = {} + "policy_file, policy, expiration or status must " + "be specified") + if policy_file and policy: + raise ValueError("specify either policy_file or policy, not both") + data: dict[str, Any] = {} if secret_key: data["newSecretKey"] = secret_key if name: @@ -814,8 +834,10 @@ def update_service_account(self, if description: data["newDescription"] = description if policy_file: - with open(policy_file, encoding="utf-8") as file: + with Path(policy_file).open(encoding="utf-8") as file: data["newPolicy"] = json.load(file) + if policy: + data["newPolicy"] = policy if expiration: data["newExpiration"] = expiration if status: From 5081c845b64812ecb74f1e1d7a3a5a59f359270a Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 27 Feb 2025 10:01:29 +0530 Subject: [PATCH 2/4] Apply suggestions from code review --- minio/minioadmin.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/minio/minioadmin.py b/minio/minioadmin.py index 7ca090c7..e32e2da6 100644 --- a/minio/minioadmin.py +++ b/minio/minioadmin.py @@ -24,7 +24,6 @@ import os from datetime import timedelta from enum import Enum, unique -from pathlib import Path from typing import Any, TextIO, Tuple, cast from urllib.parse import urlunsplit @@ -458,14 +457,12 @@ def policy_add(self, policy_file: str | os.PathLike | None = None, policy: dict | None = None) -> str: """Add new policy.""" + 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 Path(policy_file).open(encoding='utf-8') as file: + with open(policy_file, encoding='utf-8') as file: body = file.read().encode() - elif policy: - body = json.dumps(policy).encode() - else: - raise ValueError("either policy or policy_file must be specified") - response = self._url_open( "PUT", _COMMAND.ADD_CANNED_POLICY, @@ -775,8 +772,8 @@ def add_service_account(self, 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") - if policy_file and policy: - raise ValueError("specify either policy_file or policy, not both") + 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, @@ -787,7 +784,7 @@ def add_service_account(self, if description: data["description"] = description if policy_file: - with Path(policy_file).open(encoding="utf-8") as file: + with open(policy_file, encoding="utf-8") as file: data["policy"] = json.load(file) if policy: data["policy"] = policy @@ -824,8 +821,8 @@ def update_service_account(self, raise ValueError("at least one of secret_key, name, description, " "policy_file, policy, expiration or status must " "be specified") - if policy_file and policy: - raise ValueError("specify either policy_file or policy, not both") + 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 @@ -834,7 +831,7 @@ def update_service_account(self, if description: data["newDescription"] = description if policy_file: - with Path(policy_file).open(encoding="utf-8") as file: + with open(policy_file, encoding="utf-8") as file: data["newPolicy"] = json.load(file) if policy: data["newPolicy"] = policy From 572823fcae513cb218d2a250d8bc3253dc53da8d Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 27 Feb 2025 10:12:20 +0530 Subject: [PATCH 3/4] Update minio/minioadmin.py --- minio/minioadmin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minio/minioadmin.py b/minio/minioadmin.py index e32e2da6..05c43ce8 100644 --- a/minio/minioadmin.py +++ b/minio/minioadmin.py @@ -459,7 +459,7 @@ def policy_add(self, """Add new policy.""" if not (policy_file is not None) ^ (policy is not None): raise ValueError("either policy_file or policy must be provided") - body = policy + body = json.dumps(policy).encode() if policy else None if policy_file: with open(policy_file, encoding='utf-8') as file: body = file.read().encode() From fead8ea672b6a22a0ce83d0d18b52af4b47fcda9 Mon Sep 17 00:00:00 2001 From: Bala FA Date: Thu, 27 Feb 2025 10:17:07 +0530 Subject: [PATCH 4/4] Apply suggestions from code review --- minio/minioadmin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/minio/minioadmin.py b/minio/minioadmin.py index 05c43ce8..9c781b39 100644 --- a/minio/minioadmin.py +++ b/minio/minioadmin.py @@ -459,10 +459,11 @@ def policy_add(self, """Add new policy.""" if not (policy_file is not None) ^ (policy is not None): raise ValueError("either policy_file or policy must be provided") - body = json.dumps(policy).encode() if policy else None if policy_file: with open(policy_file, encoding='utf-8') as file: body = file.read().encode() + else: + body = json.dumps(policy).encode() response = self._url_open( "PUT", _COMMAND.ADD_CANNED_POLICY,