Skip to content

Commit 644642b

Browse files
authored
CNS IPAM for CNI (#584)
* Add IPAM to CNS for CNI
1 parent a537df1 commit 644642b

File tree

65 files changed

+15304
-119
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+15304
-119
lines changed

.github/ISSUE_TEMPLATE/feature_request.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
name: 'Feature Request'
3+
34
about: Suggest an idea for this project.
45

56
---

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,13 @@ test-all:
378378
./cnm/network/ \
379379
./cni/ipam/ \
380380
./cns/ipamclient/ \
381+
./cns/cnsclient/ \
381382
./cns/requestcontroller/kubecontroller/ \
382383
./cnms/service/ \
383384
./npm/iptm/ \
384385
./npm/ipsm/
386+
387+
#until the restserver tests are fixed...
388+
go test -timeout 30s \
389+
./cns/restserver -run ^TestIPAM*
390+

cni/network/network.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -549,11 +549,11 @@ func (plugin *netPlugin) Add(args *cniSkel.CmdArgs) error {
549549
Gateway: gateway,
550550
},
551551
},
552-
BridgeName: nwCfg.Bridge,
553-
EnableSnatOnHost: nwCfg.EnableSnatOnHost,
554-
DNS: nwDNSInfo,
555-
Policies: policies,
556-
NetNs: args.Netns,
552+
BridgeName: nwCfg.Bridge,
553+
EnableSnatOnHost: nwCfg.EnableSnatOnHost,
554+
DNS: nwDNSInfo,
555+
Policies: policies,
556+
NetNs: args.Netns,
557557
DisableHairpinOnHostInterface: nwCfg.DisableHairpinOnHostInterface,
558558
IPV6Mode: nwCfg.IPV6Mode,
559559
ServiceCidrs: nwCfg.ServiceCidrs,

cns/NetworkContainerContract.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const (
1818
GetNetworkContainerByOrchestratorContext = "/network/getnetworkcontainerbyorchestratorcontext"
1919
AttachContainerToNetwork = "/network/attachcontainertonetwork"
2020
DetachContainerFromNetwork = "/network/detachcontainerfromnetwork"
21+
RequestIPConfig = "/network/requestipconfig"
22+
ReleaseIPConfig = "/network/releaseipconfig"
2123
)
2224

2325
// NetworkContainer Prefixes
@@ -50,6 +52,13 @@ const (
5052
Vxlan = "Vxlan"
5153
)
5254

55+
// IPConfig States for CNS IPAM
56+
const (
57+
Available = "Available"
58+
Allocated = "Allocated"
59+
PendingRelease = "PendingRelease"
60+
)
61+
5362
// CreateNetworkContainerRequest specifies request to create a network container or network isolation boundary.
5463
type CreateNetworkContainerRequest struct {
5564
Version string
@@ -87,6 +96,11 @@ type KubernetesPodInfo struct {
8796
PodNamespace string
8897
}
8998

99+
// GetOrchestratorContext will return the orchestratorcontext as a string
100+
func (podinfo *KubernetesPodInfo) GetOrchestratorContextKey() string {
101+
return podinfo.PodName + ":" + podinfo.PodNamespace
102+
}
103+
90104
// MultiTenancyInfo contains encap type and id.
91105
type MultiTenancyInfo struct {
92106
EncapType string
@@ -100,6 +114,19 @@ type IPConfiguration struct {
100114
GatewayIPAddress string
101115
}
102116

117+
type SecondaryIPConfig struct {
118+
UUID string
119+
IPConfig IPSubnet
120+
}
121+
122+
type ContainerIPConfigState struct {
123+
IPConfig IPSubnet
124+
ID string //uuid
125+
NCID string
126+
State string
127+
OrchestratorContext json.RawMessage
128+
}
129+
103130
// IPSubnet contains ip subnet.
104131
type IPSubnet struct {
105132
IPAddress string
@@ -158,6 +185,16 @@ type GetNetworkContainerResponse struct {
158185
AllowNCToHostCommunication bool
159186
}
160187

188+
type GetIPConfigRequest struct {
189+
DesiredIPConfig IPSubnet
190+
OrchestratorContext json.RawMessage
191+
}
192+
193+
type GetIPConfigResponse struct {
194+
IPConfiguration IPConfiguration
195+
Response Response
196+
}
197+
161198
// DeleteNetworkContainerRequest specifies the details about the request to delete a specifc network container.
162199
type DeleteNetworkContainerRequest struct {
163200
NetworkContainerid string

cns/cnsclient/cnsclient.go

Lines changed: 115 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ type CNSClient struct {
1616
}
1717

1818
const (
19-
defaultCnsURL = "http://localhost:10090"
19+
defaultCnsURL = "http://localhost:10090"
20+
contentTypeJSON = "application/json"
2021
)
2122

2223
var (
@@ -67,7 +68,7 @@ func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte)
6768
return nil, err
6869
}
6970

70-
res, err := httpc.Post(url, "application/json", &body)
71+
res, err := httpc.Post(url, contentTypeJSON, &body)
7172
if err != nil {
7273
log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error())
7374
return nil, err
@@ -98,8 +99,7 @@ func (cnsClient *CNSClient) GetNetworkConfiguration(orchestratorContext []byte)
9899
}
99100

100101
// CreateHostNCApipaEndpoint creates an endpoint in APIPA network for host container connectivity.
101-
func (cnsClient *CNSClient) CreateHostNCApipaEndpoint(
102-
networkContainerID string) (string, error) {
102+
func (cnsClient *CNSClient) CreateHostNCApipaEndpoint(networkContainerID string) (string, error) {
103103
var (
104104
err error
105105
body bytes.Buffer
@@ -118,7 +118,7 @@ func (cnsClient *CNSClient) CreateHostNCApipaEndpoint(
118118
return "", err
119119
}
120120

121-
res, err := httpc.Post(url, "application/json", &body)
121+
res, err := httpc.Post(url, contentTypeJSON, &body)
122122
if err != nil {
123123
log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error())
124124
return "", err
@@ -167,7 +167,7 @@ func (cnsClient *CNSClient) DeleteHostNCApipaEndpoint(networkContainerID string)
167167
return err
168168
}
169169

170-
res, err := httpc.Post(url, "application/json", &body)
170+
res, err := httpc.Post(url, contentTypeJSON, &body)
171171
if err != nil {
172172
log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error())
173173
return err
@@ -198,3 +198,112 @@ func (cnsClient *CNSClient) DeleteHostNCApipaEndpoint(networkContainerID string)
198198

199199
return nil
200200
}
201+
202+
// RequestIPAddress calls the requestIPAddress in CNS
203+
func (cnsClient *CNSClient) RequestIPAddress(orchestratorContext []byte) (*cns.GetIPConfigResponse, error) {
204+
var (
205+
err error
206+
res *http.Response
207+
response *cns.GetIPConfigResponse
208+
)
209+
210+
defer func() {
211+
if err != nil {
212+
cnsClient.ReleaseIPAddress(orchestratorContext)
213+
}
214+
}()
215+
216+
var body bytes.Buffer
217+
218+
httpc := &http.Client{}
219+
url := cnsClient.connectionURL + cns.RequestIPConfig
220+
221+
payload := &cns.GetNetworkContainerRequest{
222+
OrchestratorContext: orchestratorContext,
223+
}
224+
225+
err = json.NewEncoder(&body).Encode(payload)
226+
if err != nil {
227+
log.Errorf("encoding json failed with %v", err)
228+
return response, err
229+
}
230+
231+
res, err = httpc.Post(url, contentTypeJSON, &body)
232+
if err != nil {
233+
log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error())
234+
return response, err
235+
}
236+
237+
defer res.Body.Close()
238+
239+
if res.StatusCode != http.StatusOK {
240+
errMsg := fmt.Sprintf("[Azure CNSClient] RequestIPAddress invalid http status code: %v", res.StatusCode)
241+
log.Errorf(errMsg)
242+
return response, fmt.Errorf(errMsg)
243+
}
244+
245+
err = json.NewDecoder(res.Body).Decode(&response)
246+
if err != nil {
247+
log.Errorf("[Azure CNSClient] Error received while parsing RequestIPAddress response resp:%v err:%v", res.Body, err.Error())
248+
return response, err
249+
}
250+
251+
if response.Response.ReturnCode != 0 {
252+
log.Errorf("[Azure CNSClient] RequestIPAddress received error response :%v", response.Response.Message)
253+
return response, fmt.Errorf(response.Response.Message)
254+
}
255+
256+
return response, err
257+
}
258+
259+
// ReleaseIPAddress calls releaseIPAddress on CNS
260+
func (cnsClient *CNSClient) ReleaseIPAddress(orchestratorContext []byte) error {
261+
var (
262+
err error
263+
res *http.Response
264+
body bytes.Buffer
265+
)
266+
267+
httpc := &http.Client{}
268+
url := cnsClient.connectionURL + cns.ReleaseIPConfig
269+
log.Printf("ReleaseIPAddress url %v", url)
270+
271+
payload := &cns.GetNetworkContainerRequest{
272+
OrchestratorContext: orchestratorContext,
273+
}
274+
275+
err = json.NewEncoder(&body).Encode(payload)
276+
if err != nil {
277+
log.Errorf("encoding json failed with %v", err)
278+
return err
279+
}
280+
281+
res, err = httpc.Post(url, contentTypeJSON, &body)
282+
if err != nil {
283+
log.Errorf("[Azure CNSClient] HTTP Post returned error %v", err.Error())
284+
return err
285+
}
286+
287+
defer res.Body.Close()
288+
289+
if res.StatusCode != http.StatusOK {
290+
errMsg := fmt.Sprintf("[Azure CNSClient] ReleaseIPAddress invalid http status code: %v", res.StatusCode)
291+
log.Errorf(errMsg)
292+
return fmt.Errorf(errMsg)
293+
}
294+
295+
var resp cns.Response
296+
297+
err = json.NewDecoder(res.Body).Decode(&resp)
298+
if err != nil {
299+
log.Errorf("[Azure CNSClient] Error received while parsing ReleaseIPAddress response resp:%v err:%v", res.Body, err.Error())
300+
return err
301+
}
302+
303+
if resp.ReturnCode != 0 {
304+
log.Errorf("[Azure CNSClient] ReleaseIPAddress received error response :%v", resp.Message)
305+
return fmt.Errorf(resp.Message)
306+
}
307+
308+
return err
309+
}

0 commit comments

Comments
 (0)