From 22d5d04f4fd16357c5d9fb8ce06b09513e1c0a70 Mon Sep 17 00:00:00 2001 From: gunjan5 Date: Tue, 20 Jun 2017 09:26:37 -0700 Subject: [PATCH] validate all the requested pools --- lib/client/ipam_block_reader_writer.go | 19 +++++++++++++++++-- lib/client/ipam_test.go | 20 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/client/ipam_block_reader_writer.go b/lib/client/ipam_block_reader_writer.go index 4f2ff9e61..34b742e9c 100644 --- a/lib/client/ipam_block_reader_writer.go +++ b/lib/client/ipam_block_reader_writer.go @@ -22,6 +22,8 @@ import ( "net" "reflect" + "fmt" + log "github.com/Sirupsen/logrus" "github.com/projectcalico/libcalico-go/lib/api" "github.com/projectcalico/libcalico-go/lib/backend/model" @@ -71,8 +73,7 @@ func (rw blockReaderWriter) getAffineBlocks(host string, ver ipVersion, pools [] return ids, nil } -func (rw blockReaderWriter) claimNewAffineBlock( - host string, version ipVersion, requestedPools []cnet.IPNet, config IPAMConfig) (*cnet.IPNet, error) { +func (rw blockReaderWriter) claimNewAffineBlock(host string, version ipVersion, requestedPools []cnet.IPNet, config IPAMConfig) (*cnet.IPNet, error) { // If requestedPools is not empty, use it. Otherwise, default to // all configured pools. @@ -92,6 +93,20 @@ func (rw blockReaderWriter) claimNewAffineBlock( } } + // Build a map so we can lookup existing pools. + pm := map[string]bool{} + for _, ap := range allPools.Items { + pm[ap.Metadata.CIDR.String()] = true + } + + // Make sure each requested pool exists. + for _, rp := range requestedPools { + if _, ok := pm[rp.String()]; !ok { + // The requested pool doesn't exist. + return nil, fmt.Errorf("The given pool (%s) does not exist", rp.IPNet.String()) + } + } + // If there are no pools, we cannot assign addresses. if len(pools) == 0 { return nil, goerrors.New("No configured Calico pools") diff --git a/lib/client/ipam_test.go b/lib/client/ipam_test.go index e4c77989a..145264c0f 100644 --- a/lib/client/ipam_test.go +++ b/lib/client/ipam_test.go @@ -332,6 +332,7 @@ var _ = testutils.E2eDatastoreDescribe("IPAM tests", testutils.DatastoreEtcdV2, pool2 := testutils.MustParseNetwork("20.0.0.0/24") pool3 := testutils.MustParseNetwork("30.0.0.0/24") pool4_v6 := testutils.MustParseNetwork("fe80::11/120") + pool5_doesnot_exist := testutils.MustParseNetwork("40.0.0.0/24") testutils.CreateNewIPPool(*c, "10.0.0.0/24", false, false, true) testutils.CreateNewIPPool(*c, "20.0.0.0/24", false, false, true) @@ -431,6 +432,25 @@ var _ = testutils.E2eDatastoreDescribe("IPAM tests", testutils.DatastoreEtcdV2, Expect(len(v4)).NotTo(Equal(209)) }) }) + + // Step-6: AutoAssign an IPv4 address. Request the IP from 2 IP Pools one of which doesn't exist. + // This should return an error. + Context("AutoAssign an IP from two pools - one valid one doesn't exist", func() { + args := client.AutoAssignArgs{ + Num4: 1, + Num6: 0, + Hostname: host, + IPv4Pools: []cnet.IPNet{pool1, pool5_doesnot_exist}, + } + + v4, _, err := ic.AutoAssign(args) + log.Println("v4: %d IPs", len(v4)) + + It("should return an error and no IPs", func() { + Expect(err.Error()).Should(Equal("The given pool (40.0.0.0/24) does not exist")) + Expect(len(v4)).To(Equal(0)) + }) + }) }) DescribeTable("AutoAssign: requested IPs vs returned IPs",