github.com/jk-he/cni@v0.8.1/pkg/types/020/types.go (about) 1 // Copyright 2016 CNI authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package types020 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "io" 21 "net" 22 "os" 23 24 "github.com/containernetworking/cni/pkg/types" 25 ) 26 27 const ImplementedSpecVersion string = "0.2.0" 28 29 var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion} 30 31 // Compatibility types for CNI version 0.1.0 and 0.2.0 32 33 func NewResult(data []byte) (types.Result, error) { 34 result := &Result{} 35 if err := json.Unmarshal(data, result); err != nil { 36 return nil, err 37 } 38 return result, nil 39 } 40 41 func GetResult(r types.Result) (*Result, error) { 42 // We expect version 0.1.0/0.2.0 results 43 result020, err := r.GetAsVersion(ImplementedSpecVersion) 44 if err != nil { 45 return nil, err 46 } 47 result, ok := result020.(*Result) 48 if !ok { 49 return nil, fmt.Errorf("failed to convert result") 50 } 51 return result, nil 52 } 53 54 // Result is what gets returned from the plugin (via stdout) to the caller 55 type Result struct { 56 CNIVersion string `json:"cniVersion,omitempty"` 57 IP4 *IPConfig `json:"ip4,omitempty"` 58 IP6 *IPConfig `json:"ip6,omitempty"` 59 DNS types.DNS `json:"dns,omitempty"` 60 } 61 62 func (r *Result) Version() string { 63 return ImplementedSpecVersion 64 } 65 66 func (r *Result) GetAsVersion(version string) (types.Result, error) { 67 for _, supportedVersion := range SupportedVersions { 68 if version == supportedVersion { 69 r.CNIVersion = version 70 return r, nil 71 } 72 } 73 return nil, fmt.Errorf("cannot convert version %q to %s", SupportedVersions, version) 74 } 75 76 func (r *Result) Print() error { 77 return r.PrintTo(os.Stdout) 78 } 79 80 func (r *Result) PrintTo(writer io.Writer) error { 81 data, err := json.MarshalIndent(r, "", " ") 82 if err != nil { 83 return err 84 } 85 _, err = writer.Write(data) 86 return err 87 } 88 89 // IPConfig contains values necessary to configure an interface 90 type IPConfig struct { 91 IP net.IPNet 92 Gateway net.IP 93 Routes []types.Route 94 } 95 96 // net.IPNet is not JSON (un)marshallable so this duality is needed 97 // for our custom IPNet type 98 99 // JSON (un)marshallable types 100 type ipConfig struct { 101 IP types.IPNet `json:"ip"` 102 Gateway net.IP `json:"gateway,omitempty"` 103 Routes []types.Route `json:"routes,omitempty"` 104 } 105 106 func (c *IPConfig) MarshalJSON() ([]byte, error) { 107 ipc := ipConfig{ 108 IP: types.IPNet(c.IP), 109 Gateway: c.Gateway, 110 Routes: c.Routes, 111 } 112 113 return json.Marshal(ipc) 114 } 115 116 func (c *IPConfig) UnmarshalJSON(data []byte) error { 117 ipc := ipConfig{} 118 if err := json.Unmarshal(data, &ipc); err != nil { 119 return err 120 } 121 122 c.IP = net.IPNet(ipc.IP) 123 c.Gateway = ipc.Gateway 124 c.Routes = ipc.Routes 125 return nil 126 }