2020-05-03 18:13:40 -05:00
import datetime
2020-05-13 06:28:22 -05:00
import re
2023-03-27 18:00:24 +01:00
from typing import Any , Dict , List , Optional
2020-05-03 18:13:40 -05:00
2022-11-10 08:43:20 -01:00
from moto . core import BaseBackend , BackendDict , BaseModel
2020-05-03 18:13:40 -05:00
2020-05-13 06:28:22 -05:00
from . exceptions import (
BadRequestException ,
ResourceNotFoundException ,
InvalidRequestException ,
ResourceLimitExceededException ,
2020-05-15 19:38:19 -05:00
ResourceAlreadyExistsException ,
2020-05-13 06:28:22 -05:00
)
2020-05-03 18:13:40 -05:00
2020-05-13 06:28:22 -05:00
from . utils import (
get_network_id ,
get_member_id ,
get_proposal_id ,
get_invitation_id ,
member_name_exist_in_network ,
number_of_members_in_network ,
admin_password_ok ,
2020-05-15 19:38:19 -05:00
get_node_id ,
number_of_nodes_in_member ,
nodes_in_member ,
2020-05-13 06:28:22 -05:00
)
2020-05-03 18:13:40 -05:00
FRAMEWORKS = [
" HYPERLEDGER_FABRIC " ,
]
FRAMEWORKVERSIONS = [
" 1.2 " ,
]
2023-03-27 18:00:24 +01:00
EDITIONS : Dict [ str , Any ] = {
2020-05-13 06:28:22 -05:00
" STARTER " : {
" MaxMembers " : 5 ,
" MaxNodesPerMember " : 2 ,
" AllowedNodeInstanceTypes " : [ " bc.t3.small " , " bc.t3.medium " ] ,
} ,
" STANDARD " : {
" MaxMembers " : 14 ,
" MaxNodesPerMember " : 3 ,
" AllowedNodeInstanceTypes " : [ " bc.t3 " , " bc.m5 " , " bc.c5 " ] ,
} ,
}
VOTEVALUES = [ " YES " , " NO " ]
2020-05-03 18:13:40 -05:00
class ManagedBlockchainNetwork ( BaseModel ) :
def __init__ (
self ,
2023-03-27 18:00:24 +01:00
network_id : str ,
name : str ,
framework : str ,
frameworkversion : str ,
frameworkconfiguration : Dict [ str , Any ] ,
voting_policy : Dict [ str , Any ] ,
member_configuration : Dict [ str , Any ] ,
region : str ,
description : Optional [ str ] = None ,
2020-05-03 18:13:40 -05:00
) :
2020-05-06 21:12:48 -05:00
self . creationdate = datetime . datetime . utcnow ( )
2022-01-14 18:51:49 -01:00
self . id = network_id
2020-05-03 18:13:40 -05:00
self . name = name
self . description = description
self . framework = framework
self . frameworkversion = frameworkversion
self . frameworkconfiguration = frameworkconfiguration
self . voting_policy = voting_policy
self . member_configuration = member_configuration
self . region = region
2020-05-13 06:28:22 -05:00
@property
2023-03-27 18:00:24 +01:00
def network_name ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . name
@property
2023-03-27 18:00:24 +01:00
def network_framework ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . framework
@property
2023-03-27 18:00:24 +01:00
def network_framework_version ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . frameworkversion
@property
2023-03-27 18:00:24 +01:00
def network_creationdate ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " )
@property
2023-03-27 18:00:24 +01:00
def network_description ( self ) - > Optional [ str ] :
2020-05-13 06:28:22 -05:00
return self . description
@property
2023-03-27 18:00:24 +01:00
def network_edition ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . frameworkconfiguration [ " Fabric " ] [ " Edition " ]
@property
2023-03-27 18:00:24 +01:00
def vote_pol_proposal_duration ( self ) - > float :
2020-05-13 06:28:22 -05:00
return self . voting_policy [ " ApprovalThresholdPolicy " ] [ " ProposalDurationInHours " ]
@property
2023-03-27 18:00:24 +01:00
def vote_pol_threshold_percentage ( self ) - > float :
2020-05-13 06:28:22 -05:00
return self . voting_policy [ " ApprovalThresholdPolicy " ] [ " ThresholdPercentage " ]
@property
2023-03-27 18:00:24 +01:00
def vote_pol_threshold_comparator ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . voting_policy [ " ApprovalThresholdPolicy " ] [ " ThresholdComparator " ]
2023-03-27 18:00:24 +01:00
def to_dict ( self ) - > Dict [ str , Any ] :
2020-05-06 21:12:48 -05:00
# 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- %d T % H: % M: % S. %f % z " ) ,
}
if self . description is not None :
d [ " Description " ] = self . description
return d
2023-03-27 18:00:24 +01:00
def get_format ( self ) - > Dict [ str , Any ] :
2020-05-13 06:28:22 -05:00
# Format for get_network
2020-05-03 18:13:40 -05:00
frameworkattributes = {
" Fabric " : {
2022-11-19 23:12:31 -01:00
" OrderingServiceEndpoint " : f " orderer. { self . id . lower ( ) } .managedblockchain. { self . region } .amazonaws.com:30001 " ,
2020-05-03 18:13:40 -05:00
" Edition " : self . frameworkconfiguration [ " Fabric " ] [ " Edition " ] ,
}
}
2022-11-19 23:12:31 -01:00
vpcendpointname = (
f " com.amazonaws. { self . region } .managedblockchain. { self . id . lower ( ) } "
2020-05-03 18:13:40 -05:00
)
2020-05-06 21:12:48 -05:00
2020-05-03 18:13:40 -05:00
d = {
" Id " : self . id ,
" Name " : self . name ,
" Framework " : self . framework ,
" FrameworkVersion " : self . frameworkversion ,
" FrameworkAttributes " : frameworkattributes ,
" VpcEndpointServiceName " : vpcendpointname ,
" VotingPolicy " : self . voting_policy ,
" Status " : " AVAILABLE " ,
2020-05-06 21:12:48 -05:00
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2020-05-03 18:13:40 -05:00
}
if self . description is not None :
d [ " Description " ] = self . description
return d
2020-05-13 06:28:22 -05:00
class ManagedBlockchainProposal ( BaseModel ) :
def __init__ (
self ,
2023-03-27 18:00:24 +01:00
proposal_id : str ,
networkid : str ,
memberid : str ,
membername : str ,
numofmembers : int ,
actions : Dict [ str , Any ] ,
network_expiration : float ,
network_threshold : float ,
network_threshold_comp : str ,
description : Optional [ str ] = None ,
2020-05-13 06:28:22 -05:00
) :
# In general, passing all values instead of creating
# an apparatus to look them up
2022-01-14 18:51:49 -01:00
self . id = proposal_id
2020-05-13 06:28:22 -05:00
self . networkid = networkid
self . memberid = memberid
self . membername = membername
self . numofmembers = numofmembers
self . actions = actions
2023-03-27 18:00:24 +01:00
self . network_expiration = network_expiration
2020-05-13 06:28:22 -05:00
self . network_threshold = network_threshold
self . network_threshold_comp = network_threshold_comp
self . description = description
self . creationdate = datetime . datetime . utcnow ( )
2023-03-27 18:00:24 +01:00
self . expirationdate = self . creationdate + datetime . timedelta (
hours = network_expiration
2020-05-13 06:28:22 -05:00
)
self . yes_vote_count = 0
self . no_vote_count = 0
self . outstanding_vote_count = self . numofmembers
self . status = " IN_PROGRESS "
2023-03-27 18:00:24 +01:00
self . votes : Dict [ str , Dict [ str , str ] ] = { }
2020-05-13 06:28:22 -05:00
@property
2023-03-27 18:00:24 +01:00
def network_id ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . networkid
@property
2023-03-27 18:00:24 +01:00
def proposal_status ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . status
@property
2023-03-27 18:00:24 +01:00
def proposal_votes ( self ) - > Dict [ str , Any ] : # type: ignore[misc]
2020-05-13 06:28:22 -05:00
return self . votes
2023-03-27 18:00:24 +01:00
def proposal_actions ( self , action_type : str ) - > List [ Dict [ str , Any ] ] :
2020-05-13 06:28:22 -05:00
if action_type . lower ( ) == " invitations " :
if " Invitations " in self . actions :
return self . actions [ " Invitations " ]
elif action_type . lower ( ) == " removals " :
if " Removals " in self . actions :
return self . actions [ " Removals " ]
2023-03-27 18:00:24 +01:00
return [ ]
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def check_to_expire_proposal ( self ) - > None :
if datetime . datetime . utcnow ( ) > self . expirationdate :
2020-05-15 19:38:19 -05:00
self . status = " EXPIRED "
2023-03-27 18:00:24 +01:00
def to_dict ( self ) - > Dict [ str , Any ] :
2020-05-13 06:28:22 -05:00
# Format for list_proposals
2023-03-27 18:00:24 +01:00
return {
2020-05-13 06:28:22 -05:00
" ProposalId " : self . id ,
" ProposedByMemberId " : self . memberid ,
" ProposedByMemberName " : self . membername ,
" Status " : self . status ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2023-03-27 18:00:24 +01:00
" ExpirationDate " : self . expirationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2020-05-13 06:28:22 -05:00
}
2023-03-27 18:00:24 +01:00
def get_format ( self ) - > Dict [ str , Any ] :
2020-05-13 06:28:22 -05:00
# Format for get_proposal
d = {
" ProposalId " : self . id ,
" NetworkId " : self . networkid ,
" Actions " : self . actions ,
" ProposedByMemberId " : self . memberid ,
" ProposedByMemberName " : self . membername ,
" Status " : self . status ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2023-03-27 18:00:24 +01:00
" ExpirationDate " : self . expirationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2020-05-13 06:28:22 -05:00
" YesVoteCount " : self . yes_vote_count ,
" NoVoteCount " : self . no_vote_count ,
" OutstandingVoteCount " : self . outstanding_vote_count ,
}
if self . description is not None :
d [ " Description " ] = self . description
return d
2023-03-27 18:00:24 +01:00
def set_vote ( self , votermemberid : str , votermembername : str , vote : str ) - > None :
2020-05-13 06:28:22 -05:00
if vote . upper ( ) == " YES " :
self . yes_vote_count + = 1
else :
self . no_vote_count + = 1
self . outstanding_vote_count - = 1
perct_yes = ( self . yes_vote_count / self . numofmembers ) * 100
perct_no = ( self . no_vote_count / self . numofmembers ) * 100
self . votes [ votermemberid ] = {
" MemberId " : votermemberid ,
" MemberName " : votermembername ,
" Vote " : vote . upper ( ) ,
}
if self . network_threshold_comp == " GREATER_THAN_OR_EQUAL_TO " :
if perct_yes > = self . network_threshold :
self . status = " APPROVED "
elif perct_no > = self . network_threshold :
self . status = " REJECTED "
else :
if perct_yes > self . network_threshold :
self . status = " APPROVED "
elif perct_no > self . network_threshold :
self . status = " REJECTED "
2020-05-15 19:38:19 -05:00
# It is a tie - reject
if (
self . status == " IN_PROGRESS "
and self . network_threshold_comp == " GREATER_THAN "
and self . outstanding_vote_count == 0
and perct_yes == perct_no
) :
self . status = " REJECTED "
2020-05-13 06:28:22 -05:00
class ManagedBlockchainInvitation ( BaseModel ) :
def __init__ (
self ,
2023-03-27 18:00:24 +01:00
invitation_id : str ,
networkid : str ,
networkname : str ,
networkframework : str ,
networkframeworkversion : str ,
networkcreationdate : str ,
region : str ,
networkdescription : Optional [ str ] = None ,
2020-05-13 06:28:22 -05:00
) :
2022-01-14 18:51:49 -01:00
self . id = invitation_id
2020-05-13 06:28:22 -05:00
self . networkid = networkid
self . networkname = networkname
self . networkdescription = networkdescription
self . networkframework = networkframework
self . networkframeworkversion = networkframeworkversion
self . networkstatus = " AVAILABLE "
self . networkcreationdate = networkcreationdate
self . status = " PENDING "
self . region = region
self . creationdate = datetime . datetime . utcnow ( )
2023-03-27 18:00:24 +01:00
self . expirationdate = self . creationdate + datetime . timedelta ( days = 7 )
2020-05-13 06:28:22 -05:00
@property
2023-03-27 18:00:24 +01:00
def invitation_status ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . status
@property
2023-03-27 18:00:24 +01:00
def invitation_networkid ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . networkid
2023-03-27 18:00:24 +01:00
def to_dict ( self ) - > Dict [ str , Any ] :
d : Dict [ str , Any ] = {
2020-05-13 06:28:22 -05:00
" InvitationId " : self . id ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2023-03-27 18:00:24 +01:00
" ExpirationDate " : self . expirationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
2020-05-13 06:28:22 -05:00
" Status " : self . status ,
" NetworkSummary " : {
" Id " : self . networkid ,
" Name " : self . networkname ,
" Framework " : self . networkframework ,
" FrameworkVersion " : self . networkframeworkversion ,
" Status " : self . networkstatus ,
" CreationDate " : self . networkcreationdate ,
} ,
}
if self . networkdescription is not None :
d [ " NetworkSummary " ] [ " Description " ] = self . networkdescription
return d
2023-03-27 18:00:24 +01:00
def accept_invitation ( self ) - > None :
2020-05-13 06:28:22 -05:00
self . status = " ACCEPTED "
2023-03-27 18:00:24 +01:00
def reject_invitation ( self ) - > None :
2020-05-13 06:28:22 -05:00
self . status = " REJECTED "
2023-03-27 18:00:24 +01:00
def set_network_status ( self , network_status : str ) - > None :
2020-05-13 06:28:22 -05:00
self . networkstatus = network_status
class ManagedBlockchainMember ( BaseModel ) :
2023-03-27 18:00:24 +01:00
def __init__ (
self ,
member_id : str ,
networkid : str ,
member_configuration : Dict [ str , Any ] ,
region : str ,
) :
2020-05-13 06:28:22 -05:00
self . creationdate = datetime . datetime . utcnow ( )
2022-01-14 18:51:49 -01:00
self . id = member_id
2020-05-13 06:28:22 -05:00
self . networkid = networkid
self . member_configuration = member_configuration
self . status = " AVAILABLE "
self . region = region
self . description = None
@property
2023-03-27 18:00:24 +01:00
def network_id ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . networkid
@property
2023-03-27 18:00:24 +01:00
def name ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . member_configuration [ " Name " ]
@property
2023-03-27 18:00:24 +01:00
def member_status ( self ) - > str :
2020-05-13 06:28:22 -05:00
return self . status
2023-03-27 18:00:24 +01:00
def to_dict ( self ) - > Dict [ str , Any ] :
2020-05-13 06:28:22 -05:00
# Format for list_members
d = {
" Id " : self . id ,
" Name " : self . member_configuration [ " Name " ] ,
" Status " : self . status ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
" IsOwned " : True ,
}
if " Description " in self . member_configuration :
self . description = self . member_configuration [ " Description " ]
return d
2023-03-27 18:00:24 +01:00
def get_format ( self ) - > Dict [ str , Any ] :
2020-05-13 06:28:22 -05:00
# Format for get_member
frameworkattributes = {
" Fabric " : {
" AdminUsername " : self . member_configuration [ " FrameworkConfiguration " ] [
" Fabric "
] [ " AdminUsername " ] ,
2022-11-19 23:12:31 -01:00
" CaEndpoint " : f " ca. { self . id . lower ( ) } . { self . networkid . lower ( ) } .managedblockchain. { self . region } .amazonaws.com:30002 " ,
2020-05-13 06:28:22 -05:00
}
}
d = {
" NetworkId " : self . networkid ,
" Id " : self . id ,
" Name " : self . name ,
" FrameworkAttributes " : frameworkattributes ,
" LogPublishingConfiguration " : self . member_configuration [
" LogPublishingConfiguration "
] ,
" Status " : self . status ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
}
if " Description " in self . member_configuration :
d [ " Description " ] = self . description
return d
2023-03-27 18:00:24 +01:00
def delete ( self ) - > None :
2020-05-13 06:28:22 -05:00
self . status = " DELETED "
2023-03-27 18:00:24 +01:00
def update ( self , logpublishingconfiguration : Dict [ str , Any ] ) - > None :
2020-05-13 06:28:22 -05:00
self . member_configuration [
" LogPublishingConfiguration "
] = logpublishingconfiguration
2020-05-15 19:38:19 -05:00
class ManagedBlockchainNode ( BaseModel ) :
def __init__ (
self ,
2023-03-27 18:00:24 +01:00
node_id : str ,
networkid : str ,
memberid : str ,
availabilityzone : str ,
instancetype : str ,
logpublishingconfiguration : Dict [ str , Any ] ,
region : str ,
2020-05-15 19:38:19 -05:00
) :
self . creationdate = datetime . datetime . utcnow ( )
2022-01-14 18:51:49 -01:00
self . id = node_id
2020-05-15 19:38:19 -05:00
self . instancetype = instancetype
self . networkid = networkid
self . memberid = memberid
self . logpublishingconfiguration = logpublishingconfiguration
self . region = region
self . status = " AVAILABLE "
self . availabilityzone = availabilityzone
@property
2023-03-27 18:00:24 +01:00
def member_id ( self ) - > str :
2020-05-15 19:38:19 -05:00
return self . memberid
@property
2023-03-27 18:00:24 +01:00
def node_status ( self ) - > str :
2020-05-15 19:38:19 -05:00
return self . status
2023-03-27 18:00:24 +01:00
def to_dict ( self ) - > Dict [ str , Any ] :
2020-05-15 19:38:19 -05:00
# Format for list_nodes
2023-03-27 18:00:24 +01:00
return {
2020-05-15 19:38:19 -05:00
" Id " : self . id ,
" Status " : self . status ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
" AvailabilityZone " : self . availabilityzone ,
" InstanceType " : self . instancetype ,
}
2023-03-27 18:00:24 +01:00
def get_format ( self ) - > Dict [ str , Any ] :
2020-05-15 19:38:19 -05:00
# Format for get_node
frameworkattributes = {
" Fabric " : {
2022-11-19 23:12:31 -01:00
" PeerEndpoint " : f " { self . id . lower ( ) } . { self . networkid . lower ( ) } . { self . memberid . lower ( ) } .managedblockchain. { self . region } .amazonaws.com:30003 " ,
" PeerEventEndpoint " : f " { self . id . lower ( ) } . { self . networkid . lower ( ) } . { self . memberid . lower ( ) } .managedblockchain. { self . region } .amazonaws.com:30004 " ,
2020-05-15 19:38:19 -05:00
}
}
2023-03-27 18:00:24 +01:00
return {
2020-05-15 19:38:19 -05:00
" NetworkId " : self . networkid ,
" MemberId " : self . memberid ,
" Id " : self . id ,
" InstanceType " : self . instancetype ,
" AvailabilityZone " : self . availabilityzone ,
" FrameworkAttributes " : frameworkattributes ,
" LogPublishingConfiguration " : self . logpublishingconfiguration ,
" Status " : self . status ,
" CreationDate " : self . creationdate . strftime ( " % Y- % m- %d T % H: % M: % S. %f % z " ) ,
}
2023-03-27 18:00:24 +01:00
def delete ( self ) - > None :
2020-05-15 19:38:19 -05:00
self . status = " DELETED "
2023-03-27 18:00:24 +01:00
def update ( self , logpublishingconfiguration : Dict [ str , Any ] ) - > None :
2020-05-15 19:38:19 -05:00
self . logpublishingconfiguration = logpublishingconfiguration
2020-05-03 18:13:40 -05:00
class ManagedBlockchainBackend ( BaseBackend ) :
2023-03-27 18:00:24 +01:00
def __init__ ( self , region_name : str , account_id : str ) :
2022-06-04 11:30:16 +00:00
super ( ) . __init__ ( region_name , account_id )
2023-03-27 18:00:24 +01:00
self . networks : Dict [ str , ManagedBlockchainNetwork ] = { }
self . members : Dict [ str , ManagedBlockchainMember ] = { }
self . proposals : Dict [ str , ManagedBlockchainProposal ] = { }
self . invitations : Dict [ str , ManagedBlockchainInvitation ] = { }
self . nodes : Dict [ str , ManagedBlockchainNode ] = { }
2020-05-03 18:13:40 -05:00
def create_network (
self ,
2023-03-27 18:00:24 +01:00
name : str ,
framework : str ,
frameworkversion : str ,
frameworkconfiguration : Dict [ str , Any ] ,
voting_policy : Dict [ str , Any ] ,
member_configuration : Dict [ str , Any ] ,
description : Optional [ str ] = None ,
) - > Dict [ str , str ] :
2020-05-03 18:13:40 -05:00
# Check framework
if framework not in FRAMEWORKS :
raise BadRequestException ( " CreateNetwork " , " Invalid request body " )
# Check framework version
if frameworkversion not in FRAMEWORKVERSIONS :
raise BadRequestException (
" CreateNetwork " ,
2022-11-19 23:12:31 -01:00
f " Invalid version { frameworkversion } requested for framework HYPERLEDGER_FABRIC " ,
2020-05-03 18:13:40 -05:00
)
# Check edition
if frameworkconfiguration [ " Fabric " ] [ " Edition " ] not in EDITIONS :
raise BadRequestException ( " CreateNetwork " , " Invalid request body " )
2020-05-15 19:38:19 -05:00
# Generate network ID
2020-05-03 18:13:40 -05:00
network_id = get_network_id ( )
2020-05-15 19:38:19 -05:00
# Generate memberid ID and initial member
2020-05-06 21:12:48 -05:00
member_id = get_member_id ( )
2020-05-13 06:28:22 -05:00
self . members [ member_id ] = ManagedBlockchainMember (
2022-01-14 18:51:49 -01:00
member_id = member_id ,
2020-05-13 06:28:22 -05:00
networkid = network_id ,
member_configuration = member_configuration ,
region = self . region_name ,
)
2020-05-06 21:12:48 -05:00
2020-05-03 18:13:40 -05:00
self . networks [ network_id ] = ManagedBlockchainNetwork (
2022-01-14 18:51:49 -01:00
network_id = network_id ,
2020-05-03 18:13:40 -05:00
name = name ,
2020-05-13 06:28:22 -05:00
framework = framework ,
frameworkversion = frameworkversion ,
frameworkconfiguration = frameworkconfiguration ,
voting_policy = voting_policy ,
member_configuration = member_configuration ,
2020-05-03 18:13:40 -05:00
region = self . region_name ,
2020-05-13 06:28:22 -05:00
description = description ,
2020-05-03 18:13:40 -05:00
)
2020-05-06 21:12:48 -05:00
# Return the network and member ID
2023-03-27 18:00:24 +01:00
return { " NetworkId " : network_id , " MemberId " : member_id }
2020-05-06 21:12:48 -05:00
2023-03-27 18:00:24 +01:00
def list_networks ( self ) - > List [ ManagedBlockchainNetwork ] :
return list ( self . networks . values ( ) )
2020-05-03 18:13:40 -05:00
2023-03-27 18:00:24 +01:00
def get_network ( self , network_id : str ) - > ManagedBlockchainNetwork :
2020-05-06 21:54:59 -05:00
if network_id not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetNetwork " , f " Network { network_id } not found. "
2020-05-06 21:54:59 -05:00
)
2023-03-27 18:00:24 +01:00
return self . networks [ network_id ]
2020-05-03 18:13:40 -05:00
2023-03-27 18:00:24 +01:00
def create_proposal (
self ,
networkid : str ,
memberid : str ,
actions : Dict [ str , Any ] ,
description : Optional [ str ] = None ,
) - > Dict [ str , str ] :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" CreateProposal " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
# Check if member exists
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" CreateProposal " , f " Member { memberid } not found. "
2020-05-13 06:28:22 -05:00
)
# CLI docs say that Invitations and Removals cannot both be passed - but it does
# not throw an error and can be performed
if " Invitations " in actions :
for propinvitation in actions [ " Invitations " ] :
if re . match ( " [0-9] {12} " , propinvitation [ " Principal " ] ) is None :
raise InvalidRequestException (
" CreateProposal " ,
" Account ID format specified in proposal is not valid. " ,
)
if " Removals " in actions :
for propmember in actions [ " Removals " ] :
if propmember [ " MemberId " ] not in self . members :
raise InvalidRequestException (
" CreateProposal " ,
" Member ID format specified in proposal is not valid. " ,
)
2020-05-15 19:38:19 -05:00
# Generate proposal ID
2020-05-13 06:28:22 -05:00
proposal_id = get_proposal_id ( )
self . proposals [ proposal_id ] = ManagedBlockchainProposal (
2022-01-14 18:51:49 -01:00
proposal_id = proposal_id ,
2020-05-13 06:28:22 -05:00
networkid = networkid ,
memberid = memberid ,
2023-03-27 18:00:24 +01:00
membername = self . members [ memberid ] . name ,
2020-05-13 06:28:22 -05:00
numofmembers = number_of_members_in_network ( self . members , networkid ) ,
actions = actions ,
2023-03-27 18:00:24 +01:00
network_expiration = self . networks [ networkid ] . vote_pol_proposal_duration ,
network_threshold = self . networks [ networkid ] . vote_pol_threshold_percentage ,
network_threshold_comp = self . networks [
2020-05-13 06:28:22 -05:00
networkid
2023-03-27 18:00:24 +01:00
] . vote_pol_threshold_comparator ,
2020-05-13 06:28:22 -05:00
description = description ,
)
# Return the proposal ID
2023-03-27 18:00:24 +01:00
return { " ProposalId " : proposal_id }
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def list_proposals ( self , networkid : str ) - > List [ ManagedBlockchainProposal ] :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListProposals " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
proposalsfornetwork = [ ]
for proposal_id in self . proposals :
2023-03-27 18:00:24 +01:00
if self . proposals [ proposal_id ] . network_id == networkid :
2020-05-15 19:38:19 -05:00
# See if any are expired
2023-03-27 18:00:24 +01:00
self . proposals [ proposal_id ] . check_to_expire_proposal ( )
2020-05-13 06:28:22 -05:00
proposalsfornetwork . append ( self . proposals [ proposal_id ] )
return proposalsfornetwork
2023-03-27 18:00:24 +01:00
def get_proposal (
self , networkid : str , proposalid : str
) - > ManagedBlockchainProposal :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetProposal " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if proposalid not in self . proposals :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetProposal " , f " Proposal { proposalid } not found. "
2020-05-13 06:28:22 -05:00
)
2020-05-15 19:38:19 -05:00
# See if it needs to be set to expipred
2023-03-27 18:00:24 +01:00
self . proposals [ proposalid ] . check_to_expire_proposal ( )
return self . proposals [ proposalid ]
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def vote_on_proposal (
self , networkid : str , proposalid : str , votermemberid : str , vote : str
) - > None :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" VoteOnProposal " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if proposalid not in self . proposals :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" VoteOnProposal " , f " Proposal { proposalid } not found. "
2020-05-13 06:28:22 -05:00
)
if votermemberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" VoteOnProposal " , f " Member { votermemberid } not found. "
2020-05-13 06:28:22 -05:00
)
if vote . upper ( ) not in VOTEVALUES :
raise BadRequestException ( " VoteOnProposal " , " Invalid request body " )
2020-05-15 19:38:19 -05:00
# See if it needs to be set to expipred
2023-03-27 18:00:24 +01:00
self . proposals [ proposalid ] . check_to_expire_proposal ( )
2020-05-15 19:38:19 -05:00
# Exception if EXPIRED
2023-03-27 18:00:24 +01:00
if self . proposals [ proposalid ] . proposal_status == " EXPIRED " :
2020-05-15 19:38:19 -05:00
raise InvalidRequestException (
" VoteOnProposal " ,
2022-11-19 23:12:31 -01:00
f " Proposal { proposalid } is expired and you cannot vote on it. " ,
2020-05-15 19:38:19 -05:00
)
# Check if IN_PROGRESS
2023-03-27 18:00:24 +01:00
if self . proposals [ proposalid ] . proposal_status != " IN_PROGRESS " :
2020-05-15 19:38:19 -05:00
raise InvalidRequestException (
" VoteOnProposal " ,
2023-03-27 18:00:24 +01:00
f " Proposal { proposalid } has status { self . proposals [ proposalid ] . proposal_status } and you cannot vote on it. " ,
2020-05-15 19:38:19 -05:00
)
2020-05-13 06:28:22 -05:00
# Check to see if this member already voted
2023-03-27 18:00:24 +01:00
if votermemberid in self . proposals [ proposalid ] . proposal_votes :
2020-05-15 19:38:19 -05:00
raise ResourceAlreadyExistsException (
" VoteOnProposal " ,
2022-11-19 23:12:31 -01:00
f " Member { votermemberid } has already voted on proposal { proposalid } . " ,
2020-05-15 19:38:19 -05:00
)
2020-05-13 06:28:22 -05:00
2020-05-15 19:38:19 -05:00
# Cast vote
2023-03-27 18:00:24 +01:00
self . proposals [ proposalid ] . set_vote (
votermemberid , self . members [ votermemberid ] . name , vote . upper ( )
2020-05-15 19:38:19 -05:00
)
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
if self . proposals [ proposalid ] . proposal_status == " APPROVED " :
2020-05-15 19:38:19 -05:00
# Generate invitations
2023-03-27 18:00:24 +01:00
for _ in self . proposals [ proposalid ] . proposal_actions ( " Invitations " ) :
2020-05-15 19:38:19 -05:00
invitation_id = get_invitation_id ( )
self . invitations [ invitation_id ] = ManagedBlockchainInvitation (
2022-01-14 18:51:49 -01:00
invitation_id = invitation_id ,
2020-05-15 19:38:19 -05:00
networkid = networkid ,
2023-03-27 18:00:24 +01:00
networkname = self . networks [ networkid ] . network_name ,
networkframework = self . networks [ networkid ] . network_framework ,
networkframeworkversion = self . networks [
2020-05-15 19:38:19 -05:00
networkid
2023-03-27 18:00:24 +01:00
] . network_framework_version ,
networkcreationdate = self . networks [ networkid ] . network_creationdate ,
2020-05-15 19:38:19 -05:00
region = self . region_name ,
2023-03-27 18:00:24 +01:00
networkdescription = self . networks [ networkid ] . network_description ,
2020-05-15 19:38:19 -05:00
)
# Delete members
2023-03-27 18:00:24 +01:00
for propmember in self . proposals [ proposalid ] . proposal_actions ( " Removals " ) :
2020-05-15 19:38:19 -05:00
self . delete_member ( networkid , propmember [ " MemberId " ] )
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def list_proposal_votes ( self , networkid : str , proposalid : str ) - > List [ str ] :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListProposalVotes " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if proposalid not in self . proposals :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListProposalVotes " , f " Proposal { proposalid } not found. "
2020-05-13 06:28:22 -05:00
)
# Output the vote summaries
proposalvotesfornetwork = [ ]
2023-03-27 18:00:24 +01:00
for proposal in self . proposals . values ( ) :
if proposal . network_id == networkid :
for proposal_vote in proposal . proposal_votes . values ( ) :
proposalvotesfornetwork . append ( proposal_vote )
2020-05-13 06:28:22 -05:00
return proposalvotesfornetwork
2023-03-27 18:00:24 +01:00
def list_invitations ( self ) - > List [ ManagedBlockchainInvitation ] :
return list ( self . invitations . values ( ) )
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def reject_invitation ( self , invitationid : str ) - > None :
2020-05-13 06:28:22 -05:00
if invitationid not in self . invitations :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" RejectInvitation " , f " InvitationId { invitationid } not found. "
2020-05-13 06:28:22 -05:00
)
2023-03-27 18:00:24 +01:00
self . invitations [ invitationid ] . reject_invitation ( )
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def create_member (
self , invitationid : str , networkid : str , member_configuration : Dict [ str , Any ]
) - > Dict [ str , str ] :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" CreateMember " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if invitationid not in self . invitations :
raise InvalidRequestException (
2022-11-19 23:12:31 -01:00
" CreateMember " , f " Invitation { invitationid } not valid "
2020-05-13 06:28:22 -05:00
)
2023-03-27 18:00:24 +01:00
if self . invitations [ invitationid ] . invitation_status != " PENDING " :
2020-05-13 06:28:22 -05:00
raise InvalidRequestException (
2022-11-19 23:12:31 -01:00
" CreateMember " , f " Invitation { invitationid } not valid "
2020-05-13 06:28:22 -05:00
)
2022-11-19 23:12:31 -01:00
if member_name_exist_in_network (
self . members , networkid , member_configuration [ " Name " ]
2020-05-13 06:28:22 -05:00
) :
raise InvalidRequestException (
" CreateMember " ,
2022-11-19 23:12:31 -01:00
f " Member name { member_configuration [ ' Name ' ] } already exists in network { networkid } . " ,
2020-05-13 06:28:22 -05:00
)
2023-03-27 18:00:24 +01:00
networkedition = self . networks [ networkid ] . network_edition
2020-05-13 06:28:22 -05:00
if (
number_of_members_in_network ( self . members , networkid )
> = EDITIONS [ networkedition ] [ " MaxMembers " ]
) :
raise ResourceLimitExceededException (
" CreateMember " ,
2022-11-19 23:12:31 -01:00
f " You cannot create a member in network { networkid } . { EDITIONS [ networkedition ] [ ' MaxMembers ' ] } is the maximum number of members allowed in a { networkedition } Edition network. " ,
2020-05-13 06:28:22 -05:00
)
memberadminpassword = member_configuration [ " FrameworkConfiguration " ] [ " Fabric " ] [
" AdminPassword "
]
if admin_password_ok ( memberadminpassword ) is False :
raise BadRequestException ( " CreateMember " , " Invalid request body " )
member_id = get_member_id ( )
self . members [ member_id ] = ManagedBlockchainMember (
2022-01-14 18:51:49 -01:00
member_id = member_id ,
2020-05-13 06:28:22 -05:00
networkid = networkid ,
member_configuration = member_configuration ,
region = self . region_name ,
)
# Accept the invitaiton
2023-03-27 18:00:24 +01:00
self . invitations [ invitationid ] . accept_invitation ( )
2020-05-13 06:28:22 -05:00
# Return the member ID
2023-03-27 18:00:24 +01:00
return { " MemberId " : member_id }
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def list_members ( self , networkid : str ) - > List [ ManagedBlockchainMember ] :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListMembers " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
membersfornetwork = [ ]
2023-03-27 18:00:24 +01:00
for member in self . members . values ( ) :
if member . network_id == networkid :
membersfornetwork . append ( member )
2020-05-13 06:28:22 -05:00
return membersfornetwork
2023-03-27 18:00:24 +01:00
def get_member ( self , networkid : str , memberid : str ) - > ManagedBlockchainMember :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetMember " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetMember " , f " Member { memberid } not found. "
2020-05-13 06:28:22 -05:00
)
2020-05-15 19:38:19 -05:00
# Cannot get a member than has been deleted (it does show up in the list)
2023-03-27 18:00:24 +01:00
if self . members [ memberid ] . member_status == " DELETED " :
2020-05-13 06:28:22 -05:00
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetMember " , f " Member { memberid } not found. "
2020-05-13 06:28:22 -05:00
)
2023-03-27 18:00:24 +01:00
return self . members [ memberid ]
2020-05-13 06:28:22 -05:00
2023-03-27 18:00:24 +01:00
def delete_member ( self , networkid : str , memberid : str ) - > None :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" DeleteMember " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" DeleteMember " , f " Member { memberid } not found. "
2020-05-13 06:28:22 -05:00
)
2023-03-27 18:00:24 +01:00
self . members [ memberid ] . delete ( )
2020-05-13 06:28:22 -05:00
# Is this the last member in the network? (all set to DELETED)
if number_of_members_in_network (
self . members , networkid , member_status = " DELETED "
) == len ( self . members ) :
# Set network status to DELETED for all invitations
2023-03-27 18:00:24 +01:00
for invitation in self . invitations . values ( ) :
if invitation . invitation_networkid == networkid :
invitation . set_network_status ( " DELETED " )
2020-05-13 06:28:22 -05:00
# Remove network
del self . networks [ networkid ]
2020-05-15 19:38:19 -05:00
# Remove any nodes associated
for nodeid in nodes_in_member ( self . nodes , memberid ) :
del self . nodes [ nodeid ]
2023-03-27 18:00:24 +01:00
def update_member (
self , networkid : str , memberid : str , logpublishingconfiguration : Dict [ str , Any ]
) - > None :
2020-05-13 06:28:22 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" UpdateMember " , f " Network { networkid } not found. "
2020-05-13 06:28:22 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" UpdateMember " , f " Member { memberid } not found. "
2020-05-13 06:28:22 -05:00
)
2023-03-27 18:00:24 +01:00
self . members [ memberid ] . update ( logpublishingconfiguration )
2020-05-13 06:28:22 -05:00
2020-05-15 19:38:19 -05:00
def create_node (
self ,
2023-03-27 18:00:24 +01:00
networkid : str ,
memberid : str ,
availabilityzone : str ,
instancetype : str ,
logpublishingconfiguration : Dict [ str , Any ] ,
) - > Dict [ str , str ] :
2020-05-15 19:38:19 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" CreateNode " , f " Network { networkid } not found. "
2020-05-15 19:38:19 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" CreateNode " , f " Member { memberid } not found. "
2020-05-15 19:38:19 -05:00
)
2023-03-27 18:00:24 +01:00
networkedition = self . networks [ networkid ] . network_edition
2020-05-15 19:38:19 -05:00
if (
number_of_nodes_in_member ( self . nodes , memberid )
> = EDITIONS [ networkedition ] [ " MaxNodesPerMember " ]
) :
raise ResourceLimitExceededException (
" CreateNode " ,
2022-11-19 23:12:31 -01:00
f " Maximum number of nodes exceeded in member { memberid } . The maximum number of nodes you can have in a member in a { networkedition } Edition network is { EDITIONS [ networkedition ] [ ' MaxNodesPerMember ' ] } " ,
2020-05-15 19:38:19 -05:00
)
# See if the instance family is correct
correctinstancefamily = False
for chkinsttypepre in EDITIONS [ " STANDARD " ] [ " AllowedNodeInstanceTypes " ] :
chkinsttypepreregex = chkinsttypepre + " .* "
if re . match ( chkinsttypepreregex , instancetype , re . IGNORECASE ) :
correctinstancefamily = True
break
if correctinstancefamily is False :
raise InvalidRequestException (
" CreateNode " ,
2022-11-19 23:12:31 -01:00
f " Requested instance { instancetype } isn ' t supported. " ,
2020-05-15 19:38:19 -05:00
)
# Check for specific types for starter
if networkedition == " STARTER " :
if instancetype not in EDITIONS [ " STARTER " ] [ " AllowedNodeInstanceTypes " ] :
raise InvalidRequestException (
" CreateNode " ,
2022-11-19 23:12:31 -01:00
f " Instance type { instancetype } is not supported with STARTER Edition networks. " ,
2020-05-15 19:38:19 -05:00
)
# Simple availability zone check
chkregionpreregex = self . region_name + " [a-z] "
if re . match ( chkregionpreregex , availabilityzone , re . IGNORECASE ) is None :
raise InvalidRequestException (
" CreateNode " , " Availability Zone is not valid "
)
node_id = get_node_id ( )
self . nodes [ node_id ] = ManagedBlockchainNode (
2022-01-14 18:51:49 -01:00
node_id = node_id ,
2020-05-15 19:38:19 -05:00
networkid = networkid ,
memberid = memberid ,
availabilityzone = availabilityzone ,
instancetype = instancetype ,
logpublishingconfiguration = logpublishingconfiguration ,
region = self . region_name ,
)
# Return the node ID
2023-03-27 18:00:24 +01:00
return { " NodeId " : node_id }
2020-05-15 19:38:19 -05:00
2023-03-27 18:00:24 +01:00
def list_nodes (
self , networkid : str , memberid : str , status : Optional [ str ] = None
) - > List [ ManagedBlockchainNode ] :
2020-05-15 19:38:19 -05:00
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListNodes " , f " Network { networkid } not found. "
2020-05-15 19:38:19 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListNodes " , f " Member { memberid } not found. "
2020-05-15 19:38:19 -05:00
)
# If member is deleted, cannot list nodes
2023-03-27 18:00:24 +01:00
if self . members [ memberid ] . member_status == " DELETED " :
2020-05-15 19:38:19 -05:00
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" ListNodes " , f " Member { memberid } not found. "
2020-05-15 19:38:19 -05:00
)
nodesformember = [ ]
2023-03-27 18:00:24 +01:00
for node in self . nodes . values ( ) :
if node . member_id == memberid and (
status is None or node . node_status == status
2020-05-15 19:38:19 -05:00
) :
2023-03-27 18:00:24 +01:00
nodesformember . append ( node )
2020-05-15 19:38:19 -05:00
return nodesformember
2023-03-27 18:00:24 +01:00
def get_node (
self , networkid : str , memberid : str , nodeid : str
) - > ManagedBlockchainNode :
2020-05-15 19:38:19 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" GetNode " , f " Network { networkid } not found. "
2020-05-15 19:38:19 -05:00
)
if memberid not in self . members :
2022-11-19 23:12:31 -01:00
raise ResourceNotFoundException ( " GetNode " , f " Member { memberid } not found. " )
2020-05-15 19:38:19 -05:00
if nodeid not in self . nodes :
2022-11-19 23:12:31 -01:00
raise ResourceNotFoundException ( " GetNode " , f " Node { nodeid } not found. " )
2020-05-15 19:38:19 -05:00
# Cannot get a node than has been deleted (it does show up in the list)
2023-03-27 18:00:24 +01:00
if self . nodes [ nodeid ] . node_status == " DELETED " :
2022-11-19 23:12:31 -01:00
raise ResourceNotFoundException ( " GetNode " , f " Node { nodeid } not found. " )
2020-05-15 19:38:19 -05:00
2023-03-27 18:00:24 +01:00
return self . nodes [ nodeid ]
2020-05-15 19:38:19 -05:00
2023-03-27 18:00:24 +01:00
def delete_node ( self , networkid : str , memberid : str , nodeid : str ) - > None :
2020-05-15 19:38:19 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" DeleteNode " , f " Network { networkid } not found. "
2020-05-15 19:38:19 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" DeleteNode " , f " Member { memberid } not found. "
2020-05-15 19:38:19 -05:00
)
if nodeid not in self . nodes :
2022-11-19 23:12:31 -01:00
raise ResourceNotFoundException ( " DeleteNode " , f " Node { nodeid } not found. " )
2020-05-15 19:38:19 -05:00
2023-03-27 18:00:24 +01:00
self . nodes [ nodeid ] . delete ( )
2020-05-15 19:38:19 -05:00
2023-03-27 18:00:24 +01:00
def update_node (
self ,
networkid : str ,
memberid : str ,
nodeid : str ,
logpublishingconfiguration : Dict [ str , Any ] ,
) - > None :
2020-05-15 19:38:19 -05:00
# Check if network exists
if networkid not in self . networks :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" UpdateNode " , f " Network { networkid } not found. "
2020-05-15 19:38:19 -05:00
)
if memberid not in self . members :
raise ResourceNotFoundException (
2022-11-19 23:12:31 -01:00
" UpdateNode " , f " Member { memberid } not found. "
2020-05-15 19:38:19 -05:00
)
if nodeid not in self . nodes :
2022-11-19 23:12:31 -01:00
raise ResourceNotFoundException ( " UpdateNode " , f " Node { nodeid } not found. " )
2020-05-15 19:38:19 -05:00
2023-03-27 18:00:24 +01:00
self . nodes [ nodeid ] . update ( logpublishingconfiguration )
2020-05-15 19:38:19 -05:00
2020-05-03 18:13:40 -05:00
2021-12-24 20:02:45 -01:00
managedblockchain_backends = BackendDict ( ManagedBlockchainBackend , " managedblockchain " )