This repository was archived by the owner on Jun 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 680
/
Copy pathcni.go
137 lines (115 loc) · 3.04 KB
/
cni.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package ipamplugin
import (
"encoding/json"
"errors"
"fmt"
"net"
"github.com/containernetworking/cni/pkg/skel"
"github.com/containernetworking/cni/pkg/types"
"github.com/containernetworking/cni/pkg/types/current"
)
func (i *Ipam) CmdAdd(args *skel.CmdArgs) error {
var conf types.NetConf
if err := json.Unmarshal(args.StdinData, &conf); err != nil {
return fmt.Errorf("failed to load netconf: %v", err)
}
result, err := i.Allocate(args)
if err != nil {
return err
}
return types.PrintResult(result, conf.CNIVersion)
}
func (i *Ipam) Allocate(args *skel.CmdArgs) (types.Result, error) {
// extract the things we care about
conf, err := loadIPAMConf(args.StdinData)
if err != nil {
return nil, err
}
if conf == nil {
conf = &ipamConf{}
}
containerID := args.ContainerID
if containerID == "" {
return nil, fmt.Errorf("Weave CNI Allocate: blank container name")
}
var ipconfigs []*current.IPConfig
if len(conf.IPs) > 0 {
// configuration includes desired IPs
var ips []net.IP
for _, ip := range conf.IPs {
ip4 := net.ParseIP(ip).To4()
ip16 := net.ParseIP(ip).To16()
if ip4 == nil && ip16 == nil {
return nil, errors.New("provided value is not an IP")
}
if ip4 == nil && ip16 != nil {
return nil, errors.New("allocation of ipv6 addresses is not implemented")
}
ips = append(ips, ip4)
}
for j := range ips {
ipnet := &net.IPNet{
IP: ips[j],
Mask: ips[j].DefaultMask(),
}
err := i.weave.ClaimIP(containerID, ipnet, false)
if err != nil {
return nil, err
}
ipconfigs = append(ipconfigs, ¤t.IPConfig{
Version: "4",
Address: *ipnet,
Gateway: conf.Gateway,
})
}
} else if conf.Subnet == "" {
// configuration doesn't include Subnet or IPs, so ask the allocator for an IP
ipnet, err := i.weave.AllocateIP(containerID, false)
if err != nil {
return nil, err
}
ipconfigs = append(ipconfigs, ¤t.IPConfig{
Version: "4",
Address: *ipnet,
Gateway: conf.Gateway,
})
} else {
// configuration includes desired Subnet
subnet, err := types.ParseCIDR(conf.Subnet)
if err != nil {
return nil, fmt.Errorf("subnet given in config, but not parseable: %s", err)
}
ipnet, err := i.weave.AllocateIPInSubnet(containerID, subnet, false)
if err != nil {
return nil, err
}
ipconfigs = append(ipconfigs, ¤t.IPConfig{
Version: "4",
Address: *ipnet,
Gateway: conf.Gateway,
})
}
return ¤t.Result{
IPs: ipconfigs,
Routes: conf.Routes,
}, nil
}
func (i *Ipam) CmdDel(args *skel.CmdArgs) error {
return i.Release(args)
}
func (i *Ipam) Release(args *skel.CmdArgs) error {
return i.weave.ReleaseIPsFor(args.ContainerID)
}
type ipamConf struct {
Subnet string `json:"subnet,omitempty"`
Gateway net.IP `json:"gateway,omitempty"`
Routes []*types.Route `json:"routes"`
IPs []string `json:"ips,omitempty"`
}
type netConf struct {
IPAM *ipamConf `json:"ipam"`
}
func loadIPAMConf(stdinData []byte) (*ipamConf, error) {
var conf netConf
return conf.IPAM, json.Unmarshal(stdinData, &conf)
}