MQ - Initial implementation (#4789)
This commit is contained in:
parent
35d3c72039
commit
cf50da6938
@ -3587,6 +3587,34 @@
|
|||||||
- [X] put_object
|
- [X] put_object
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
## mq
|
||||||
|
<details>
|
||||||
|
<summary>86% implemented</summary>
|
||||||
|
|
||||||
|
- [X] create_broker
|
||||||
|
- [X] create_configuration
|
||||||
|
- [X] create_tags
|
||||||
|
- [X] create_user
|
||||||
|
- [X] delete_broker
|
||||||
|
- [X] delete_tags
|
||||||
|
- [X] delete_user
|
||||||
|
- [X] describe_broker
|
||||||
|
- [ ] describe_broker_engine_types
|
||||||
|
- [ ] describe_broker_instance_options
|
||||||
|
- [X] describe_configuration
|
||||||
|
- [X] describe_configuration_revision
|
||||||
|
- [X] describe_user
|
||||||
|
- [X] list_brokers
|
||||||
|
- [ ] list_configuration_revisions
|
||||||
|
- [X] list_configurations
|
||||||
|
- [X] list_tags
|
||||||
|
- [X] list_users
|
||||||
|
- [X] reboot_broker
|
||||||
|
- [X] update_broker
|
||||||
|
- [X] update_configuration
|
||||||
|
- [X] update_user
|
||||||
|
</details>
|
||||||
|
|
||||||
## opsworks
|
## opsworks
|
||||||
<details>
|
<details>
|
||||||
<summary>12% implemented</summary>
|
<summary>12% implemented</summary>
|
||||||
@ -5372,7 +5400,6 @@
|
|||||||
- migrationhub-config
|
- migrationhub-config
|
||||||
- migrationhubstrategy
|
- migrationhubstrategy
|
||||||
- mobile
|
- mobile
|
||||||
- mq
|
|
||||||
- mturk
|
- mturk
|
||||||
- mwaa
|
- mwaa
|
||||||
- neptune
|
- neptune
|
||||||
|
64
docs/docs/services/mq.rst
Normal file
64
docs/docs/services/mq.rst
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
.. _implementedservice_mq:
|
||||||
|
|
||||||
|
.. |start-h3| raw:: html
|
||||||
|
|
||||||
|
<h3>
|
||||||
|
|
||||||
|
.. |end-h3| raw:: html
|
||||||
|
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
==
|
||||||
|
mq
|
||||||
|
==
|
||||||
|
|
||||||
|
.. autoclass:: moto.mq.models.MQBackend
|
||||||
|
|
||||||
|
|start-h3| Example usage |end-h3|
|
||||||
|
|
||||||
|
.. sourcecode:: python
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_mq_behaviour:
|
||||||
|
boto3.client("mq")
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|start-h3| Implemented features for this service |end-h3|
|
||||||
|
|
||||||
|
- [X] create_broker
|
||||||
|
- [X] create_configuration
|
||||||
|
- [X] create_tags
|
||||||
|
- [X] create_user
|
||||||
|
- [X] delete_broker
|
||||||
|
- [X] delete_tags
|
||||||
|
- [X] delete_user
|
||||||
|
- [X] describe_broker
|
||||||
|
- [ ] describe_broker_engine_types
|
||||||
|
- [ ] describe_broker_instance_options
|
||||||
|
- [X] describe_configuration
|
||||||
|
- [X] describe_configuration_revision
|
||||||
|
- [X] describe_user
|
||||||
|
- [X] list_brokers
|
||||||
|
|
||||||
|
Pagination is not yet implemented
|
||||||
|
|
||||||
|
|
||||||
|
- [ ] list_configuration_revisions
|
||||||
|
- [X] list_configurations
|
||||||
|
|
||||||
|
Pagination has not yet been implemented.
|
||||||
|
|
||||||
|
|
||||||
|
- [X] list_tags
|
||||||
|
- [X] list_users
|
||||||
|
- [X] reboot_broker
|
||||||
|
- [X] update_broker
|
||||||
|
- [X] update_configuration
|
||||||
|
|
||||||
|
No validation occurs on the provided XML. The authenticationStrategy may be changed depending on the provided configuration.
|
||||||
|
|
||||||
|
|
||||||
|
- [X] update_user
|
||||||
|
|
@ -84,6 +84,7 @@ mock_kinesis = lazy_load(".kinesis", "mock_kinesis")
|
|||||||
mock_kms = lazy_load(".kms", "mock_kms")
|
mock_kms = lazy_load(".kms", "mock_kms")
|
||||||
mock_logs = lazy_load(".logs", "mock_logs")
|
mock_logs = lazy_load(".logs", "mock_logs")
|
||||||
mock_managedblockchain = lazy_load(".managedblockchain", "mock_managedblockchain")
|
mock_managedblockchain = lazy_load(".managedblockchain", "mock_managedblockchain")
|
||||||
|
mock_mq = lazy_load(".mq", "mock_mq", boto3_name="mq")
|
||||||
mock_opsworks = lazy_load(".opsworks", "mock_opsworks")
|
mock_opsworks = lazy_load(".opsworks", "mock_opsworks")
|
||||||
mock_organizations = lazy_load(".organizations", "mock_organizations")
|
mock_organizations = lazy_load(".organizations", "mock_organizations")
|
||||||
mock_polly = lazy_load(".polly", "mock_polly")
|
mock_polly = lazy_load(".polly", "mock_polly")
|
||||||
|
@ -91,6 +91,7 @@ backend_url_patterns = [
|
|||||||
("mediapackage", re.compile("https?://mediapackage\\.(.+)\\.amazonaws.com")),
|
("mediapackage", re.compile("https?://mediapackage\\.(.+)\\.amazonaws.com")),
|
||||||
("mediastore", re.compile("https?://mediastore\\.(.+)\\.amazonaws\\.com")),
|
("mediastore", re.compile("https?://mediastore\\.(.+)\\.amazonaws\\.com")),
|
||||||
("mediastore-data", re.compile("https?://data.mediastore\\.(.+)\\.amazonaws.com")),
|
("mediastore-data", re.compile("https?://data.mediastore\\.(.+)\\.amazonaws.com")),
|
||||||
|
("mq", re.compile("https?://mq\\.(.+)\\.amazonaws\\.com")),
|
||||||
("opsworks", re.compile("https?://opsworks\\.us-east-1\\.amazonaws.com")),
|
("opsworks", re.compile("https?://opsworks\\.us-east-1\\.amazonaws.com")),
|
||||||
("organizations", re.compile("https?://organizations\\.(.+)\\.amazonaws\\.com")),
|
("organizations", re.compile("https?://organizations\\.(.+)\\.amazonaws\\.com")),
|
||||||
("polly", re.compile("https?://polly\\.(.+)\\.amazonaws.com")),
|
("polly", re.compile("https?://polly\\.(.+)\\.amazonaws.com")),
|
||||||
|
5
moto/mq/__init__.py
Normal file
5
moto/mq/__init__.py
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
"""mq module initialization; sets value for base decorator."""
|
||||||
|
from .models import mq_backends
|
||||||
|
from ..core.models import base_decorator
|
||||||
|
|
||||||
|
mock_mq = base_decorator(mq_backends)
|
183
moto/mq/configuration.py
Normal file
183
moto/mq/configuration.py
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
DEFAULT_CONFIGURATION_DATA = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<broker xmlns="http://activemq.apache.org/schema/core" schedulePeriodForDestinationPurge="10000">
|
||||||
|
<!--
|
||||||
|
A configuration contains all of the settings for your ActiveMQ broker, in XML format (similar to ActiveMQ's activemq.xml file).
|
||||||
|
You can create a configuration before creating any brokers. You can then apply the configuration to one or more brokers.
|
||||||
|
|
||||||
|
You can use additional attributes for the broker element above. These attributes allow you to configure broker-wide settings.
|
||||||
|
|
||||||
|
For more information, see Configuration and Amazon MQ Broker Configuration Parameters in the Amazon MQ Developer Guide:
|
||||||
|
https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-broker-configuration-parameters.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
Mirrored queues let you send a copy of each message to a topic with a similar name automatically.
|
||||||
|
For more information, see http://activemq.apache.org/mirrored-queues.html
|
||||||
|
|
||||||
|
Virtual destinations let you configure advanced routing of messages between destinations.
|
||||||
|
For more information, see http://activemq.apache.org/virtual-destinations.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<destinationInterceptors>
|
||||||
|
<mirroredQueue copyMessage="true" postfix=".qmirror" prefix=""/>
|
||||||
|
<virtualDestinationInterceptor>
|
||||||
|
<virtualDestinations>
|
||||||
|
<virtualTopic name=">" prefix="VirtualTopicConsumers.*." selectorAware="false"/>
|
||||||
|
<compositeQueue name="MY.QUEUE">
|
||||||
|
<forwardTo>
|
||||||
|
<queue physicalName="FOO"/>
|
||||||
|
<topic physicalName="BAR"/>
|
||||||
|
</forwardTo>
|
||||||
|
</compositeQueue>
|
||||||
|
</virtualDestinations>
|
||||||
|
</virtualDestinationInterceptor>
|
||||||
|
</destinationInterceptors>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
By default, Amazon MQ optimizes for queues with fast consumers:
|
||||||
|
Consumers are considered fast if they are able to keep up with the rate of messages generated by producers.
|
||||||
|
Consumers are considered slow if a queue builds up a backlog of unacknowledged messages, potentially causing a decrease in producer throughput.
|
||||||
|
To instruct Amazon MQ to optimize for queues with slow consumers, set the concurrentStoreAndDispatchQueues attribute to false.
|
||||||
|
For more information, see https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/ensuring-effective-amazon-mq-performance.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<persistenceAdapter>
|
||||||
|
<kahaDB concurrentStoreAndDispatchQueues="false"/>
|
||||||
|
</persistenceAdapter>
|
||||||
|
-->
|
||||||
|
<destinationPolicy>
|
||||||
|
<policyMap>
|
||||||
|
<policyEntries>
|
||||||
|
<!--
|
||||||
|
gcInactiveDestinations is used to automatically purge inactive destinations
|
||||||
|
preventing them from unnecessarily using broker resources.
|
||||||
|
|
||||||
|
An 'inactive' destination is one that has no messages pending and no consumers connected.
|
||||||
|
|
||||||
|
For more information, see: http://activemq.apache.org/delete-inactive-destinations.html
|
||||||
|
-->
|
||||||
|
<policyEntry topic=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="600000">
|
||||||
|
<!--
|
||||||
|
The constantPendingMessageLimitStrategy is used to prevent
|
||||||
|
slow topic consumers to block producers and affect other consumers
|
||||||
|
by limiting the number of messages that are retained
|
||||||
|
|
||||||
|
For more information, see: http://activemq.apache.org/slow-consumer-handling.html
|
||||||
|
-->
|
||||||
|
<pendingMessageLimitStrategy>
|
||||||
|
<constantPendingMessageLimitStrategy limit="1000"/>
|
||||||
|
</pendingMessageLimitStrategy>
|
||||||
|
</policyEntry>
|
||||||
|
<policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="600000" />
|
||||||
|
<!--
|
||||||
|
Destination policies let you configure a rich set of behaviors for your queues and topics.
|
||||||
|
For more information, see http://activemq.apache.org/per-destination-policies.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<policyEntry topic="FOO.>">
|
||||||
|
<dispatchPolicy>
|
||||||
|
<roundRobinDispatchPolicy/>
|
||||||
|
</dispatchPolicy>
|
||||||
|
<subscriptionRecoveryPolicy>
|
||||||
|
<lastImageSubscriptionRecoveryPolicy/>
|
||||||
|
</subscriptionRecoveryPolicy>
|
||||||
|
</policyEntry>
|
||||||
|
<policyEntry advisoryForConsumed="true" tempTopic="true"/>
|
||||||
|
<policyEntry advisoryForConsumed="true" tempQueue="true"/>
|
||||||
|
-->
|
||||||
|
</policyEntries>
|
||||||
|
</policyMap>
|
||||||
|
</destinationPolicy>
|
||||||
|
<!--
|
||||||
|
Typically, destinations are created automatically when they are used. Amazon MQ lets you create destinations when the broker is started.
|
||||||
|
For more information, see http://activemq.apache.org/configure-startup-destinations.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<destinations>
|
||||||
|
<queue physicalName="FOO.BAR"/>
|
||||||
|
<topic physicalName="SOME.TOPIC"/>
|
||||||
|
</destinations>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
You can control advanced ActiveMQ features using plugins.
|
||||||
|
-->
|
||||||
|
<plugins>
|
||||||
|
<!--
|
||||||
|
The Authorization plugin allows you to control the groups of users that are allowed to perform certain operations on your destinations.
|
||||||
|
For more information, see http://activemq.apache.org/security.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<authorizationPlugin>
|
||||||
|
<map>
|
||||||
|
<authorizationMap>
|
||||||
|
<authorizationEntries>
|
||||||
|
<authorizationEntry admin="guests,users" queue="GUEST.>" read="guests" write="guests,users"/>
|
||||||
|
<authorizationEntry admin="guests,users" read="guests,users" topic="ActiveMQ.Advisory.>" write="guests,users"/>
|
||||||
|
</authorizationEntries>
|
||||||
|
<tempDestinationAuthorizationEntry>
|
||||||
|
<tempDestinationAuthorizationEntry admin="tempDestinationAdmins" read="tempDestinationAdmins" write="tempDestinationAdmins"/>
|
||||||
|
</tempDestinationAuthorizationEntry>
|
||||||
|
</authorizationMap>
|
||||||
|
</map>
|
||||||
|
</authorizationPlugin>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
The Discarding DLQ plugin simplifies the configuration of your global dead-letter queue strategy.
|
||||||
|
You can take advantage of a more granular per-destination control by using destination policies.
|
||||||
|
For more information, see http://activemq.apache.org/message-redelivery-and-dlq-handling.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<discardingDLQBrokerPlugin dropAll="true" dropTemporaryQueues="true" dropTemporaryTopics="true"/>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
The Force Persistency Mode plugin can override the persistency mode set on messages.
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<forcePersistencyModeBrokerPlugin persistenceFlag="true"/>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
The Redelivery plugin extends the capabilities of destination policies with respect to message redelivery.
|
||||||
|
For more information, see http://activemq.apache.org/message-redelivery-and-dlq-handling.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<redeliveryPlugin fallbackToDeadLetter="true" sendToDlqIfMaxRetriesExceeded="true">
|
||||||
|
<redeliveryPolicyMap>
|
||||||
|
<redeliveryPolicyMap>
|
||||||
|
<redeliveryPolicyEntries>
|
||||||
|
<redeliveryPolicy maximumRedeliveries="4" queue="SpecialQueue" redeliveryDelay="10000"/>
|
||||||
|
</redeliveryPolicyEntries>
|
||||||
|
<defaultEntry>
|
||||||
|
<redeliveryPolicy initialRedeliveryDelay="5000" maximumRedeliveries="4" redeliveryDelay="10000"/>
|
||||||
|
</defaultEntry>
|
||||||
|
</redeliveryPolicyMap>
|
||||||
|
</redeliveryPolicyMap>
|
||||||
|
</redeliveryPlugin>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
The Statistics plugin lets you query broker or destination statistics by sending messages to the broker.
|
||||||
|
For more information, see http://activemq.apache.org/statisticsplugin.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<statisticsBrokerPlugin/>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
The Timestamping plugin lets the broker use server-side time instead of client-provided time for messages.
|
||||||
|
For more information, see http://activemq.apache.org/timestampplugin.html
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<timeStampingBrokerPlugin ttlCeiling="86400000" zeroExpirationOverride="86400000"/>
|
||||||
|
-->
|
||||||
|
</plugins>
|
||||||
|
<!--
|
||||||
|
Network connectors let you connect brokers into networks of brokers.
|
||||||
|
For more information, see Creating and Configuring an Amazon MQ Network of Brokers
|
||||||
|
(https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-creating-configuring-network-of-brokers.html)
|
||||||
|
in the Amazon MQ Developer Guide and also Networks of Brokers
|
||||||
|
(http://activemq.apache.org/networks-of-brokers.html) in the ActiveMQ documentation.
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<networkConnectors>
|
||||||
|
<networkConnector name="myNetworkConnector" userName="commonUser" uri="masterslave:(ssl://b-1a2b3c4d-1.mq.region.amazonaws.com:61617,ssl://b-1a2b3c4d-2.mq.region.amazonaws.com:61617)"/>
|
||||||
|
</networkConnectors>
|
||||||
|
-->
|
||||||
|
</broker>
|
||||||
|
"""
|
71
moto/mq/exceptions.py
Normal file
71
moto/mq/exceptions.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import json
|
||||||
|
from moto.core.exceptions import JsonRESTError
|
||||||
|
|
||||||
|
|
||||||
|
class MQError(JsonRESTError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownBroker(MQError):
|
||||||
|
def __init__(self, broker_id):
|
||||||
|
super().__init__("NotFoundException", "Can't find requested broker")
|
||||||
|
self.broker_id = broker_id
|
||||||
|
|
||||||
|
def get_body(self):
|
||||||
|
body = {
|
||||||
|
"errorAttribute": "broker-id",
|
||||||
|
"message": f"Can't find requested broker [{self.broker_id}]. Make sure your broker exists.",
|
||||||
|
}
|
||||||
|
return json.dumps(body)
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownConfiguration(MQError):
|
||||||
|
def __init__(self, config_id):
|
||||||
|
super().__init__("NotFoundException", "Can't find requested configuration")
|
||||||
|
self.config_id = config_id
|
||||||
|
|
||||||
|
def get_body(self):
|
||||||
|
body = {
|
||||||
|
"errorAttribute": "configuration_id",
|
||||||
|
"message": f"Can't find requested configuration [{self.config_id}]. Make sure your configuration exists.",
|
||||||
|
}
|
||||||
|
return json.dumps(body)
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownUser(MQError):
|
||||||
|
def __init__(self, username):
|
||||||
|
super().__init__("NotFoundException", "Can't find requested user")
|
||||||
|
self.username = username
|
||||||
|
|
||||||
|
def get_body(self):
|
||||||
|
body = {
|
||||||
|
"errorAttribute": "username",
|
||||||
|
"message": f"Can't find requested user [{self.username}]. Make sure your user exists.",
|
||||||
|
}
|
||||||
|
return json.dumps(body)
|
||||||
|
|
||||||
|
|
||||||
|
class UnsupportedEngineType(MQError):
|
||||||
|
def __init__(self, engine_type):
|
||||||
|
super().__init__("BadRequestException", "")
|
||||||
|
self.engine_type = engine_type
|
||||||
|
|
||||||
|
def get_body(self):
|
||||||
|
body = {
|
||||||
|
"errorAttribute": "engineType",
|
||||||
|
"message": f"Broker engine type [{self.engine_type}] does not support configuration.",
|
||||||
|
}
|
||||||
|
return json.dumps(body)
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownEngineType(MQError):
|
||||||
|
def __init__(self, engine_type):
|
||||||
|
super().__init__("BadRequestException", "")
|
||||||
|
self.engine_type = engine_type
|
||||||
|
|
||||||
|
def get_body(self):
|
||||||
|
body = {
|
||||||
|
"errorAttribute": "engineType",
|
||||||
|
"message": f"Broker engine type [{self.engine_type}] is invalid. Valid values are: [ACTIVEMQ]",
|
||||||
|
}
|
||||||
|
return json.dumps(body)
|
528
moto/mq/models.py
Normal file
528
moto/mq/models.py
Normal file
@ -0,0 +1,528 @@
|
|||||||
|
import base64
|
||||||
|
import xmltodict
|
||||||
|
|
||||||
|
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
|
||||||
|
from moto.core.utils import BackendDict, get_random_hex, unix_time
|
||||||
|
from moto.utilities.tagging_service import TaggingService
|
||||||
|
|
||||||
|
from .configuration import DEFAULT_CONFIGURATION_DATA
|
||||||
|
from .exceptions import (
|
||||||
|
UnknownBroker,
|
||||||
|
UnknownConfiguration,
|
||||||
|
UnknownUser,
|
||||||
|
UnsupportedEngineType,
|
||||||
|
UnknownEngineType,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ConfigurationRevision(BaseModel):
|
||||||
|
def __init__(self, configuration_id, revision_id, description, data=None):
|
||||||
|
self.configuration_id = configuration_id
|
||||||
|
self.created = unix_time()
|
||||||
|
self.description = description
|
||||||
|
self.is_invalid = False
|
||||||
|
self.revision_id = revision_id
|
||||||
|
|
||||||
|
if data is None:
|
||||||
|
self.data = base64.b64encode(
|
||||||
|
DEFAULT_CONFIGURATION_DATA.encode("UTF-8")
|
||||||
|
).decode("utf-8")
|
||||||
|
else:
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
def has_ldap_auth(self):
|
||||||
|
try:
|
||||||
|
xml = base64.b64decode(self.data)
|
||||||
|
dct = xmltodict.parse(xml, dict_constructor=dict)
|
||||||
|
return (
|
||||||
|
"cachedLDAPAuthorizationMap"
|
||||||
|
in dct["broker"]["plugins"]["authorizationPlugin"]["map"]
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
# There are many configurations to enable LDAP
|
||||||
|
# We're only checking for one here
|
||||||
|
# If anything fails, lets assume it's not LDAP
|
||||||
|
return False
|
||||||
|
|
||||||
|
def to_json(self, full=True):
|
||||||
|
resp = {
|
||||||
|
"created": self.created,
|
||||||
|
"description": self.description,
|
||||||
|
"revision": int(self.revision_id),
|
||||||
|
}
|
||||||
|
if full:
|
||||||
|
resp["configurationId"] = self.configuration_id
|
||||||
|
resp["data"] = self.data
|
||||||
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
class Configuration(BaseModel):
|
||||||
|
def __init__(self, region, name, engine_type, engine_version):
|
||||||
|
self.id = f"c-{get_random_hex(6)}"
|
||||||
|
self.arn = f"arn:aws:mq:{region}:{ACCOUNT_ID}:configuration:{self.id}"
|
||||||
|
self.created = unix_time()
|
||||||
|
|
||||||
|
self.name = name
|
||||||
|
self.engine_type = engine_type
|
||||||
|
self.engine_version = engine_version
|
||||||
|
|
||||||
|
self.revisions = dict()
|
||||||
|
default_desc = (
|
||||||
|
f"Auto-generated default for {self.name} on {engine_type} {engine_version}"
|
||||||
|
)
|
||||||
|
latest_revision = ConfigurationRevision(
|
||||||
|
configuration_id=self.id, revision_id="1", description=default_desc
|
||||||
|
)
|
||||||
|
self.revisions[latest_revision.revision_id] = latest_revision
|
||||||
|
|
||||||
|
self.authentication_strategy = (
|
||||||
|
"ldap" if latest_revision.has_ldap_auth() else "simple"
|
||||||
|
)
|
||||||
|
|
||||||
|
def update(self, data, description):
|
||||||
|
max_revision_id, _ = sorted(self.revisions.items())[-1]
|
||||||
|
next_revision_id = str(int(max_revision_id) + 1)
|
||||||
|
latest_revision = ConfigurationRevision(
|
||||||
|
configuration_id=self.id,
|
||||||
|
revision_id=next_revision_id,
|
||||||
|
description=description,
|
||||||
|
data=data,
|
||||||
|
)
|
||||||
|
self.revisions[next_revision_id] = latest_revision
|
||||||
|
|
||||||
|
self.authentication_strategy = (
|
||||||
|
"ldap" if latest_revision.has_ldap_auth() else "simple"
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_revision(self, revision_id):
|
||||||
|
return self.revisions[revision_id]
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
_, latest_revision = sorted(self.revisions.items())[-1]
|
||||||
|
return {
|
||||||
|
"arn": self.arn,
|
||||||
|
"authenticationStrategy": self.authentication_strategy,
|
||||||
|
"created": self.created,
|
||||||
|
"engineType": self.engine_type,
|
||||||
|
"engineVersion": self.engine_version,
|
||||||
|
"id": self.id,
|
||||||
|
"name": self.name,
|
||||||
|
"latestRevision": latest_revision.to_json(full=False),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class User(BaseModel):
|
||||||
|
def __init__(self, broker_id, username, console_access=None, groups=None):
|
||||||
|
self.broker_id = broker_id
|
||||||
|
self.username = username
|
||||||
|
self.console_access = console_access or False
|
||||||
|
self.groups = groups or []
|
||||||
|
|
||||||
|
def update(self, console_access, groups):
|
||||||
|
if console_access is not None:
|
||||||
|
self.console_access = console_access
|
||||||
|
if groups:
|
||||||
|
self.groups = groups
|
||||||
|
|
||||||
|
def summary(self):
|
||||||
|
return {"username": self.username}
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
return {
|
||||||
|
"brokerId": self.broker_id,
|
||||||
|
"username": self.username,
|
||||||
|
"consoleAccess": self.console_access,
|
||||||
|
"groups": self.groups,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Broker(BaseModel):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
region,
|
||||||
|
authentication_strategy,
|
||||||
|
auto_minor_version_upgrade,
|
||||||
|
configuration,
|
||||||
|
deployment_mode,
|
||||||
|
encryption_options,
|
||||||
|
engine_type,
|
||||||
|
engine_version,
|
||||||
|
host_instance_type,
|
||||||
|
ldap_server_metadata,
|
||||||
|
logs,
|
||||||
|
maintenance_window_start_time,
|
||||||
|
publicly_accessible,
|
||||||
|
security_groups,
|
||||||
|
storage_type,
|
||||||
|
subnet_ids,
|
||||||
|
users,
|
||||||
|
):
|
||||||
|
self.name = name
|
||||||
|
self.id = get_random_hex(6)
|
||||||
|
self.arn = f"arn:aws:mq:{region}:{ACCOUNT_ID}:broker:{self.id}"
|
||||||
|
self.state = "RUNNING"
|
||||||
|
self.created = unix_time()
|
||||||
|
|
||||||
|
self.authentication_strategy = authentication_strategy
|
||||||
|
self.auto_minor_version_upgrade = auto_minor_version_upgrade
|
||||||
|
self.deployment_mode = deployment_mode
|
||||||
|
self.encryption_options = encryption_options
|
||||||
|
if not self.encryption_options:
|
||||||
|
self.encryption_options = {"useAwsOwnedKey": True}
|
||||||
|
self.engine_type = engine_type
|
||||||
|
self.engine_version = engine_version
|
||||||
|
self.host_instance_type = host_instance_type
|
||||||
|
self.ldap_server_metadata = ldap_server_metadata
|
||||||
|
self.logs = logs
|
||||||
|
if "general" not in self.logs:
|
||||||
|
self.logs["general"] = False
|
||||||
|
if "audit" not in self.logs:
|
||||||
|
if self.engine_type.upper() == "ACTIVEMQ":
|
||||||
|
self.logs["audit"] = False
|
||||||
|
self.maintenance_window_start_time = maintenance_window_start_time
|
||||||
|
if not self.maintenance_window_start_time:
|
||||||
|
self.maintenance_window_start_time = {
|
||||||
|
"dayOfWeek": "Sunday",
|
||||||
|
"timeOfDay": "00:00",
|
||||||
|
"timeZone": "UTC",
|
||||||
|
}
|
||||||
|
self.publicly_accessible = publicly_accessible
|
||||||
|
self.security_groups = security_groups
|
||||||
|
self.storage_type = storage_type
|
||||||
|
self.subnet_ids = subnet_ids
|
||||||
|
if not self.subnet_ids:
|
||||||
|
if self.deployment_mode == "CLUSTER_MULTI_AZ":
|
||||||
|
self.subnet_ids = [
|
||||||
|
"default-az1",
|
||||||
|
"default-az2",
|
||||||
|
"default-az3",
|
||||||
|
"default-az4",
|
||||||
|
]
|
||||||
|
elif self.deployment_mode == "ACTIVE_STANDBY_MULTI_AZ":
|
||||||
|
self.subnet_ids = ["active-subnet", "standby-subnet"]
|
||||||
|
else:
|
||||||
|
self.subnet_ids = ["default-subnet"]
|
||||||
|
|
||||||
|
self.users = dict()
|
||||||
|
for user in users:
|
||||||
|
self.create_user(
|
||||||
|
username=user["username"],
|
||||||
|
groups=user.get("groups", []),
|
||||||
|
console_access=user.get("consoleAccess", False),
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.engine_type.upper() == "RABBITMQ":
|
||||||
|
self.configurations = None
|
||||||
|
else:
|
||||||
|
current_config = configuration or {
|
||||||
|
"id": f"c-{get_random_hex(6)}",
|
||||||
|
"revision": 1,
|
||||||
|
}
|
||||||
|
self.configurations = {
|
||||||
|
"current": current_config,
|
||||||
|
"history": [],
|
||||||
|
}
|
||||||
|
if self.engine_type.upper() == "RABBITMQ":
|
||||||
|
console_url = f"https://0000.mq.{region}.amazonaws.com"
|
||||||
|
endpoints = ["amqps://mockmq:5671"]
|
||||||
|
else:
|
||||||
|
console_url = f"https://0000.mq.{region}.amazonaws.com:8162"
|
||||||
|
endpoints = [
|
||||||
|
"ssl://mockmq:61617",
|
||||||
|
"amqp+ssl://mockmq:5671",
|
||||||
|
"stomp+ssl://mockmq:61614",
|
||||||
|
"mqtt+ssl://mockmq:8883",
|
||||||
|
"wss://mockmq:61619",
|
||||||
|
]
|
||||||
|
self.instances = [
|
||||||
|
{
|
||||||
|
"consoleURL": console_url,
|
||||||
|
"endpoints": endpoints,
|
||||||
|
"ipAddress": "192.168.0.1",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
if deployment_mode == "ACTIVE_STANDBY_MULTI_AZ":
|
||||||
|
self.instances.append(
|
||||||
|
{
|
||||||
|
"consoleURL": console_url,
|
||||||
|
"endpoints": endpoints,
|
||||||
|
"ipAddress": "192.168.0.2",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
def update(
|
||||||
|
self,
|
||||||
|
authentication_strategy,
|
||||||
|
auto_minor_version_upgrade,
|
||||||
|
configuration,
|
||||||
|
engine_version,
|
||||||
|
host_instance_type,
|
||||||
|
ldap_server_metadata,
|
||||||
|
logs,
|
||||||
|
maintenance_window_start_time,
|
||||||
|
security_groups,
|
||||||
|
):
|
||||||
|
if authentication_strategy:
|
||||||
|
self.authentication_strategy = authentication_strategy
|
||||||
|
if auto_minor_version_upgrade is not None:
|
||||||
|
self.auto_minor_version_upgrade = auto_minor_version_upgrade
|
||||||
|
if configuration:
|
||||||
|
self.configurations["history"].append(self.configurations["current"])
|
||||||
|
self.configurations["current"] = configuration
|
||||||
|
if engine_version:
|
||||||
|
self.engine_version = engine_version
|
||||||
|
if host_instance_type:
|
||||||
|
self.host_instance_type = host_instance_type
|
||||||
|
if ldap_server_metadata:
|
||||||
|
self.ldap_server_metadata = ldap_server_metadata
|
||||||
|
if logs:
|
||||||
|
self.logs = logs
|
||||||
|
if maintenance_window_start_time:
|
||||||
|
self.maintenance_window_start_time = maintenance_window_start_time
|
||||||
|
if security_groups:
|
||||||
|
self.security_groups = security_groups
|
||||||
|
|
||||||
|
def reboot(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def create_user(self, username, console_access, groups):
|
||||||
|
user = User(self.id, username, console_access, groups)
|
||||||
|
self.users[username] = user
|
||||||
|
|
||||||
|
def update_user(self, username, console_access, groups):
|
||||||
|
user = self.get_user(username)
|
||||||
|
user.update(console_access, groups)
|
||||||
|
|
||||||
|
def get_user(self, username):
|
||||||
|
if username not in self.users:
|
||||||
|
raise UnknownUser(username)
|
||||||
|
return self.users[username]
|
||||||
|
|
||||||
|
def delete_user(self, username):
|
||||||
|
self.users.pop(username, None)
|
||||||
|
|
||||||
|
def list_users(self):
|
||||||
|
return self.users.values()
|
||||||
|
|
||||||
|
def summary(self):
|
||||||
|
return {
|
||||||
|
"brokerArn": self.arn,
|
||||||
|
"brokerId": self.id,
|
||||||
|
"brokerName": self.name,
|
||||||
|
"brokerState": self.state,
|
||||||
|
"created": self.created,
|
||||||
|
"deploymentMode": self.deployment_mode,
|
||||||
|
"engineType": self.engine_type,
|
||||||
|
"hostInstanceType": self.host_instance_type,
|
||||||
|
}
|
||||||
|
|
||||||
|
def to_json(self):
|
||||||
|
return {
|
||||||
|
"brokerId": self.id,
|
||||||
|
"brokerArn": self.arn,
|
||||||
|
"brokerName": self.name,
|
||||||
|
"brokerState": self.state,
|
||||||
|
"brokerInstances": self.instances,
|
||||||
|
"created": self.created,
|
||||||
|
"configurations": self.configurations,
|
||||||
|
"authenticationStrategy": self.authentication_strategy,
|
||||||
|
"autoMinorVersionUpgrade": self.auto_minor_version_upgrade,
|
||||||
|
"deploymentMode": self.deployment_mode,
|
||||||
|
"encryptionOptions": self.encryption_options,
|
||||||
|
"engineType": self.engine_type,
|
||||||
|
"engineVersion": self.engine_version,
|
||||||
|
"hostInstanceType": self.host_instance_type,
|
||||||
|
"ldapServerMetadata": self.ldap_server_metadata,
|
||||||
|
"logs": self.logs,
|
||||||
|
"maintenanceWindowStartTime": self.maintenance_window_start_time,
|
||||||
|
"publiclyAccessible": self.publicly_accessible,
|
||||||
|
"securityGroups": self.security_groups,
|
||||||
|
"storageType": self.storage_type,
|
||||||
|
"subnetIds": self.subnet_ids,
|
||||||
|
"users": [u.summary() for u in self.users.values()],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MQBackend(BaseBackend):
|
||||||
|
"""
|
||||||
|
No EC2 integration exists yet - subnet ID's and security group values are not validated. Default values may not exist.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, region_name=None):
|
||||||
|
self.region_name = region_name
|
||||||
|
self.brokers = dict()
|
||||||
|
self.configs = dict()
|
||||||
|
self.tagger = TaggingService()
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""Re-initialize all attributes for this instance."""
|
||||||
|
region_name = self.region_name
|
||||||
|
self.__dict__ = {}
|
||||||
|
self.__init__(region_name)
|
||||||
|
|
||||||
|
def create_broker(
|
||||||
|
self,
|
||||||
|
authentication_strategy,
|
||||||
|
auto_minor_version_upgrade,
|
||||||
|
broker_name,
|
||||||
|
configuration,
|
||||||
|
creator_request_id,
|
||||||
|
deployment_mode,
|
||||||
|
encryption_options,
|
||||||
|
engine_type,
|
||||||
|
engine_version,
|
||||||
|
host_instance_type,
|
||||||
|
ldap_server_metadata,
|
||||||
|
logs,
|
||||||
|
maintenance_window_start_time,
|
||||||
|
publicly_accessible,
|
||||||
|
security_groups,
|
||||||
|
storage_type,
|
||||||
|
subnet_ids,
|
||||||
|
tags,
|
||||||
|
users,
|
||||||
|
):
|
||||||
|
broker = Broker(
|
||||||
|
name=broker_name,
|
||||||
|
region=self.region_name,
|
||||||
|
authentication_strategy=authentication_strategy,
|
||||||
|
auto_minor_version_upgrade=auto_minor_version_upgrade,
|
||||||
|
configuration=configuration,
|
||||||
|
deployment_mode=deployment_mode,
|
||||||
|
encryption_options=encryption_options,
|
||||||
|
engine_type=engine_type,
|
||||||
|
engine_version=engine_version,
|
||||||
|
host_instance_type=host_instance_type,
|
||||||
|
ldap_server_metadata=ldap_server_metadata,
|
||||||
|
logs=logs,
|
||||||
|
maintenance_window_start_time=maintenance_window_start_time,
|
||||||
|
publicly_accessible=publicly_accessible,
|
||||||
|
security_groups=security_groups,
|
||||||
|
storage_type=storage_type,
|
||||||
|
subnet_ids=subnet_ids,
|
||||||
|
users=users,
|
||||||
|
)
|
||||||
|
self.brokers[broker.id] = broker
|
||||||
|
self.create_tags(broker.arn, tags)
|
||||||
|
return broker.arn, broker.id
|
||||||
|
|
||||||
|
def delete_broker(self, broker_id):
|
||||||
|
del self.brokers[broker_id]
|
||||||
|
|
||||||
|
def describe_broker(self, broker_id):
|
||||||
|
if broker_id not in self.brokers:
|
||||||
|
raise UnknownBroker(broker_id)
|
||||||
|
return self.brokers[broker_id]
|
||||||
|
|
||||||
|
def reboot_broker(self, broker_id):
|
||||||
|
self.brokers[broker_id].reboot()
|
||||||
|
|
||||||
|
def list_brokers(self):
|
||||||
|
"""
|
||||||
|
Pagination is not yet implemented
|
||||||
|
"""
|
||||||
|
return self.brokers.values()
|
||||||
|
|
||||||
|
def create_user(self, broker_id, username, console_access, groups):
|
||||||
|
broker = self.describe_broker(broker_id)
|
||||||
|
broker.create_user(username, console_access, groups)
|
||||||
|
|
||||||
|
def update_user(self, broker_id, console_access, groups, username):
|
||||||
|
broker = self.describe_broker(broker_id)
|
||||||
|
broker.update_user(username, console_access, groups)
|
||||||
|
|
||||||
|
def describe_user(self, broker_id, username):
|
||||||
|
broker = self.describe_broker(broker_id)
|
||||||
|
return broker.get_user(username)
|
||||||
|
|
||||||
|
def delete_user(self, broker_id, username):
|
||||||
|
broker = self.describe_broker(broker_id)
|
||||||
|
broker.delete_user(username)
|
||||||
|
|
||||||
|
def list_users(self, broker_id):
|
||||||
|
broker = self.describe_broker(broker_id)
|
||||||
|
return broker.list_users()
|
||||||
|
|
||||||
|
def create_configuration(self, name, engine_type, engine_version, tags):
|
||||||
|
if engine_type.upper() == "RABBITMQ":
|
||||||
|
raise UnsupportedEngineType(engine_type)
|
||||||
|
if engine_type.upper() != "ACTIVEMQ":
|
||||||
|
raise UnknownEngineType(engine_type)
|
||||||
|
config = Configuration(
|
||||||
|
region=self.region_name,
|
||||||
|
name=name,
|
||||||
|
engine_type=engine_type,
|
||||||
|
engine_version=engine_version,
|
||||||
|
)
|
||||||
|
self.configs[config.id] = config
|
||||||
|
self.tagger.tag_resource(
|
||||||
|
config.arn, self.tagger.convert_dict_to_tags_input(tags)
|
||||||
|
)
|
||||||
|
return config
|
||||||
|
|
||||||
|
def update_configuration(self, config_id, data, description):
|
||||||
|
"""
|
||||||
|
No validation occurs on the provided XML. The authenticationStrategy may be changed depending on the provided configuration.
|
||||||
|
"""
|
||||||
|
config = self.configs[config_id]
|
||||||
|
config.update(data, description)
|
||||||
|
return config
|
||||||
|
|
||||||
|
def describe_configuration(self, config_id):
|
||||||
|
if config_id not in self.configs:
|
||||||
|
raise UnknownConfiguration(config_id)
|
||||||
|
return self.configs[config_id]
|
||||||
|
|
||||||
|
def describe_configuration_revision(self, config_id, revision_id):
|
||||||
|
config = self.configs[config_id]
|
||||||
|
return config.get_revision(revision_id)
|
||||||
|
|
||||||
|
def list_configurations(self):
|
||||||
|
"""
|
||||||
|
Pagination has not yet been implemented.
|
||||||
|
"""
|
||||||
|
return self.configs.values()
|
||||||
|
|
||||||
|
def create_tags(self, resource_arn, tags):
|
||||||
|
self.tagger.tag_resource(
|
||||||
|
resource_arn, self.tagger.convert_dict_to_tags_input(tags)
|
||||||
|
)
|
||||||
|
|
||||||
|
def list_tags(self, arn):
|
||||||
|
return self.tagger.get_tag_dict_for_resource(arn)
|
||||||
|
|
||||||
|
def delete_tags(self, resource_arn, tag_keys):
|
||||||
|
if not isinstance(tag_keys, list):
|
||||||
|
tag_keys = [tag_keys]
|
||||||
|
self.tagger.untag_resource_using_names(resource_arn, tag_keys)
|
||||||
|
|
||||||
|
def update_broker(
|
||||||
|
self,
|
||||||
|
authentication_strategy,
|
||||||
|
auto_minor_version_upgrade,
|
||||||
|
broker_id,
|
||||||
|
configuration,
|
||||||
|
engine_version,
|
||||||
|
host_instance_type,
|
||||||
|
ldap_server_metadata,
|
||||||
|
logs,
|
||||||
|
maintenance_window_start_time,
|
||||||
|
security_groups,
|
||||||
|
):
|
||||||
|
broker = self.describe_broker(broker_id)
|
||||||
|
broker.update(
|
||||||
|
authentication_strategy=authentication_strategy,
|
||||||
|
auto_minor_version_upgrade=auto_minor_version_upgrade,
|
||||||
|
configuration=configuration,
|
||||||
|
engine_version=engine_version,
|
||||||
|
host_instance_type=host_instance_type,
|
||||||
|
ldap_server_metadata=ldap_server_metadata,
|
||||||
|
logs=logs,
|
||||||
|
maintenance_window_start_time=maintenance_window_start_time,
|
||||||
|
security_groups=security_groups,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
mq_backends = BackendDict(MQBackend, "mq")
|
281
moto/mq/responses.py
Normal file
281
moto/mq/responses.py
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
"""Handles incoming mq requests, invokes methods, returns responses."""
|
||||||
|
import json
|
||||||
|
from functools import wraps
|
||||||
|
from urllib.parse import unquote
|
||||||
|
|
||||||
|
from moto.core.responses import BaseResponse
|
||||||
|
from .exceptions import MQError
|
||||||
|
from .models import mq_backends
|
||||||
|
|
||||||
|
|
||||||
|
def error_handler(f):
|
||||||
|
@wraps(f)
|
||||||
|
def _wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
except MQError as e:
|
||||||
|
return e.code, e.get_headers(), e.get_body()
|
||||||
|
|
||||||
|
return _wrapper
|
||||||
|
|
||||||
|
|
||||||
|
class MQResponse(BaseResponse):
|
||||||
|
"""Handler for MQ requests and responses."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mq_backend(self):
|
||||||
|
"""Return backend instance specific for this region."""
|
||||||
|
return mq_backends[self.region]
|
||||||
|
|
||||||
|
@error_handler
|
||||||
|
def broker(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.describe_broker()
|
||||||
|
if request.method == "DELETE":
|
||||||
|
return self.delete_broker()
|
||||||
|
if request.method == "PUT":
|
||||||
|
return self.update_broker()
|
||||||
|
|
||||||
|
def brokers(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "POST":
|
||||||
|
return self.create_broker()
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.list_brokers()
|
||||||
|
|
||||||
|
@error_handler
|
||||||
|
def configuration(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.describe_configuration()
|
||||||
|
if request.method == "PUT":
|
||||||
|
return self.update_configuration()
|
||||||
|
|
||||||
|
@error_handler
|
||||||
|
def configurations(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "POST":
|
||||||
|
return self.create_configuration()
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.list_configurations()
|
||||||
|
|
||||||
|
def configuration_revision(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.get_configuration_revision()
|
||||||
|
|
||||||
|
def tags(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "POST":
|
||||||
|
return self.create_tags()
|
||||||
|
if request.method == "DELETE":
|
||||||
|
return self.delete_tags()
|
||||||
|
|
||||||
|
@error_handler
|
||||||
|
def user(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "POST":
|
||||||
|
return self.create_user()
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.describe_user()
|
||||||
|
if request.method == "PUT":
|
||||||
|
return self.update_user()
|
||||||
|
if request.method == "DELETE":
|
||||||
|
return self.delete_user()
|
||||||
|
|
||||||
|
def users(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "GET":
|
||||||
|
return self.list_users()
|
||||||
|
|
||||||
|
def create_broker(self):
|
||||||
|
params = json.loads(self.body)
|
||||||
|
authentication_strategy = params.get("authenticationStrategy")
|
||||||
|
auto_minor_version_upgrade = params.get("autoMinorVersionUpgrade")
|
||||||
|
broker_name = params.get("brokerName")
|
||||||
|
configuration = params.get("configuration")
|
||||||
|
creator_request_id = params.get("creatorRequestId")
|
||||||
|
deployment_mode = params.get("deploymentMode")
|
||||||
|
encryption_options = params.get("encryptionOptions")
|
||||||
|
engine_type = params.get("engineType")
|
||||||
|
engine_version = params.get("engineVersion")
|
||||||
|
host_instance_type = params.get("hostInstanceType")
|
||||||
|
ldap_server_metadata = params.get("ldapServerMetadata")
|
||||||
|
logs = params.get("logs", {})
|
||||||
|
maintenance_window_start_time = params.get("maintenanceWindowStartTime")
|
||||||
|
publicly_accessible = params.get("publiclyAccessible")
|
||||||
|
security_groups = params.get("securityGroups")
|
||||||
|
storage_type = params.get("storageType")
|
||||||
|
subnet_ids = params.get("subnetIds", [])
|
||||||
|
tags = params.get("tags")
|
||||||
|
users = params.get("users", [])
|
||||||
|
broker_arn, broker_id = self.mq_backend.create_broker(
|
||||||
|
authentication_strategy=authentication_strategy,
|
||||||
|
auto_minor_version_upgrade=auto_minor_version_upgrade,
|
||||||
|
broker_name=broker_name,
|
||||||
|
configuration=configuration,
|
||||||
|
creator_request_id=creator_request_id,
|
||||||
|
deployment_mode=deployment_mode,
|
||||||
|
encryption_options=encryption_options,
|
||||||
|
engine_type=engine_type,
|
||||||
|
engine_version=engine_version,
|
||||||
|
host_instance_type=host_instance_type,
|
||||||
|
ldap_server_metadata=ldap_server_metadata,
|
||||||
|
logs=logs,
|
||||||
|
maintenance_window_start_time=maintenance_window_start_time,
|
||||||
|
publicly_accessible=publicly_accessible,
|
||||||
|
security_groups=security_groups,
|
||||||
|
storage_type=storage_type,
|
||||||
|
subnet_ids=subnet_ids,
|
||||||
|
tags=tags,
|
||||||
|
users=users,
|
||||||
|
)
|
||||||
|
# Lowercase members - boto3 will convert it into UpperCase
|
||||||
|
resp = {"brokerArn": broker_arn, "brokerId": broker_id}
|
||||||
|
return 200, {}, json.dumps(resp)
|
||||||
|
|
||||||
|
def update_broker(self):
|
||||||
|
params = json.loads(self.body)
|
||||||
|
broker_id = self.path.split("/")[-1]
|
||||||
|
authentication_strategy = params.get("authenticationStrategy")
|
||||||
|
auto_minor_version_upgrade = params.get("autoMinorVersionUpgrade")
|
||||||
|
configuration = params.get("configuration")
|
||||||
|
engine_version = params.get("engineVersion")
|
||||||
|
host_instance_type = params.get("hostInstanceType")
|
||||||
|
ldap_server_metadata = params.get("ldapServerMetadata")
|
||||||
|
logs = params.get("logs")
|
||||||
|
maintenance_window_start_time = params.get("maintenanceWindowStartTime")
|
||||||
|
security_groups = params.get("securityGroups")
|
||||||
|
self.mq_backend.update_broker(
|
||||||
|
authentication_strategy=authentication_strategy,
|
||||||
|
auto_minor_version_upgrade=auto_minor_version_upgrade,
|
||||||
|
broker_id=broker_id,
|
||||||
|
configuration=configuration,
|
||||||
|
engine_version=engine_version,
|
||||||
|
host_instance_type=host_instance_type,
|
||||||
|
ldap_server_metadata=ldap_server_metadata,
|
||||||
|
logs=logs,
|
||||||
|
maintenance_window_start_time=maintenance_window_start_time,
|
||||||
|
security_groups=security_groups,
|
||||||
|
)
|
||||||
|
return self.describe_broker()
|
||||||
|
|
||||||
|
def delete_broker(self):
|
||||||
|
broker_id = self.path.split("/")[-1]
|
||||||
|
self.mq_backend.delete_broker(broker_id=broker_id)
|
||||||
|
return 200, {}, json.dumps(dict(brokerId=broker_id))
|
||||||
|
|
||||||
|
def describe_broker(self):
|
||||||
|
broker_id = self.path.split("/")[-1]
|
||||||
|
broker = self.mq_backend.describe_broker(broker_id=broker_id)
|
||||||
|
resp = broker.to_json()
|
||||||
|
resp["tags"] = self.mq_backend.list_tags(broker.arn)
|
||||||
|
return 200, {}, json.dumps(resp)
|
||||||
|
|
||||||
|
def list_brokers(self):
|
||||||
|
brokers = self.mq_backend.list_brokers()
|
||||||
|
return 200, {}, json.dumps(dict(brokerSummaries=[b.summary() for b in brokers]))
|
||||||
|
|
||||||
|
def create_user(self):
|
||||||
|
params = json.loads(self.body)
|
||||||
|
broker_id = self.path.split("/")[-3]
|
||||||
|
username = self.path.split("/")[-1]
|
||||||
|
console_access = params.get("consoleAccess", False)
|
||||||
|
groups = params.get("groups", [])
|
||||||
|
self.mq_backend.create_user(broker_id, username, console_access, groups)
|
||||||
|
return 200, {}, "{}"
|
||||||
|
|
||||||
|
def update_user(self):
|
||||||
|
params = json.loads(self.body)
|
||||||
|
broker_id = self.path.split("/")[-3]
|
||||||
|
username = self.path.split("/")[-1]
|
||||||
|
console_access = params.get("consoleAccess", False)
|
||||||
|
groups = params.get("groups", [])
|
||||||
|
self.mq_backend.update_user(
|
||||||
|
broker_id=broker_id,
|
||||||
|
console_access=console_access,
|
||||||
|
groups=groups,
|
||||||
|
username=username,
|
||||||
|
)
|
||||||
|
return 200, {}, "{}"
|
||||||
|
|
||||||
|
def describe_user(self):
|
||||||
|
broker_id = self.path.split("/")[-3]
|
||||||
|
username = self.path.split("/")[-1]
|
||||||
|
user = self.mq_backend.describe_user(broker_id, username)
|
||||||
|
return 200, {}, json.dumps(user.to_json())
|
||||||
|
|
||||||
|
def delete_user(self):
|
||||||
|
broker_id = self.path.split("/")[-3]
|
||||||
|
username = self.path.split("/")[-1]
|
||||||
|
self.mq_backend.delete_user(broker_id, username)
|
||||||
|
return 200, {}, "{}"
|
||||||
|
|
||||||
|
def list_users(self):
|
||||||
|
broker_id = self.path.split("/")[-2]
|
||||||
|
users = self.mq_backend.list_users(broker_id=broker_id)
|
||||||
|
resp = {
|
||||||
|
"brokerId": broker_id,
|
||||||
|
"users": [{"username": u.username} for u in users],
|
||||||
|
}
|
||||||
|
return 200, {}, json.dumps(resp)
|
||||||
|
|
||||||
|
def create_configuration(self):
|
||||||
|
params = json.loads(self.body)
|
||||||
|
name = params.get("name")
|
||||||
|
engine_type = params.get("engineType")
|
||||||
|
engine_version = params.get("engineVersion")
|
||||||
|
tags = params.get("tags", {})
|
||||||
|
|
||||||
|
config = self.mq_backend.create_configuration(
|
||||||
|
name, engine_type, engine_version, tags
|
||||||
|
)
|
||||||
|
return 200, {}, json.dumps(config.to_json())
|
||||||
|
|
||||||
|
def describe_configuration(self):
|
||||||
|
config_id = self.path.split("/")[-1]
|
||||||
|
config = self.mq_backend.describe_configuration(config_id)
|
||||||
|
resp = config.to_json()
|
||||||
|
resp["tags"] = self.mq_backend.list_tags(config.arn)
|
||||||
|
return 200, {}, json.dumps(resp)
|
||||||
|
|
||||||
|
def list_configurations(self):
|
||||||
|
configs = self.mq_backend.list_configurations()
|
||||||
|
resp = {"configurations": [c.to_json() for c in configs]}
|
||||||
|
return 200, {}, json.dumps(resp)
|
||||||
|
|
||||||
|
def update_configuration(self):
|
||||||
|
config_id = self.path.split("/")[-1]
|
||||||
|
params = json.loads(self.body)
|
||||||
|
data = params.get("data")
|
||||||
|
description = params.get("description")
|
||||||
|
config = self.mq_backend.update_configuration(config_id, data, description)
|
||||||
|
return 200, {}, json.dumps(config.to_json())
|
||||||
|
|
||||||
|
def get_configuration_revision(self):
|
||||||
|
revision_id = self.path.split("/")[-1]
|
||||||
|
config_id = self.path.split("/")[-3]
|
||||||
|
revision = self.mq_backend.describe_configuration_revision(
|
||||||
|
config_id, revision_id
|
||||||
|
)
|
||||||
|
return 200, {}, json.dumps(revision.to_json())
|
||||||
|
|
||||||
|
def create_tags(self):
|
||||||
|
resource_arn = unquote(self.path.split("/")[-1])
|
||||||
|
tags = json.loads(self.body).get("tags", {})
|
||||||
|
self.mq_backend.create_tags(resource_arn, tags)
|
||||||
|
return 200, {}, "{}"
|
||||||
|
|
||||||
|
def delete_tags(self):
|
||||||
|
resource_arn = unquote(self.path.split("/")[-1])
|
||||||
|
tag_keys = self._get_param("tagKeys")
|
||||||
|
self.mq_backend.delete_tags(resource_arn, tag_keys)
|
||||||
|
return 200, {}, "{}"
|
||||||
|
|
||||||
|
def reboot(self, request, full_url, headers):
|
||||||
|
self.setup_class(request, full_url, headers)
|
||||||
|
if request.method == "POST":
|
||||||
|
broker_id = self.path.split("/")[-2]
|
||||||
|
self.mq_backend.reboot_broker(broker_id=broker_id)
|
||||||
|
return 200, {}, "{}"
|
22
moto/mq/urls.py
Normal file
22
moto/mq/urls.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
"""mq base URL and path."""
|
||||||
|
from .responses import MQResponse
|
||||||
|
|
||||||
|
url_bases = [
|
||||||
|
r"https?://mq\.(.+)\.amazonaws\.com",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
response = MQResponse()
|
||||||
|
|
||||||
|
|
||||||
|
url_paths = {
|
||||||
|
"{0}/v1/brokers/(?P<broker_id>[^/]+)$": response.broker,
|
||||||
|
"{0}/v1/brokers/(?P<broker_id>[^/]+)/reboot$": response.reboot,
|
||||||
|
"{0}/v1/brokers/(?P<broker_id>[^/]+)/users$": response.users,
|
||||||
|
"{0}/v1/brokers/(?P<broker_id>[^/]+)/users/(?P<user_name>[^/]+)$": response.user,
|
||||||
|
"{0}/v1/brokers$": response.brokers,
|
||||||
|
"{0}/v1/configurations$": response.configurations,
|
||||||
|
"{0}/v1/configurations/(?P<config_id>[^/]+)$": response.configuration,
|
||||||
|
"{0}/v1/configurations/(?P<config_id>[^/]+)/revisions/(?P<revision_id>[^/]+)$": response.configuration_revision,
|
||||||
|
"{0}/v1/tags/(?P<resource_arn>[^/]+)$": response.tags,
|
||||||
|
}
|
@ -68,6 +68,7 @@ TestAccAWSIAMUserPolicy
|
|||||||
TestAccAWSIPRanges
|
TestAccAWSIPRanges
|
||||||
TestAccAWSKmsAlias
|
TestAccAWSKmsAlias
|
||||||
TestAccAWSKmsSecretDataSource
|
TestAccAWSKmsSecretDataSource
|
||||||
|
TestAccAWSMq
|
||||||
TestAccAWSPartition
|
TestAccAWSPartition
|
||||||
TestAccAWSProvider
|
TestAccAWSProvider
|
||||||
TestAccAWSRedshiftServiceAccount
|
TestAccAWSRedshiftServiceAccount
|
||||||
|
0
tests/test_mq/__init__.py
Normal file
0
tests/test_mq/__init__.py
Normal file
427
tests/test_mq/test_mq.py
Normal file
427
tests/test_mq/test_mq.py
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
import boto3
|
||||||
|
import pytest
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
from moto import mock_mq
|
||||||
|
|
||||||
|
# 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_mq
|
||||||
|
def test_create_broker_minimal():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
resp = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId")
|
||||||
|
resp.should.have.key("BrokerArn").match("arn:aws")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_with_tags():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="CLUSTER_MULTI_AZ",
|
||||||
|
EngineType="RabbitMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Tags={"key1": "val2", "key2": "val2"},
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Tags").equals({"key1": "val2", "key2": "val2"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_with_multiple_users():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="CLUSTER_MULTI_AZ",
|
||||||
|
EngineType="RabbitMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[
|
||||||
|
{
|
||||||
|
"ConsoleAccess": True,
|
||||||
|
"Groups": ["second", "first", "third"],
|
||||||
|
"Password": "SecondTestTest1234",
|
||||||
|
"Username": "SecondTest",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ConsoleAccess": False,
|
||||||
|
"Groups": [],
|
||||||
|
"Password": "TestTest1234",
|
||||||
|
"Username": "Test",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
user1 = client.describe_user(BrokerId=broker_id, Username="SecondTest")
|
||||||
|
user1.should.have.key("Username").equals("SecondTest")
|
||||||
|
user1.should.have.key("Groups").equals(["second", "first", "third"])
|
||||||
|
user1.should.have.key("ConsoleAccess").equals(True)
|
||||||
|
|
||||||
|
user2 = client.describe_user(BrokerId=broker_id, Username="Test")
|
||||||
|
user2.should.have.key("Username").equals("Test")
|
||||||
|
user2.should.have.key("Groups").equals([])
|
||||||
|
user2.should.have.key("ConsoleAccess").equals(False)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_with_configuration():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
Configuration={"Id": "config_id_x", "Revision": 3},
|
||||||
|
DeploymentMode="CLUSTER_SINGLE",
|
||||||
|
EngineType="ActiveMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Tags={"key1": "val2", "key2": "val2"},
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Configurations")
|
||||||
|
resp["Configurations"].should.have.key("Current").equals(
|
||||||
|
{"Id": "config_id_x", "Revision": 3}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_update_with_configuration():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
Configuration={"Id": "config_id_x", "Revision": 1},
|
||||||
|
DeploymentMode="CLUSTER_SINGLE",
|
||||||
|
EngineType="ActiveMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Tags={"key1": "val2", "key2": "val2"},
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
client.update_broker(
|
||||||
|
BrokerId=broker_id, Configuration={"Id": "config_id_x", "Revision": 2}
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Configurations")
|
||||||
|
resp["Configurations"].should.have.key("Current").equals(
|
||||||
|
{"Id": "config_id_x", "Revision": 2}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_delete_broker():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.delete_broker(BrokerId=broker_id)
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
|
||||||
|
client.list_brokers().should.have.key("BrokerSummaries").length_of(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_broker():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AuthenticationStrategy="SIMPLE",
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EncryptionOptions={"KmsKeyId": "kms-key", "UseAwsOwnedKey": False},
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
LdapServerMetadata={
|
||||||
|
"Hosts": ["host1"],
|
||||||
|
"RoleBase": "role_base_thingy",
|
||||||
|
"RoleSearchMatching": "rsm",
|
||||||
|
"ServiceAccountUsername": "sau",
|
||||||
|
"ServiceAccountPassword": "sap",
|
||||||
|
"UserBase": "ub",
|
||||||
|
"UserSearchMatching": "usm",
|
||||||
|
},
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
SecurityGroups=["secgroup1"],
|
||||||
|
StorageType="efs",
|
||||||
|
SubnetIds=["s-id"],
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("BrokerArn").match("arn:aws")
|
||||||
|
resp.should.have.key("BrokerState").equals("RUNNING")
|
||||||
|
|
||||||
|
resp.should.have.key("Created")
|
||||||
|
|
||||||
|
resp.should.have.key("AuthenticationStrategy").equals("SIMPLE")
|
||||||
|
resp.should.have.key("AutoMinorVersionUpgrade").equals(False)
|
||||||
|
resp.should.have.key("BrokerName").equals("testbroker")
|
||||||
|
resp.should.have.key("DeploymentMode").equals("dm")
|
||||||
|
resp.should.have.key("EncryptionOptions").equals(
|
||||||
|
{"KmsKeyId": "kms-key", "UseAwsOwnedKey": False}
|
||||||
|
)
|
||||||
|
resp.should.have.key("EngineType").equals("ACTIVEMQ")
|
||||||
|
resp.should.have.key("EngineVersion").equals("version")
|
||||||
|
resp.should.have.key("HostInstanceType").equals("hit")
|
||||||
|
resp.should.have.key("LdapServerMetadata").equals(
|
||||||
|
{
|
||||||
|
"Hosts": ["host1"],
|
||||||
|
"RoleBase": "role_base_thingy",
|
||||||
|
"RoleSearchMatching": "rsm",
|
||||||
|
"ServiceAccountUsername": "sau",
|
||||||
|
"UserBase": "ub",
|
||||||
|
"UserSearchMatching": "usm",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
resp.should.have.key("PubliclyAccessible").equals(True)
|
||||||
|
resp.should.have.key("SecurityGroups").equals(["secgroup1"])
|
||||||
|
resp.should.have.key("StorageType").equals("efs")
|
||||||
|
resp.should.have.key("SubnetIds").equals(["s-id"])
|
||||||
|
resp.should.have.key("Users").equals([{"Username": "admin"}])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_broker_with_defaults():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerInstances").length_of(1)
|
||||||
|
|
||||||
|
resp.should.have.key("Configurations")
|
||||||
|
resp["Configurations"].should.have.key("Current")
|
||||||
|
resp["Configurations"].should.have.key("History").length_of(0)
|
||||||
|
resp["Configurations"].shouldnt.have.key("Pending")
|
||||||
|
|
||||||
|
resp.should.have.key("EncryptionOptions").equals({"UseAwsOwnedKey": True})
|
||||||
|
|
||||||
|
resp.should.have.key("MaintenanceWindowStartTime").equals(
|
||||||
|
{"DayOfWeek": "Sunday", "TimeOfDay": "00:00", "TimeZone": "UTC"}
|
||||||
|
)
|
||||||
|
|
||||||
|
resp.should.have.key("Logs").equals({"Audit": False, "General": False})
|
||||||
|
|
||||||
|
resp.should.have.key("SubnetIds").length_of(1)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_multiple_rabbits():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="CLUSTER_MULTI_AZ",
|
||||||
|
EngineType="RabbitMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerInstances")
|
||||||
|
resp["BrokerInstances"][0]["ConsoleURL"].should.equal(
|
||||||
|
"https://0000.mq.us-east-2.amazonaws.com"
|
||||||
|
)
|
||||||
|
resp["BrokerInstances"][0]["Endpoints"].should.have.length_of(1)
|
||||||
|
resp.shouldnt.have.key("Configurations")
|
||||||
|
resp.should.have.key("Logs").equals({"General": False})
|
||||||
|
resp.should.have.key("SubnetIds").length_of(4)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_active_mq_with_standby():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="ACTIVE_STANDBY_MULTI_AZ",
|
||||||
|
EngineType="ActiveMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
# Instances and subnets in two regions - one active, one standby
|
||||||
|
resp.should.have.key("BrokerInstances").length_of(2)
|
||||||
|
resp.should.have.key("SubnetIds").length_of(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_broker_unknown():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.describe_broker(BrokerId="unknown")
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("NotFoundException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"Can't find requested broker [unknown]. Make sure your broker exists."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_list_brokers_empty():
|
||||||
|
client = boto3.client("mq", region_name="eu-west-1")
|
||||||
|
resp = client.list_brokers()
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerSummaries").equals([])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_list_brokers():
|
||||||
|
client = boto3.client("mq", region_name="eu-west-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.list_brokers()
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerSummaries").length_of(1)
|
||||||
|
|
||||||
|
summary = resp["BrokerSummaries"][0]
|
||||||
|
summary.should.have.key("BrokerArn")
|
||||||
|
summary.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
summary.should.have.key("BrokerName").equals("testbroker")
|
||||||
|
summary.should.have.key("BrokerState").equals("RUNNING")
|
||||||
|
summary.should.have.key("Created")
|
||||||
|
summary.should.have.key("DeploymentMode").equals("dm")
|
||||||
|
summary.should.have.key("EngineType").equals("ACTIVEMQ")
|
||||||
|
summary.should.have.key("HostInstanceType").equals("hit")
|
||||||
|
|
||||||
|
summary.shouldnt.have.key("Users")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_update_broker_single_attribute():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
resp = client.update_broker(AutoMinorVersionUpgrade=True, BrokerId=broker_id)
|
||||||
|
|
||||||
|
# Changed
|
||||||
|
resp.should.have.key("AutoMinorVersionUpgrade").equals(True)
|
||||||
|
|
||||||
|
# Unchanged
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("EngineVersion").equals("version")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_update_broker_multiple_attributes():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
SecurityGroups=["sg-1"],
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
resp = client.update_broker(
|
||||||
|
AutoMinorVersionUpgrade=True,
|
||||||
|
BrokerId=broker_id,
|
||||||
|
Logs={"Audit": True, "General": True},
|
||||||
|
EngineVersion="version2",
|
||||||
|
SecurityGroups=["sg-1", "sg-2"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Changed
|
||||||
|
resp.should.have.key("AutoMinorVersionUpgrade").equals(True)
|
||||||
|
resp.should.have.key("Logs").equals({"Audit": True, "General": True})
|
||||||
|
resp.should.have.key("EngineVersion").equals("version2")
|
||||||
|
resp.should.have.key("SecurityGroups").equals(["sg-1", "sg-2"])
|
||||||
|
|
||||||
|
# Unchanged
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_reboot_broker():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
client.reboot_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
# Noop - nothing to assert or verify
|
||||||
|
pass
|
210
tests/test_mq/test_mq_configuration.py
Normal file
210
tests/test_mq/test_mq_configuration.py
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
"""Unit tests for mq-supported APIs."""
|
||||||
|
import base64
|
||||||
|
|
||||||
|
import boto3
|
||||||
|
import pytest
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
from moto import mock_mq
|
||||||
|
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_mq
|
||||||
|
def test_create_configuration_minimal():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
resp = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ", EngineVersion="rabbit1", Name="myconfig"
|
||||||
|
)
|
||||||
|
|
||||||
|
resp.should.have.key("Id").match("^c-")
|
||||||
|
resp.should.have.key("Arn").equals(
|
||||||
|
f"arn:aws:mq:ap-southeast-1:{ACCOUNT_ID}:configuration:{resp['Id']}"
|
||||||
|
)
|
||||||
|
resp.should.have.key("AuthenticationStrategy").equals("simple")
|
||||||
|
resp.should.have.key("Created")
|
||||||
|
resp.should.have.key("Name").equals("myconfig")
|
||||||
|
resp.should.have.key("LatestRevision")
|
||||||
|
|
||||||
|
revision = resp["LatestRevision"]
|
||||||
|
revision.should.have.key("Created")
|
||||||
|
revision.should.have.key("Description")
|
||||||
|
revision.should.have.key("Revision").equals(1)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_configuration_for_rabbitmq():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.create_configuration(
|
||||||
|
EngineType="RABBITMQ", EngineVersion="rabbit1", Name="myconfig"
|
||||||
|
)
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("BadRequestException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"Broker engine type [RABBITMQ] does not support configuration."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_configuration_for_unknown_engine():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.create_configuration(
|
||||||
|
EngineType="unknown", EngineVersion="rabbit1", Name="myconfig"
|
||||||
|
)
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("BadRequestException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"Broker engine type [unknown] is invalid. Valid values are: [ACTIVEMQ]"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_configuration():
|
||||||
|
client = boto3.client("mq", region_name="eu-north-1")
|
||||||
|
config_id = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ", EngineVersion="active2", Name="myconfig"
|
||||||
|
)["Id"]
|
||||||
|
|
||||||
|
resp = client.describe_configuration(ConfigurationId=config_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Id").match("^c-")
|
||||||
|
resp.should.have.key("Arn").equals(
|
||||||
|
f"arn:aws:mq:eu-north-1:{ACCOUNT_ID}:configuration:{resp['Id']}"
|
||||||
|
)
|
||||||
|
resp.should.have.key("AuthenticationStrategy").equals("simple")
|
||||||
|
resp.should.have.key("Created")
|
||||||
|
resp.should.have.key("Name").equals("myconfig")
|
||||||
|
resp.should.have.key("LatestRevision")
|
||||||
|
|
||||||
|
revision = resp["LatestRevision"]
|
||||||
|
revision.should.have.key("Created")
|
||||||
|
revision.should.have.key("Description")
|
||||||
|
revision.should.have.key("Revision").equals(1)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_configuration_revision():
|
||||||
|
client = boto3.client("mq", region_name="eu-north-1")
|
||||||
|
config_id = client.create_configuration(
|
||||||
|
EngineType="ActiveMQ", EngineVersion="5.16.3", Name="myconfig"
|
||||||
|
)["Id"]
|
||||||
|
|
||||||
|
resp = client.describe_configuration_revision(
|
||||||
|
ConfigurationId=config_id, ConfigurationRevision="1"
|
||||||
|
)
|
||||||
|
|
||||||
|
resp.should.have.key("ConfigurationId").equals(config_id)
|
||||||
|
resp.should.have.key("Created")
|
||||||
|
resp.should.have.key("Description").equals(
|
||||||
|
"Auto-generated default for myconfig on ActiveMQ 5.16.3"
|
||||||
|
)
|
||||||
|
|
||||||
|
resp.should.have.key("Data")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_configuration_unknown():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.describe_configuration(ConfigurationId="c-unknown")
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
|
||||||
|
err["Code"].should.equal("NotFoundException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"Can't find requested configuration [c-unknown]. Make sure your configuration exists."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_list_configurations_empty():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
|
||||||
|
resp = client.list_configurations()
|
||||||
|
|
||||||
|
resp.should.have.key("Configurations").equals([])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_list_configurations():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
config_id = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ", EngineVersion="active1", Name="myconfig"
|
||||||
|
)["Id"]
|
||||||
|
|
||||||
|
resp = client.list_configurations()
|
||||||
|
|
||||||
|
resp.should.have.key("Configurations").length_of(1)
|
||||||
|
|
||||||
|
config = resp["Configurations"][0]
|
||||||
|
config.should.have.key("Arn").match("arn:aws")
|
||||||
|
config.should.have.key("Created")
|
||||||
|
config.should.have.key("Id").equals(config_id)
|
||||||
|
config.should.have.key("Name").equals("myconfig")
|
||||||
|
config.should.have.key("EngineType").equals("ACTIVEMQ")
|
||||||
|
config.should.have.key("EngineVersion").equals("active1")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_update_configuration():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
config_id = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ", EngineVersion="rabbit1", Name="myconfig"
|
||||||
|
)["Id"]
|
||||||
|
|
||||||
|
resp = client.update_configuration(
|
||||||
|
ConfigurationId=config_id,
|
||||||
|
Data="base64encodedxmlconfig",
|
||||||
|
Description="updated config",
|
||||||
|
)
|
||||||
|
|
||||||
|
resp.should.have.key("Arn").match("arn:aws:mq")
|
||||||
|
resp.should.have.key("Created")
|
||||||
|
resp.should.have.key("Id")
|
||||||
|
resp.should.have.key("Name").equals("myconfig")
|
||||||
|
resp.should.have.key("LatestRevision")
|
||||||
|
|
||||||
|
revision = resp["LatestRevision"]
|
||||||
|
revision.should.have.key("Created")
|
||||||
|
revision.should.have.key("Description").equals("updated config")
|
||||||
|
revision.should.have.key("Revision").equals(2)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_update_configuration_to_ldap():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
config_id = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ", EngineVersion="rabbit1", Name="myconfig"
|
||||||
|
)["Id"]
|
||||||
|
|
||||||
|
ldap_config = """<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<broker xmlns="http://activemq.apache.org/schema/core">
|
||||||
|
<plugins>
|
||||||
|
<authorizationPlugin>
|
||||||
|
<map>
|
||||||
|
<cachedLDAPAuthorizationMap legacyGroupMapping="false" queueSearchBase="ou=Queue,ou=Destination,ou=ActiveMQ,dc=example,dc=org" refreshInterval="0" tempSearchBase="ou=Temp,ou=Destination,ou=ActiveMQ,dc=example,dc=org" topicSearchBase="ou=Topic,ou=Destination,ou=ActiveMQ,dc=example,dc=org"/>
|
||||||
|
</map>
|
||||||
|
</authorizationPlugin>
|
||||||
|
<forcePersistencyModeBrokerPlugin persistenceFlag="true"/>
|
||||||
|
<statisticsBrokerPlugin/>
|
||||||
|
<timeStampingBrokerPlugin ttlCeiling="86400000" zeroExpirationOverride="86400000"/>
|
||||||
|
</plugins>
|
||||||
|
</broker>
|
||||||
|
"""
|
||||||
|
|
||||||
|
client.update_configuration(
|
||||||
|
ConfigurationId=config_id,
|
||||||
|
Data=base64.b64encode(ldap_config.encode("utf-8")).decode("utf-8"),
|
||||||
|
Description="update config to use LDAP authorization",
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = client.describe_configuration(ConfigurationId=config_id)
|
||||||
|
|
||||||
|
resp.should.have.key("AuthenticationStrategy").equals("ldap")
|
109
tests/test_mq/test_mq_tags.py
Normal file
109
tests/test_mq/test_mq_tags.py
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import boto3
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
|
||||||
|
from moto import mock_mq
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_broker_with_tags():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="CLUSTER_MULTI_AZ",
|
||||||
|
EngineType="RabbitMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Tags={"key1": "val2", "key2": "val2"},
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Tags").equals({"key1": "val2", "key2": "val2"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_tags():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
resp = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="CLUSTER_MULTI_AZ",
|
||||||
|
EngineType="RabbitMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)
|
||||||
|
|
||||||
|
broker_arn = resp["BrokerArn"]
|
||||||
|
broker_id = resp["BrokerId"]
|
||||||
|
|
||||||
|
client.create_tags(ResourceArn=broker_arn, Tags={"key1": "val2", "key2": "val2"})
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Tags").equals({"key1": "val2", "key2": "val2"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_delete_tags():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
resp = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="CLUSTER_MULTI_AZ",
|
||||||
|
EngineType="RabbitMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)
|
||||||
|
|
||||||
|
broker_arn = resp["BrokerArn"]
|
||||||
|
broker_id = resp["BrokerId"]
|
||||||
|
|
||||||
|
client.create_tags(ResourceArn=broker_arn, Tags={"key1": "val2", "key2": "val2"})
|
||||||
|
|
||||||
|
client.delete_tags(ResourceArn=broker_arn, TagKeys=["key1"])
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Tags").equals({"key2": "val2"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_configuration_with_tags():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
resp = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="rabbit1",
|
||||||
|
Name="myconfig",
|
||||||
|
Tags={"key1": "val1", "key2": "val2"},
|
||||||
|
)
|
||||||
|
|
||||||
|
# The CreateConfiguration call does not return tags
|
||||||
|
resp.shouldnt.have.key("Tags")
|
||||||
|
|
||||||
|
# Only when describing will they be returned
|
||||||
|
resp = client.describe_configuration(ConfigurationId=resp["Id"])
|
||||||
|
resp.should.have.key("Tags").equals({"key1": "val1", "key2": "val2"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_add_tags_to_configuration():
|
||||||
|
client = boto3.client("mq", region_name="ap-southeast-1")
|
||||||
|
resp = client.create_configuration(
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="rabbit1",
|
||||||
|
Name="myconfig",
|
||||||
|
Tags={"key1": "val1", "key2": "val2"},
|
||||||
|
)
|
||||||
|
|
||||||
|
client.create_tags(ResourceArn=resp["Arn"], Tags={"key1": "val1", "key2": "val2"})
|
||||||
|
|
||||||
|
# Only when describing will they be returned
|
||||||
|
resp = client.describe_configuration(ConfigurationId=resp["Id"])
|
||||||
|
resp.should.have.key("Tags").equals({"key1": "val1", "key2": "val2"})
|
172
tests/test_mq/test_mq_users.py
Normal file
172
tests/test_mq/test_mq_users.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
import boto3
|
||||||
|
import pytest
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
from moto import mock_mq
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_create_user():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
client.create_user(BrokerId=broker_id, Username="admin", Password="adm1n")
|
||||||
|
|
||||||
|
resp = client.describe_broker(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("Users").equals([{"Username": "admin"}])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_user():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
client.create_user(
|
||||||
|
BrokerId=broker_id,
|
||||||
|
Username="admin",
|
||||||
|
Password="adm1n",
|
||||||
|
ConsoleAccess=True,
|
||||||
|
Groups=["group1", "group2"],
|
||||||
|
)
|
||||||
|
|
||||||
|
resp = client.describe_user(BrokerId=broker_id, Username="admin")
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("ConsoleAccess").equals(True)
|
||||||
|
resp.should.have.key("Groups").equals(["group1", "group2"])
|
||||||
|
resp.should.have.key("Username").equals("admin")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_describe_user_unknown():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
with pytest.raises(ClientError) as exc:
|
||||||
|
client.describe_user(BrokerId=broker_id, Username="unknown")
|
||||||
|
err = exc.value.response["Error"]
|
||||||
|
err["Code"].should.equal("NotFoundException")
|
||||||
|
err["Message"].should.equal(
|
||||||
|
"Can't find requested user [unknown]. Make sure your user exists."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_list_users_empty():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
resp = client.list_users(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("Users").equals([])
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_list_users():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
client.create_user(BrokerId=broker_id, Username="user1", Password="us3r1")
|
||||||
|
|
||||||
|
resp = client.list_users(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("Users").length_of(2)
|
||||||
|
resp["Users"].should.contain({"Username": "admin"})
|
||||||
|
resp["Users"].should.contain({"Username": "user1"})
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_update_user():
|
||||||
|
client = boto3.client("mq", region_name="us-east-2")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
client.update_user(BrokerId=broker_id, Username="admin", Groups=["administrators"])
|
||||||
|
|
||||||
|
resp = client.describe_user(BrokerId=broker_id, Username="admin")
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("Groups").equals(["administrators"])
|
||||||
|
resp.should.have.key("Username").equals("admin")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_delete_user():
|
||||||
|
client = boto3.client("mq", region_name="us-east-1")
|
||||||
|
broker_id = client.create_broker(
|
||||||
|
AutoMinorVersionUpgrade=False,
|
||||||
|
BrokerName="testbroker",
|
||||||
|
DeploymentMode="dm",
|
||||||
|
EngineType="ACTIVEMQ",
|
||||||
|
EngineVersion="version",
|
||||||
|
HostInstanceType="hit",
|
||||||
|
PubliclyAccessible=True,
|
||||||
|
Users=[{"Username": "admin", "Password": "adm1n"}],
|
||||||
|
)["BrokerId"]
|
||||||
|
|
||||||
|
client.create_user(BrokerId=broker_id, Username="user1", Password="us3r1")
|
||||||
|
|
||||||
|
client.delete_user(BrokerId=broker_id, Username="admin")
|
||||||
|
|
||||||
|
resp = client.list_users(BrokerId=broker_id)
|
||||||
|
|
||||||
|
resp.should.have.key("BrokerId").equals(broker_id)
|
||||||
|
resp.should.have.key("Users").length_of(1)
|
||||||
|
resp["Users"].should.contain({"Username": "user1"})
|
15
tests/test_mq/test_server.py
Normal file
15
tests/test_mq/test_server.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import json
|
||||||
|
import sure # noqa # pylint: disable=unused-import
|
||||||
|
|
||||||
|
from moto import mock_mq
|
||||||
|
import moto.server as server
|
||||||
|
|
||||||
|
|
||||||
|
@mock_mq
|
||||||
|
def test_mq_list():
|
||||||
|
backend = server.create_backend_app("mq")
|
||||||
|
test_client = backend.test_client()
|
||||||
|
|
||||||
|
resp = test_client.get("/v1/brokers")
|
||||||
|
resp.status_code.should.equal(200)
|
||||||
|
json.loads(resp.data).should.equal({"brokerSummaries": []})
|
Loading…
x
Reference in New Issue
Block a user