Feature: QuickSight (initial implementation) (#4973)
This commit is contained in:
parent
4ed5a837de
commit
60e48c101e
@ -4040,6 +4040,127 @@
|
||||
- [ ] synthesize_speech
|
||||
</details>
|
||||
|
||||
## quicksight
|
||||
<details>
|
||||
<summary>6% implemented</summary>
|
||||
|
||||
- [ ] cancel_ingestion
|
||||
- [ ] create_account_customization
|
||||
- [ ] create_analysis
|
||||
- [ ] create_dashboard
|
||||
- [ ] create_data_set
|
||||
- [ ] create_data_source
|
||||
- [ ] create_folder
|
||||
- [ ] create_folder_membership
|
||||
- [X] create_group
|
||||
- [ ] create_group_membership
|
||||
- [ ] create_iam_policy_assignment
|
||||
- [ ] create_ingestion
|
||||
- [ ] create_namespace
|
||||
- [ ] create_template
|
||||
- [ ] create_template_alias
|
||||
- [ ] create_theme
|
||||
- [ ] create_theme_alias
|
||||
- [ ] delete_account_customization
|
||||
- [ ] delete_analysis
|
||||
- [ ] delete_dashboard
|
||||
- [ ] delete_data_set
|
||||
- [ ] delete_data_source
|
||||
- [ ] delete_folder
|
||||
- [ ] delete_folder_membership
|
||||
- [X] delete_group
|
||||
- [ ] delete_group_membership
|
||||
- [ ] delete_iam_policy_assignment
|
||||
- [ ] delete_namespace
|
||||
- [ ] delete_template
|
||||
- [ ] delete_template_alias
|
||||
- [ ] delete_theme
|
||||
- [ ] delete_theme_alias
|
||||
- [X] delete_user
|
||||
- [ ] delete_user_by_principal_id
|
||||
- [ ] describe_account_customization
|
||||
- [ ] describe_account_settings
|
||||
- [ ] describe_analysis
|
||||
- [ ] describe_analysis_permissions
|
||||
- [ ] describe_dashboard
|
||||
- [ ] describe_dashboard_permissions
|
||||
- [ ] describe_data_set
|
||||
- [ ] describe_data_set_permissions
|
||||
- [ ] describe_data_source
|
||||
- [ ] describe_data_source_permissions
|
||||
- [ ] describe_folder
|
||||
- [ ] describe_folder_permissions
|
||||
- [ ] describe_folder_resolved_permissions
|
||||
- [X] describe_group
|
||||
- [ ] describe_iam_policy_assignment
|
||||
- [ ] describe_ingestion
|
||||
- [ ] describe_ip_restriction
|
||||
- [ ] describe_namespace
|
||||
- [ ] describe_template
|
||||
- [ ] describe_template_alias
|
||||
- [ ] describe_template_permissions
|
||||
- [ ] describe_theme
|
||||
- [ ] describe_theme_alias
|
||||
- [ ] describe_theme_permissions
|
||||
- [X] describe_user
|
||||
- [ ] generate_embed_url_for_anonymous_user
|
||||
- [ ] generate_embed_url_for_registered_user
|
||||
- [ ] get_dashboard_embed_url
|
||||
- [ ] get_session_embed_url
|
||||
- [ ] list_analyses
|
||||
- [ ] list_dashboard_versions
|
||||
- [ ] list_dashboards
|
||||
- [ ] list_data_sets
|
||||
- [ ] list_data_sources
|
||||
- [ ] list_folder_members
|
||||
- [ ] list_folders
|
||||
- [ ] list_group_memberships
|
||||
- [ ] list_groups
|
||||
- [ ] list_iam_policy_assignments
|
||||
- [ ] list_iam_policy_assignments_for_user
|
||||
- [ ] list_ingestions
|
||||
- [ ] list_namespaces
|
||||
- [ ] list_tags_for_resource
|
||||
- [ ] list_template_aliases
|
||||
- [ ] list_template_versions
|
||||
- [ ] list_templates
|
||||
- [ ] list_theme_aliases
|
||||
- [ ] list_theme_versions
|
||||
- [ ] list_themes
|
||||
- [ ] list_user_groups
|
||||
- [ ] list_users
|
||||
- [X] register_user
|
||||
- [ ] restore_analysis
|
||||
- [ ] search_analyses
|
||||
- [ ] search_dashboards
|
||||
- [ ] search_folders
|
||||
- [ ] tag_resource
|
||||
- [ ] untag_resource
|
||||
- [ ] update_account_customization
|
||||
- [ ] update_account_settings
|
||||
- [ ] update_analysis
|
||||
- [ ] update_analysis_permissions
|
||||
- [ ] update_dashboard
|
||||
- [ ] update_dashboard_permissions
|
||||
- [ ] update_dashboard_published_version
|
||||
- [ ] update_data_set
|
||||
- [ ] update_data_set_permissions
|
||||
- [ ] update_data_source
|
||||
- [ ] update_data_source_permissions
|
||||
- [ ] update_folder
|
||||
- [ ] update_folder_permissions
|
||||
- [X] update_group
|
||||
- [ ] update_iam_policy_assignment
|
||||
- [ ] update_ip_restriction
|
||||
- [ ] update_template
|
||||
- [ ] update_template_alias
|
||||
- [ ] update_template_permissions
|
||||
- [ ] update_theme
|
||||
- [ ] update_theme_alias
|
||||
- [ ] update_theme_permissions
|
||||
- [ ] update_user
|
||||
</details>
|
||||
|
||||
## ram
|
||||
<details>
|
||||
<summary>20% implemented</summary>
|
||||
@ -5762,7 +5883,6 @@
|
||||
- proton
|
||||
- qldb
|
||||
- qldb-session
|
||||
- quicksight
|
||||
- rbin
|
||||
- rds-data
|
||||
- rekognition
|
||||
|
150
docs/docs/services/quicksight.rst
Normal file
150
docs/docs/services/quicksight.rst
Normal file
@ -0,0 +1,150 @@
|
||||
.. _implementedservice_quicksight:
|
||||
|
||||
.. |start-h3| raw:: html
|
||||
|
||||
<h3>
|
||||
|
||||
.. |end-h3| raw:: html
|
||||
|
||||
</h3>
|
||||
|
||||
==========
|
||||
quicksight
|
||||
==========
|
||||
|
||||
.. autoclass:: moto.quicksight.models.QuickSightBackend
|
||||
|
||||
|start-h3| Example usage |end-h3|
|
||||
|
||||
.. sourcecode:: python
|
||||
|
||||
@mock_quicksight
|
||||
def test_quicksight_behaviour:
|
||||
boto3.client("quicksight")
|
||||
...
|
||||
|
||||
|
||||
|
||||
|start-h3| Implemented features for this service |end-h3|
|
||||
|
||||
- [ ] cancel_ingestion
|
||||
- [ ] create_account_customization
|
||||
- [ ] create_analysis
|
||||
- [ ] create_dashboard
|
||||
- [ ] create_data_set
|
||||
- [ ] create_data_source
|
||||
- [ ] create_folder
|
||||
- [ ] create_folder_membership
|
||||
- [X] create_group
|
||||
- [ ] create_group_membership
|
||||
- [ ] create_iam_policy_assignment
|
||||
- [ ] create_ingestion
|
||||
- [ ] create_namespace
|
||||
- [ ] create_template
|
||||
- [ ] create_template_alias
|
||||
- [ ] create_theme
|
||||
- [ ] create_theme_alias
|
||||
- [ ] delete_account_customization
|
||||
- [ ] delete_analysis
|
||||
- [ ] delete_dashboard
|
||||
- [ ] delete_data_set
|
||||
- [ ] delete_data_source
|
||||
- [ ] delete_folder
|
||||
- [ ] delete_folder_membership
|
||||
- [X] delete_group
|
||||
- [ ] delete_group_membership
|
||||
- [ ] delete_iam_policy_assignment
|
||||
- [ ] delete_namespace
|
||||
- [ ] delete_template
|
||||
- [ ] delete_template_alias
|
||||
- [ ] delete_theme
|
||||
- [ ] delete_theme_alias
|
||||
- [X] delete_user
|
||||
- [ ] delete_user_by_principal_id
|
||||
- [ ] describe_account_customization
|
||||
- [ ] describe_account_settings
|
||||
- [ ] describe_analysis
|
||||
- [ ] describe_analysis_permissions
|
||||
- [ ] describe_dashboard
|
||||
- [ ] describe_dashboard_permissions
|
||||
- [ ] describe_data_set
|
||||
- [ ] describe_data_set_permissions
|
||||
- [ ] describe_data_source
|
||||
- [ ] describe_data_source_permissions
|
||||
- [ ] describe_folder
|
||||
- [ ] describe_folder_permissions
|
||||
- [ ] describe_folder_resolved_permissions
|
||||
- [X] describe_group
|
||||
- [ ] describe_iam_policy_assignment
|
||||
- [ ] describe_ingestion
|
||||
- [ ] describe_ip_restriction
|
||||
- [ ] describe_namespace
|
||||
- [ ] describe_template
|
||||
- [ ] describe_template_alias
|
||||
- [ ] describe_template_permissions
|
||||
- [ ] describe_theme
|
||||
- [ ] describe_theme_alias
|
||||
- [ ] describe_theme_permissions
|
||||
- [X] describe_user
|
||||
- [ ] generate_embed_url_for_anonymous_user
|
||||
- [ ] generate_embed_url_for_registered_user
|
||||
- [ ] get_dashboard_embed_url
|
||||
- [ ] get_session_embed_url
|
||||
- [ ] list_analyses
|
||||
- [ ] list_dashboard_versions
|
||||
- [ ] list_dashboards
|
||||
- [ ] list_data_sets
|
||||
- [ ] list_data_sources
|
||||
- [ ] list_folder_members
|
||||
- [ ] list_folders
|
||||
- [ ] list_group_memberships
|
||||
- [ ] list_groups
|
||||
- [ ] list_iam_policy_assignments
|
||||
- [ ] list_iam_policy_assignments_for_user
|
||||
- [ ] list_ingestions
|
||||
- [ ] list_namespaces
|
||||
- [ ] list_tags_for_resource
|
||||
- [ ] list_template_aliases
|
||||
- [ ] list_template_versions
|
||||
- [ ] list_templates
|
||||
- [ ] list_theme_aliases
|
||||
- [ ] list_theme_versions
|
||||
- [ ] list_themes
|
||||
- [ ] list_user_groups
|
||||
- [ ] list_users
|
||||
- [X] register_user
|
||||
|
||||
The following parameters are not yet implemented:
|
||||
IamArn, SessionName, CustomsPermissionsName, ExternalLoginFederationProviderType, CustomFederationProviderUrl, ExternalLoginId
|
||||
|
||||
|
||||
- [ ] restore_analysis
|
||||
- [ ] search_analyses
|
||||
- [ ] search_dashboards
|
||||
- [ ] search_folders
|
||||
- [ ] tag_resource
|
||||
- [ ] untag_resource
|
||||
- [ ] update_account_customization
|
||||
- [ ] update_account_settings
|
||||
- [ ] update_analysis
|
||||
- [ ] update_analysis_permissions
|
||||
- [ ] update_dashboard
|
||||
- [ ] update_dashboard_permissions
|
||||
- [ ] update_dashboard_published_version
|
||||
- [ ] update_data_set
|
||||
- [ ] update_data_set_permissions
|
||||
- [ ] update_data_source
|
||||
- [ ] update_data_source_permissions
|
||||
- [ ] update_folder
|
||||
- [ ] update_folder_permissions
|
||||
- [X] update_group
|
||||
- [ ] update_iam_policy_assignment
|
||||
- [ ] update_ip_restriction
|
||||
- [ ] update_template
|
||||
- [ ] update_template_alias
|
||||
- [ ] update_template_permissions
|
||||
- [ ] update_theme
|
||||
- [ ] update_theme_alias
|
||||
- [ ] update_theme_permissions
|
||||
- [ ] update_user
|
||||
|
@ -124,6 +124,7 @@ mock_opsworks = lazy_load(".opsworks", "mock_opsworks")
|
||||
mock_organizations = lazy_load(".organizations", "mock_organizations")
|
||||
mock_pinpoint = lazy_load(".pinpoint", "mock_pinpoint")
|
||||
mock_polly = lazy_load(".polly", "mock_polly")
|
||||
mock_quicksight = lazy_load(".quicksight", "mock_quicksight")
|
||||
mock_ram = lazy_load(".ram", "mock_ram")
|
||||
mock_rds = lazy_load(".rds", "mock_rds")
|
||||
mock_rds2 = lazy_load(".rds", "mock_rds", use_instead=("mock_rds2", "mock_rds"))
|
||||
|
@ -1,4 +1,4 @@
|
||||
# autogenerated by ./scripts/update_backend_index.py
|
||||
# autogenerated by scripts/update_backend_index.py
|
||||
import re
|
||||
|
||||
backend_url_patterns = [
|
||||
@ -32,7 +32,6 @@ backend_url_patterns = [
|
||||
("dms", re.compile("https?://dms\\.(.+)\\.amazonaws\\.com")),
|
||||
("ds", re.compile("https?://ds\\.(.+)\\.amazonaws\\.com")),
|
||||
("dynamodb", re.compile("https?://dynamodb\\.(.+)\\.amazonaws\\.com")),
|
||||
("dynamodb2", re.compile("https?://dynamodb\\.(.+)\\.amazonaws\\.com")),
|
||||
(
|
||||
"dynamodbstreams",
|
||||
re.compile("https?://streams\\.dynamodb\\.(.+)\\.amazonaws.com"),
|
||||
@ -97,6 +96,7 @@ backend_url_patterns = [
|
||||
("organizations", re.compile("https?://organizations\\.(.+)\\.amazonaws\\.com")),
|
||||
("pinpoint", re.compile("https?://pinpoint\\.(.+)\\.amazonaws\\.com")),
|
||||
("polly", re.compile("https?://polly\\.(.+)\\.amazonaws.com")),
|
||||
("quicksight", re.compile("https?://quicksight\\.(.+)\\.amazonaws\\.com")),
|
||||
("ram", re.compile("https?://ram\\.(.+)\\.amazonaws.com")),
|
||||
("rds", re.compile("https?://rds\\.(.+)\\.amazonaws\\.com")),
|
||||
("rds", re.compile("https?://rds\\.amazonaws\\.com")),
|
||||
@ -154,4 +154,5 @@ backend_url_patterns = [
|
||||
("transcribe", re.compile("https?://transcribe\\.(.+)\\.amazonaws\\.com")),
|
||||
("wafv2", re.compile("https?://wafv2\\.(.+)\\.amazonaws.com")),
|
||||
("xray", re.compile("https?://xray\\.(.+)\\.amazonaws.com")),
|
||||
("dynamodb_v20111205", re.compile("https?://dynamodb\\.(.+)\\.amazonaws\\.com")),
|
||||
]
|
||||
|
5
moto/quicksight/__init__.py
Normal file
5
moto/quicksight/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
"""quicksight module initialization; sets value for base decorator."""
|
||||
from .models import quicksight_backends
|
||||
from ..core.models import base_decorator
|
||||
|
||||
mock_quicksight = base_decorator(quicksight_backends)
|
7
moto/quicksight/exceptions.py
Normal file
7
moto/quicksight/exceptions.py
Normal file
@ -0,0 +1,7 @@
|
||||
"""Exceptions raised by the quicksight service."""
|
||||
from moto.core.exceptions import JsonRESTError
|
||||
|
||||
|
||||
class ResourceNotFoundException(JsonRESTError):
|
||||
def __init__(self, msg):
|
||||
super().__init__("ResourceNotFoundException", msg)
|
112
moto/quicksight/models.py
Normal file
112
moto/quicksight/models.py
Normal file
@ -0,0 +1,112 @@
|
||||
"""QuickSightBackend class with methods for supported APIs."""
|
||||
|
||||
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
|
||||
from moto.core.utils import BackendDict
|
||||
from .exceptions import ResourceNotFoundException
|
||||
|
||||
|
||||
class QuicksightGroup(BaseModel):
|
||||
def __init__(self, region, group_name, description, aws_account_id, namespace):
|
||||
self.arn = (
|
||||
f"arn:aws:quicksight:{region}:{ACCOUNT_ID}:group/default/{group_name}"
|
||||
)
|
||||
self.group_name = group_name
|
||||
self.description = description
|
||||
self.aws_account_id = aws_account_id
|
||||
self.namespace = namespace
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
"Arn": self.arn,
|
||||
"GroupName": self.group_name,
|
||||
"Description": self.description,
|
||||
"PrincipalId": self.aws_account_id,
|
||||
"Namespace": self.namespace,
|
||||
}
|
||||
|
||||
|
||||
class QuicksightUser(BaseModel):
|
||||
def __init__(self, region, email, identity_type, username, user_role):
|
||||
self.arn = f"arn:aws:quicksight:{region}:{ACCOUNT_ID}:user/default/{username}"
|
||||
self.email = email
|
||||
self.identity_type = identity_type
|
||||
self.username = username
|
||||
self.user_role = user_role
|
||||
self.active = False
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
"Arn": self.arn,
|
||||
"Email": self.email,
|
||||
"IdentityType": self.identity_type,
|
||||
"Role": self.user_role,
|
||||
"UserName": self.username,
|
||||
"Active": self.active,
|
||||
}
|
||||
|
||||
|
||||
class QuickSightBackend(BaseBackend):
|
||||
"""Implementation of QuickSight APIs."""
|
||||
|
||||
def __init__(self, region_name=None):
|
||||
self.region_name = region_name
|
||||
self.groups = dict()
|
||||
self.users = dict()
|
||||
|
||||
def reset(self):
|
||||
"""Re-initialize all attributes for this instance."""
|
||||
region_name = self.region_name
|
||||
self.__dict__ = {}
|
||||
self.__init__(region_name)
|
||||
|
||||
def create_group(self, group_name, description, aws_account_id, namespace):
|
||||
group = QuicksightGroup(
|
||||
region=self.region_name,
|
||||
group_name=group_name,
|
||||
description=description,
|
||||
aws_account_id=aws_account_id,
|
||||
namespace=namespace,
|
||||
)
|
||||
self.groups[f"{aws_account_id}:{namespace}:{group_name}"] = group
|
||||
return group
|
||||
|
||||
def delete_group(self, aws_account_id, namespace, group_name):
|
||||
self.groups.pop(f"{aws_account_id}:{namespace}:{group_name}", None)
|
||||
|
||||
def delete_user(self, aws_account_id, namespace, user_name):
|
||||
self.users.pop(f"{aws_account_id}:{namespace}:{user_name}", None)
|
||||
|
||||
def describe_group(self, aws_account_id, namespace, group_name):
|
||||
if f"{aws_account_id}:{namespace}:{group_name}" not in self.groups:
|
||||
raise ResourceNotFoundException(f"Group {group_name} not found")
|
||||
return self.groups[f"{aws_account_id}:{namespace}:{group_name}"]
|
||||
|
||||
def describe_user(self, aws_account_id, namespace, user_name):
|
||||
if f"{aws_account_id}:{namespace}:{user_name}" not in self.users:
|
||||
raise ResourceNotFoundException(f"User {user_name} not found")
|
||||
return self.users[f"{aws_account_id}:{namespace}:{user_name}"]
|
||||
|
||||
def register_user(
|
||||
self, identity_type, email, user_role, aws_account_id, namespace, user_name
|
||||
):
|
||||
"""
|
||||
The following parameters are not yet implemented:
|
||||
IamArn, SessionName, CustomsPermissionsName, ExternalLoginFederationProviderType, CustomFederationProviderUrl, ExternalLoginId
|
||||
"""
|
||||
user = QuicksightUser(
|
||||
region=self.region_name,
|
||||
email=email,
|
||||
identity_type=identity_type,
|
||||
user_role=user_role,
|
||||
username=user_name,
|
||||
)
|
||||
self.users[f"{aws_account_id}:{namespace}:{user_name}"] = user
|
||||
return user
|
||||
|
||||
def update_group(self, aws_account_id, namespace, group_name, description):
|
||||
group = self.describe_group(aws_account_id, namespace, group_name)
|
||||
group.description = description
|
||||
return group
|
||||
|
||||
|
||||
quicksight_backends = BackendDict(QuickSightBackend, "quicksight")
|
119
moto/quicksight/responses.py
Normal file
119
moto/quicksight/responses.py
Normal file
@ -0,0 +1,119 @@
|
||||
"""Handles incoming quicksight requests, invokes methods, returns responses."""
|
||||
import json
|
||||
|
||||
from moto.core.responses import BaseResponse
|
||||
from .models import quicksight_backends
|
||||
|
||||
|
||||
class QuickSightResponse(BaseResponse):
|
||||
"""Handler for QuickSight requests and responses."""
|
||||
|
||||
@property
|
||||
def quicksight_backend(self):
|
||||
"""Return backend instance specific for this region."""
|
||||
return quicksight_backends[self.region]
|
||||
|
||||
def groups(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
if request.method == "POST":
|
||||
return self.create_group()
|
||||
|
||||
def group(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
if request.method == "GET":
|
||||
return self.describe_group()
|
||||
if request.method == "DELETE":
|
||||
return self.delete_group()
|
||||
if request.method == "PUT":
|
||||
return self.update_group()
|
||||
|
||||
def users(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
if request.method == "POST":
|
||||
return self.register_user()
|
||||
|
||||
def user(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
if request.method == "GET":
|
||||
return self.describe_user()
|
||||
if request.method == "DELETE":
|
||||
return self.delete_user()
|
||||
|
||||
def create_group(self):
|
||||
params = json.loads(self.body)
|
||||
group_name = params.get("GroupName")
|
||||
description = params.get("Description")
|
||||
aws_account_id = self.path.split("/")[-4]
|
||||
namespace = self.path.split("/")[-2]
|
||||
group = self.quicksight_backend.create_group(
|
||||
group_name=group_name,
|
||||
description=description,
|
||||
aws_account_id=aws_account_id,
|
||||
namespace=namespace,
|
||||
)
|
||||
return 200, {}, json.dumps(dict(Group=group.to_json()))
|
||||
|
||||
def register_user(self):
|
||||
params = json.loads(self.body)
|
||||
identity_type = params.get("IdentityType")
|
||||
email = params.get("Email")
|
||||
user_role = params.get("UserRole")
|
||||
aws_account_id = self.path.split("/")[-4]
|
||||
namespace = self.path.split("/")[-2]
|
||||
user_name = params.get("UserName")
|
||||
user = self.quicksight_backend.register_user(
|
||||
identity_type=identity_type,
|
||||
email=email,
|
||||
user_role=user_role,
|
||||
aws_account_id=aws_account_id,
|
||||
namespace=namespace,
|
||||
user_name=user_name,
|
||||
)
|
||||
return 200, {}, json.dumps(dict(User=user.to_json(), UserInvitationUrl="TBD"))
|
||||
|
||||
def describe_group(self):
|
||||
aws_account_id = self.path.split("/")[-5]
|
||||
namespace = self.path.split("/")[-3]
|
||||
group_name = self.path.split("/")[-1]
|
||||
|
||||
group = self.quicksight_backend.describe_group(
|
||||
aws_account_id, namespace, group_name
|
||||
)
|
||||
return 200, {}, json.dumps(dict(Group=group.to_json()))
|
||||
|
||||
def describe_user(self):
|
||||
aws_account_id = self.path.split("/")[-5]
|
||||
namespace = self.path.split("/")[-3]
|
||||
user_name = self.path.split("/")[-1]
|
||||
|
||||
user = self.quicksight_backend.describe_user(
|
||||
aws_account_id, namespace, user_name
|
||||
)
|
||||
return 200, {}, json.dumps(dict(User=user.to_json()))
|
||||
|
||||
def delete_group(self):
|
||||
aws_account_id = self.path.split("/")[-5]
|
||||
namespace = self.path.split("/")[-3]
|
||||
group_name = self.path.split("/")[-1]
|
||||
|
||||
self.quicksight_backend.delete_group(aws_account_id, namespace, group_name)
|
||||
return 204, {}, json.dumps({"Status": 204})
|
||||
|
||||
def delete_user(self):
|
||||
aws_account_id = self.path.split("/")[-5]
|
||||
namespace = self.path.split("/")[-3]
|
||||
user_name = self.path.split("/")[-1]
|
||||
|
||||
self.quicksight_backend.delete_user(aws_account_id, namespace, user_name)
|
||||
return 204, {}, json.dumps({"Status": 204})
|
||||
|
||||
def update_group(self):
|
||||
aws_account_id = self.path.split("/")[-5]
|
||||
namespace = self.path.split("/")[-3]
|
||||
group_name = self.path.split("/")[-1]
|
||||
description = json.loads(self.body).get("Description")
|
||||
|
||||
group = self.quicksight_backend.update_group(
|
||||
aws_account_id, namespace, group_name, description
|
||||
)
|
||||
return 200, {}, json.dumps(dict(Group=group.to_json()))
|
17
moto/quicksight/urls.py
Normal file
17
moto/quicksight/urls.py
Normal file
@ -0,0 +1,17 @@
|
||||
"""quicksight base URL and path."""
|
||||
from .responses import QuickSightResponse
|
||||
|
||||
url_bases = [
|
||||
r"https?://quicksight\.(.+)\.amazonaws\.com",
|
||||
]
|
||||
|
||||
|
||||
response = QuickSightResponse()
|
||||
|
||||
|
||||
url_paths = {
|
||||
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[^/.]+)/groups$": response.groups,
|
||||
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[^/.]+)/groups/(?P<groupname>[^/.]+)$": response.group,
|
||||
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[^/.]+)/users$": response.users,
|
||||
r"{0}/accounts/(?P<account_id>[\d]+)/namespaces/(?P<namespace>[^/.]+)/users/(?P<username>[^/.]+)$": response.user,
|
||||
}
|
@ -113,6 +113,8 @@ TestAccAWSPartition
|
||||
TestAccAWSPinpointApp
|
||||
TestAccAWSPinpointEventStream
|
||||
TestAccAWSProvider
|
||||
TestAccAWSQuickSightGroup
|
||||
TestAccAWSQuickSightUser
|
||||
TestAccAWSRedshiftServiceAccount
|
||||
TestAccAWSRolePolicyAttachment
|
||||
TestAccAWSRouteTable_
|
||||
|
0
tests/test_quicksight/__init__.py
Normal file
0
tests/test_quicksight/__init__.py
Normal file
108
tests/test_quicksight/test_quicksight_groups.py
Normal file
108
tests/test_quicksight/test_quicksight_groups.py
Normal file
@ -0,0 +1,108 @@
|
||||
"""Unit tests for quicksight-supported APIs."""
|
||||
import boto3
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_quicksight
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
# See our Development Tips on writing tests for hints on how to write good tests:
|
||||
# http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_create_group():
|
||||
client = boto3.client("quicksight", region_name="us-west-2")
|
||||
resp = client.create_group(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
GroupName="mygroup",
|
||||
Description="my new fancy group",
|
||||
)
|
||||
|
||||
resp.should.have.key("Group")
|
||||
|
||||
resp["Group"].should.have.key("Arn").equals(
|
||||
f"arn:aws:quicksight:us-west-2:{ACCOUNT_ID}:group/default/mygroup"
|
||||
)
|
||||
resp["Group"].should.have.key("GroupName").equals("mygroup")
|
||||
resp["Group"].should.have.key("Description").equals("my new fancy group")
|
||||
resp["Group"].should.have.key("PrincipalId").equals(f"{ACCOUNT_ID}")
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_describe_group():
|
||||
client = boto3.client("quicksight", region_name="us-west-2")
|
||||
client.create_group(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
GroupName="mygroup",
|
||||
Description="my new fancy group",
|
||||
)
|
||||
|
||||
resp = client.describe_group(
|
||||
GroupName="mygroup", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
|
||||
resp.should.have.key("Group")
|
||||
|
||||
resp["Group"].should.have.key("Arn").equals(
|
||||
f"arn:aws:quicksight:us-west-2:{ACCOUNT_ID}:group/default/mygroup"
|
||||
)
|
||||
resp["Group"].should.have.key("GroupName").equals("mygroup")
|
||||
resp["Group"].should.have.key("Description").equals("my new fancy group")
|
||||
resp["Group"].should.have.key("PrincipalId").equals(f"{ACCOUNT_ID}")
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_update_group():
|
||||
client = boto3.client("quicksight", region_name="us-west-2")
|
||||
client.create_group(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
GroupName="mygroup",
|
||||
Description="desc1",
|
||||
)
|
||||
|
||||
resp = client.update_group(
|
||||
GroupName="mygroup",
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
Description="desc2",
|
||||
)
|
||||
resp.should.have.key("Group").should.have.key("Description").equals("desc2")
|
||||
|
||||
resp = client.describe_group(
|
||||
GroupName="mygroup", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
|
||||
resp.should.have.key("Group")
|
||||
resp["Group"].should.have.key("Arn").equals(
|
||||
f"arn:aws:quicksight:us-west-2:{ACCOUNT_ID}:group/default/mygroup"
|
||||
)
|
||||
resp["Group"].should.have.key("GroupName").equals("mygroup")
|
||||
resp["Group"].should.have.key("Description").equals("desc2")
|
||||
resp["Group"].should.have.key("PrincipalId").equals(f"{ACCOUNT_ID}")
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_delete_group():
|
||||
client = boto3.client("quicksight", region_name="us-east-2")
|
||||
client.create_group(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
GroupName="mygroup",
|
||||
Description="my new fancy group",
|
||||
)
|
||||
|
||||
client.delete_group(
|
||||
GroupName="mygroup", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.describe_group(
|
||||
GroupName="mygroup", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ResourceNotFoundException")
|
88
tests/test_quicksight/test_quicksight_users.py
Normal file
88
tests/test_quicksight/test_quicksight_users.py
Normal file
@ -0,0 +1,88 @@
|
||||
"""Unit tests for quicksight-supported APIs."""
|
||||
import boto3
|
||||
import pytest
|
||||
import sure # noqa # pylint: disable=unused-import
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from moto import mock_quicksight
|
||||
from moto.core import ACCOUNT_ID
|
||||
|
||||
# See our Development Tips on writing tests for hints on how to write good tests:
|
||||
# http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_register_user__quicksight():
|
||||
client = boto3.client("quicksight", region_name="us-east-2")
|
||||
resp = client.register_user(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
Email="fakeemail@example.com",
|
||||
IdentityType="QUICKSIGHT",
|
||||
UserName="tfacctestm9hpsr970z",
|
||||
UserRole="READER",
|
||||
)
|
||||
|
||||
resp.should.have.key("UserInvitationUrl")
|
||||
resp.should.have.key("User")
|
||||
|
||||
resp["User"].should.have.key("Arn").equals(
|
||||
f"arn:aws:quicksight:us-east-2:{ACCOUNT_ID}:user/default/tfacctestm9hpsr970z"
|
||||
)
|
||||
resp["User"].should.have.key("UserName").equals("tfacctestm9hpsr970z")
|
||||
resp["User"].should.have.key("Email").equals("fakeemail@example.com")
|
||||
resp["User"].should.have.key("Role").equals("READER")
|
||||
resp["User"].should.have.key("IdentityType").equals("QUICKSIGHT")
|
||||
resp["User"].should.have.key("Active").equals(False)
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_describe_user__quicksight():
|
||||
client = boto3.client("quicksight", region_name="us-east-1")
|
||||
client.register_user(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
Email="fakeemail@example.com",
|
||||
IdentityType="QUICKSIGHT",
|
||||
UserName="tfacctestm9hpsr970z",
|
||||
UserRole="READER",
|
||||
)
|
||||
|
||||
resp = client.describe_user(
|
||||
UserName="tfacctestm9hpsr970z", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
|
||||
resp.should.have.key("User")
|
||||
|
||||
resp["User"].should.have.key("Arn").equals(
|
||||
f"arn:aws:quicksight:us-east-1:{ACCOUNT_ID}:user/default/tfacctestm9hpsr970z"
|
||||
)
|
||||
resp["User"].should.have.key("UserName").equals("tfacctestm9hpsr970z")
|
||||
resp["User"].should.have.key("Email").equals("fakeemail@example.com")
|
||||
resp["User"].should.have.key("Role").equals("READER")
|
||||
resp["User"].should.have.key("IdentityType").equals("QUICKSIGHT")
|
||||
resp["User"].should.have.key("Active").equals(False)
|
||||
|
||||
|
||||
@mock_quicksight
|
||||
def test_delete_user__quicksight():
|
||||
client = boto3.client("quicksight", region_name="us-east-2")
|
||||
client.register_user(
|
||||
AwsAccountId=ACCOUNT_ID,
|
||||
Namespace="default",
|
||||
Email="fakeemail@example.com",
|
||||
IdentityType="QUICKSIGHT",
|
||||
UserName="tfacctestm9hpsr970z",
|
||||
UserRole="READER",
|
||||
)
|
||||
|
||||
client.delete_user(
|
||||
UserName="tfacctestm9hpsr970z", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.describe_user(
|
||||
UserName="tfacctestm9hpsr970z", AwsAccountId=ACCOUNT_ID, Namespace="default"
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ResourceNotFoundException")
|
Loading…
Reference in New Issue
Block a user