diff --git a/pkg/config/config.go b/pkg/config/config.go index 2ac16c29e29..fc4df6a5f75 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -179,53 +179,6 @@ func CreateSignedConfigUpdateEnvelope(configUpdate *cb.ConfigUpdate, signingIden return signedEnvelope, nil } -// AddOrgToConsortium adds an org definition to a named consortium in a given -// channel configuration. -func AddOrgToConsortium( - org *Organization, - consortium, channelID string, - config *cb.Config, - mspConfig *mb.MSPConfig, -) (*cb.ConfigUpdate, error) { - if org == nil { - return nil, errors.New("organization is empty") - } - - if consortium == "" { - return nil, errors.New("consortium is empty") - } - - updatedConfig := proto.Clone(config).(*cb.Config) - - consortiumsGroup, ok := updatedConfig.ChannelGroup.Groups[ConsortiumsGroupKey] - if !ok { - return nil, errors.New("consortiums group does not exist") - } - - consortiumGroup, ok := consortiumsGroup.Groups[consortium] - if !ok { - return nil, fmt.Errorf("consortium '%s' does not exist", consortium) - } - - orgGroup, err := newOrgConfigGroup(org, mspConfig) - if err != nil { - return nil, fmt.Errorf("failed to create consortium org: %v", err) - } - - if consortiumGroup.Groups == nil { - consortiumGroup.Groups = map[string]*cb.ConfigGroup{} - } - - consortiumGroup.Groups[org.Name] = orgGroup - - configUpdate, err := ComputeUpdate(config, updatedConfig, channelID) - if err != nil { - return nil, err - } - - return configUpdate, nil -} - func signatureHeader(signingIdentity *SigningIdentity) (*cb.SignatureHeader, error) { buffer := bytes.NewBuffer(nil) diff --git a/pkg/config/consortiums.go b/pkg/config/consortiums.go index fc6ecdd7f78..26d9c328e77 100644 --- a/pkg/config/consortiums.go +++ b/pkg/config/consortiums.go @@ -22,39 +22,6 @@ type Consortium struct { Organizations []*Organization } -// AddOrgToConsortium adds an org definition to a named consortium in a given -// channel configuration. -func AddOrgToConsortium(config *cb.Config, org *Organization, consortium string, mspConfig *mb.MSPConfig) error { - if org == nil { - return errors.New("organization is required") - } - if consortium == "" { - return errors.New("consortium is required") - } - - consortiumsGroup, ok := config.ChannelGroup.Groups[ConsortiumsGroupKey] - if !ok { - return errors.New("consortiums group does not exist") - } - - consortiumGroup, ok := consortiumsGroup.Groups[consortium] - if !ok { - return fmt.Errorf("consortium '%s' does not exist", consortium) - } - - orgGroup, err := newConsortiumOrgGroup(org, mspConfig) - if err != nil { - return fmt.Errorf("failed to create consortium org: %v", err) - } - - if consortiumGroup.Groups == nil { - consortiumGroup.Groups = map[string]*cb.ConfigGroup{} - } - consortiumGroup.Groups[org.Name] = orgGroup - - return nil -} - // NewConsortiumsGroup returns the consortiums component of the channel configuration. This element is only defined for // the ordering system channel. // It sets the mod_policy for all elements to "/Channel/Orderer/Admins". @@ -86,6 +53,34 @@ func NewConsortiumsGroup(consortiums []*Consortium, mspConfig *mb.MSPConfig) (*c return consortiumsGroup, nil } +// AddOrgToConsortium adds an org definition to a named consortium in a given +// channel configuration. +func AddOrgToConsortium(config *cb.Config, org *Organization, consortium string, mspConfig *mb.MSPConfig) error { + var err error + + if org == nil { + return errors.New("organization is required") + } + + if consortium == "" { + return errors.New("consortium is required") + } + + consortiumsGroup := config.ChannelGroup.Groups[ConsortiumsGroupKey] + + consortiumGroup, ok := consortiumsGroup.Groups[consortium] + if !ok { + return fmt.Errorf("consortium '%s' does not exist", consortium) + } + + consortiumGroup.Groups[org.Name], err = newOrgConfigGroup(org, mspConfig) + if err != nil { + return fmt.Errorf("failed to create consortium org: %v", err) + } + + return nil +} + // newConsortiumGroup returns a consortiums component of the channel configuration. func newConsortiumGroup(consortium *Consortium, mspConfig *mb.MSPConfig) (*cb.ConfigGroup, error) { var err error diff --git a/pkg/config/consortiums_test.go b/pkg/config/consortiums_test.go index 855b4ba94ed..ac66300d67d 100644 --- a/pkg/config/consortiums_test.go +++ b/pkg/config/consortiums_test.go @@ -17,119 +17,270 @@ import ( . "github.com/onsi/gomega" ) +func TestNewConsortiumsGroup(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + consortiums := baseConsortiums() + + mspConfig := &mb.MSPConfig{} + + consortiumsGroup, err := NewConsortiumsGroup(consortiums, mspConfig) + gt.Expect(err).NotTo(HaveOccurred()) + + // ConsortiumsGroup checks + gt.Expect(len(consortiumsGroup.Groups)).To(Equal(1)) + gt.Expect(consortiumsGroup.Groups["Consortium1"]).NotTo(BeNil()) + gt.Expect(len(consortiumsGroup.Values)).To(Equal(0)) + gt.Expect(len(consortiumsGroup.Policies)).To(Equal(1)) + gt.Expect(consortiumsGroup.Policies[AdminsPolicyKey]).NotTo(BeNil()) + + // ConsortiumGroup checks + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups)).To(Equal(2)) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"]).NotTo(BeNil()) + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Values)).To(Equal(1)) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Values[ChannelCreationPolicyKey]).NotTo(BeNil()) + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Policies)).To(Equal(0)) + + // ConsortiumOrgGroup checks + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Groups)).To(Equal(0)) + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Values)).To(Equal(1)) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Values[MSPKey]).NotTo(BeNil()) + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies)).To(Equal(4)) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[ReadersPolicyKey]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[WritersPolicyKey]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[AdminsPolicyKey]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[EndorsementPolicyKey]).NotTo(BeNil()) + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Groups)).To(Equal(0)) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Values[MSPKey]).NotTo(BeNil()) + gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies)).To(Equal(4)) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[ReadersPolicyKey]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[WritersPolicyKey]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[AdminsPolicyKey]).NotTo(BeNil()) + gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[EndorsementPolicyKey]).NotTo(BeNil()) +} + +func TestNewConsortiumsGroupFailure(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + consortiums := baseConsortiums() + consortiums[0].Organizations[0].Policies = nil + + mspConfig := &mb.MSPConfig{} + + consortiumsGroup, err := NewConsortiumsGroup(consortiums, mspConfig) + gt.Expect(err).To(MatchError("org group 'Org1': no policies defined")) + gt.Expect(consortiumsGroup).To(BeNil()) +} + func TestAddOrgToConsortium(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + consortiums := baseConsortiums() + + consortiumsGroup, err := NewConsortiumsGroup(consortiums, &mb.MSPConfig{}) + gt.Expect(err).NotTo(HaveOccurred()) + config := &cb.Config{ ChannelGroup: &cb.ConfigGroup{ Groups: map[string]*cb.ConfigGroup{ - "Consortiums": { - Groups: map[string]*cb.ConfigGroup{ - "test-consortium": {}, - }, - }, + "Consortiums": consortiumsGroup, }, }, } - org := &Organization{ + orgToAdd := &Organization{ Name: "Org1", ID: "Org1MSP", Policies: applicationOrgStandardPolicies(), } - err := AddOrgToConsortium(config, org, "test-consortium", &mb.MSPConfig{}) - gt.Expect(err).NotTo(HaveOccurred()) - expectedConfig := ` { "channel_group": { "groups": { "Consortiums": { "groups": { - "test-consortium": { + "Consortium1": { "groups": { "Org1": { "groups": {}, "mod_policy": "Admins", "policies": { "Admins": { - "mod_policy": "Admins", - "policy": { - "type": 3, - "value": { - "rule": "MAJORITY", - "sub_policy": "Admins" - } - }, - "version": "0" + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Admins" + } + }, + "version": "0" }, "Endorsement": { - "mod_policy": "Admins", - "policy": { - "type": 3, - "value": { - "rule": "MAJORITY", - "sub_policy": "Endorsement" - } - }, - "version": "0" + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Endorsement" + } + }, + "version": "0" }, "LifecycleEndorsement": { - "mod_policy": "Admins", - "policy": { - "type": 3, - "value": { - "rule": "MAJORITY", - "sub_policy": "Endorsement" - } - }, - "version": "0" + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Endorsement" + } + }, + "version": "0" }, "Readers": { - "mod_policy": "Admins", - "policy": { - "type": 3, - "value": { - "rule": "ANY", - "sub_policy": "Readers" - } - }, - "version": "0" + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Readers" + } + }, + "version": "0" }, "Writers": { - "mod_policy": "Admins", - "policy": { - "type": 3, - "value": { - "rule": "ANY", - "sub_policy": "Writers" - } - }, - "version": "0" + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Writers" + } + }, + "version": "0" } }, "values": { "MSP": { - "mod_policy": "Admins", - "value": { - "config": null, - "type": 0 - }, - "version": "0" + "mod_policy": "Admins", + "value": { + "config": null, + "type": 0 + }, + "version": "0" + } + }, + "version": "0" + }, + "Org2": { + "groups": {}, + "mod_policy": "Admins", + "policies": { + "Admins": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Admins" + } + }, + "version": "0" + }, + "Endorsement": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "MAJORITY", + "sub_policy": "Endorsement" + } + }, + "version": "0" + }, + "Readers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Readers" + } + }, + "version": "0" + }, + "Writers": { + "mod_policy": "Admins", + "policy": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Writers" + } + }, + "version": "0" + } + }, + "values": { + "MSP": { + "mod_policy": "Admins", + "value": { + "config": null, + "type": 0 + }, + "version": "0" } }, "version": "0" } }, - "mod_policy": "", + "mod_policy": "/Channel/Orderer/Admins", "policies": {}, - "values": {}, + "values": { + "ChannelCreationPolicy": { + "mod_policy": "/Channel/Orderer/Admins", + "value": { + "type": 3, + "value": { + "rule": "ANY", + "sub_policy": "Admins" + } + }, + "version": "0" + } + }, + "version": "0" + } + }, + "mod_policy": "/Channel/Orderer/Admins", + "policies": { + "Admins": { + "mod_policy": "/Channel/Orderer/Admins", + "policy": { + "type": 1, + "value": { + "identities": [], + "rule": { + "n_out_of": { + "n": 0, + "rules": [] + } + }, + "version": 0 + } + }, "version": "0" } }, - "mod_policy": "", - "policies": {}, "values": {}, "version": "0" } @@ -145,26 +296,18 @@ func TestAddOrgToConsortium(t *testing.T) { expectedConfigProto := cb.Config{} err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedConfig), &expectedConfigProto) - gt.Expect(err).To(BeNil()) + gt.Expect(err).NotTo(HaveOccurred()) + + err = AddOrgToConsortium(config, orgToAdd, "Consortium1", &mb.MSPConfig{}) + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(proto.Equal(config, &expectedConfigProto)).To(BeTrue()) } func TestAddOrgToConsortiumFailures(t *testing.T) { t.Parallel() - baseConfig := &cb.Config{ - ChannelGroup: &cb.ConfigGroup{ - Groups: map[string]*cb.ConfigGroup{ - "Consortiums": { - Groups: map[string]*cb.ConfigGroup{ - "test-consortium": {}, - }, - }, - }, - }, - } - - org := &Organization{ + orgToAdd := &Organization{ Name: "test-org", ID: "test-org-msp-id", Policies: applicationOrgStandardPolicies(), @@ -180,33 +323,19 @@ func TestAddOrgToConsortiumFailures(t *testing.T) { { name: "When the organization is nil", org: nil, - consortium: "test-consortium", - config: baseConfig, + consortium: "Consortium1", expectedErr: "organization is required", }, { name: "When the consortium name is not specified", - org: org, + org: orgToAdd, consortium: "", - config: baseConfig, expectedErr: "consortium is required", }, - { - name: "When the config doesn't contain a consortiums group", - org: org, - consortium: "test-consortium", - config: &cb.Config{ - ChannelGroup: &cb.ConfigGroup{ - Groups: map[string]*cb.ConfigGroup{}, - }, - }, - expectedErr: "consortiums group does not exist", - }, { name: "When the config doesn't contain the consortium", - org: org, + org: orgToAdd, consortium: "what-the-what", - config: baseConfig, expectedErr: "consortium 'what-the-what' does not exist", }, { @@ -218,8 +347,7 @@ func TestAddOrgToConsortiumFailures(t *testing.T) { "Admins": nil, }, }, - consortium: "test-consortium", - config: baseConfig, + consortium: "Consortium1", expectedErr: "failed to create consortium org: no Admins policy defined", }, } { @@ -228,69 +356,23 @@ func TestAddOrgToConsortiumFailures(t *testing.T) { t.Parallel() gt := NewGomegaWithT(t) - err := AddOrgToConsortium(test.config, test.org, test.consortium, &mb.MSPConfig{}) - gt.Expect(err).To(MatchError(test.expectedErr)) - }) - } -} -func TestNewConsortiumsGroup(t *testing.T) { - t.Parallel() - - gt := NewGomegaWithT(t) - - consortiums := baseConsortiums() - - mspConfig := &mb.MSPConfig{} - - consortiumsGroup, err := NewConsortiumsGroup(consortiums, mspConfig) - gt.Expect(err).NotTo(HaveOccurred()) - - // ConsortiumsGroup checks - gt.Expect(len(consortiumsGroup.Groups)).To(Equal(1)) - gt.Expect(consortiumsGroup.Groups["Consortium1"]).NotTo(BeNil()) - gt.Expect(len(consortiumsGroup.Values)).To(Equal(0)) - gt.Expect(len(consortiumsGroup.Policies)).To(Equal(1)) - gt.Expect(consortiumsGroup.Policies[AdminsPolicyKey]).NotTo(BeNil()) + consortiums := baseConsortiums() - // ConsortiumGroup checks - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups)).To(Equal(2)) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"]).NotTo(BeNil()) - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Values)).To(Equal(1)) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Values[ChannelCreationPolicyKey]).NotTo(BeNil()) - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Policies)).To(Equal(0)) + consortiumsGroup, err := NewConsortiumsGroup(consortiums, &mb.MSPConfig{}) + gt.Expect(err).NotTo(HaveOccurred()) - // ConsortiumOrgGroup checks - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Groups)).To(Equal(0)) - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Values)).To(Equal(1)) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Values[MSPKey]).NotTo(BeNil()) - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies)).To(Equal(4)) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[ReadersPolicyKey]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[WritersPolicyKey]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[AdminsPolicyKey]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org1"].Policies[EndorsementPolicyKey]).NotTo(BeNil()) - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Groups)).To(Equal(0)) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Values[MSPKey]).NotTo(BeNil()) - gt.Expect(len(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies)).To(Equal(4)) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[ReadersPolicyKey]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[WritersPolicyKey]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[AdminsPolicyKey]).NotTo(BeNil()) - gt.Expect(consortiumsGroup.Groups["Consortium1"].Groups["Org2"].Policies[EndorsementPolicyKey]).NotTo(BeNil()) -} - -func TestNewConsortiumsGroupFailure(t *testing.T) { - t.Parallel() - - gt := NewGomegaWithT(t) - - consortiums := baseConsortiums() - consortiums[0].Organizations[0].Policies = nil - - mspConfig := &mb.MSPConfig{} + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + "Consortiums": consortiumsGroup, + }, + }, + } - consortiumsGroup, err := NewConsortiumsGroup(consortiums, mspConfig) - gt.Expect(err).To(MatchError("org group 'Org1': no policies defined")) - gt.Expect(consortiumsGroup).To(BeNil()) + err = AddOrgToConsortium(config, test.org, test.consortium, &mb.MSPConfig{}) + gt.Expect(err).To(MatchError(test.expectedErr)) + }) + } } func TestSkipAsForeignForConsortiumOrg(t *testing.T) {