From e638f2dbe4061207f13b6d1d5dd2d89699def975 Mon Sep 17 00:00:00 2001 From: Will Lahti Date: Tue, 28 Apr 2020 16:48:04 -0400 Subject: [PATCH] Chain APIs for consortium operations FAB-17744 Signed-off-by: Will Lahti --- configtx/config.go | 2 +- configtx/consortiums.go | 283 ++++++++++++++++++++++++++++++---- configtx/consortiums_test.go | 47 ++---- configtx/example_test.go | 10 +- configtx/msp.go | 68 -------- configtx/msp_test.go | 53 ++----- configtx/organization.go | 31 ---- configtx/organization_test.go | 18 +-- configtx/policies.go | 61 -------- configtx/policies_test.go | 51 +++--- 10 files changed, 307 insertions(+), 317 deletions(-) diff --git a/configtx/config.go b/configtx/config.go index 6a9de8d..6c0acbe 100644 --- a/configtx/config.go +++ b/configtx/config.go @@ -168,7 +168,7 @@ func (c *ConfigTx) ChannelConfiguration() (Channel, error) { } if _, ok := channelGroup.Groups[ConsortiumsGroupKey]; ok { - consortiums, err = c.Consortiums() + consortiums, err = c.OriginalConfig().Consortiums().Configuration() if err != nil { return Channel{}, err } diff --git a/configtx/consortiums.go b/configtx/consortiums.go index 22631c6..dd4113c 100644 --- a/configtx/consortiums.go +++ b/configtx/consortiums.go @@ -7,6 +7,8 @@ SPDX-License-Identifier: Apache-2.0 package configtx import ( + "crypto/x509" + "crypto/x509/pkix" "errors" "fmt" @@ -21,15 +23,79 @@ type Consortium struct { Organizations []Organization } +// ConsortiumsGroup encapsulates the parts of the config that control +// consortiums. This type implements retrieval of the various consortiums +// config values. +type ConsortiumsGroup struct { + consortiumsGroup *cb.ConfigGroup +} + +// UpdatedConsortiumsGroup is a ConsortiumsGroup that can be modified in +// order to generate a config update. +type UpdatedConsortiumsGroup struct { + *ConsortiumsGroup +} + +// ConsortiumGroup encapsulates the parts of the config that control +// a specific consortium. This type implements retrieval of the various +// consortium config values. +type ConsortiumGroup struct { + consortiumGroup *cb.ConfigGroup + name string +} + +// UpdatedConsortiumGroup is a ConsortiumGroup that can be modified in order +// to generate a config update. +type UpdatedConsortiumGroup struct { + *ConsortiumGroup +} + +// ConsortiumOrg encapsulates the parts of the config that control a +// consortium organization's configuration. +type ConsortiumOrg struct { + orgGroup *cb.ConfigGroup + name string +} + +// UpdatedConsortiumOrg is a ConsortiumOrg that can be modified in order +// to generate a config update. +type UpdatedConsortiumOrg struct { + *ConsortiumOrg +} + +// Consortiums returns the consortiums group from the original config. +func (o *OriginalConfig) Consortiums() *ConsortiumsGroup { + consortiumsGroup := o.ChannelGroup.Groups[ConsortiumsGroupKey] + return &ConsortiumsGroup{consortiumsGroup: consortiumsGroup} +} + +// Consortiums returns the consortiums group from the updated config. +func (u *UpdatedConfig) Consortiums() *UpdatedConsortiumsGroup { + consortiumsGroup := u.ChannelGroup.Groups[ConsortiumsGroupKey] + return &UpdatedConsortiumsGroup{&ConsortiumsGroup{consortiumsGroup: consortiumsGroup}} +} + +// Consortium returns a consortium group from the original config. +func (c *ConsortiumsGroup) Consortium(name string) *ConsortiumGroup { + consortiumGroup, ok := c.consortiumsGroup.Groups[name] + if !ok { + return nil + } + return &ConsortiumGroup{name: name, consortiumGroup: consortiumGroup} +} + +// Consortium returns a consortium group from the updated config. +func (u *UpdatedConsortiumsGroup) Consortium(name string) *UpdatedConsortiumGroup { + return &UpdatedConsortiumGroup{ConsortiumGroup: u.ConsortiumsGroup.Consortium(name)} +} + // SetConsortium sets the consortium in a channel configuration. // If the consortium already exists in the current configuration, its value will be overwritten. -func (c *ConfigTx) SetConsortium(consortium Consortium) error { - consortiumsGroup := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey] - - consortiumsGroup.Groups[consortium.Name] = newConfigGroup() +func (u *UpdatedConsortiumsGroup) SetConsortium(consortium Consortium) error { + u.consortiumsGroup.Groups[consortium.Name] = newConfigGroup() for _, org := range consortium.Organizations { - err := c.SetConsortiumOrg(org, consortium.Name) + err := u.Consortium(consortium.Name).SetOrganization(org) if err != nil { return err } @@ -40,43 +106,51 @@ func (c *ConfigTx) SetConsortium(consortium Consortium) error { // RemoveConsortium removes a consortium from a channel configuration. // Removal will panic if the consortiums group does not exist. -func (c *ConfigTx) RemoveConsortium(consortiumName string) { - consortiumGroup := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups - - delete(consortiumGroup, consortiumName) +func (u *UpdatedConsortiumsGroup) RemoveConsortium(name string) { + delete(u.consortiumsGroup.Groups, name) } -// SetConsortiumOrg sets the organization config group for the given org key in a existing -// Consortium configuration's Groups map. -// If the consortium org already exists in the current configuration, its value will be overwritten. -func (c *ConfigTx) SetConsortiumOrg(org Organization, consortium string) error { - var err error - - if consortium == "" { - return errors.New("consortium is required") +// Organization returns the consortium org from the original config. +func (c *ConsortiumGroup) Organization(name string) *ConsortiumOrg { + orgGroup, ok := c.consortiumGroup.Groups[name] + if !ok { + return nil } + return &ConsortiumOrg{name: name, orgGroup: orgGroup} +} - consortiumGroup := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortium] +// Organization returns the consortium org from the original updated config. +func (u *UpdatedConsortiumGroup) Organization(name string) *UpdatedConsortiumOrg { + return &UpdatedConsortiumOrg{ConsortiumOrg: u.ConsortiumGroup.Organization(name)} +} - consortiumGroup.Groups[org.Name], err = newOrgConfigGroup(org) +// SetOrganization sets the organization config group for the given org key in +// an existing Consortium configuration's Groups map. +// If the consortium org already exists in the current configuration, its +// value will be overwritten. +func (u *UpdatedConsortiumGroup) SetOrganization(org Organization) error { + orgGroup, err := newOrgConfigGroup(org) if err != nil { - return fmt.Errorf("failed to create consortium org: %v", err) + return fmt.Errorf("failed to create consortium org %s: %v", org.Name, err) } + u.consortiumGroup.Groups[org.Name] = orgGroup + return nil } -// Consortiums returns a list of consortiums for the channel configuration. -// Consortiums is only defined for the ordering system channel. -func (c *ConfigTx) Consortiums() ([]Consortium, error) { - consortiumsGroup, ok := c.original.ChannelGroup.Groups[ConsortiumsGroupKey] - if !ok { - return nil, errors.New("channel configuration does not have consortiums") - } +// RemoveOrganization removes an org from a consortium group. +// Removal will panic if either the consortiums group or consortium group does not exist. +func (u *UpdatedConsortiumGroup) RemoveOrganization(name string) { + delete(u.consortiumGroup.Groups, name) +} +// Configuration returns a list of consortium configurations from the original +// config. Consortiums are only defined for the ordering system channel. +func (c *ConsortiumsGroup) Configuration() ([]Consortium, error) { consortiums := []Consortium{} - for consortiumName, consortiumGroup := range consortiumsGroup.Groups { - consortium, err := consortium(consortiumGroup, consortiumName) + for consortiumName := range c.consortiumsGroup.Groups { + consortium, err := c.Consortium(consortiumName).Configuration() if err != nil { return nil, err } @@ -86,22 +160,163 @@ func (c *ConfigTx) Consortiums() ([]Consortium, error) { return consortiums, nil } -// consortium returns a value of consortium from the given consortium configGroup -func consortium(consortiumGroup *cb.ConfigGroup, consortiumName string) (Consortium, error) { +// Configuration returns a list of consortium configurations from the updated +// config. Consortiums are only defined for the ordering system channel. +func (u *UpdatedConsortiumsGroup) Configuration() ([]Consortium, error) { + return u.ConsortiumsGroup.Configuration() +} + +// Configuration returns the configuration for a consortium group +func (c *ConsortiumGroup) Configuration() (Consortium, error) { orgs := []Organization{} - for orgName, orgGroup := range consortiumGroup.Groups { + for orgName, orgGroup := range c.consortiumGroup.Groups { org, err := getOrganization(orgGroup, orgName) if err != nil { - return Consortium{}, fmt.Errorf("failed to retrieve organization %s from consortium %s: ", orgName, consortiumName) + return Consortium{}, fmt.Errorf("failed to retrieve organization %s from consortium %s: ", orgName, c.name) } orgs = append(orgs, org) } return Consortium{ - Name: consortiumName, + Name: c.name, Organizations: orgs, }, nil } +// Configuration returns the configuration for a consortium group +func (u *UpdatedConsortiumGroup) Configuration() (Consortium, error) { + return u.ConsortiumGroup.Configuration() +} + +// Configuration retrieves an existing org's configuration from a consortium organization +// config group in the original config. +func (c *ConsortiumOrg) Configuration() (Organization, error) { + org, err := getOrganization(c.orgGroup, c.name) + if err != nil { + return Organization{}, err + } + + // Remove AnchorPeers which are application org specific. + org.AnchorPeers = nil + + return org, err +} + +// Configuration retrieves an existing org's configuration from a consortium organization +// config group in the updated config. +func (u *UpdatedConsortiumOrg) Configuration() (Organization, error) { + return u.ConsortiumOrg.Configuration() +} + +// MSP returns the MSP configuration for an existing consortium +// org in a config transaction. +func (c *ConsortiumOrg) MSP() (MSP, error) { + return getMSPConfig(c.orgGroup) +} + +// MSP returns the MSP configuration for an existing consortium +// org in a config transaction. +func (u *UpdatedConsortiumOrg) MSP() (MSP, error) { + return getMSPConfig(u.ConsortiumOrg.orgGroup) +} + +// CreateMSPCRL creates a CRL that revokes the provided certificates +// for the specified consortium org signed by the provided SigningIdentity. +func (u *UpdatedConsortiumOrg) CreateMSPCRL(signingIdentity *SigningIdentity, certs ...*x509.Certificate) (*pkix.CertificateList, error) { + msp, err := u.MSP() + if err != nil { + return nil, fmt.Errorf("retrieving consortium org msp: %s", err) + } + + return msp.newMSPCRL(signingIdentity, certs...) +} + +// SetMSP updates the MSP config for the specified consortium org group. +func (u *UpdatedConsortiumOrg) SetMSP(updatedMSP MSP) error { + currentMSP, err := u.MSP() + if err != nil { + return fmt.Errorf("retrieving msp: %v", err) + } + + if currentMSP.Name != updatedMSP.Name { + return errors.New("MSP name cannot be changed") + } + + err = updatedMSP.validateCACerts() + if err != nil { + return err + } + + err = u.setMSPConfig(updatedMSP) + if err != nil { + return err + } + + return nil +} + +func (u *UpdatedConsortiumOrg) setMSPConfig(updatedMSP MSP) error { + mspConfig, err := newMSPConfig(updatedMSP) + if err != nil { + return fmt.Errorf("new msp config: %v", err) + } + + err = setValue(u.ConsortiumOrg.orgGroup, mspValue(mspConfig), AdminsPolicyKey) + if err != nil { + return err + } + + return nil +} + +// SetChannelCreationPolicy sets the ConsortiumChannelCreationPolicy for +// the given configuration Group. +// If the policy already exist in current configuration, its value will be overwritten. +func (u *UpdatedConsortiumGroup) SetChannelCreationPolicy(policy Policy) error { + imp, err := implicitMetaFromString(policy.Rule) + if err != nil { + return fmt.Errorf("invalid implicit meta policy rule '%s': %v", policy.Rule, err) + } + + implicitMetaPolicy, err := implicitMetaPolicy(imp.SubPolicy, imp.Rule) + if err != nil { + return fmt.Errorf("failed to make implicit meta policy: %v", err) + } + + // update channel creation policy value back to consortium + if err = setValue(u.ConsortiumGroup.consortiumGroup, channelCreationPolicyValue(implicitMetaPolicy), ordererAdminsPolicyName); err != nil { + return fmt.Errorf("failed to update channel creation policy to consortium %s: %v", u.name, err) + } + + return nil +} + +// Policies returns a map of policies for a specific consortium org. +func (c *ConsortiumOrg) Policies() (map[string]Policy, error) { + return getPolicies(c.orgGroup.Policies) +} + +// Policies returns a map of policies for a specific consortium org. +func (u *UpdatedConsortiumOrg) Policies() (map[string]Policy, error) { + return u.ConsortiumOrg.Policies() +} + +// 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. +func (u *UpdatedConsortiumOrg) SetPolicy(name string, policy Policy) error { + err := setPolicy(u.ConsortiumOrg.orgGroup, AdminsPolicyKey, name, policy) + if err != nil { + return fmt.Errorf("failed to set policy '%s' to consortium org '%s': %v", name, u.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 (u *UpdatedConsortiumOrg) RemovePolicy(name string) { + delete(u.ConsortiumOrg.orgGroup.Policies, name) +} + // 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". diff --git a/configtx/consortiums_test.go b/configtx/consortiums_test.go index 92fed45..1e84b8d 100644 --- a/configtx/consortiums_test.go +++ b/configtx/consortiums_test.go @@ -778,7 +778,7 @@ func TestSetConsortiumOrg(t *testing.T) { err = protolator.DeepUnmarshalJSON(bytes.NewBufferString(expectedConfigJSON), expectedConfigProto) gt.Expect(err).NotTo(HaveOccurred()) - err = c.SetConsortiumOrg(orgToAdd, "Consortium1") + err = c.UpdatedConfig().Consortiums().Consortium("Consortium1").SetOrganization(orgToAdd) gt.Expect(err).NotTo(HaveOccurred()) gt.Expect(proto.Equal(c.UpdatedConfig().Config, expectedConfigProto)).To(BeTrue()) @@ -788,8 +788,7 @@ func TestSetConsortiumOrgFailures(t *testing.T) { t.Parallel() orgToAdd := Organization{ - Name: "test-org", - Policies: orgStandardPolicies(), + Name: "test-org", } for _, test := range []struct { @@ -800,10 +799,10 @@ func TestSetConsortiumOrgFailures(t *testing.T) { expectedErr string }{ { - name: "When the consortium name is not specified", + name: "When the organization doesn't have policies defined", org: orgToAdd, consortium: "", - expectedErr: "consortium is required", + expectedErr: "failed to create consortium org test-org: no policies defined", }, } { test := test @@ -826,7 +825,7 @@ func TestSetConsortiumOrgFailures(t *testing.T) { c := New(config) - err = c.SetConsortiumOrg(test.org, test.consortium) + err = c.UpdatedConfig().Consortiums().Consortium(test.consortium).SetOrganization(test.org) gt.Expect(err).To(MatchError(test.expectedErr)) }) } @@ -853,10 +852,10 @@ func TestRemoveConsortium(t *testing.T) { c := New(config) - c.RemoveConsortium("Consortium1") + c.UpdatedConfig().Consortiums().RemoveConsortium("Consortium1") - updatedConsortiumsGroup := c.UpdatedConfig().ChannelGroup.Groups[ConsortiumsGroupKey] - gt.Expect(updatedConsortiumsGroup.Groups["Consortium1"]).To(BeNil()) + updatedConsortiumsGroup := c.UpdatedConfig().Consortiums() + gt.Expect(updatedConsortiumsGroup.Consortium("Consortium1").ConsortiumGroup).To(BeNil()) } func TestGetConsortiums(t *testing.T) { @@ -880,7 +879,7 @@ func TestGetConsortiums(t *testing.T) { config := &cb.Config{ChannelGroup: channelGroup} c := New(config) - consortiums, err := c.Consortiums() + consortiums, err := c.OriginalConfig().Consortiums().Configuration() gt.Expect(err).NotTo(HaveOccurred()) gt.Expect(len(baseConsortiums)).To(Equal(len(consortiums))) } @@ -922,7 +921,7 @@ func TestSetConsortium(t *testing.T) { newConsortium := consortiums[0] newConsortium.Name = "Consortium2" - err = c.SetConsortium(newConsortium) + err = c.UpdatedConfig().Consortiums().SetConsortium(newConsortium) gt.Expect(err).NotTo(HaveOccurred()) org1CertBase64, org1PKBase64, org1CRLBase64 := certPrivKeyCRLBase64(t, consortiums[0].Organizations[0].MSP) @@ -1471,32 +1470,6 @@ func TestSetConsortium(t *testing.T) { gt.Expect(proto.Equal(c.UpdatedConfig().Config, expectedConfigProto)).To(BeTrue()) } -func TestSetConsortiumFailures(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{ - "Consortiums": consortiumsGroup, - }, - }, - } - - c := New(config) - - newConsortium := consortiums[0] - newConsortium.Name = "" - - err = c.SetConsortium(newConsortium) - gt.Expect(err).To(MatchError("consortium is required")) -} - func baseConsortiums(t *testing.T) []Consortium { return []Consortium{ { diff --git a/configtx/example_test.go b/configtx/example_test.go index 69acf3c..bd25d94 100644 --- a/configtx/example_test.go +++ b/configtx/example_test.go @@ -87,7 +87,7 @@ func Example_basic() { baseConfig := fetchSystemChannelConfig() c := configtx.New(baseConfig) - err := c.SetConsortiumChannelCreationPolicy("SampleConsortium", + err := c.UpdatedConfig().Consortiums().Consortium("SampleConsortium").SetChannelCreationPolicy( configtx.Policy{Type: configtx.ImplicitMetaPolicyType, Rule: "MAJORITY Admins"}) if err != nil { @@ -548,11 +548,13 @@ func ExampleUpdatedOrdererOrg_SetMSP() { // This example shows the addition of a certificate to a consortium org's intermediate // certificate list. -func ExampleConfigTx_SetConsortiumMSP() { +func ExampleUpdatedConsortiumOrg_SetMSP() { baseConfig := fetchSystemChannelConfig() c := configtx.New(baseConfig) - msp, err := c.ConsortiumMSP("SampleConsortium", "Org1") + sampleConsortiumOrg1 := c.UpdatedConfig().Consortiums().Consortium("SampleConsortium").Organization("Org1") + + msp, err := sampleConsortiumOrg1.MSP() if err != nil { panic(err) } @@ -564,7 +566,7 @@ func ExampleConfigTx_SetConsortiumMSP() { msp.IntermediateCerts = append(msp.IntermediateCerts, newIntermediateCert) - err = c.SetConsortiumMSP(msp, "SampleConsortium", "Org1") + err = sampleConsortiumOrg1.SetMSP(msp) if err != nil { panic(err) } diff --git a/configtx/msp.go b/configtx/msp.go index d844bc4..fd5ece1 100644 --- a/configtx/msp.go +++ b/configtx/msp.go @@ -13,7 +13,6 @@ import ( "crypto/x509/pkix" "encoding/asn1" "encoding/pem" - "errors" "fmt" "time" @@ -76,36 +75,9 @@ type MSP struct { NodeOus membership.NodeOUs } -// ConsortiumMSP returns the MSP configuration for an existing consortium -// org in a config transaction. -func (c *ConfigTx) ConsortiumMSP(consortiumName, orgName string) (MSP, error) { - consortiumGroup, ok := c.original.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName] - if !ok { - return MSP{}, fmt.Errorf("consortium %s does not exist in config", consortiumName) - } - - consortiumOrgGroup, ok := consortiumGroup.Groups[orgName] - if !ok { - return MSP{}, fmt.Errorf("consortium org %s does not exist in config", orgName) - } - - return getMSPConfig(consortiumOrgGroup) -} - // YEAR is a time duration for a standard 365 day year. const YEAR = 365 * 24 * time.Hour -// CreateConsortiumOrgMSPCRL creates a CRL that revokes the provided certificates -// for the specified consortium org signed by the provided SigningIdentity. -func (c *ConfigTx) CreateConsortiumOrgMSPCRL(consortiumName string, orgName string, signingIdentity *SigningIdentity, certs ...*x509.Certificate) (*pkix.CertificateList, error) { - msp, err := c.ConsortiumMSP(consortiumName, orgName) - if err != nil { - return nil, fmt.Errorf("retrieving consortium org msp: %s", err) - } - - return msp.newMSPCRL(signingIdentity, certs...) -} - // newMSPCRL creates a CRL that revokes the provided certificates for the specified org // signed by the provided SigningIdentity. If any of the provided certs were // not signed by any of the root/intermediate CA cets in the MSP configuration, @@ -516,30 +488,6 @@ func pemEncodePKCS8PrivateKey(priv crypto.PrivateKey) ([]byte, error) { return pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}), nil } -// SetConsortiumMSP updates the MSP config for the specified consortium org group. -func (c *ConfigTx) SetConsortiumMSP(updatedMSP MSP, consortiumName string, orgName string) error { - currentMSP, err := c.ConsortiumMSP(consortiumName, orgName) - if err != nil { - return fmt.Errorf("retrieving msp: %v", err) - } - - if currentMSP.Name != updatedMSP.Name { - return errors.New("MSP name cannot be changed") - } - - err = updatedMSP.validateCACerts() - if err != nil { - return err - } - - err = setMSPConfigForConsortium(c.UpdatedConfig().Config, updatedMSP, consortiumName, orgName) - if err != nil { - return err - } - - return nil -} - // newMSPConfig returns an config for a msp. func newMSPConfig(updatedMSP MSP) (*mb.MSPConfig, error) { fabricMSPConfig, err := updatedMSP.toProto() @@ -559,22 +507,6 @@ func newMSPConfig(updatedMSP MSP) (*mb.MSPConfig, error) { return mspConfig, nil } -func setMSPConfigForConsortium(config *cb.Config, updatedMSP MSP, consortiumName string, orgName string) error { - mspConfig, err := newMSPConfig(updatedMSP) - if err != nil { - return fmt.Errorf("new msp config: %v", err) - } - - consortiumGroup := getConsortiumOrg(config, consortiumName, orgName) - - err = setValue(consortiumGroup, mspValue(mspConfig), AdminsPolicyKey) - if err != nil { - return err - } - - return nil -} - func (m *MSP) validateCACerts() error { err := validateCACerts(m.RootCerts) if err != nil { diff --git a/configtx/msp_test.go b/configtx/msp_test.go index 7972ac2..8aef3ee 100644 --- a/configtx/msp_test.go +++ b/configtx/msp_test.go @@ -115,7 +115,7 @@ func TestConsortiumMSP(t *testing.T) { c := New(config) - msp, err := c.ConsortiumMSP("Consortium1", "Org1") + msp, err := c.OriginalConfig().Consortiums().Consortium("Consortium1").Organization("Org1").MSP() gt.Expect(err).NotTo(HaveOccurred()) gt.Expect(msp).To(Equal(expectedMSP)) } @@ -133,19 +133,6 @@ func TestMSPConfigurationFailures(t *testing.T) { mspMod func(*MSP) expectedErr string }{ - { - name: "Consortium does not exist", - orgType: ConsortiumsGroupKey, - consortiumName: "BadConsortium", - expectedErr: "consortium BadConsortium does not exist in config", - }, - { - name: "Consortium Org does not exist", - orgType: ConsortiumsGroupKey, - consortiumName: "Consortium1", - orgName: "BadOrg", - expectedErr: "consortium org BadOrg does not exist in config", - }, { name: "Bad root cert", orgType: OrdererGroupKey, @@ -306,7 +293,7 @@ func TestMSPConfigurationFailures(t *testing.T) { _, err := c.OriginalConfig().Orderer().Organization(tt.orgName).MSP() gt.Expect(err).To(MatchError(tt.expectedErr)) case ConsortiumsGroupKey: - _, err := c.ConsortiumMSP(tt.consortiumName, tt.orgName) + _, err := c.UpdatedConfig().Consortiums().Consortium(tt.consortiumName).Organization(tt.orgName).MSP() gt.Expect(err).To(MatchError(tt.expectedErr)) default: t.Fatalf("invalid org type %s", tt.orgType) @@ -404,7 +391,7 @@ func TestMSPToProtoFailure(t *testing.T) { gt.Expect(fabricMSPConfigProto).To(BeNil()) } -func TestUpdateConsortiumMsp(t *testing.T) { +func TestSetConsortiumMSP(t *testing.T) { t.Parallel() gt := NewGomegaWithT(t) @@ -416,9 +403,10 @@ func TestUpdateConsortiumMsp(t *testing.T) { } c := New(config) - consortiumOrg1MSP, err := c.ConsortiumMSP("Consortium1", "Org1") + consortium1 := c.UpdatedConfig().Consortiums().Consortium("Consortium1") + consortiumOrg1MSP, err := consortium1.Organization("Org1").MSP() gt.Expect(err).NotTo(HaveOccurred()) - consortiumOrg2MSP, err := c.ConsortiumMSP("Consortium1", "Org2") + consortiumOrg2MSP, err := consortium1.Organization("Org2").MSP() gt.Expect(err).NotTo(HaveOccurred()) consortiumOrg1CertBase64, consortiumOrg1PKBase64, consortiumOrg1CRLBase64 := certPrivKeyCRLBase64(t, consortiumOrg1MSP) consortiumOrg2CertBase64, consortiumOrg2PKBase64, consortiumOrg2CRLBase64 := certPrivKeyCRLBase64(t, consortiumOrg2MSP) @@ -438,14 +426,14 @@ func TestUpdateConsortiumMsp(t *testing.T) { PrivateKey: privKey, MSPID: "MSPID", } - newCRL, err := c.CreateConsortiumOrgMSPCRL("Consortium1", "Org1", signingIdentity, certToRevoke) + newCRL, err := consortium1.Organization("Org1").CreateMSPCRL(signingIdentity, certToRevoke) gt.Expect(err).NotTo(HaveOccurred()) pemNewCRL, err := pemEncodeCRL(newCRL) gt.Expect(err).NotTo(HaveOccurred()) newCRLBase64 := base64.StdEncoding.EncodeToString(pemNewCRL) consortiumOrg1MSP.RevocationList = append(consortiumOrg1MSP.RevocationList, newCRL) - err = c.SetConsortiumMSP(consortiumOrg1MSP, "Consortium1", "Org1") + err = consortium1.Organization("Org1").SetMSP(consortiumOrg1MSP) gt.Expect(err).NotTo(HaveOccurred()) expectedConfigJSON := fmt.Sprintf(` @@ -752,7 +740,7 @@ func TestUpdateConsortiumMsp(t *testing.T) { gt.Expect(buf.String()).To(MatchJSON(expectedConfigJSON)) } -func TestUpdateConsortiumMspFailure(t *testing.T) { +func TestSetConsortiumMSPFailure(t *testing.T) { t.Parallel() tests := []struct { @@ -762,24 +750,6 @@ func TestUpdateConsortiumMspFailure(t *testing.T) { orgName string expectedErr string }{ - { - spec: "consortium not defined", - mspMod: func(msp MSP) MSP { - return msp - }, - consortiumName: "undefined-consortium", - orgName: "Org1", - expectedErr: "retrieving msp: consortium undefined-consortium does not exist in config", - }, - { - spec: "consortium org msp not defined", - mspMod: func(msp MSP) MSP { - return msp - }, - consortiumName: "Consortium1", - orgName: "undefined-org", - expectedErr: "retrieving msp: consortium org undefined-org does not exist in config", - }, { spec: "updating msp name", mspMod: func(msp MSP) MSP { @@ -821,11 +791,12 @@ func TestUpdateConsortiumMspFailure(t *testing.T) { } c := New(config) - consortiumOrg1MSP, err := c.ConsortiumMSP("Consortium1", "Org1") + consortiumOrg1 := c.UpdatedConfig().Consortiums().Consortium("Consortium1").Organization("Org1") + consortiumOrg1MSP, err := consortiumOrg1.MSP() gt.Expect(err).NotTo(HaveOccurred()) consortiumOrg1MSP = tc.mspMod(consortiumOrg1MSP) - err = c.SetConsortiumMSP(consortiumOrg1MSP, tc.consortiumName, tc.orgName) + err = consortiumOrg1.SetMSP(consortiumOrg1MSP) gt.Expect(err).To(MatchError(tc.expectedErr)) }) } diff --git a/configtx/organization.go b/configtx/organization.go index 74c0c51..84ccbfb 100644 --- a/configtx/organization.go +++ b/configtx/organization.go @@ -15,37 +15,6 @@ import ( pb "github.com/hyperledger/fabric-protos-go/peer" ) -// ConsortiumOrg retrieves an existing org from a consortium organization config group. -func (c *ConfigTx) ConsortiumOrg(consortiumName, orgName string) (Organization, error) { - consortium, ok := c.original.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName] - if !ok { - return Organization{}, fmt.Errorf("consortium %s does not exist in channel config", consortiumName) - } - orgGroup, ok := consortium.Groups[orgName] - if !ok { - return Organization{}, fmt.Errorf("consortium org %s does not exist in channel config", orgName) - } - - org, err := getOrganization(orgGroup, orgName) - if err != nil { - return Organization{}, err - } - - // Remove AnchorPeers which are application org specific. - org.AnchorPeers = nil - - return org, err -} - -// RemoveConsortiumOrg removes an org from a consortium's group. -// Removal will panic if either the consortiums group or consortium group does not exist. -func (c *ConfigTx) RemoveConsortiumOrg(consortiumName, orgName string) { - consortium := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName] - - delete(consortium.Groups, orgName) - -} - // newOrgConfigGroup returns an config group for an organization. // It defines the crypto material for the organization (its MSP). // It sets the mod_policy of all elements to "Admins". diff --git a/configtx/organization_test.go b/configtx/organization_test.go index cf3eceb..33e4268 100644 --- a/configtx/organization_test.go +++ b/configtx/organization_test.go @@ -197,18 +197,6 @@ func TestConsortiumOrg(t *testing.T) { orgName: "Org1", expectedErr: "", }, - { - name: "consortium not defined", - consortiumName: "bad-consortium", - orgName: "Org1", - expectedErr: "consortium bad-consortium does not exist in channel config", - }, - { - name: "organization not defined", - consortiumName: "Consortium1", - orgName: "bad-org", - expectedErr: "consortium org bad-org does not exist in channel config", - }, } for _, tc := range tests { @@ -217,7 +205,7 @@ func TestConsortiumOrg(t *testing.T) { t.Parallel() gt := NewGomegaWithT(t) - org, err := c.ConsortiumOrg(tc.consortiumName, tc.orgName) + org, err := c.UpdatedConfig().Consortiums().Consortium(tc.consortiumName).Organization(tc.orgName).Configuration() if tc.expectedErr != "" { gt.Expect(Organization{}).To(Equal(org)) gt.Expect(err).To(MatchError(tc.expectedErr)) @@ -243,8 +231,8 @@ func TestRemoveConsortiumOrg(t *testing.T) { c := New(config) - c.RemoveConsortiumOrg("Consortium1", "Org1") - gt.Expect(c.UpdatedConfig().ChannelGroup.Groups[ConsortiumsGroupKey].Groups["Consortium1"].Groups["Org1"]).To(BeNil()) + c.UpdatedConfig().Consortiums().Consortium("Consortium1").RemoveOrganization("Org1") + gt.Expect(c.UpdatedConfig().Consortiums().Consortium("Consortium1").Organization("Org1").ConsortiumOrg).To(BeNil()) } func TestNewOrgConfigGroup(t *testing.T) { diff --git a/configtx/policies.go b/configtx/policies.go index d92cafb..0639035 100644 --- a/configtx/policies.go +++ b/configtx/policies.go @@ -18,72 +18,11 @@ import ( mb "github.com/hyperledger/fabric-protos-go/msp" ) -// SetConsortiumChannelCreationPolicy sets the ConsortiumChannelCreationPolicy for -// the given configuration Group. -// If the policy already exist in current configuration, its value will be overwritten. -func (c *ConfigTx) SetConsortiumChannelCreationPolicy(consortiumName string, policy Policy) error { - consortium := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName] - - imp, err := implicitMetaFromString(policy.Rule) - if err != nil { - return fmt.Errorf("invalid implicit meta policy rule '%s': %v", policy.Rule, err) - } - - implicitMetaPolicy, err := implicitMetaPolicy(imp.SubPolicy, imp.Rule) - if err != nil { - return fmt.Errorf("failed to make implicit meta policy: %v", err) - } - - // update channel creation policy value back to consortium - if err = setValue(consortium, channelCreationPolicyValue(implicitMetaPolicy), ordererAdminsPolicyName); err != nil { - return fmt.Errorf("failed to update channel creation policy to consortium %s: %v", consortiumName, err) - } - - return nil -} - -// ConsortiumOrgPolicies returns a map of policies for a specific consortium org. -func (c *ConfigTx) ConsortiumOrgPolicies(consortiumName, orgName string) (map[string]Policy, error) { - consortium, ok := c.original.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName] - if !ok { - return nil, fmt.Errorf("consortium %s does not exist in channel config", consortiumName) - } - - org, ok := consortium.Groups[orgName] - if !ok { - return nil, fmt.Errorf("consortium org %s does not exist in channel config", orgName) - } - - return getPolicies(org.Policies) -} - // ChannelPolicies returns a map of policies for channel configuration. func (c *ConfigTx) ChannelPolicies() (map[string]Policy, error) { return getPolicies(c.original.ChannelGroup.Policies) } -// SetConsortiumOrgPolicy 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. -func (c *ConfigTx) SetConsortiumOrgPolicy(consortiumName, orgName, policyName string, policy Policy) error { - orgGroup := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName].Groups[orgName] - - err := setPolicy(orgGroup, AdminsPolicyKey, policyName, policy) - if err != nil { - return fmt.Errorf("failed to set policy '%s' to consortium org '%s': %v", policyName, orgName, err) - } - - return nil -} - -// RemoveConsortiumOrgPolicy 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 *ConfigTx) RemoveConsortiumOrgPolicy(consortiumName, orgName, policyName string) { - orgGroup := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups[consortiumName].Groups[orgName] - - delete(orgGroup.Policies, policyName) - -} - // SetChannelPolicy 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. func (c *ConfigTx) SetChannelPolicy(modPolicy, policyName string, policy Policy) error { diff --git a/configtx/policies_test.go b/configtx/policies_test.go index 849cbe9..33a1580 100644 --- a/configtx/policies_test.go +++ b/configtx/policies_test.go @@ -361,11 +361,11 @@ func TestSetConsortiumOrgPolicy(t *testing.T) { }, } - err = c.SetConsortiumOrgPolicy("Consortium1", "Org1", "TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "MAJORITY Endorsement"}) + consortium1Org1 := c.UpdatedConfig().Consortiums().Consortium("Consortium1").Organization("Org1") + err = consortium1Org1.SetPolicy("TestPolicy", Policy{Type: ImplicitMetaPolicyType, Rule: "MAJORITY Endorsement"}) gt.Expect(err).NotTo(HaveOccurred()) - consortium1Org1 := c.updated.ChannelGroup.Groups[ConsortiumsGroupKey].Groups["Consortium1"].Groups["Org1"] - updatedPolicies, err := getPolicies(consortium1Org1.Policies) + updatedPolicies, err := consortium1Org1.Policies() gt.Expect(err).NotTo(HaveOccurred()) gt.Expect(updatedPolicies).To(Equal(expectedPolicies)) } @@ -405,7 +405,7 @@ func TestSetConsortiumOrgPolicyFailures(t *testing.T) { expectedErr: "failed to set policy 'TestPolicy' to consortium org 'Org1': unknown policy type: ", }, } { - err := c.SetConsortiumOrgPolicy(test.consortium, test.org, "TestPolicy", test.policy) + err := c.UpdatedConfig().Consortiums().Consortium(test.consortium).Organization(test.org).SetPolicy("TestPolicy", test.policy) gt.Expect(err).To(MatchError(test.expectedErr)) } } @@ -451,10 +451,10 @@ func TestRemoveConsortiumOrgPolicy(t *testing.T) { }, } - c.RemoveConsortiumOrgPolicy("Consortium1", "Org1", "TestPolicy") + consortium1Org1 := c.UpdatedConfig().Consortiums().Consortium("Consortium1").Organization("Org1") + consortium1Org1.RemovePolicy("TestPolicy") - consortium1Org1 := c.UpdatedConfig().ChannelGroup.Groups[ConsortiumsGroupKey].Groups["Consortium1"].Groups["Org1"] - updatedPolicies, err := getPolicies(consortium1Org1.Policies) + updatedPolicies, err := consortium1Org1.Policies() gt.Expect(err).NotTo(HaveOccurred()) gt.Expect(updatedPolicies).To(Equal(expectedPolicies)) } @@ -783,11 +783,11 @@ func TestSetConsortiumChannelCreationPolicy(t *testing.T) { updatedPolicy := Policy{Type: ImplicitMetaPolicyType, Rule: "MAJORITY Admins"} - err = c.SetConsortiumChannelCreationPolicy("Consortium1", updatedPolicy) + consortium1 := c.UpdatedConfig().Consortiums().Consortium("Consortium1") + err = consortium1.SetChannelCreationPolicy(updatedPolicy) gt.Expect(err).NotTo(HaveOccurred()) - consortium := c.UpdatedConfig().ChannelGroup.Groups[ConsortiumsGroupKey].Groups["Consortium1"] - creationPolicy := consortium.Values[ChannelCreationPolicyKey] + creationPolicy := consortium1.consortiumGroup.Values[ChannelCreationPolicyKey] policy := &cb.Policy{} err = proto.Unmarshal(creationPolicy.Value, policy) gt.Expect(err).NotTo(HaveOccurred()) @@ -836,7 +836,7 @@ func TestSetConsortiumChannelCreationPolicyFailures(t *testing.T) { tt := tt t.Run(tt.name, func(t *testing.T) { gt := NewGomegaWithT(t) - err := c.SetConsortiumChannelCreationPolicy(tt.consortiumName, tt.updatedpolicy) + err := c.UpdatedConfig().Consortiums().Consortium(tt.consortiumName).SetChannelCreationPolicy(tt.updatedpolicy) gt.Expect(err).To(MatchError(tt.expectedErr)) }) } @@ -971,11 +971,12 @@ func TestConsortiumOrgPolicies(t *testing.T) { }, } - policies, err := c.ConsortiumOrgPolicies("Consortium1", "Org1") + policies, err := c.UpdatedConfig().Consortiums().Consortium("Consortium1").Organization("Org1").Policies() gt.Expect(err).NotTo(HaveOccurred()) gt.Expect(policies).To(Equal(expectedPolicies)) } +// TODO add valid tests here func TestConsortiumOrgPoliciesFailures(t *testing.T) { t.Parallel() @@ -1002,24 +1003,24 @@ func TestConsortiumOrgPoliciesFailures(t *testing.T) { orgName string expectedErr string }{ - { - testName: "when consortium does not exist", - consortiumName: "BadConsortium", - orgName: "Org1", - expectedErr: "consortium BadConsortium does not exist in channel config", - }, - { - testName: "when org does not exist", - consortiumName: "Consortium1", - orgName: "BadOrg", - expectedErr: "consortium org BadOrg does not exist in channel config", - }, + // { + // testName: "when consortium does not exist", + // consortiumName: "BadConsortium", + // orgName: "Org1", + // expectedErr: "consortium BadConsortium does not exist in channel config", + // }, + // { + // testName: "when org does not exist", + // consortiumName: "Consortium1", + // orgName: "BadOrg", + // expectedErr: "consortium org BadOrg does not exist in channel config", + // }, } for _, tt := range tests { tt := tt t.Run(tt.testName, func(t *testing.T) { - _, err = c.ConsortiumOrgPolicies(tt.consortiumName, tt.orgName) + _, err = c.UpdatedConfig().Consortiums().Consortium(tt.consortiumName).Organization(tt.orgName).Policies() gt.Expect(err).To(MatchError(tt.expectedErr)) }) }