Skip to content

Commit eb634ae

Browse files
authored
Merge pull request #42 from Azure/development
Development
2 parents e7d1e75 + 6373b2b commit eb634ae

File tree

17 files changed

+479
-222
lines changed

17 files changed

+479
-222
lines changed

Makefile

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
SOURCEFILES = \
2-
$(wildcard cni/*.go) \
3-
$(wildcard cni/ipam/*.go) \
4-
$(wildcard cni/network/*.go) \
5-
$(wildcard cni/plugin/*.go) \
6-
$(wildcard cnm/*.go) \
7-
$(wildcard cnm/ipam/*.go) \
8-
$(wildcard cnm/network/*.go) \
9-
$(wildcard cnm/plugin/*.go) \
1+
# Source files common to all targets.
2+
COREFILES = \
103
$(wildcard common/*.go) \
114
$(wildcard ebtables/*.go) \
125
$(wildcard ipam/*.go) \
@@ -15,6 +8,22 @@ SOURCEFILES = \
158
$(wildcard network/*.go) \
169
$(wildcard store/*.go)
1710

11+
# Source files for building CNM plugin.
12+
CNMFILES = \
13+
$(wildcard cnm/*.go) \
14+
$(wildcard cnm/ipam/*.go) \
15+
$(wildcard cnm/network/*.go) \
16+
$(wildcard cnm/plugin/*.go) \
17+
$(COREFILES)
18+
19+
# Source files for building CNI plugin.
20+
CNIFILES = \
21+
$(wildcard cni/*.go) \
22+
$(wildcard cni/ipam/*.go) \
23+
$(wildcard cni/network/*.go) \
24+
$(wildcard cni/plugin/*.go) \
25+
$(COREFILES)
26+
1827
CNMDIR = cnm/plugin
1928

2029
CNIDIR = cni/plugin
@@ -35,11 +44,11 @@ clean:
3544
rm -rf $(OUTPUTDIR)
3645

3746
# Build the Azure CNM plugin.
38-
$(OUTPUTDIR)/azure-cnm-plugin: $(SOURCEFILES)
47+
$(OUTPUTDIR)/azure-cnm-plugin: $(CNMFILES)
3948
go build -v -o $(OUTPUTDIR)/azure-cnm-plugin -ldflags "-X main.version=$(VERSION) -s -w" $(CNMDIR)/*.go
4049

4150
# Build the Azure CNI plugin.
42-
$(OUTPUTDIR)/azure-cni-plugin: $(SOURCEFILES)
51+
$(OUTPUTDIR)/azure-cni-plugin: $(CNIFILES)
4352
go build -v -o $(OUTPUTDIR)/azure-cni-plugin -ldflags "-X main.version=$(VERSION) -s -w" $(CNIDIR)/*.go
4453

4554
install:

cni/cni.go

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,70 @@ package cni
55

66
import (
77
"encoding/json"
8+
9+
cniSkel "github.com/containernetworking/cni/pkg/skel"
10+
cniTypes "github.com/containernetworking/cni/pkg/types"
11+
)
12+
13+
const (
14+
Internal = "internal"
15+
16+
CmdAdd = "ADD"
17+
CmdDel = "DEL"
818
)
919

20+
// CNI contract.
21+
type CniPlugin interface {
22+
Add(args *cniSkel.CmdArgs) error
23+
Delete(args *cniSkel.CmdArgs) error
24+
}
25+
26+
// CallPlugin calls the given CNI plugin through the internal interface.
27+
func CallPlugin(plugin CniPlugin, cmd string, args *cniSkel.CmdArgs, nwCfg *NetworkConfig) (*cniTypes.Result, error) {
28+
var err error
29+
30+
savedType := nwCfg.Ipam.Type
31+
nwCfg.Ipam.Type = Internal
32+
args.StdinData = nwCfg.Serialize()
33+
34+
// Call the plugin's internal interface.
35+
if cmd == CmdAdd {
36+
err = plugin.Add(args)
37+
} else {
38+
err = plugin.Delete(args)
39+
}
40+
41+
nwCfg.Ipam.Type = savedType
42+
43+
if err != nil {
44+
return nil, err
45+
}
46+
47+
// Read back the result.
48+
var result cniTypes.Result
49+
err = json.Unmarshal(args.StdinData, &result)
50+
if err != nil {
51+
return nil, err
52+
}
53+
54+
return &result, nil
55+
}
56+
1057
// NetworkConfig represents the Azure CNI plugin's network configuration.
1158
type NetworkConfig struct {
1259
CniVersion string `json:"cniVersion"`
1360
Name string `json:"name"`
1461
Type string `json:"type"`
1562
Bridge string `json:"bridge,omitempty"`
16-
IfName string `json:"ifName,omitempty"`
63+
LogLevel string `json:"logLevel,omitempty"`
64+
LogTarget string `json:"logTarget,omitempty"`
1765
Ipam struct {
18-
Type string `json:"type"`
19-
AddrSpace string `json:"addressSpace,omitempty"`
20-
Subnet string `json:"subnet,omitempty"`
21-
Address string `json:"ipAddress,omitempty"`
66+
Type string `json:"type"`
67+
Environment string `json:"environment,omitempty"`
68+
AddrSpace string `json:"addressSpace,omitempty"`
69+
Subnet string `json:"subnet,omitempty"`
70+
Address string `json:"ipAddress,omitempty"`
71+
QueryInterval string `json:"queryInterval,omitempty"`
2272
}
2373
}
2474

cni/ipam/ipam.go

Lines changed: 94 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package ipam
55

66
import (
7+
"encoding/json"
78
"net"
89

910
"github.com/Azure/azure-container-networking/cni"
@@ -23,6 +24,15 @@ const (
2324
defaultAddressSpaceId = "LocalDefaultAddressSpace"
2425
)
2526

27+
var (
28+
// Azure VNET pre-allocated host IDs.
29+
ipv4DefaultGatewayHostId = net.ParseIP("::1")
30+
ipv4DnsPrimaryHostId = net.ParseIP("::2")
31+
ipv4DnsSecondaryHostId = net.ParseIP("::3")
32+
33+
ipv4DefaultRouteDstPrefix = net.IPNet{net.IPv4zero, net.IPv4Mask(0, 0, 0, 0)}
34+
)
35+
2636
// IpamPlugin represents a CNI IPAM plugin.
2737
type ipamPlugin struct {
2838
*common.Plugin
@@ -43,31 +53,34 @@ func NewPlugin(config *common.PluginConfig) (*ipamPlugin, error) {
4353
return nil, err
4454
}
4555

46-
config.IpamApi = am
47-
48-
return &ipamPlugin{
56+
// Create IPAM plugin.
57+
ipamPlg := &ipamPlugin{
4958
Plugin: plugin,
5059
am: am,
51-
}, nil
60+
}
61+
62+
config.IpamApi = ipamPlg
63+
64+
return ipamPlg, nil
5265
}
5366

5467
// Starts the plugin.
5568
func (plugin *ipamPlugin) Start(config *common.PluginConfig) error {
5669
// Initialize base plugin.
5770
err := plugin.Initialize(config)
5871
if err != nil {
59-
log.Printf("[ipam] Failed to initialize base plugin, err:%v.", err)
72+
log.Printf("[cni-ipam] Failed to initialize base plugin, err:%v.", err)
6073
return err
6174
}
6275

6376
// Initialize address manager.
6477
err = plugin.am.Initialize(config, plugin.Options)
6578
if err != nil {
66-
log.Printf("[ipam] Failed to initialize address manager, err:%v.", err)
79+
log.Printf("[cni-ipam] Failed to initialize address manager, err:%v.", err)
6780
return err
6881
}
6982

70-
log.Printf("[ipam] Plugin started.")
83+
log.Printf("[cni-ipam] Plugin started.")
7184

7285
return nil
7386
}
@@ -76,7 +89,7 @@ func (plugin *ipamPlugin) Start(config *common.PluginConfig) error {
7689
func (plugin *ipamPlugin) Stop() {
7790
plugin.am.Uninitialize()
7891
plugin.Uninitialize()
79-
log.Printf("[ipam] Plugin stopped.")
92+
log.Printf("[cni-ipam] Plugin stopped.")
8093
}
8194

8295
//
@@ -86,77 +99,125 @@ func (plugin *ipamPlugin) Stop() {
8699

87100
// Add handles CNI add commands.
88101
func (plugin *ipamPlugin) Add(args *cniSkel.CmdArgs) error {
89-
log.Printf("[ipam] Processing ADD command with args {ContainerID:%v Netns:%v IfName:%v Args:%v Path:%v}.",
102+
log.Printf("[cni-ipam] Processing ADD command with args {ContainerID:%v Netns:%v IfName:%v Args:%v Path:%v}.",
90103
args.ContainerID, args.Netns, args.IfName, args.Args, args.Path)
91104

92105
// Parse network configuration from stdin.
93106
nwCfg, err := cni.ParseNetworkConfig(args.StdinData)
94107
if err != nil {
95-
log.Printf("[ipam] Failed to parse network configuration: %v.", err)
108+
log.Printf("[cni-ipam] Failed to parse network configuration: %v.", err)
96109
return nil
97110
}
98111

99-
log.Printf("[ipam] Read network configuration %+v.", nwCfg)
112+
log.Printf("[cni-ipam] Read network configuration %+v.", nwCfg)
100113

101114
// Assume default address space if not specified.
102115
if nwCfg.Ipam.AddrSpace == "" {
103116
nwCfg.Ipam.AddrSpace = defaultAddressSpaceId
104117
}
105118

119+
var poolId string
120+
var subnet string
121+
var ipv4Address *net.IPNet
122+
var result *cniTypes.Result
123+
var apInfo *ipam.AddressPoolInfo
124+
106125
// Check if an address pool is specified.
107126
if nwCfg.Ipam.Subnet == "" {
108127
// Allocate an address pool.
109-
poolId, subnet, err := plugin.am.RequestPool(nwCfg.Ipam.AddrSpace, "", "", nil, false)
128+
poolId, subnet, err = plugin.am.RequestPool(nwCfg.Ipam.AddrSpace, "", "", nil, false)
110129
if err != nil {
111-
log.Printf("[ipam] Failed to allocate pool, err:%v.", err)
130+
log.Printf("[cni-ipam] Failed to allocate pool, err:%v.", err)
112131
return nil
113132
}
114133

115134
nwCfg.Ipam.Subnet = subnet
116-
log.Printf("[ipam] Allocated address poolId %v with subnet %v.", poolId, subnet)
135+
log.Printf("[cni-ipam] Allocated address poolId %v with subnet %v.", poolId, subnet)
117136
}
118137

119138
// Allocate an address for the endpoint.
120139
address, err := plugin.am.RequestAddress(nwCfg.Ipam.AddrSpace, nwCfg.Ipam.Subnet, nwCfg.Ipam.Address, nil)
121140
if err != nil {
122-
log.Printf("[ipam] Failed to allocate address, err:%v.", err)
123-
return nil
141+
log.Printf("[cni-ipam] Failed to allocate address, err:%v.", err)
142+
goto Rollback
124143
}
125144

126-
log.Printf("[ipam] Allocated address %v.", address)
145+
log.Printf("[cni-ipam] Allocated address %v.", address)
127146

128-
// Output the result.
129-
ip, cidr, err := net.ParseCIDR(address)
130-
cidr.IP = ip
147+
// Parse IP address.
148+
ipv4Address, err = ipam.ConvertAddressToIPNet(address)
131149
if err != nil {
132-
log.Printf("[ipam] Failed to parse address, err:%v.", err)
133-
return nil
150+
goto Rollback
151+
}
152+
153+
// Query pool information for gateways and DNS servers.
154+
apInfo, err = plugin.am.GetPoolInfo(nwCfg.Ipam.AddrSpace, nwCfg.Ipam.Subnet)
155+
if err != nil {
156+
goto Rollback
134157
}
135158

136-
result := &cniTypes.Result{
137-
IP4: &cniTypes.IPConfig{IP: *cidr},
159+
// Populate IP configuration.
160+
result = &cniTypes.Result{
161+
IP4: &cniTypes.IPConfig{
162+
IP: *ipv4Address,
163+
Gateway: apInfo.Gateway,
164+
Routes: []cniTypes.Route{
165+
cniTypes.Route{
166+
Dst: ipv4DefaultRouteDstPrefix,
167+
GW: apInfo.Gateway,
168+
},
169+
},
170+
},
138171
}
139172

140-
result.Print()
173+
// Populate DNS servers.
174+
for _, ip := range apInfo.DnsServers {
175+
result.DNS.Nameservers = append(result.DNS.Nameservers, ip.String())
176+
}
177+
178+
// Output the result.
179+
if nwCfg.Ipam.Type == cni.Internal {
180+
// Called via the internal interface. Pass output back in args.
181+
args.StdinData, _ = json.Marshal(result)
182+
} else {
183+
// Called via the executable interface. Print output to stdout.
184+
result.Print()
185+
}
186+
187+
log.Printf("[cni-ipam] ADD succeeded with output %+v.", result)
188+
189+
return nil
190+
191+
Rollback:
192+
// Roll back allocations made during this call.
193+
log.Printf("[cni-ipam] ADD failed, err:%v.", err)
141194

142-
log.Printf("[ipam] ADD succeeded with output %+v.", result)
195+
if address != "" {
196+
log.Printf("[cni-ipam] Releasing address %v.", address)
197+
err = plugin.am.ReleaseAddress(nwCfg.Ipam.AddrSpace, nwCfg.Ipam.Subnet, address)
198+
}
199+
200+
if poolId != "" {
201+
log.Printf("[cni-ipam] Releasing pool %v.", poolId)
202+
err = plugin.am.ReleasePool(nwCfg.Ipam.AddrSpace, poolId)
203+
}
143204

144205
return err
145206
}
146207

147208
// Delete handles CNI delete commands.
148209
func (plugin *ipamPlugin) Delete(args *cniSkel.CmdArgs) error {
149-
log.Printf("[ipam] Processing DEL command with args {ContainerID:%v Netns:%v IfName:%v Args:%v Path:%v}.",
210+
log.Printf("[cni-ipam] Processing DEL command with args {ContainerID:%v Netns:%v IfName:%v Args:%v Path:%v}.",
150211
args.ContainerID, args.Netns, args.IfName, args.Args, args.Path)
151212

152213
// Parse network configuration from stdin.
153214
nwCfg, err := cni.ParseNetworkConfig(args.StdinData)
154215
if err != nil {
155-
log.Printf("[ipam] Failed to parse network configuration: %v.", err)
216+
log.Printf("[cni-ipam] Failed to parse network configuration: %v.", err)
156217
return nil
157218
}
158219

159-
log.Printf("[ipam] Read network configuration %+v.", nwCfg)
220+
log.Printf("[cni-ipam] Read network configuration %+v.", nwCfg)
160221

161222
// Assume default address space if not specified.
162223
if nwCfg.Ipam.AddrSpace == "" {
@@ -168,19 +229,19 @@ func (plugin *ipamPlugin) Delete(args *cniSkel.CmdArgs) error {
168229
// Release the address.
169230
err := plugin.am.ReleaseAddress(nwCfg.Ipam.AddrSpace, nwCfg.Ipam.Subnet, nwCfg.Ipam.Address)
170231
if err != nil {
171-
log.Printf("[cni] Failed to release address, err:%v.", err)
232+
log.Printf("[cni-ipam] Failed to release address, err:%v.", err)
172233
return nil
173234
}
174235
} else {
175236
// Release the pool.
176237
err := plugin.am.ReleasePool(nwCfg.Ipam.AddrSpace, nwCfg.Ipam.Subnet)
177238
if err != nil {
178-
log.Printf("[cni] Failed to release pool, err:%v.", err)
239+
log.Printf("[cni-ipam] Failed to release pool, err:%v.", err)
179240
return nil
180241
}
181242
}
182243

183-
log.Printf("[ipam] DEL succeeded.")
244+
log.Printf("[cni-ipam] DEL succeeded.")
184245

185-
return err
246+
return nil
186247
}

0 commit comments

Comments
 (0)