github.com/mccv1r0/cni@v0.7.0-alpha1/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 "net" 21 "os" 22 23 "github.com/containernetworking/cni/pkg/types" 24 ) 25 26 const ImplementedSpecVersion string = "0.2.0" 27 28 var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion} 29 30 // Compatibility types for CNI version 0.1.0 and 0.2.0 31 32 func NewResult(data []byte) (types.Result, error) { 33 result := &Result{} 34 if err := json.Unmarshal(data, result); err != nil { 35 return nil, err 36 } 37 return result, nil 38 } 39 40 func GetResult(r types.Result) (*Result, error) { 41 // We expect version 0.1.0/0.2.0 results 42 result020, err := r.GetAsVersion(ImplementedSpecVersion) 43 if err != nil { 44 return nil, err 45 } 46 result, ok := result020.(*Result) 47 if !ok { 48 return nil, fmt.Errorf("failed to convert result") 49 } 50 return result, nil 51 } 52 53 // Result is what gets returned from the plugin (via stdout) to the caller 54 type Result struct { 55 CNIVersion string `json:"cniVersion,omitempty"` 56 IP4 *IPConfig `json:"ip4,omitempty"` 57 IP6 *IPConfig `json:"ip6,omitempty"` 58 DNS types.DNS `json:"dns,omitempty"` 59 } 60 61 func (r *Result) Version() string { 62 return ImplementedSpecVersion 63 } 64 65 func (r *Result) GetAsVersion(version string) (types.Result, error) { 66 for _, supportedVersion := range SupportedVersions { 67 if version == supportedVersion { 68 r.CNIVersion = version 69 return r, nil 70 } 71 } 72 return nil, fmt.Errorf("cannot convert version %q to %s", SupportedVersions, version) 73 } 74 75 func (r *Result) Print() error { 76 data, err := json.MarshalIndent(r, "", " ") 77 if err != nil { 78 return err 79 } 80 _, err = os.Stdout.Write(data) 81 return err 82 } 83 84 // String returns a formatted string in the form of "[IP4: $1,][ IP6: $2,] DNS: $3" where 85 // $1 represents the receiver's IPv4, $2 represents the receiver's IPv6 and $3 the 86 // receiver's DNS. If $1 or $2 are nil, they won't be present in the returned string. 87 func (r *Result) String() string { 88 var str string 89 if r.IP4 != nil { 90 str = fmt.Sprintf("IP4:%+v, ", *r.IP4) 91 } 92 if r.IP6 != nil { 93 str += fmt.Sprintf("IP6:%+v, ", *r.IP6) 94 } 95 return fmt.Sprintf("%sDNS:%+v", str, r.DNS) 96 } 97 98 // IPConfig contains values necessary to configure an interface 99 type IPConfig struct { 100 IP net.IPNet 101 Gateway net.IP 102 Routes []types.Route 103 } 104 105 // net.IPNet is not JSON (un)marshallable so this duality is needed 106 // for our custom IPNet type 107 108 // JSON (un)marshallable types 109 type ipConfig struct { 110 IP types.IPNet `json:"ip"` 111 Gateway net.IP `json:"gateway,omitempty"` 112 Routes []types.Route `json:"routes,omitempty"` 113 } 114 115 func (c *IPConfig) MarshalJSON() ([]byte, error) { 116 ipc := ipConfig{ 117 IP: types.IPNet(c.IP), 118 Gateway: c.Gateway, 119 Routes: c.Routes, 120 } 121 122 return json.Marshal(ipc) 123 } 124 125 func (c *IPConfig) UnmarshalJSON(data []byte) error { 126 ipc := ipConfig{} 127 if err := json.Unmarshal(data, &ipc); err != nil { 128 return err 129 } 130 131 c.IP = net.IPNet(ipc.IP) 132 c.Gateway = ipc.Gateway 133 c.Routes = ipc.Routes 134 return nil 135 }