@@ -2,6 +2,7 @@ package ipamplugin
2
2
3
3
import (
4
4
"encoding/json"
5
+ "errors"
5
6
"fmt"
6
7
"net"
7
8
@@ -35,31 +36,80 @@ func (i *Ipam) Allocate(args *skel.CmdArgs) (types.Result, error) {
35
36
if containerID == "" {
36
37
return nil , fmt .Errorf ("Weave CNI Allocate: blank container name" )
37
38
}
38
- var ipnet * net.IPNet
39
39
40
- if conf .Subnet == "" {
41
- ipnet , err = i .weave .AllocateIP (containerID , false )
40
+ var ipconfigs []* current.IPConfig
41
+
42
+ if len (conf .IPs ) > 0 {
43
+ // configuration includes desired IPs
44
+
45
+ var ips []net.IP
46
+ for _ , ip := range conf .IPs {
47
+ ip4 := net .ParseIP (ip ).To4 ()
48
+ ip16 := net .ParseIP (ip ).To16 ()
49
+
50
+ if ip4 == nil && ip16 == nil {
51
+ return nil , errors .New ("provided value is not an IP" )
52
+ }
53
+
54
+ if ip4 == nil && ip16 != nil {
55
+ return nil , errors .New ("allocation of ipv6 addresses is not implemented" )
56
+ }
57
+
58
+ ips = append (ips , ip4 )
59
+ }
60
+
61
+ for j := range ips {
62
+ ipnet := & net.IPNet {
63
+ IP : ips [j ],
64
+ Mask : net .CIDRMask (32 , 32 ),
65
+ }
66
+
67
+ err := i .weave .ClaimIP (containerID , ipnet , false )
68
+ if err != nil {
69
+ return nil , err
70
+ }
71
+
72
+ ipconfigs = append (ipconfigs , & current.IPConfig {
73
+ Version : "4" ,
74
+ Address : * ipnet ,
75
+ Gateway : conf .Gateway ,
76
+ })
77
+ }
78
+ } else if conf .Subnet == "" {
79
+ // configuration doesn't include Subnet or IPs, so ask the allocator for an IP
80
+ ipnet , err := i .weave .AllocateIP (containerID , false )
81
+ if err != nil {
82
+ return nil , err
83
+ }
84
+
85
+ ipconfigs = append (ipconfigs , & current.IPConfig {
86
+ Version : "4" ,
87
+ Address : * ipnet ,
88
+ Gateway : conf .Gateway ,
89
+ })
42
90
} else {
43
- var subnet * net.IPNet
44
- subnet , err = types .ParseCIDR (conf .Subnet )
91
+ // configuration includes desired Subnet
92
+
93
+ subnet , err := types .ParseCIDR (conf .Subnet )
45
94
if err != nil {
46
95
return nil , fmt .Errorf ("subnet given in config, but not parseable: %s" , err )
47
96
}
48
- ipnet , err = i .weave .AllocateIPInSubnet (containerID , subnet , false )
49
- }
97
+ ipnet , err := i .weave .AllocateIPInSubnet (containerID , subnet , false )
98
+ if err != nil {
99
+ return nil , err
100
+ }
50
101
51
- if err != nil {
52
- return nil , err
53
- }
54
- result := & current.Result {
55
- IPs : []* current.IPConfig {{
102
+ ipconfigs = append (ipconfigs , & current.IPConfig {
56
103
Version : "4" ,
57
104
Address : * ipnet ,
58
105
Gateway : conf .Gateway ,
59
- }},
60
- Routes : conf .Routes ,
106
+ })
61
107
}
62
- return result , nil
108
+
109
+ return & current.Result {
110
+ IPs : ipconfigs ,
111
+ Routes : conf .Routes ,
112
+ }, nil
63
113
}
64
114
65
115
func (i * Ipam ) CmdDel (args * skel.CmdArgs ) error {
@@ -74,6 +124,7 @@ type ipamConf struct {
74
124
Subnet string `json:"subnet,omitempty"`
75
125
Gateway net.IP `json:"gateway,omitempty"`
76
126
Routes []* types.Route `json:"routes"`
127
+ IPs []string `json:"ips,omitempty"`
77
128
}
78
129
79
130
type netConf struct {
0 commit comments