Skip to content

Commit

Permalink
types/version: add helper to parse PrevResult
Browse files Browse the repository at this point in the history
Plugins can use the new helpers to parse a prevResult.  When parsing
their NetConf structure, assuming it has a types.NetConf embedded:

  type MyConf struct {
    types.NetConf
    ...
  }

  conf := MyConf{}
  if err := json.Unmarshal(stdin, &conf); err != nil {
    return nil, fmt.Errorf("failed to parse network configuration: %v", err)
  }

  if err := version.ParsePrevResult(&conf.NetConf); err != nil {
    return nil, err
  }

and then when the plugin wishes to access the PrevResult it can transform
conf.PrevResult into any Result version it wants:

  if conf.PrevResult != nil {
    res, err := current.NewResultFromResult(conf.PrevResult)
    if err != nil {
      return nil, fmt.Errorf("could not convert result to current version: %v", err)
    }
    for _, ip := range res.IPs {
      ...
    }
  }
  • Loading branch information
dcbw committed Aug 9, 2018
1 parent cbd2718 commit d2836a7
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 0 deletions.
3 changes: 3 additions & 0 deletions pkg/types/types.go
Expand Up @@ -65,6 +65,9 @@ type NetConf struct {
Capabilities map[string]bool `json:"capabilities,omitempty"`
IPAM IPAM `json:"ipam,omitempty"`
DNS DNS `json:"dns"`

RawPrevResult map[string]interface{} `json:"prevResult,omitempty"`
PrevResult Result `json:"-"`
}

type IPAM struct {
Expand Down
22 changes: 22 additions & 0 deletions pkg/version/version.go
Expand Up @@ -15,6 +15,7 @@
package version

import (
"encoding/json"
"fmt"

"github.com/containernetworking/cni/pkg/types"
Expand Down Expand Up @@ -59,3 +60,24 @@ func NewResult(version string, resultBytes []byte) (types.Result, error) {

return nil, fmt.Errorf("unsupported CNI result version %q", version)
}

// ParsePrevResult parses a prevResult in a NetConf structure and sets
// the NetConf's PrevResult member to the parsed Result object.
func ParsePrevResult(conf *types.NetConf) error {
if conf.RawPrevResult == nil {
return nil
}

resultBytes, err := json.Marshal(conf.RawPrevResult)
if err != nil {
return fmt.Errorf("could not serialize prevResult: %v", err)
}

conf.RawPrevResult = nil
conf.PrevResult, err = NewResult(conf.CNIVersion, resultBytes)
if err != nil {
return fmt.Errorf("could not parse prevResult: %v", err)
}

return nil
}
131 changes: 131 additions & 0 deletions pkg/version/version_test.go
@@ -0,0 +1,131 @@
// Copyright 2018 CNI authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package version_test

import (
"encoding/json"
"net"
"reflect"

"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/cni/pkg/version"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Version operations", func() {
Context("when a prevResult is available", func() {
It("parses the prevResult", func() {
rawBytes := []byte(`{
"cniVersion": "0.3.0",
"interfaces": [
{
"name": "eth0",
"mac": "00:11:22:33:44:55",
"sandbox": "/proc/3553/ns/net"
}
],
"ips": [
{
"version": "4",
"interface": 0,
"address": "1.2.3.30/24",
"gateway": "1.2.3.1"
}
]
}`)
var raw map[string]interface{}
err := json.Unmarshal(rawBytes, &raw)
Expect(err).NotTo(HaveOccurred())

conf := &types.NetConf{
CNIVersion: "0.3.0",
Name: "foobar",
Type: "baz",
RawPrevResult: raw,
}

err = version.ParsePrevResult(conf)
Expect(err).NotTo(HaveOccurred())

expectedResult := &current.Result{
CNIVersion: "0.3.0",
Interfaces: []*current.Interface{
{
Name: "eth0",
Mac: "00:11:22:33:44:55",
Sandbox: "/proc/3553/ns/net",
},
},
IPs: []*current.IPConfig{
{
Version: "4",
Interface: current.Int(0),
Address: net.IPNet{
IP: net.ParseIP("1.2.3.30"),
Mask: net.IPv4Mask(255, 255, 255, 0),
},
Gateway: net.ParseIP("1.2.3.1"),
},
},
}
Expect(reflect.DeepEqual(conf.PrevResult, expectedResult)).To(BeTrue())
})

It("fails if the prevResult version is unknown", func() {
conf := &types.NetConf{
CNIVersion: "0.3.0",
Name: "foobar",
Type: "baz",
RawPrevResult: map[string]interface{}{
"cniVersion": "5678.456",
},
}

err := version.ParsePrevResult(conf)
Expect(err).NotTo(HaveOccurred())
})

It("fails if the prevResult is invalid", func() {
conf := &types.NetConf{
CNIVersion: "0.3.0",
Name: "foobar",
Type: "baz",
RawPrevResult: map[string]interface{}{
"adsfasdfasdfasdfasdfaf": nil,
},
}

err := version.ParsePrevResult(conf)
Expect(err).NotTo(HaveOccurred())
})
})

Context("when a prevResult is not available", func() {
It("does not fail", func() {
conf := &types.NetConf{
CNIVersion: "0.3.0",
Name: "foobar",
Type: "baz",
}

err := version.ParsePrevResult(conf)
Expect(err).NotTo(HaveOccurred())
Expect(conf.PrevResult).To(BeNil())
})
})
})

0 comments on commit d2836a7

Please sign in to comment.