github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/initializer/orderer/configtx/encoder.go (about) 1 /* 2 * Copyright contributors to the Hyperledger Fabric Operator project 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package configtx 20 21 import ( 22 cb "github.com/hyperledger/fabric-protos-go/common" 23 pb "github.com/hyperledger/fabric-protos-go/peer" 24 "github.com/hyperledger/fabric/common/cauthdsl" 25 "github.com/hyperledger/fabric/common/channelconfig" 26 "github.com/hyperledger/fabric/common/policies" 27 "github.com/hyperledger/fabric/msp" 28 "github.com/hyperledger/fabric/protoutil" 29 "github.com/pkg/errors" 30 ) 31 32 // NewApplicationGroup returns the application component of the channel configuration. It defines the organizations which are involved 33 // in application logic like chaincodes, and how these members may interact with the orderer. It sets the mod_policy of all elements to "Admins". 34 func NewApplicationGroup(conf *Application) (*cb.ConfigGroup, error) { 35 applicationGroup := protoutil.NewConfigGroup() 36 if err := AddPolicies(applicationGroup, conf.Policies, channelconfig.AdminsPolicyKey); err != nil { 37 return nil, errors.Wrapf(err, "error adding policies to application group") 38 } 39 40 if len(conf.ACLs) > 0 { 41 addValue(applicationGroup, channelconfig.ACLValues(conf.ACLs), channelconfig.AdminsPolicyKey) 42 } 43 44 if len(conf.Capabilities) > 0 { 45 addValue(applicationGroup, channelconfig.CapabilitiesValue(conf.Capabilities), channelconfig.AdminsPolicyKey) 46 } 47 48 for _, org := range conf.Organizations { 49 var err error 50 applicationGroup.Groups[org.Name], err = NewApplicationOrgGroup(org) 51 if err != nil { 52 return nil, errors.Wrap(err, "failed to create application org") 53 } 54 } 55 56 applicationGroup.ModPolicy = channelconfig.AdminsPolicyKey 57 return applicationGroup, nil 58 } 59 60 // NewApplicationOrgGroup returns an application org component of the channel configuration. It defines the crypto material for the organization 61 // (its MSP) as well as its anchor peers for use by the gossip network. It sets the mod_policy of all elements to "Admins". 62 func NewApplicationOrgGroup(conf *Organization) (*cb.ConfigGroup, error) { 63 applicationOrgGroup := protoutil.NewConfigGroup() 64 applicationOrgGroup.ModPolicy = channelconfig.AdminsPolicyKey 65 66 if conf.SkipAsForeign { 67 return applicationOrgGroup, nil 68 } 69 70 mspConfig, err := msp.GetVerifyingMspConfig(conf.MSPDir, conf.ID, conf.MSPType) 71 if err != nil { 72 return nil, errors.Wrapf(err, "1 - Error loading MSP configuration for org %s", conf.Name) 73 } 74 75 if err := AddPolicies(applicationOrgGroup, conf.Policies, channelconfig.AdminsPolicyKey); err != nil { 76 return nil, errors.Wrapf(err, "error adding policies to application org group %s", conf.Name) 77 } 78 addValue(applicationOrgGroup, channelconfig.MSPValue(mspConfig), channelconfig.AdminsPolicyKey) 79 80 var anchorProtos []*pb.AnchorPeer 81 for _, anchorPeer := range conf.AnchorPeers { 82 anchorProtos = append(anchorProtos, &pb.AnchorPeer{ 83 Host: anchorPeer.Host, 84 Port: int32(anchorPeer.Port), 85 }) 86 } 87 88 // Avoid adding an unnecessary anchor peers element when one is not required. This helps 89 // prevent a delta from the orderer system channel when computing more complex channel 90 // creation transactions 91 if len(anchorProtos) > 0 { 92 addValue(applicationOrgGroup, channelconfig.AnchorPeersValue(anchorProtos), channelconfig.AdminsPolicyKey) 93 } 94 95 return applicationOrgGroup, nil 96 } 97 98 // NewConsortiumsGroup returns the consortiums component of the channel configuration. This element is only defined for the ordering system channel. 99 // It sets the mod_policy for all elements to "/Channel/Orderer/Admins". 100 func NewConsortiumsGroup(conf map[string]*Consortium) (*cb.ConfigGroup, error) { 101 consortiumsGroup := protoutil.NewConfigGroup() 102 // This policy is not referenced anywhere, it is only used as part of the implicit meta policy rule at the channel level, so this setting 103 // effectively degrades control of the ordering system channel to the ordering admins 104 addPolicy(consortiumsGroup, policies.SignaturePolicy(channelconfig.AdminsPolicyKey, cauthdsl.AcceptAllPolicy), ordererAdminsPolicyName) 105 106 for consortiumName, consortium := range conf { 107 var err error 108 consortiumsGroup.Groups[consortiumName], err = NewConsortiumGroup(consortium) 109 if err != nil { 110 return nil, errors.Wrapf(err, "failed to create consortium %s", consortiumName) 111 } 112 } 113 114 consortiumsGroup.ModPolicy = ordererAdminsPolicyName 115 return consortiumsGroup, nil 116 } 117 118 // NewConsortiums returns a consortiums component of the channel configuration. Each consortium defines the organizations which may be involved in channel 119 // creation, as well as the channel creation policy the orderer checks at channel creation time to authorize the action. It sets the mod_policy of all 120 // elements to "/Channel/Orderer/Admins". 121 func NewConsortiumGroup(conf *Consortium) (*cb.ConfigGroup, error) { 122 consortiumGroup := protoutil.NewConfigGroup() 123 124 for _, org := range conf.Organizations { 125 var err error 126 consortiumGroup.Groups[org.Name], err = NewConsortiumOrgGroup(org) 127 if err != nil { 128 return nil, errors.Wrap(err, "failed to create consortium org") 129 } 130 } 131 132 addValue(consortiumGroup, channelconfig.ChannelCreationPolicyValue(policies.ImplicitMetaAnyPolicy(channelconfig.AdminsPolicyKey).Value()), ordererAdminsPolicyName) 133 134 consortiumGroup.ModPolicy = ordererAdminsPolicyName 135 return consortiumGroup, nil 136 } 137 138 // NewConsortiumsGroup returns an org component of the channel configuration. It defines the crypto material for the 139 // organization (its MSP). It sets the mod_policy of all elements to "Admins". 140 func NewConsortiumOrgGroup(conf *Organization) (*cb.ConfigGroup, error) { 141 consortiumsOrgGroup := protoutil.NewConfigGroup() 142 consortiumsOrgGroup.ModPolicy = channelconfig.AdminsPolicyKey 143 144 if conf.SkipAsForeign { 145 return consortiumsOrgGroup, nil 146 } 147 148 mspConfig, err := msp.GetVerifyingMspConfig(conf.MSPDir, conf.ID, conf.MSPType) 149 if err != nil { 150 return nil, errors.Wrapf(err, "error loading MSP configuration for org: %s", conf.Name) 151 } 152 153 if err := AddPolicies(consortiumsOrgGroup, conf.Policies, channelconfig.AdminsPolicyKey); err != nil { 154 return nil, errors.Wrapf(err, "error adding policies to consortiums org group '%s'", conf.Name) 155 } 156 157 addValue(consortiumsOrgGroup, channelconfig.MSPValue(mspConfig), channelconfig.AdminsPolicyKey) 158 159 return consortiumsOrgGroup, nil 160 } 161 162 func AddPolicies(cg *cb.ConfigGroup, policyMap map[string]*Policy, modPolicy string) error { 163 switch { 164 case policyMap == nil: 165 return errors.Errorf("no policies defined") 166 case policyMap[channelconfig.AdminsPolicyKey] == nil: 167 return errors.Errorf("no Admins policy defined") 168 case policyMap[channelconfig.ReadersPolicyKey] == nil: 169 return errors.Errorf("no Readers policy defined") 170 case policyMap[channelconfig.WritersPolicyKey] == nil: 171 return errors.Errorf("no Writers policy defined") 172 } 173 174 for policyName, policy := range policyMap { 175 switch policy.Type { 176 case ImplicitMetaPolicyType: 177 imp, err := policies.ImplicitMetaFromString(policy.Rule) 178 if err != nil { 179 return errors.Wrapf(err, "invalid implicit meta policy rule '%s'", policy.Rule) 180 } 181 cg.Policies[policyName] = &cb.ConfigPolicy{ 182 ModPolicy: modPolicy, 183 Policy: &cb.Policy{ 184 Type: int32(cb.Policy_IMPLICIT_META), 185 Value: protoutil.MarshalOrPanic(imp), 186 }, 187 } 188 case SignaturePolicyType: 189 sp, err := cauthdsl.FromString(policy.Rule) 190 if err != nil { 191 return errors.Wrapf(err, "invalid signature policy rule '%s'", policy.Rule) 192 } 193 cg.Policies[policyName] = &cb.ConfigPolicy{ 194 ModPolicy: modPolicy, 195 Policy: &cb.Policy{ 196 Type: int32(cb.Policy_SIGNATURE), 197 Value: protoutil.MarshalOrPanic(sp), 198 }, 199 } 200 default: 201 return errors.Errorf("unknown policy type: %s", policy.Type) 202 } 203 } 204 return nil 205 }