Skip to content

Commit

Permalink
[FAB-17571] Implement adding/removing policies from orderer
Browse files Browse the repository at this point in the history
- Adding a policy to orderer or orderer org will not error if policy exists
- Removing a policy from an orderer or orderer org will error if policy
    does not exist
- Removing the BlockValidation policy is not allowed

Signed-off-by: Tiffany Harris <tiffany.harris@ibm.com>
  • Loading branch information
stephyee authored and sykesm committed Mar 18, 2020
1 parent 984c3e2 commit 64d6c66
Show file tree
Hide file tree
Showing 3 changed files with 293 additions and 0 deletions.
1 change: 1 addition & 0 deletions pkg/config/orderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ func addOrdererPolicies(cg *cb.ConfigGroup, policyMap map[string]Policy, modPoli
if policyMap == nil {
return errors.New("no policies defined")
}

if _, ok := policyMap[BlockValidationPolicyKey]; !ok {
return errors.New("no BlockValidation policy defined")
}
Expand Down
43 changes: 43 additions & 0 deletions pkg/config/policies.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,49 @@ func RemoveConsortiumOrgPolicy(config *cb.Config, consortiumName, orgName, polic
return nil
}

// AddOrdererPolicy modifies an existing orderer policy configuration.
// When the policy exists it will overwrite the existing policy.
func AddOrdererPolicy(config *cb.Config, modPolicy, policyName string, policy Policy) error {
err := addPolicy(config.ChannelGroup.Groups[OrdererGroupKey], modPolicy, policyName, policy)
if err != nil {
return fmt.Errorf("failed to add policy '%s': %v", policyName, err)
}

return nil
}

// RemoveOrdererPolicy removes an existing orderer policy configuration.
// The policy must exist in the config.
func RemoveOrdererPolicy(config *cb.Config, policyName string) error {
if policyName == BlockValidationPolicyKey {
return errors.New("BlockValidation policy must be defined")
}

policies, err := GetPoliciesForOrderer(*config)
if err != nil {
return err
}

return removePolicy(config.ChannelGroup.Groups[OrdererGroupKey], policyName, policies)
}

// AddOrdererOrgPolicy modifies an existing organization in a orderer configuration's policies.
// When the policy exists it will overwrite the existing policy.
func AddOrdererOrgPolicy(config *cb.Config, orgName, modPolicy, policyName string, policy Policy) error {
return addPolicy(config.ChannelGroup.Groups[OrdererGroupKey].Groups[orgName], modPolicy, policyName, policy)
}

// RemoveOrdererOrgPolicy removes an existing policy from an orderer organization.
// The removed policy must exist however will not error if it does not exist in configuration.
func RemoveOrdererOrgPolicy(config *cb.Config, orgName, policyName string) error {
policies, err := GetPoliciesForOrdererOrg(*config, orgName)
if err != nil {
return err
}

return removePolicy(config.ChannelGroup.Groups[OrdererGroupKey].Groups[orgName], policyName, policies)
}

// getPolicies returns a map of Policy from given map of ConfigPolicy in organization config group.
func getPolicies(policies map[string]*cb.ConfigPolicy) (map[string]Policy, error) {
p := map[string]Policy{}
Expand Down
249 changes: 249 additions & 0 deletions pkg/config/policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,3 +438,252 @@ func TestRemoveConsortiumOrgPolicyFailures(t *testing.T) {
gt.Expect(err).To(MatchError(test.expectedErr))
}
}

func TestAddOrdererPolicy(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = AddOrdererPolicy(config, AdminsPolicyKey, "TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Endorsement"})
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(len(config.ChannelGroup.Groups[OrdererGroupKey].Policies)).To(Equal(5))
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Policies[AdminsPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Policies[ReadersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Policies[WritersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Policies["TestPolicy"]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Policies[BlockValidationPolicyKey]).NotTo(BeNil())
}

func TestAddOrdererPolicyFailures(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = AddOrdererPolicy(config, AdminsPolicyKey, "TestPolicy", Policy{})
gt.Expect(err).To(MatchError("failed to add policy 'TestPolicy': unknown policy type: "))
}

func TestRemoveOrdererPolicy(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()
baseOrdererConf.Policies["TestPolicy"] = baseOrdererConf.Policies[AdminsPolicyKey]

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = RemoveOrdererPolicy(config, "TestPolicy")
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(len(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies)).To(Equal(4))
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[AdminsPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[ReadersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[WritersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[EndorsementPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Policies[BlockValidationPolicyKey]).NotTo(BeNil())
}

func TestRemoveOrdererPolicyFailures(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()
baseOrdererConf.Policies["TestPolicy"] = baseOrdererConf.Policies[AdminsPolicyKey]

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
OrdererGroupKey: ordererGroup,
},
},
}

tests := []struct {
testName string
ordererGrpMod func(cb.ConfigGroup) *cb.ConfigGroup
policyName string
expectedErr string
}{
{
testName: "when removing blockvalidation policy",
ordererGrpMod: func(og cb.ConfigGroup) *cb.ConfigGroup {
return &og
},
policyName: BlockValidationPolicyKey,
expectedErr: "BlockValidation policy must be defined",
},
{
testName: "when orderer is missing",
ordererGrpMod: func(og cb.ConfigGroup) *cb.ConfigGroup {
return nil
},
policyName: "TestPolicy",
expectedErr: "orderer missing from config",
},
{
testName: "when policy does not exist",
ordererGrpMod: func(og cb.ConfigGroup) *cb.ConfigGroup {
delete(og.Policies, "TestPolicy")
return &og
},
policyName: "TestPolicy",
expectedErr: "could not find policy 'TestPolicy'",
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.testName, func(t *testing.T) {
gt := NewGomegaWithT(t)

orderer := tt.ordererGrpMod(*ordererGroup)
if orderer == nil {
delete(config.ChannelGroup.Groups, OrdererGroupKey)
} else {
config.ChannelGroup.Groups[OrdererGroupKey] = orderer
}

err = RemoveOrdererPolicy(config, tt.policyName)
gt.Expect(err).To(MatchError(tt.expectedErr))
})
}
}

func TestAddOrdererOrgPolicy(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = AddOrdererOrgPolicy(config, "OrdererOrg", AdminsPolicyKey, "TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "ANY Endorsement"})
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(len(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies)).To(Equal(5))
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[AdminsPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[ReadersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[WritersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies["TestPolicy"]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[EndorsementPolicyKey]).NotTo(BeNil())
}

func TestAddOrdererOrgPolicyFailures(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = AddOrdererOrgPolicy(config, "OrdererOrg", AdminsPolicyKey, "TestPolicy", Policy{})
gt.Expect(err).To(MatchError("unknown policy type: "))
}

func TestRemoveOrdererOrgPolicy(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()
baseOrdererConf.Organizations[0].Policies["TestPolicy"] = baseOrdererConf.Organizations[0].Policies[AdminsPolicyKey]

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = RemoveOrdererOrgPolicy(config, "OrdererOrg", "TestPolicy")
gt.Expect(err).NotTo(HaveOccurred())
gt.Expect(len(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies)).To(Equal(4))
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[AdminsPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[ReadersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[WritersPolicyKey]).NotTo(BeNil())
gt.Expect(config.ChannelGroup.Groups[OrdererGroupKey].Groups["OrdererOrg"].Policies[EndorsementPolicyKey]).NotTo(BeNil())
}

func TestRemoveOrdererOrgPolicyFailures(t *testing.T) {
t.Parallel()

gt := NewGomegaWithT(t)

baseOrdererConf := baseOrderer()

ordererGroup, err := newOrdererGroup(baseOrdererConf)
gt.Expect(err).NotTo(HaveOccurred())

config := &cb.Config{
ChannelGroup: &cb.ConfigGroup{
Groups: map[string]*cb.ConfigGroup{
"Orderer": ordererGroup,
},
},
}

err = RemoveOrdererOrgPolicy(config, "bad-org", "TestPolicy")
gt.Expect(err).To(MatchError("orderer org bad-org does not exist in channel config"))
}

0 comments on commit 64d6c66

Please sign in to comment.