diff --git a/src/frostfs_testlib/s3/aws_cli_client.py b/src/frostfs_testlib/s3/aws_cli_client.py index 69a097b..3bf335e 100644 --- a/src/frostfs_testlib/s3/aws_cli_client.py +++ b/src/frostfs_testlib/s3/aws_cli_client.py @@ -1332,4 +1332,47 @@ class AwsCliClient(S3ClientWrapper): return response + @reporter.step("Adds one or more tags to an IAM user") + def iam_tag_user(self, user_name: str, tags: list) -> dict: + tags_json = [{"Key": tag_key, "Value": tag_value} for tag_key, tag_value in tags] + cmd = ( + f"aws {self.common_flags} iam tag-user --user-name {user_name} --tags '{json.dumps(tags_json)}' --endpoint {self.iam_endpoint}" + ) + if self.profile: + cmd += f" --profile {self.profile}" + + output = self.local_shell.exec(cmd).stdout + response = self._to_json(output) + + return response + + + @reporter.step("List tags of IAM user") + def iam_list_user_tags(self, user_name: str) -> dict: + cmd = ( + f"aws {self.common_flags} iam list-user-tags --user-name {user_name} --endpoint {self.iam_endpoint}" + ) + if self.profile: + cmd += f" --profile {self.profile}" + + output = self.local_shell.exec(cmd).stdout + response = self._to_json(output) + + return response + + + @reporter.step("Removes the specified tags from the user") + def iam_untag_user(self, user_name: str, tag_keys: list) -> dict: + tag_keys_joined = ' '.join(tag_keys) + cmd = ( + f"aws {self.common_flags} iam untag-user --user-name {user_name} --tag-keys {tag_keys_joined} --endpoint {self.iam_endpoint}" + ) + if self.profile: + cmd += f" --profile {self.profile}" + + output = self.local_shell.exec(cmd).stdout + response = self._to_json(output) + + return response + diff --git a/src/frostfs_testlib/s3/boto3_client.py b/src/frostfs_testlib/s3/boto3_client.py index 59da55a..bed316b 100644 --- a/src/frostfs_testlib/s3/boto3_client.py +++ b/src/frostfs_testlib/s3/boto3_client.py @@ -963,4 +963,23 @@ class Boto3ClientWrapper(S3ClientWrapper): @reporter.step("Updates the name and/or the path of the specified IAM user") def iam_update_user(self, user_name: str, new_name: str, new_path: Optional[str] = None) -> dict: response = self.boto3_iam_client.update_user(UserName=user_name, NewUserName=new_name, NewPath='/') + return response + + + @reporter.step("Adds one or more tags to an IAM user") + def iam_tag_user(self, user_name: str, tags: list) -> dict: + tags_json = [{"Key": tag_key, "Value": tag_value} for tag_key, tag_value in tags] + response = self.boto3_iam_client.tag_user(UserName=user_name, Tags=tags_json) + return response + + + @reporter.step("List tags of IAM user") + def iam_list_user_tags(self, user_name: str) -> dict: + response = self.boto3_iam_client.list_user_tags(UserName=user_name) + return response + + + @reporter.step("Removes the specified tags from the user") + def iam_untag_user(self, user_name: str, tag_keys: list) -> dict: + response = self.boto3_iam_client.untag_user(UserName=user_name, TagKeys=tag_keys) return response \ No newline at end of file diff --git a/src/frostfs_testlib/s3/interfaces.py b/src/frostfs_testlib/s3/interfaces.py index 8cfc2bb..651be7a 100644 --- a/src/frostfs_testlib/s3/interfaces.py +++ b/src/frostfs_testlib/s3/interfaces.py @@ -550,3 +550,15 @@ class S3ClientWrapper(HumanReadableABC): @abstractmethod def iam_update_user(self, user_name: str, new_name: Optional[str] = None, new_path: Optional[str] = None) -> dict: '''Updates the name and/or the path of the specified IAM user''' + + @abstractmethod + def iam_tag_user(self, user_name: str, tags: list) -> dict: + '''Adds one or more tags to an IAM user''' + + @abstractmethod + def iam_list_user_tags(self, user_name: str) -> dict: + '''List tags of IAM user''' + + @abstractmethod + def iam_untag_user(self, user_name: str, tag_keys: list) -> dict: + '''Removes the specified tags from the user''' \ No newline at end of file