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  }