diff --git a/configtx/application.go b/configtx/application.go index 17bdeb8..e738770 100644 --- a/configtx/application.go +++ b/configtx/application.go @@ -139,7 +139,7 @@ func (a *ApplicationGroup) Capabilities() ([]string, error) { } // AddCapability sets capability to the provided channel config. -// If the provided capability already exist in current configuration, this action +// If the provided capability already exists in current configuration, this action // will be a no-op. func (a *ApplicationGroup) AddCapability(capability string) error { capabilities, err := a.Capabilities() @@ -177,7 +177,7 @@ func (a *ApplicationGroup) Policies() (map[string]Policy, error) { } // SetPolicy sets the specified policy in the application group's config policy map. -// If the policy already exist in current configuration, its value will be overwritten. +// If the policy already exists in current configuration, its value will be overwritten. func (a *ApplicationGroup) SetPolicy(modPolicy, policyName string, policy Policy) error { err := setPolicy(a.applicationGroup, modPolicy, policyName, policy) if err != nil { @@ -187,6 +187,17 @@ func (a *ApplicationGroup) SetPolicy(modPolicy, policyName string, policy Policy return nil } +// SetPolicies sets the specified policies in the application group's config policy map. +// If the policies already exist in current configuration, the values will be replaced with new policies. +func (a *ApplicationGroup) SetPolicies(modPolicy string, policies map[string]Policy) error { + err := setPolicies(a.applicationGroup, policies, modPolicy) + if err != nil { + return fmt.Errorf("failed to set policies: %v", err) + } + + return nil +} + // RemovePolicy removes an existing policy from an application's configuration. // Removal will panic if the application group does not exist. func (a *ApplicationGroup) RemovePolicy(policyName string) error { @@ -200,13 +211,13 @@ func (a *ApplicationGroup) RemovePolicy(policyName string) error { } // Policies returns the map of policies for a specific application org in -// the updated config.. +// the updated config. func (a *ApplicationOrg) Policies() (map[string]Policy, error) { return getPolicies(a.orgGroup.Policies) } // SetPolicy sets the specified policy in the application org group's config policy map. -// If an Organization policy already exist in current configuration, its value will be overwritten. +// If an Organization policy already exists in current configuration, its value will be overwritten. func (a *ApplicationOrg) SetPolicy(modPolicy, policyName string, policy Policy) error { err := setPolicy(a.orgGroup, modPolicy, policyName, policy) if err != nil { @@ -216,6 +227,17 @@ func (a *ApplicationOrg) SetPolicy(modPolicy, policyName string, policy Policy) return nil } +// SetPolicies sets the specified policies in the application org group's config policy map. +// If the policies already exist in current configuration, the values will be replaced with new policies. +func (a *ApplicationOrg) SetPolicies(modPolicy string, policies map[string]Policy) error { + err := setPolicies(a.orgGroup, policies, modPolicy) + if err != nil { + return fmt.Errorf("failed to set policies: %v", err) + } + + return nil +} + // RemovePolicy removes an existing policy from an application organization. func (a *ApplicationOrg) RemovePolicy(policyName string) error { policies, err := a.Policies() @@ -357,7 +379,7 @@ func (a *ApplicationGroup) ACLs() (map[string]string, error) { } // SetACLs sets ACLS to an existing channel config application. -// If an ACL already exist in current configuration, it will be replaced with new ACL. +// If an ACL already exists in current configuration, it will be replaced with new ACL. func (a *ApplicationGroup) SetACLs(acls map[string]string) error { err := setValue(a.applicationGroup, aclValues(acls), AdminsPolicyKey) if err != nil { diff --git a/configtx/application_test.go b/configtx/application_test.go index 7e50058..30f4e56 100644 --- a/configtx/application_test.go +++ b/configtx/application_test.go @@ -1760,6 +1760,124 @@ func TestSetApplicationOrgPolicyFailures(t *testing.T) { gt.Expect(err).To(MatchError("failed to set policy 'TestPolicy': unknown policy type: ")) } +func TestSetApplicationOrgPolicies(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + + channelGroup := newConfigGroup() + applicationGroup := newConfigGroup() + + application, _ := baseApplication(t) + + for _, org := range application.Organizations { + org.Policies = applicationOrgStandardPolicies() + org.Policies["TestPolicy_Remove"] = org.Policies[EndorsementPolicyKey] + + orgGroup, err := newOrgConfigGroup(org) + gt.Expect(err).NotTo(HaveOccurred()) + + applicationGroup.Groups[org.Name] = orgGroup + } + channelGroup.Groups[ApplicationGroupKey] = applicationGroup + config := &cb.Config{ + ChannelGroup: channelGroup, + } + + c := New(config) + + applicationOrg1 := c.Application().Organization("Org1") + policies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + EndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + LifecycleEndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add1": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add2": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + } + err := applicationOrg1.SetPolicies(AdminsPolicyKey, policies) + gt.Expect(err).NotTo(HaveOccurred()) + + updatedPolicies, err := applicationOrg1.Policies() + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(updatedPolicies).To(Equal(policies)) + + originalPolicies := c.original.ChannelGroup.Groups[ApplicationGroupKey].Groups["Org1"].Policies + gt.Expect(originalPolicies).To(Equal(applicationGroup.Groups["Org1"].Policies)) +} + +func TestSetApplicationOrgPoliciesFailures(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + + channelGroup := newConfigGroup() + applicationGroup := newConfigGroup() + + application, _ := baseApplication(t) + for _, org := range application.Organizations { + org.Policies = applicationOrgStandardPolicies() + + orgGroup, err := newOrgConfigGroup(org) + gt.Expect(err).NotTo(HaveOccurred()) + + applicationGroup.Groups[org.Name] = orgGroup + } + channelGroup.Groups[ApplicationGroupKey] = applicationGroup + config := &cb.Config{ + ChannelGroup: channelGroup, + } + + c := New(config) + + policies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + EndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + LifecycleEndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy": {}, + } + + err := c.Application().Organization("Org1").SetPolicies(AdminsPolicyKey, policies) + gt.Expect(err).To(MatchError("failed to set policies: unknown policy type: ")) +} + func TestSetApplicationPolicy(t *testing.T) { t.Parallel() gt := NewGomegaWithT(t) @@ -1829,6 +1947,96 @@ func TestSetApplicationPolicyFailures(t *testing.T) { gt.Expect(err).To(MatchError("failed to set policy 'TestPolicy': unknown policy type: ")) } +func TestSetApplicationPolicies(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + + channelGroup := newConfigGroup() + application, _ := baseApplication(t) + application.Policies["TestPolicy_Remove"] = application.Policies[ReadersPolicyKey] + + applicationGroup, err := newApplicationGroupTemplate(application) + gt.Expect(err).NotTo(HaveOccurred()) + + channelGroup.Groups[ApplicationGroupKey] = applicationGroup + config := &cb.Config{ + ChannelGroup: channelGroup, + } + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + "TestPolicy_Add1": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add2": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + } + + a := c.Application() + err = a.SetPolicies(AdminsPolicyKey, newPolicies) + gt.Expect(err).NotTo(HaveOccurred()) + + updatedPolicies, err := a.Policies() + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(updatedPolicies).To(Equal(newPolicies)) + + originalPolicies := c.original.ChannelGroup.Groups[ApplicationGroupKey].Policies + gt.Expect(originalPolicies).To(Equal(applicationGroup.Policies)) +} + +func TestSetApplicationPoliciesFailures(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + + channelGroup := newConfigGroup() + application, _ := baseApplication(t) + + applicationGroup, err := newApplicationGroupTemplate(application) + gt.Expect(err).NotTo(HaveOccurred()) + + channelGroup.Groups[ApplicationGroupKey] = applicationGroup + config := &cb.Config{ + ChannelGroup: channelGroup, + } + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + "TestPolicy": {}, + } + + err = c.Application().SetPolicies(AdminsPolicyKey, newPolicies) + gt.Expect(err).To(MatchError("failed to set policies: unknown policy type: ")) +} + func TestAppOrgRemoveApplicationPolicy(t *testing.T) { t.Parallel() gt := NewGomegaWithT(t) diff --git a/configtx/channel.go b/configtx/channel.go index 76bf833..b3ac783 100644 --- a/configtx/channel.go +++ b/configtx/channel.go @@ -84,11 +84,17 @@ func (c *ChannelGroup) Policies() (map[string]Policy, error) { } // SetPolicy sets the specified policy in the channel group's config policy map. -// If the policy already exist in current configuration, its value will be overwritten. +// If the policy already exists in current configuration, its value will be overwritten. func (c *ChannelGroup) SetPolicy(modPolicy, policyName string, policy Policy) error { return setPolicy(c.channelGroup, modPolicy, policyName, policy) } +// SetPolicies sets the specified policies in the channel group's config policy map. +// If the policies already exist in current configuration, the values will be replaced with new policies. +func (c *ChannelGroup) SetPolicies(modPolicy string, policies map[string]Policy) error { + return setPolicies(c.channelGroup, policies, modPolicy) +} + // RemovePolicy removes an existing channel level policy. func (c *ChannelGroup) RemovePolicy(policyName string) error { policies, err := c.Policies() @@ -112,7 +118,7 @@ func (c *ChannelGroup) Capabilities() ([]string, error) { } // AddCapability adds capability to the provided channel config. -// If the provided capability already exist in current configuration, this action +// If the provided capability already exists in current configuration, this action // will be a no-op. func (c *ChannelGroup) AddCapability(capability string) error { capabilities, err := c.Capabilities() diff --git a/configtx/channel_test.go b/configtx/channel_test.go index 4068fab..f9eb26d 100644 --- a/configtx/channel_test.go +++ b/configtx/channel_test.go @@ -258,6 +258,89 @@ func TestSetChannelPolicy(t *testing.T) { gt.Expect(baseChannel.Policies["TestPolicy"]).To(BeNil()) } +func TestSetChannelPolicies(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + + channel, _, err := baseApplicationChannelGroup(t) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: channel, + } + basePolicies := standardPolicies() + basePolicies["TestPolicy_Remove"] = Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Readers"} + err = setPolicies(channel, basePolicies, AdminsPolicyKey) + gt.Expect(err).NotTo(HaveOccurred()) + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Admins", + }, + "TestPolicy_Add1": { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + "TestPolicy_Add2": { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + } + + err = c.Channel().SetPolicies(AdminsPolicyKey, newPolicies) + gt.Expect(err).NotTo(HaveOccurred()) + + updatedChannelPolicies, err := c.Channel().Policies() + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(updatedChannelPolicies).To(Equal(newPolicies)) + + originalChannel := c.original.ChannelGroup + gt.Expect(originalChannel.Policies).To(Equal(config.ChannelGroup.Policies)) +} + +func TestSetChannelPoliciesFailures(t *testing.T) { + t.Parallel() + gt := NewGomegaWithT(t) + + channel, _, err := baseApplicationChannelGroup(t) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: channel, + } + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + "TestPolicy": {}, + } + + err = c.Channel().SetPolicies(AdminsPolicyKey, newPolicies) + gt.Expect(err).To(MatchError("unknown policy type: ")) +} + func TestRemoveChannelPolicy(t *testing.T) { t.Parallel() gt := NewGomegaWithT(t) diff --git a/configtx/consortiums.go b/configtx/consortiums.go index 8ec5472..1ea7746 100644 --- a/configtx/consortiums.go +++ b/configtx/consortiums.go @@ -204,7 +204,7 @@ func (c *ConsortiumOrg) setMSPConfig(updatedMSP MSP) error { // SetChannelCreationPolicy sets the ConsortiumChannelCreationPolicy for // the given configuration Group. -// If the policy already exist in current configuration, its value will be overwritten. +// If the policy already exists in current configuration, its value will be overwritten. func (c *ConsortiumGroup) SetChannelCreationPolicy(policy Policy) error { imp, err := implicitMetaFromString(policy.Rule) if err != nil { @@ -230,7 +230,7 @@ func (c *ConsortiumOrg) Policies() (map[string]Policy, error) { } // SetPolicy sets the specified policy in the consortium org group's config policy map. -// If the policy already exist in current configuration, its value will be overwritten. +// If the policy already exists in current configuration, its value will be overwritten. func (c *ConsortiumOrg) SetPolicy(name string, policy Policy) error { err := setPolicy(c.orgGroup, AdminsPolicyKey, name, policy) if err != nil { @@ -240,6 +240,17 @@ func (c *ConsortiumOrg) SetPolicy(name string, policy Policy) error { return nil } +// SetPolicies sets the specified policies in the consortium org group's config policy map. +// If the policies already exist in current configuration, the values will be replaced with new policies. +func (c *ConsortiumOrg) SetPolicies(policies map[string]Policy) error { + err := setPolicies(c.orgGroup, policies, AdminsPolicyKey) + if err != nil { + return fmt.Errorf("failed to set policies to consortium org '%s': %v", c.name, err) + } + + return nil +} + // RemovePolicy removes an existing policy from a consortium's organization. // Removal will panic if either the consortiums group, consortium group, or consortium org group does not exist. func (c *ConsortiumOrg) RemovePolicy(name string) { diff --git a/configtx/consortiums_test.go b/configtx/consortiums_test.go index 9d2743b..6c8cc29 100644 --- a/configtx/consortiums_test.go +++ b/configtx/consortiums_test.go @@ -1578,6 +1578,108 @@ func TestSetConsortiumOrgPolicyFailures(t *testing.T) { } } +func TestSetConsortiumOrgPolicies(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + consortiums, _ := baseConsortiums(t) + consortiums[0].Organizations[0].Policies["TestPolicy_Remove"] = Policy{Type: ImplicitMetaPolicyType, Rule: "MAJORITY Endorsement"} + + consortiumsGroup, err := newConsortiumsGroup(consortiums) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + ConsortiumsGroupKey: consortiumsGroup, + }, + }, + } + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + EndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add1": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add2": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + } + + consortium1Org1 := c.Consortium("Consortium1").Organization("Org1") + err = consortium1Org1.SetPolicies(newPolicies) + gt.Expect(err).NotTo(HaveOccurred()) + + updatedPolicies, err := consortium1Org1.Policies() + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(updatedPolicies).To(Equal(newPolicies)) +} + +func TestSetConsortiumOrgPoliciesFailures(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + consortiums, _ := baseConsortiums(t) + + consortiumsGroup, err := newConsortiumsGroup(consortiums) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + ConsortiumsGroupKey: consortiumsGroup, + }, + }, + } + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + EndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy": {}, + } + + consortium1Org1 := c.Consortium("Consortium1").Organization("Org1") + err = consortium1Org1.SetPolicies(newPolicies) + gt.Expect(err).To(MatchError("failed to set policies to consortium org 'Org1': unknown policy type: ")) +} + func TestRemoveConsortiumOrgPolicy(t *testing.T) { t.Parallel() diff --git a/configtx/orderer.go b/configtx/orderer.go index 48c4917..ef731df 100644 --- a/configtx/orderer.go +++ b/configtx/orderer.go @@ -519,7 +519,7 @@ func (o *OrdererGroup) Capabilities() ([]string, error) { } // AddCapability adds capability to the provided channel config. -// If the provided capability already exist in current configuration, this action +// If the provided capability already exists in current configuration, this action // will be a no-op. func (o *OrdererGroup) AddCapability(capability string) error { capabilities, err := o.Capabilities() @@ -551,7 +551,7 @@ func (o *OrdererGroup) RemoveCapability(capability string) error { } // SetEndpoint adds an orderer's endpoint to an existing channel config transaction. -// If the same endpoint already exist in current configuration, this will be a no-op. +// If the same endpoint already exists in current configuration, this will be a no-op. func (o *OrdererOrg) SetEndpoint(endpoint Address) error { ordererAddrProto := &cb.OrdererAddresses{} @@ -613,7 +613,7 @@ func (o *OrdererOrg) RemoveEndpoint(endpoint Address) error { } // SetPolicy sets the specified policy in the orderer group's config policy map. -// If the policy already exist in current configuration, its value will be overwritten. +// If the policy already exists in current configuration, its value will be overwritten. func (o *OrdererGroup) SetPolicy(modPolicy, policyName string, policy Policy) error { err := setPolicy(o.ordererGroup, modPolicy, policyName, policy) if err != nil { @@ -623,6 +623,22 @@ func (o *OrdererGroup) SetPolicy(modPolicy, policyName string, policy Policy) er return nil } +// SetPolicies sets the specified policy in the orderer group's config policy map. +// If the policies already exist in current configuration, the values will be replaced with new policies. +func (o *OrdererGroup) SetPolicies(modPolicy string, policies map[string]Policy) error { + + if _, ok := policies[BlockValidationPolicyKey]; !ok { + return errors.New("BlockValidation policy must be defined") + } + + err := setPolicies(o.ordererGroup, policies, modPolicy) + if err != nil { + return fmt.Errorf("failed to set policies: %v", err) + } + + return nil +} + // RemovePolicy removes an existing orderer policy configuration. func (o *OrdererGroup) RemovePolicy(policyName string) error { if policyName == BlockValidationPolicyKey { @@ -670,11 +686,17 @@ func (o *OrdererOrg) SetMSP(updatedMSP MSP) error { } // SetPolicy sets the specified policy in the orderer org group's config policy map. -// If the policy already exist in current configuration, its value will be overwritten. +// If the policy already exists in current configuration, its value will be overwritten. func (o *OrdererOrg) SetPolicy(modPolicy, policyName string, policy Policy) error { return setPolicy(o.orgGroup, modPolicy, policyName, policy) } +// SetPolicies sets the specified policies in the orderer org group's config policy map. +// If the policies already exist in current configuration, the values will be replaced with new policies. +func (o *OrdererOrg) SetPolicies(modPolicy string, policies map[string]Policy) error { + return setPolicies(o.orgGroup, policies, modPolicy) +} + // RemovePolicy removes an existing policy from an orderer organization. func (o *OrdererOrg) RemovePolicy(policyName string) error { policies, err := o.Policies() diff --git a/configtx/orderer_test.go b/configtx/orderer_test.go index ef829e8..f082039 100644 --- a/configtx/orderer_test.go +++ b/configtx/orderer_test.go @@ -3341,6 +3341,148 @@ func TestSetOrdererPolicyFailures(t *testing.T) { gt.Expect(err).To(MatchError("failed to set policy 'TestPolicy': unknown policy type: ")) } +func TestSetOrdererPolicies(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + baseOrdererConf, _ := baseSoloOrderer(t) + baseOrdererConf.Policies["TestPolicy_Remove"] = baseOrdererConf.Policies[ReadersPolicyKey] + + ordererGroup, err := newOrdererGroup(baseOrdererConf) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + "Orderer": ordererGroup, + }, + }, + } + + c := New(config) + + newPolices := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + BlockValidationPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + "TestPolicy_Add1": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add2": { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + } + + err = c.Orderer().SetPolicies(AdminsPolicyKey, newPolices) + gt.Expect(err).NotTo(HaveOccurred()) + + updatedPolicies, err := c.Orderer().Policies() + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(updatedPolicies).To(Equal(newPolices)) + + originalPolicies := c.original.ChannelGroup.Groups[OrdererGroupKey].Policies + gt.Expect(originalPolicies).To(Equal(ordererGroup.Policies)) +} + +func TestSetOrdererPoliciesFailures(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + baseOrdererConf, _ := baseSoloOrderer(t) + + ordererGroup, err := newOrdererGroup(baseOrdererConf) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + "Orderer": ordererGroup, + }, + }, + } + + c := New(config) + + newPolices := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + BlockValidationPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + "TestPolicy": {}, + } + + err = c.Orderer().SetPolicies(AdminsPolicyKey, newPolices) + gt.Expect(err).To(MatchError("failed to set policies: unknown policy type: ")) +} + +func TestSetOrdererPoliciesWithoutBlockValidationPolicyFailures(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + baseOrdererConf, _ := baseSoloOrderer(t) + + ordererGroup, err := newOrdererGroup(baseOrdererConf) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + "Orderer": ordererGroup, + }, + }, + } + + c := New(config) + + newPolices := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + } + + err = c.Orderer().SetPolicies(AdminsPolicyKey, newPolices) + gt.Expect(err).To(MatchError("BlockValidation policy must be defined")) +} + func TestRemoveOrdererPolicy(t *testing.T) { t.Parallel() @@ -3520,6 +3662,110 @@ func TestSetOrdererOrgPolicyFailures(t *testing.T) { gt.Expect(err).To(MatchError("unknown policy type: ")) } +func TestSetOrdererOrgPolicies(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + baseOrdererConf, _ := baseSoloOrderer(t) + baseOrdererConf.Organizations[0].Policies["TestPolicy_Remove"] = baseOrdererConf.Organizations[0].Policies[ReadersPolicyKey] + + ordererGroup, err := newOrdererGroup(baseOrdererConf) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + "Orderer": ordererGroup, + }, + }, + } + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + EndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy_Add1": { + Type: ImplicitMetaPolicyType, + Rule: "ANY Endorsement", + }, + "TestPolicy_Add2": { + Type: ImplicitMetaPolicyType, + Rule: "ANY Endorsement", + }, + } + + ordererOrg := c.Orderer().Organization("OrdererOrg") + err = ordererOrg.SetPolicies(AdminsPolicyKey, newPolicies) + gt.Expect(err).NotTo(HaveOccurred()) + + updatedPolicies, err := ordererOrg.Policies() + gt.Expect(err).NotTo(HaveOccurred()) + gt.Expect(updatedPolicies).To(Equal(newPolicies)) + + originalPolicies := c.original.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies + gt.Expect(originalPolicies).To(Equal(ordererGroup.Groups["OrdererOrg"].Policies)) +} + +func TestSetOrdererOrgPoliciesFailures(t *testing.T) { + t.Parallel() + + gt := NewGomegaWithT(t) + + baseOrdererConf, _ := baseSoloOrderer(t) + + ordererGroup, err := newOrdererGroup(baseOrdererConf) + gt.Expect(err).NotTo(HaveOccurred()) + + config := &cb.Config{ + ChannelGroup: &cb.ConfigGroup{ + Groups: map[string]*cb.ConfigGroup{ + "Orderer": ordererGroup, + }, + }, + } + + c := New(config) + + newPolicies := map[string]Policy{ + ReadersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Readers", + }, + WritersPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "ANY Writers", + }, + AdminsPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Admins", + }, + EndorsementPolicyKey: { + Type: ImplicitMetaPolicyType, + Rule: "MAJORITY Endorsement", + }, + "TestPolicy": {}, + } + + err = c.Orderer().Organization("OrdererOrg").SetPolicies(AdminsPolicyKey, newPolicies) + gt.Expect(err).To(MatchError("unknown policy type: ")) +} + func TestRemoveOrdererOrgPolicy(t *testing.T) { t.Parallel() diff --git a/configtx/policies.go b/configtx/policies.go index 8d39992..d15f92e 100644 --- a/configtx/policies.go +++ b/configtx/policies.go @@ -202,6 +202,7 @@ func setPolicies(cg *cb.ConfigGroup, policyMap map[string]Policy, modPolicy stri return errors.New("no Writers policy defined") } + cg.Policies = make(map[string]*cb.ConfigPolicy) for policyName, policy := range policyMap { err := setPolicy(cg, modPolicy, policyName, policy) if err != nil {