Skip to content

Commit 5319878

Browse files
authored
Merge pull request #535 from Azure/consumeFromNCContainerRequest
Consume ACL for APIPA Endpoint from CreateNC Req
2 parents 512ffed + e44eca0 commit 5319878

File tree

4 files changed

+103
-7
lines changed

4 files changed

+103
-7
lines changed

cns/NetworkContainerContract.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package cns
22

33
import (
44
"encoding/json"
5+
"fmt"
6+
"strings"
57
)
68

79
// Container Network Service DNC Contract
@@ -63,6 +65,14 @@ type CreateNetworkContainerRequest struct {
6365
Routes []Route
6466
AllowHostToNCCommunication bool
6567
AllowNCToHostCommunication bool
68+
EndpointPolicies []NetworkContainerRequestPolicies
69+
}
70+
71+
// NetworkContainerRequestPolicies - specifies policies associated with create network request
72+
type NetworkContainerRequestPolicies struct {
73+
Type string
74+
EndpointType string
75+
Settings json.RawMessage
6676
}
6777

6878
// ConfigureContainerNetworkingRequest - specifies request to attach/detach container to network.
@@ -220,3 +230,51 @@ type UnpublishNetworkContainerResponse struct {
220230
UnpublishStatusCode int
221231
UnpublishResponseBody []byte
222232
}
233+
234+
// ValidAclPolicySetting - Used to validate ACL policy
235+
type ValidAclPolicySetting struct {
236+
Protocols string `json:","`
237+
Action string `json:","`
238+
Direction string `json:","`
239+
LocalAddresses string `json:","`
240+
RemoteAddresses string `json:","`
241+
LocalPorts string `json:","`
242+
RemotePorts string `json:","`
243+
RuleType string `json:","`
244+
Priority uint16 `json:","`
245+
}
246+
247+
// Validate - Validates network container request policies
248+
func (networkContainerRequestPolicy *NetworkContainerRequestPolicies) Validate() error {
249+
// validate ACL policy
250+
if networkContainerRequestPolicy != nil {
251+
if strings.EqualFold(networkContainerRequestPolicy.Type, "ACLPolicy") && strings.EqualFold(networkContainerRequestPolicy.EndpointType, "APIPA") {
252+
var requestedAclPolicy ValidAclPolicySetting
253+
if err := json.Unmarshal(networkContainerRequestPolicy.Settings, &requestedAclPolicy); err != nil {
254+
return fmt.Errorf("ACL policy failed to pass validation with error: %+v ", err)
255+
}
256+
//Deny request if ACL Action is empty
257+
if len(strings.TrimSpace(string(requestedAclPolicy.Action))) == 0 {
258+
return fmt.Errorf("Action field cannot be empty in ACL Policy")
259+
}
260+
//Deny request if ACL Action is not Allow or Deny
261+
if !strings.EqualFold(requestedAclPolicy.Action, "Allow") && !strings.EqualFold(requestedAclPolicy.Action, "Deny") {
262+
return fmt.Errorf("Only Allow or Deny is supported in Action field")
263+
}
264+
//Deny request if ACL Direction is empty
265+
if len(strings.TrimSpace(string(requestedAclPolicy.Direction))) == 0 {
266+
return fmt.Errorf("Direction field cannot be empty in ACL Policy")
267+
}
268+
//Deny request if ACL direction is not In or Out
269+
if !strings.EqualFold(requestedAclPolicy.Direction, "In") && !strings.EqualFold(requestedAclPolicy.Direction, "Out") {
270+
return fmt.Errorf("Only In or Out is supported in Direction field")
271+
}
272+
if requestedAclPolicy.Priority == 0 {
273+
return fmt.Errorf("Priority field cannot be empty in ACL Policy")
274+
}
275+
} else {
276+
return fmt.Errorf("Only ACL Policies on APIPA endpoint supported")
277+
}
278+
}
279+
return nil
280+
}

cns/hnsclient/hnsclient_linux.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ func CreateHostNCApipaEndpoint(
3838
networkContainerID string,
3939
localIPConfiguration cns.IPConfiguration,
4040
allowNCToHostCommunication bool,
41-
allowHostToNCCommunication bool) (string, error) {
41+
allowHostToNCCommunication bool,
42+
ncPolicies []cns.NetworkContainerRequestPolicies) (string, error) {
4243
return "", nil
4344
}
4445

cns/hnsclient/hnsclient_windows.go

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ const (
6666

6767
// aclPriority200 indicates the ACL priority of 200
6868
aclPriority200 = 200
69+
70+
// aclPolicyType indicates a ACL policy
71+
aclPolicyType = "ACLPolicy"
72+
73+
//signals a APIPA endpoint type
74+
apipaEndpointType = "APIPA"
6975
)
7076

7177
var (
@@ -347,7 +353,8 @@ func configureAclSettingHostNCApipaEndpoint(
347353
networkContainerApipaIP string,
348354
hostApipaIP string,
349355
allowNCToHostCommunication bool,
350-
allowHostToNCCommunication bool) ([]hcn.EndpointPolicy, error) {
356+
allowHostToNCCommunication bool,
357+
ncRequestedPolicies []cns.NetworkContainerRequestPolicies) ([]hcn.EndpointPolicy, error) {
351358
var (
352359
err error
353360
endpointPolicies []hcn.EndpointPolicy
@@ -426,8 +433,33 @@ func configureAclSettingHostNCApipaEndpoint(
426433
return nil, err
427434
}
428435
}
436+
429437
}
430438

439+
if ncRequestedPolicies != nil {
440+
// Iterate thru the requested endpoint policies where policy type is ACL, endpoint type is APIPA
441+
// include the raw json message in the endpoint policies
442+
for _, requestedPolicy := range ncRequestedPolicies {
443+
if strings.EqualFold(requestedPolicy.Type, aclPolicyType) && strings.EqualFold(requestedPolicy.EndpointType, apipaEndpointType) {
444+
var requestedAclPolicy hcn.AclPolicySetting
445+
if err = json.Unmarshal(requestedPolicy.Settings, &requestedAclPolicy); err != nil {
446+
return nil, fmt.Errorf("Failed to Unmarshal requested ACL policy: %+v with error: %S", requestedPolicy.Settings, err)
447+
}
448+
//Using {NetworkContainerIP} as a placeholder to signal using Network Container IP
449+
if strings.EqualFold(requestedAclPolicy.LocalAddresses, "{NetworkContainerIP}") {
450+
requestedAclPolicy.LocalAddresses = networkContainerApipaIP
451+
}
452+
//Using {HostApipaIP} as a placeholder to signal using Host Apipa IP
453+
if strings.EqualFold(requestedAclPolicy.RemoteAddresses, "{HostApipaIP}") {
454+
requestedAclPolicy.RemoteAddresses = hostApipaIP
455+
}
456+
logger.Printf("ACL Policy requested in NcGoalState %+v", requestedAclPolicy)
457+
if err = addAclToEndpointPolicy(requestedAclPolicy, &endpointPolicies); err != nil {
458+
return nil, err
459+
}
460+
}
461+
}
462+
}
431463
return endpointPolicies, nil
432464
}
433465

@@ -436,7 +468,8 @@ func configureHostNCApipaEndpoint(
436468
networkID string,
437469
localIPConfiguration cns.IPConfiguration,
438470
allowNCToHostCommunication bool,
439-
allowHostToNCCommunication bool) (*hcn.HostComputeEndpoint, error) {
471+
allowHostToNCCommunication bool,
472+
ncPolicies []cns.NetworkContainerRequestPolicies) (*hcn.HostComputeEndpoint, error) {
440473
endpoint := &hcn.HostComputeEndpoint{
441474
Name: endpointName,
442475
HostComputeNetwork: networkID,
@@ -455,7 +488,8 @@ func configureHostNCApipaEndpoint(
455488
networkContainerApipaIP,
456489
hostApipaIP,
457490
allowNCToHostCommunication,
458-
allowHostToNCCommunication)
491+
allowHostToNCCommunication,
492+
ncPolicies)
459493

460494
if err != nil {
461495
logger.Errorf("[Azure CNS] Failed to configure ACL for HostNCApipaEndpoint. Error: %v", err)
@@ -490,7 +524,8 @@ func CreateHostNCApipaEndpoint(
490524
networkContainerID string,
491525
localIPConfiguration cns.IPConfiguration,
492526
allowNCToHostCommunication bool,
493-
allowHostToNCCommunication bool) (string, error) {
527+
allowHostToNCCommunication bool,
528+
ncPolicies []cns.NetworkContainerRequestPolicies) (string, error) {
494529
var (
495530
network *hcn.HostComputeNetwork
496531
endpoint *hcn.HostComputeEndpoint
@@ -528,7 +563,8 @@ func CreateHostNCApipaEndpoint(
528563
network.Id,
529564
localIPConfiguration,
530565
allowNCToHostCommunication,
531-
allowHostToNCCommunication); err != nil {
566+
allowHostToNCCommunication,
567+
ncPolicies); err != nil {
532568
logger.Errorf("[Azure CNS] Failed to configure HostNCApipaEndpoint: %s. Error: %v", endpointName, err)
533569
return "", err
534570
}

cns/restserver/restserver.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,8 @@ func (service *HTTPRestService) createHostNCApipaEndpoint(w http.ResponseWriter,
16981698
req.NetworkContainerID,
16991699
networkContainerDetails.CreateNetworkContainerRequest.LocalIPConfiguration,
17001700
networkContainerDetails.CreateNetworkContainerRequest.AllowNCToHostCommunication,
1701-
networkContainerDetails.CreateNetworkContainerRequest.AllowHostToNCCommunication); err != nil {
1701+
networkContainerDetails.CreateNetworkContainerRequest.AllowHostToNCCommunication,
1702+
networkContainerDetails.CreateNetworkContainerRequest.EndpointPolicies); err != nil {
17021703
returnMessage = fmt.Sprintf("CreateHostNCApipaEndpoint failed with error: %v", err)
17031704
returnCode = UnexpectedError
17041705
}

0 commit comments

Comments
 (0)