Fixes and additional tests
This commit is contained in:
parent
4365c2bd4e
commit
5ec814a604
@ -39,6 +39,7 @@ BACKENDS = {
|
|||||||
"kms": ("kms", "kms_backends"),
|
"kms": ("kms", "kms_backends"),
|
||||||
"lambda": ("awslambda", "lambda_backends"),
|
"lambda": ("awslambda", "lambda_backends"),
|
||||||
"logs": ("logs", "logs_backends"),
|
"logs": ("logs", "logs_backends"),
|
||||||
|
"managedblockchain": ("managedblockchain", "managedblockchain_backends"),
|
||||||
"moto_api": ("core", "moto_api_backends"),
|
"moto_api": ("core", "moto_api_backends"),
|
||||||
"opsworks": ("opsworks", "opsworks_backends"),
|
"opsworks": ("opsworks", "opsworks_backends"),
|
||||||
"organizations": ("organizations", "organizations_backends"),
|
"organizations": ("organizations", "organizations_backends"),
|
||||||
|
@ -8,7 +8,7 @@ from moto.core import BaseBackend, BaseModel
|
|||||||
|
|
||||||
from .exceptions import BadRequestException
|
from .exceptions import BadRequestException
|
||||||
|
|
||||||
from .utils import get_network_id
|
from .utils import get_network_id, get_member_id
|
||||||
|
|
||||||
FRAMEWORKS = [
|
FRAMEWORKS = [
|
||||||
"HYPERLEDGER_FABRIC",
|
"HYPERLEDGER_FABRIC",
|
||||||
@ -37,7 +37,7 @@ class ManagedBlockchainNetwork(BaseModel):
|
|||||||
region,
|
region,
|
||||||
description=None,
|
description=None,
|
||||||
):
|
):
|
||||||
self.st = datetime.datetime.now(datetime.timezone.utc)
|
self.creationdate = datetime.datetime.utcnow()
|
||||||
self.id = id
|
self.id = id
|
||||||
self.name = name
|
self.name = name
|
||||||
self.description = description
|
self.description = description
|
||||||
@ -49,19 +49,34 @@ class ManagedBlockchainNetwork(BaseModel):
|
|||||||
self.region = region
|
self.region = region
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
|
# Format for list_networks
|
||||||
|
d = {
|
||||||
|
"Id": self.id,
|
||||||
|
"Name": self.name,
|
||||||
|
"Framework": self.framework,
|
||||||
|
"FrameworkVersion": self.frameworkversion,
|
||||||
|
"Status": "AVAILABLE",
|
||||||
|
"CreationDate": self.creationdate.strftime("%Y-%m-%dT%H:%M:%S.%f%z"),
|
||||||
|
}
|
||||||
|
if self.description is not None:
|
||||||
|
d["Description"] = self.description
|
||||||
|
return d
|
||||||
|
|
||||||
|
def get_format(self):
|
||||||
|
# Format for get_networks
|
||||||
frameworkattributes = {
|
frameworkattributes = {
|
||||||
"Fabric": {
|
"Fabric": {
|
||||||
"OrderingServiceEndpoint": "orderer.{0}.managedblockchain.{1}.amazonaws.com:30001".format(
|
"OrderingServiceEndpoint": "orderer.{0}.managedblockchain.{1}.amazonaws.com:30001".format(
|
||||||
self.id, self.region
|
self.id.lower(), self.region
|
||||||
),
|
),
|
||||||
"Edition": self.frameworkconfiguration["Fabric"]["Edition"],
|
"Edition": self.frameworkconfiguration["Fabric"]["Edition"],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vpcendpointname = "com.amazonaws.{0}.managedblockchain.{1}".format(
|
vpcendpointname = "com.amazonaws.{0}.managedblockchain.{1}".format(
|
||||||
self.region, self.id
|
self.region, self.id.lower()
|
||||||
)
|
)
|
||||||
# Use iso_8601_datetime_with_milliseconds ?
|
|
||||||
d = {
|
d = {
|
||||||
"Id": self.id,
|
"Id": self.id,
|
||||||
"Name": self.name,
|
"Name": self.name,
|
||||||
@ -71,7 +86,7 @@ class ManagedBlockchainNetwork(BaseModel):
|
|||||||
"VpcEndpointServiceName": vpcendpointname,
|
"VpcEndpointServiceName": vpcendpointname,
|
||||||
"VotingPolicy": self.voting_policy,
|
"VotingPolicy": self.voting_policy,
|
||||||
"Status": "AVAILABLE",
|
"Status": "AVAILABLE",
|
||||||
"CreationDate": self.st.strftime("%Y-%m-%dT%H:%M:%S.%f%z"),
|
"CreationDate": self.creationdate.strftime("%Y-%m-%dT%H:%M:%S.%f%z"),
|
||||||
}
|
}
|
||||||
if self.description is not None:
|
if self.description is not None:
|
||||||
d["Description"] = self.description
|
d["Description"] = self.description
|
||||||
@ -90,14 +105,21 @@ class ManagedBlockchainBackend(BaseBackend):
|
|||||||
|
|
||||||
def create_network(
|
def create_network(
|
||||||
self,
|
self,
|
||||||
json_body,
|
name,
|
||||||
|
framework,
|
||||||
|
frameworkversion,
|
||||||
|
frameworkconfiguration,
|
||||||
|
voting_policy,
|
||||||
|
member_configuration,
|
||||||
|
description=None,
|
||||||
):
|
):
|
||||||
name = json_body["Name"]
|
self.name = name
|
||||||
framework = json_body["Framework"]
|
self.framework = framework
|
||||||
frameworkversion = json_body["FrameworkVersion"]
|
self.frameworkversion = frameworkversion
|
||||||
frameworkconfiguration = json_body["FrameworkConfiguration"]
|
self.frameworkconfiguration = frameworkconfiguration
|
||||||
voting_policy = json_body["VotingPolicy"]
|
self.voting_policy = voting_policy
|
||||||
member_configuration = json_body["MemberConfiguration"]
|
self.member_configuration = member_configuration
|
||||||
|
self.description = description
|
||||||
|
|
||||||
# Check framework
|
# Check framework
|
||||||
if framework not in FRAMEWORKS:
|
if framework not in FRAMEWORKS:
|
||||||
@ -119,33 +141,32 @@ class ManagedBlockchainBackend(BaseBackend):
|
|||||||
## Generate network ID
|
## Generate network ID
|
||||||
network_id = get_network_id()
|
network_id = get_network_id()
|
||||||
|
|
||||||
|
## Generate memberid ID - will need to actually create member
|
||||||
|
member_id = get_member_id()
|
||||||
|
|
||||||
self.networks[network_id] = ManagedBlockchainNetwork(
|
self.networks[network_id] = ManagedBlockchainNetwork(
|
||||||
id=network_id,
|
id=network_id,
|
||||||
name=name,
|
name=name,
|
||||||
framework=framework,
|
framework=self.framework,
|
||||||
frameworkversion=frameworkversion,
|
frameworkversion=self.frameworkversion,
|
||||||
frameworkconfiguration=frameworkconfiguration,
|
frameworkconfiguration=self.frameworkconfiguration,
|
||||||
voting_policy=voting_policy,
|
voting_policy=self.voting_policy,
|
||||||
member_configuration=member_configuration,
|
member_configuration=self.member_configuration,
|
||||||
region=self.region_name,
|
region=self.region_name,
|
||||||
|
description=self.description,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Return the network and member ID
|
||||||
|
d = {"NetworkId": network_id, "MemberId": member_id}
|
||||||
|
return d
|
||||||
|
|
||||||
def list_networks(self):
|
def list_networks(self):
|
||||||
return self.networks.values()
|
return self.networks.values()
|
||||||
|
|
||||||
def get_network(self, network_id):
|
def get_network(self, network_id):
|
||||||
return self.networks[network_id]
|
return self.networks.get(network_id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
managedblockchain_backends = {}
|
managedblockchain_backends = {}
|
||||||
for region in Session().get_available_regions("managedblockchain"):
|
for region in Session().get_available_regions("managedblockchain"):
|
||||||
managedblockchain_backends[region] = ManagedBlockchainBackend(region)
|
managedblockchain_backends[region] = ManagedBlockchainBackend(region)
|
||||||
for region in Session().get_available_regions(
|
|
||||||
"managedblockchain", partition_name="aws-us-gov"
|
|
||||||
):
|
|
||||||
managedblockchain_backends[region] = ManagedBlockchainBackend(region)
|
|
||||||
for region in Session().get_available_regions(
|
|
||||||
"managedblockchain", partition_name="aws-cn"
|
|
||||||
):
|
|
||||||
managedblockchain_backends[region] = ManagedBlockchainBackend(region)
|
|
||||||
|
@ -5,7 +5,10 @@ from six.moves.urllib.parse import urlparse, parse_qs
|
|||||||
|
|
||||||
from moto.core.responses import BaseResponse
|
from moto.core.responses import BaseResponse
|
||||||
from .models import managedblockchain_backends
|
from .models import managedblockchain_backends
|
||||||
from .utils import region_from_managedblckchain_url, networkid_from_managedblockchain_url
|
from .utils import (
|
||||||
|
region_from_managedblckchain_url,
|
||||||
|
networkid_from_managedblockchain_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ManagedBlockchainResponse(BaseResponse):
|
class ManagedBlockchainResponse(BaseResponse):
|
||||||
@ -16,7 +19,9 @@ class ManagedBlockchainResponse(BaseResponse):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def network_response(clazz, request, full_url, headers):
|
def network_response(clazz, request, full_url, headers):
|
||||||
region_name = region_from_managedblckchain_url(full_url)
|
region_name = region_from_managedblckchain_url(full_url)
|
||||||
response_instance = ManagedBlockchainResponse(managedblockchain_backends[region_name])
|
response_instance = ManagedBlockchainResponse(
|
||||||
|
managedblockchain_backends[region_name]
|
||||||
|
)
|
||||||
return response_instance._network_response(request, full_url, headers)
|
return response_instance._network_response(request, full_url, headers)
|
||||||
|
|
||||||
def _network_response(self, request, full_url, headers):
|
def _network_response(self, request, full_url, headers):
|
||||||
@ -42,13 +47,35 @@ class ManagedBlockchainResponse(BaseResponse):
|
|||||||
return 200, headers, response
|
return 200, headers, response
|
||||||
|
|
||||||
def _network_response_post(self, json_body, querystring, headers):
|
def _network_response_post(self, json_body, querystring, headers):
|
||||||
self.backend.create_network(json_body)
|
name = json_body["Name"]
|
||||||
return 201, headers, ""
|
framework = json_body["Framework"]
|
||||||
|
frameworkversion = json_body["FrameworkVersion"]
|
||||||
|
frameworkconfiguration = json_body["FrameworkConfiguration"]
|
||||||
|
voting_policy = json_body["VotingPolicy"]
|
||||||
|
member_configuration = json_body["MemberConfiguration"]
|
||||||
|
|
||||||
|
# Optional
|
||||||
|
description = None
|
||||||
|
if "Description" in json_body:
|
||||||
|
description = json_body["Description"]
|
||||||
|
|
||||||
|
response = self.backend.create_network(
|
||||||
|
name,
|
||||||
|
framework,
|
||||||
|
frameworkversion,
|
||||||
|
frameworkconfiguration,
|
||||||
|
voting_policy,
|
||||||
|
member_configuration,
|
||||||
|
description,
|
||||||
|
)
|
||||||
|
return 201, headers, json.dumps(response)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def networkid_response(clazz, request, full_url, headers):
|
def networkid_response(clazz, request, full_url, headers):
|
||||||
region_name = region_from_managedblckchain_url(full_url)
|
region_name = region_from_managedblckchain_url(full_url)
|
||||||
response_instance = ManagedBlockchainResponse(managedblockchain_backends[region_name])
|
response_instance = ManagedBlockchainResponse(
|
||||||
|
managedblockchain_backends[region_name]
|
||||||
|
)
|
||||||
return response_instance._networkid_response(request, full_url, headers)
|
return response_instance._networkid_response(request, full_url, headers)
|
||||||
|
|
||||||
def _networkid_response(self, request, full_url, headers):
|
def _networkid_response(self, request, full_url, headers):
|
||||||
@ -60,8 +87,6 @@ class ManagedBlockchainResponse(BaseResponse):
|
|||||||
|
|
||||||
def _networkid_response_get(self, network_id, headers):
|
def _networkid_response_get(self, network_id, headers):
|
||||||
mbcnetwork = self.backend.get_network(network_id)
|
mbcnetwork = self.backend.get_network(network_id)
|
||||||
response = json.dumps(
|
response = json.dumps({"Network": mbcnetwork.get_format()})
|
||||||
{"Network": mbcnetwork.to_dict()}
|
|
||||||
)
|
|
||||||
headers["content-type"] = "application/json"
|
headers["content-type"] = "application/json"
|
||||||
return 200, headers, response
|
return 200, headers, response
|
||||||
|
@ -21,3 +21,9 @@ def get_network_id():
|
|||||||
return "n-" + "".join(
|
return "n-" + "".join(
|
||||||
random.choice(string.ascii_uppercase + string.digits) for _ in range(26)
|
random.choice(string.ascii_uppercase + string.digits) for _ in range(26)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_member_id():
|
||||||
|
return "m-" + "".join(
|
||||||
|
random.choice(string.ascii_uppercase + string.digits) for _ in range(26)
|
||||||
|
)
|
||||||
|
@ -3,43 +3,46 @@ from __future__ import unicode_literals
|
|||||||
import boto3
|
import boto3
|
||||||
import sure # noqa
|
import sure # noqa
|
||||||
|
|
||||||
|
from moto.managedblockchain.exceptions import BadRequestException
|
||||||
from moto import mock_managedblockchain
|
from moto import mock_managedblockchain
|
||||||
|
|
||||||
|
|
||||||
|
default_frameworkconfiguration = {"Fabric": {"Edition": "STARTER"}}
|
||||||
|
|
||||||
|
default_votingpolicy = {
|
||||||
|
"ApprovalThresholdPolicy": {
|
||||||
|
"ThresholdPercentage": 50,
|
||||||
|
"ProposalDurationInHours": 24,
|
||||||
|
"ThresholdComparator": "GREATER_THAN_OR_EQUAL_TO",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default_memberconfiguration = {
|
||||||
|
"Name": "testmember1",
|
||||||
|
"Description": "Test Member 1",
|
||||||
|
"FrameworkConfiguration": {
|
||||||
|
"Fabric": {"AdminUsername": "admin", "AdminPassword": "Admin12345"}
|
||||||
|
},
|
||||||
|
"LogPublishingConfiguration": {
|
||||||
|
"Fabric": {"CaLogs": {"Cloudwatch": {"Enabled": False}}}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@mock_managedblockchain
|
@mock_managedblockchain
|
||||||
def test_create_network():
|
def test_create_network():
|
||||||
conn = boto3.client("managedblockchain", region_name="us-east-1")
|
conn = boto3.client("managedblockchain", region_name="us-east-1")
|
||||||
|
|
||||||
frameworkconfiguration = {"Fabric": {"Edition": "STARTER"}}
|
response = conn.create_network(
|
||||||
|
|
||||||
votingpolicy = {
|
|
||||||
"ApprovalThresholdPolicy": {
|
|
||||||
"ThresholdPercentage": 50,
|
|
||||||
"ProposalDurationInHours": 24,
|
|
||||||
"ThresholdComparator": "GREATER_THAN_OR_EQUAL_TO",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memberconfiguration = {
|
|
||||||
"Name": "testmember1",
|
|
||||||
"Description": "Test Member 1",
|
|
||||||
"FrameworkConfiguration": {
|
|
||||||
"Fabric": {"AdminUsername": "admin", "AdminPassword": "Admin12345"}
|
|
||||||
},
|
|
||||||
"LogPublishingConfiguration": {
|
|
||||||
"Fabric": {"CaLogs": {"Cloudwatch": {"Enabled": False}}}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
conn.create_network(
|
|
||||||
Name="testnetwork1",
|
Name="testnetwork1",
|
||||||
Description="Test Network 1",
|
|
||||||
Framework="HYPERLEDGER_FABRIC",
|
Framework="HYPERLEDGER_FABRIC",
|
||||||
FrameworkVersion="1.2",
|
FrameworkVersion="1.2",
|
||||||
FrameworkConfiguration=frameworkconfiguration,
|
FrameworkConfiguration=default_frameworkconfiguration,
|
||||||
VotingPolicy=votingpolicy,
|
VotingPolicy=default_votingpolicy,
|
||||||
MemberConfiguration=memberconfiguration,
|
MemberConfiguration=default_memberconfiguration,
|
||||||
)
|
)
|
||||||
|
response["NetworkId"].should.match("n-[A-Z0-9]{26}")
|
||||||
|
response["MemberId"].should.match("m-[A-Z0-9]{26}")
|
||||||
|
|
||||||
# Find in full list
|
# Find in full list
|
||||||
response = conn.list_networks()
|
response = conn.list_networks()
|
||||||
@ -51,3 +54,80 @@ def test_create_network():
|
|||||||
network_id = mbcnetworks[0]["Id"]
|
network_id = mbcnetworks[0]["Id"]
|
||||||
response = conn.get_network(NetworkId=network_id)
|
response = conn.get_network(NetworkId=network_id)
|
||||||
response["Network"]["Name"].should.equal("testnetwork1")
|
response["Network"]["Name"].should.equal("testnetwork1")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_managedblockchain
|
||||||
|
def test_create_network_withopts():
|
||||||
|
conn = boto3.client("managedblockchain", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = conn.create_network(
|
||||||
|
Name="testnetwork1",
|
||||||
|
Description="Test Network 1",
|
||||||
|
Framework="HYPERLEDGER_FABRIC",
|
||||||
|
FrameworkVersion="1.2",
|
||||||
|
FrameworkConfiguration=default_frameworkconfiguration,
|
||||||
|
VotingPolicy=default_votingpolicy,
|
||||||
|
MemberConfiguration=default_memberconfiguration,
|
||||||
|
)
|
||||||
|
response["NetworkId"].should.match("n-[A-Z0-9]{26}")
|
||||||
|
response["MemberId"].should.match("m-[A-Z0-9]{26}")
|
||||||
|
|
||||||
|
# Find in full list
|
||||||
|
response = conn.list_networks()
|
||||||
|
mbcnetworks = response["Networks"]
|
||||||
|
mbcnetworks.should.have.length_of(1)
|
||||||
|
mbcnetworks[0]["Description"].should.equal("Test Network 1")
|
||||||
|
|
||||||
|
# Get network details
|
||||||
|
network_id = mbcnetworks[0]["Id"]
|
||||||
|
response = conn.get_network(NetworkId=network_id)
|
||||||
|
response["Network"]["Description"].should.equal("Test Network 1")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_managedblockchain
|
||||||
|
def test_create_network_noframework():
|
||||||
|
conn = boto3.client("managedblockchain", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = conn.create_network.when.called_with(
|
||||||
|
Name="testnetwork1",
|
||||||
|
Description="Test Network 1",
|
||||||
|
Framework="HYPERLEDGER_VINYL",
|
||||||
|
FrameworkVersion="1.2",
|
||||||
|
FrameworkConfiguration=default_frameworkconfiguration,
|
||||||
|
VotingPolicy=default_votingpolicy,
|
||||||
|
MemberConfiguration=default_memberconfiguration,
|
||||||
|
).should.throw(Exception, "Invalid request body")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_managedblockchain
|
||||||
|
def test_create_network_badframeworkver():
|
||||||
|
conn = boto3.client("managedblockchain", region_name="us-east-1")
|
||||||
|
|
||||||
|
response = conn.create_network.when.called_with(
|
||||||
|
Name="testnetwork1",
|
||||||
|
Description="Test Network 1",
|
||||||
|
Framework="HYPERLEDGER_FABRIC",
|
||||||
|
FrameworkVersion="1.X",
|
||||||
|
FrameworkConfiguration=default_frameworkconfiguration,
|
||||||
|
VotingPolicy=default_votingpolicy,
|
||||||
|
MemberConfiguration=default_memberconfiguration,
|
||||||
|
).should.throw(
|
||||||
|
Exception, "Invalid version 1.X requested for framework HYPERLEDGER_FABRIC"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_managedblockchain
|
||||||
|
def test_create_network_badedition():
|
||||||
|
conn = boto3.client("managedblockchain", region_name="us-east-1")
|
||||||
|
|
||||||
|
frameworkconfiguration = {"Fabric": {"Edition": "SUPER"}}
|
||||||
|
|
||||||
|
response = conn.create_network.when.called_with(
|
||||||
|
Name="testnetwork1",
|
||||||
|
Description="Test Network 1",
|
||||||
|
Framework="HYPERLEDGER_FABRIC",
|
||||||
|
FrameworkVersion="1.2",
|
||||||
|
FrameworkConfiguration=frameworkconfiguration,
|
||||||
|
VotingPolicy=default_votingpolicy,
|
||||||
|
MemberConfiguration=default_memberconfiguration,
|
||||||
|
).should.throw(Exception, "Invalid request body")
|
||||||
|
Loading…
Reference in New Issue
Block a user