diff --git a/config/crd/crd.projectcalico.org_ippools.yaml b/config/crd/crd.projectcalico.org_ippools.yaml index 5fbdc9488a8..41814a20a09 100644 --- a/config/crd/crd.projectcalico.org_ippools.yaml +++ b/config/crd/crd.projectcalico.org_ippools.yaml @@ -45,6 +45,10 @@ spec: cidr: description: The pool CIDR. type: string + disableBGPExport: + description: 'Disable exporting routes from this IP Pool’s CIDR over + BGP. [Default: false]' + type: boolean disabled: description: When disabled is true, Calico IPAM will not assign addresses from this pool. diff --git a/go.mod b/go.mod index c636bae6818..9ca70674934 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/leodido/go-urn v0.0.0-20181204092800-a67a23e1c1af // indirect github.com/onsi/ginkgo v1.14.1 github.com/onsi/gomega v1.10.1 - github.com/projectcalico/api v0.0.0-20211027233830-6b11a0f525e1 + github.com/projectcalico/api v0.0.0-20211102181812-edfaf495a5c8 github.com/projectcalico/go-json v0.0.0-20161128004156-6219dc7339ba // indirect github.com/projectcalico/go-yaml-wrapper v0.0.0-20191112210931-090425220c54 github.com/prometheus/client_golang v1.4.0 diff --git a/go.sum b/go.sum index 4c820efd7ed..ef55aa89601 100644 --- a/go.sum +++ b/go.sum @@ -348,8 +348,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/projectcalico/api v0.0.0-20211027233830-6b11a0f525e1 h1:VIIzlUd68DpoXGQR/9DIyDVZqeNPjl9vrpwsPgHAgJA= -github.com/projectcalico/api v0.0.0-20211027233830-6b11a0f525e1/go.mod h1:QUvycRdtbC3tSCzePX7+gxA0ZebEeHcW8ojpVwEdQVk= +github.com/projectcalico/api v0.0.0-20211102181812-edfaf495a5c8 h1:tf883nciQPUZut8Br0Cdkw/JTakiizX+eq2XTNHzJS0= +github.com/projectcalico/api v0.0.0-20211102181812-edfaf495a5c8/go.mod h1:QUvycRdtbC3tSCzePX7+gxA0ZebEeHcW8ojpVwEdQVk= github.com/projectcalico/go-json v0.0.0-20161128004156-6219dc7339ba h1:aaF2byUCZhzszHsfPEr2M3qcU4ibtD/yk/il2R7T1PU= github.com/projectcalico/go-json v0.0.0-20161128004156-6219dc7339ba/go.mod h1:q8EdCgBdMQzgiX/uk4GXLWLk+gIHd1a7mWUAamJKDb4= github.com/projectcalico/go-yaml-wrapper v0.0.0-20191112210931-090425220c54 h1:Jt2Pic9dxgJisekm8q2WV9FaWxUJhhRfwHSP640drww= diff --git a/lib/backend/model/ippool.go b/lib/backend/model/ippool.go index 04f1e39651b..adeabf2af13 100644 --- a/lib/backend/model/ippool.go +++ b/lib/backend/model/ippool.go @@ -96,11 +96,12 @@ func (options IPPoolListOptions) KeyFromDefaultPath(path string) Key { } type IPPool struct { - CIDR net.IPNet `json:"cidr"` - IPIPInterface string `json:"ipip"` - IPIPMode encap.Mode `json:"ipip_mode"` - VXLANMode encap.Mode `json:"vxlan_mode"` - Masquerade bool `json:"masquerade"` - IPAM bool `json:"ipam"` - Disabled bool `json:"disabled"` + CIDR net.IPNet `json:"cidr"` + IPIPInterface string `json:"ipip"` + IPIPMode encap.Mode `json:"ipip_mode"` + VXLANMode encap.Mode `json:"vxlan_mode"` + Masquerade bool `json:"masquerade"` + IPAM bool `json:"ipam"` + Disabled bool `json:"disabled"` + DisableBGPExport bool `json:"disableBGPExport"` } diff --git a/lib/backend/syncersv1/updateprocessors/ippoolprocessor.go b/lib/backend/syncersv1/updateprocessors/ippoolprocessor.go index c488d2a33ef..dc556f4add4 100644 --- a/lib/backend/syncersv1/updateprocessors/ippoolprocessor.go +++ b/lib/backend/syncersv1/updateprocessors/ippoolprocessor.go @@ -78,13 +78,14 @@ func convertIPPoolV2ToV1(kvp *model.KVPair) (*model.KVPair, error) { return &model.KVPair{ Key: v1key, Value: &model.IPPool{ - CIDR: *cidr, - IPIPInterface: ipipInterface, - IPIPMode: ipipMode, - VXLANMode: vxlanMode, - Masquerade: v3res.Spec.NATOutgoing, - IPAM: !v3res.Spec.Disabled, - Disabled: v3res.Spec.Disabled, + CIDR: *cidr, + IPIPInterface: ipipInterface, + IPIPMode: ipipMode, + VXLANMode: vxlanMode, + Masquerade: v3res.Spec.NATOutgoing, + IPAM: !v3res.Spec.Disabled, + Disabled: v3res.Spec.Disabled, + DisableBGPExport: v3res.Spec.DisableBGPExport, }, Revision: kvp.Revision, }, nil diff --git a/lib/backend/syncersv1/updateprocessors/ippoolprocessor_test.go b/lib/backend/syncersv1/updateprocessors/ippoolprocessor_test.go index b1f35e40d9c..ac6fdf69143 100644 --- a/lib/backend/syncersv1/updateprocessors/ippoolprocessor_test.go +++ b/lib/backend/syncersv1/updateprocessors/ippoolprocessor_test.go @@ -63,11 +63,12 @@ var _ = Describe("Test the IPPool update processor", func() { Expect(kvps[0]).To(Equal(&model.KVPair{ Key: v1PoolKeyCidr1, Value: &model.IPPool{ - CIDR: v1PoolKeyCidr1.CIDR, - IPIPMode: encap.Undefined, - Masquerade: false, - IPAM: true, - Disabled: false, + CIDR: v1PoolKeyCidr1.CIDR, + IPIPMode: encap.Undefined, + Masquerade: false, + IPAM: true, + Disabled: false, + DisableBGPExport: false, }, Revision: "abcde", })) @@ -101,29 +102,58 @@ var _ = Describe("Test the IPPool update processor", func() { { Key: v1PoolKeyCidr1, Value: &model.IPPool{ - CIDR: v1PoolKeyCidr1.CIDR, - IPIPInterface: "tunl0", - IPIPMode: encap.Always, - Masquerade: true, - IPAM: false, - Disabled: true, + CIDR: v1PoolKeyCidr1.CIDR, + IPIPInterface: "tunl0", + IPIPMode: encap.Always, + Masquerade: true, + IPAM: false, + Disabled: true, + DisableBGPExport: false, }, Revision: "1234", }, { Key: v1PoolKeyCidr2, Value: &model.IPPool{ - CIDR: v1PoolKeyCidr2.CIDR, - IPIPInterface: "", - IPIPMode: encap.Undefined, - Masquerade: false, - IPAM: true, - Disabled: false, + CIDR: v1PoolKeyCidr2.CIDR, + IPIPInterface: "", + IPIPMode: encap.Undefined, + Masquerade: false, + IPAM: true, + Disabled: false, + DisableBGPExport: false, }, Revision: "abcdef", }, })) + By("updating the first IPPool to have disableBGPExport = true - expect an update") + res = apiv3.NewIPPool() + res.Name = v3PoolKey1.Name + res.Spec.CIDR = cidr2str + res.Spec.DisableBGPExport = true + kvps, err = up.Process(&model.KVPair{ + Key: v3PoolKey1, + Value: res, + Revision: "abcdefg", + }) + Expect(err).NotTo(HaveOccurred()) + Expect(kvps).To(Equal([]*model.KVPair{ + { + Key: v1PoolKeyCidr2, + Value: &model.IPPool{ + CIDR: v1PoolKeyCidr2.CIDR, + IPIPInterface: "", + IPIPMode: encap.Undefined, + Masquerade: false, + IPAM: true, + Disabled: false, + DisableBGPExport: true, + }, + Revision: "abcdefg", + }, + })) + By("deleting the first pool") kvps, err = up.Process(&model.KVPair{ Key: v3PoolKey1, @@ -169,12 +199,13 @@ var _ = Describe("Test the IPPool update processor", func() { Expect(kvps[0]).To(Equal(&model.KVPair{ Key: v1PoolKeyCidr1, Value: &model.IPPool{ - CIDR: v1PoolKeyCidr1.CIDR, - IPIPMode: encap.Undefined, - Masquerade: false, - IPAM: true, - Disabled: false, - VXLANMode: encap.CrossSubnet, + CIDR: v1PoolKeyCidr1.CIDR, + IPIPMode: encap.Undefined, + Masquerade: false, + IPAM: true, + Disabled: false, + DisableBGPExport: false, + VXLANMode: encap.CrossSubnet, }, Revision: "abcde", })) diff --git a/lib/clientv3/ippool_e2e_test.go b/lib/clientv3/ippool_e2e_test.go index 190dfce439b..1ee0f6d0cf9 100644 --- a/lib/clientv3/ippool_e2e_test.go +++ b/lib/clientv3/ippool_e2e_test.go @@ -50,30 +50,33 @@ var _ = testutils.E2eDatastoreDescribe("IPPool tests", testutils.DatastoreAll, f AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, } spec1_2 := apiv3.IPPoolSpec{ - CIDR: "1.2.3.0/24", - NATOutgoing: true, - IPIPMode: apiv3.IPIPModeNever, - VXLANMode: apiv3.VXLANModeAlways, - BlockSize: 26, - NodeSelector: `foo == "bar"`, - AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, + CIDR: "1.2.3.0/24", + NATOutgoing: true, + IPIPMode: apiv3.IPIPModeNever, + VXLANMode: apiv3.VXLANModeAlways, + BlockSize: 26, + NodeSelector: `foo == "bar"`, + AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, + DisableBGPExport: true, } spec2 := apiv3.IPPoolSpec{ - CIDR: "2001::/120", - NATOutgoing: true, - IPIPMode: apiv3.IPIPModeNever, - VXLANMode: apiv3.VXLANModeNever, - BlockSize: 122, - NodeSelector: "all()", - AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, + CIDR: "2001::/120", + NATOutgoing: true, + IPIPMode: apiv3.IPIPModeNever, + VXLANMode: apiv3.VXLANModeNever, + BlockSize: 122, + NodeSelector: "all()", + AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, + DisableBGPExport: true, } spec2_1 := apiv3.IPPoolSpec{ - CIDR: "2001::/120", - IPIPMode: apiv3.IPIPModeNever, - VXLANMode: apiv3.VXLANModeNever, - BlockSize: 122, - NodeSelector: "all()", - AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, + CIDR: "2001::/120", + IPIPMode: apiv3.IPIPModeNever, + VXLANMode: apiv3.VXLANModeNever, + BlockSize: 122, + NodeSelector: "all()", + AllowedUses: []apiv3.IPPoolAllowedUse{apiv3.IPPoolAllowedUseWorkload, apiv3.IPPoolAllowedUseTunnel}, + DisableBGPExport: false, } It("should error when creating an IPPool with no name", func() {