Skip to content

Commit b29454d

Browse files
committed
refactored code per pr comments
1 parent 512b258 commit b29454d

File tree

4 files changed

+279
-155
lines changed

4 files changed

+279
-155
lines changed

cns/middlewares/k8sSwiftV2.go

Lines changed: 89 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"github.com/Azure/azure-container-networking/cns/middlewares/utils"
1111
"github.com/Azure/azure-container-networking/cns/types"
1212
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
13-
"github.com/Azure/azure-container-networking/network/policy"
1413
"github.com/pkg/errors"
1514
v1 "k8s.io/api/core/v1"
1615
k8stypes "k8s.io/apimachinery/pkg/types"
@@ -37,158 +36,32 @@ type K8sSWIFTv2Middleware struct {
3736
// Verify interface compliance at compile time
3837
var _ cns.IPConfigsHandlerMiddleware = (*K8sSWIFTv2Middleware)(nil)
3938

40-
// IPConfigsRequestHandlerWrapper is the middleware function for handling SWIFT v2 IP configs requests for AKS-SWIFT. This function wrapped the default SWIFT request
41-
// and release IP configs handlers.
42-
func (k *K8sSWIFTv2Middleware) IPConfigsRequestHandlerWrapper(defaultHandler, failureHandler cns.IPConfigsHandlerFunc) cns.IPConfigsHandlerFunc {
43-
return func(ctx context.Context, req cns.IPConfigsRequest) (*cns.IPConfigsResponse, error) {
44-
podInfo, respCode, defaultDenyACLbool, message := k.GetPodInfoForIPConfigsRequest(ctx, &req)
39+
func (k *K8sSWIFTv2Middleware) GetPodInfoForIPConfigsRequest(ctx context.Context, req *cns.IPConfigsRequest) (podInfo cns.PodInfo, respCode types.ResponseCode, message string) {
40+
// gets pod info for the specified request
41+
podInfo, pod, respCode, message := k.GetPodInfo(ctx, req)
42+
if respCode != types.Success {
43+
return nil, respCode, message
44+
}
4545

46-
logger.Printf("defaultDenyACLbool value is: %v", defaultDenyACLbool)
46+
// validates if pod is swiftv2
47+
isSwiftv2 := ValidateSwiftv2Pod(pod)
4748

49+
var mtpnc v1alpha1.MultitenantPodNetworkConfig
50+
// if swiftv2 is enabled, check if mtpnc is ready
51+
if isSwiftv2 {
52+
mtpnc, respCode, message = k.getMTPNC(ctx, podInfo)
4853
if respCode != types.Success {
49-
return &cns.IPConfigsResponse{
50-
Response: cns.Response{
51-
ReturnCode: respCode,
52-
Message: message,
53-
},
54-
}, errors.New("failed to validate IP configs request")
55-
}
56-
ipConfigsResp, err := defaultHandler(ctx, req)
57-
// If the pod is not v2, return the response from the handler
58-
if !req.SecondaryInterfacesExist {
59-
return ipConfigsResp, err
60-
}
61-
62-
// ipConfigsResp has infra IP configs -> if defaultDenyACLbool is enabled, add the default deny endpoint policies as a property in PodIpInfo
63-
for i := range ipConfigsResp.PodIPInfo {
64-
ipInfo := &ipConfigsResp.PodIPInfo[i]
65-
// there will be no pod connectivity to and from those pods
66-
var defaultDenyEgressPolicy, defaultDenyIngressPolicy policy.Policy
67-
68-
if defaultDenyACLbool && ipInfo.NICType == cns.InfraNIC {
69-
defaultDenyEgressPolicy, err = getEndpointPolicy(string(policy.ACLPolicy), cns.ActionTypeBlock, cns.DirectionTypeOut, 10_000)
70-
if err != nil {
71-
logger.Errorf("failed to add default deny acl's for pod %v with err %v", podInfo.Name(), err)
72-
}
73-
74-
defaultDenyIngressPolicy, err = getEndpointPolicy(string(policy.ACLPolicy), cns.ActionTypeBlock, cns.DirectionTypeIn, 10_000)
75-
if err != nil {
76-
logger.Errorf("failed to add default deny acl's for pod %v with err %v", podInfo.Name(), err)
77-
}
78-
79-
ipInfo.EndpointPolicies = append(ipInfo.EndpointPolicies, defaultDenyEgressPolicy, defaultDenyIngressPolicy)
80-
logger.Printf("Created endpoint policies for defaultDenyEgressPolicy and defaultDenyIngressPolicy")
81-
82-
break
83-
}
54+
return nil, respCode, message
8455
}
8556

86-
// If the pod is v2, get the infra IP configs from the handler first and then add the SWIFTv2 IP config
87-
defer func() {
88-
// Release the default IP config if there is an error
89-
if err != nil {
90-
_, err = failureHandler(ctx, req)
91-
if err != nil {
92-
logger.Errorf("failed to release default IP config : %v", err)
93-
}
94-
}
95-
}()
96-
if err != nil {
97-
return ipConfigsResp, err
98-
}
99-
SWIFTv2PodIPInfos, err := k.getIPConfig(ctx, podInfo)
100-
if err != nil {
101-
return &cns.IPConfigsResponse{
102-
Response: cns.Response{
103-
ReturnCode: types.FailedToAllocateIPConfig,
104-
Message: fmt.Sprintf("AllocateIPConfig failed: %v, IP config request is %v", err, req),
105-
},
106-
PodIPInfo: []cns.PodIpInfo{},
107-
}, errors.Wrapf(err, "failed to get SWIFTv2 IP config : %v", req)
108-
}
109-
ipConfigsResp.PodIPInfo = append(ipConfigsResp.PodIPInfo, SWIFTv2PodIPInfos...)
110-
// Set routes for the pod
111-
for i := range ipConfigsResp.PodIPInfo {
112-
ipInfo := &ipConfigsResp.PodIPInfo[i]
113-
// Backend nics doesn't need routes to be set
114-
if ipInfo.NICType != cns.BackendNIC {
115-
err = k.setRoutes(ipInfo)
116-
if err != nil {
117-
return &cns.IPConfigsResponse{
118-
Response: cns.Response{
119-
ReturnCode: types.FailedToAllocateIPConfig,
120-
Message: fmt.Sprintf("AllocateIPConfig failed: %v, IP config request is %v", err, req),
121-
},
122-
PodIPInfo: []cns.PodIpInfo{},
123-
}, errors.Wrapf(err, "failed to set routes for pod %s", podInfo.Name())
124-
}
125-
}
57+
// update ipConfigRequest
58+
respCode, message = k.UpdateIPConfigRequest(mtpnc, podInfo, req)
59+
if respCode != types.Success {
60+
return nil, respCode, message
12661
}
127-
return ipConfigsResp, nil
128-
}
129-
}
130-
131-
// GetPodInfoForIPConfigsRequest validates if pod is multitenant by checking the pod labels, used in SWIFT V2 AKS scenario.
132-
// nolint
133-
func (k *K8sSWIFTv2Middleware) GetPodInfoForIPConfigsRequest(ctx context.Context, req *cns.IPConfigsRequest) (podInfo cns.PodInfo, respCode types.ResponseCode, defaultDenyACL bool, message string) {
134-
defaultDenyACLbool := false
135-
136-
// Retrieve the pod from the cluster
137-
podInfo, err := cns.UnmarshalPodInfo(req.OrchestratorContext)
138-
if err != nil {
139-
errBuf := errors.Wrapf(err, "failed to unmarshalling pod info from ipconfigs request %+v", req)
140-
return nil, types.UnexpectedError, defaultDenyACLbool, errBuf.Error()
141-
}
142-
logger.Printf("[SWIFTv2Middleware] validate ipconfigs request for pod %s", podInfo.Name())
143-
podNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
144-
pod := v1.Pod{}
145-
if err := k.Cli.Get(ctx, podNamespacedName, &pod); err != nil {
146-
errBuf := errors.Wrapf(err, "failed to get pod %+v", podNamespacedName)
147-
return nil, types.UnexpectedError, defaultDenyACLbool, errBuf.Error()
14862
}
14963

150-
// check the pod labels for Swift V2, set the request's SecondaryInterfaceSet flag to true and check if its MTPNC CRD is ready
151-
_, swiftV2PodNetworkLabel := pod.Labels[configuration.LabelPodSwiftV2]
152-
_, swiftV2PodNetworkInstanceLabel := pod.Labels[configuration.LabelPodNetworkInstanceSwiftV2]
153-
if swiftV2PodNetworkLabel || swiftV2PodNetworkInstanceLabel {
154-
155-
// Check if the MTPNC CRD exists for the pod, if not, return error
156-
mtpnc := v1alpha1.MultitenantPodNetworkConfig{}
157-
mtpncNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
158-
if err := k.Cli.Get(ctx, mtpncNamespacedName, &mtpnc); err != nil {
159-
return nil, types.UnexpectedError, defaultDenyACLbool, fmt.Errorf("failed to get pod's mtpnc from cache : %w", err).Error()
160-
}
161-
// Check if the MTPNC CRD is ready. If one of the fields is empty, return error
162-
if !mtpnc.IsReady() {
163-
return nil, types.UnexpectedError, defaultDenyACLbool, errMTPNCNotReady.Error()
164-
}
165-
166-
// copying defaultDenyACL bool from mtpnc
167-
defaultDenyACLbool = mtpnc.Status.DefaultDenyACL
168-
169-
// If primary Ip is set in status field, it indicates the presence of secondary interfaces
170-
if mtpnc.Status.PrimaryIP != "" {
171-
req.SecondaryInterfacesExist = true
172-
}
173-
interfaceInfos := mtpnc.Status.InterfaceInfos
174-
for _, interfaceInfo := range interfaceInfos {
175-
if interfaceInfo.DeviceType == v1alpha1.DeviceTypeInfiniBandNIC {
176-
if interfaceInfo.MacAddress == "" || interfaceInfo.NCID == "" {
177-
return nil, types.UnexpectedError, defaultDenyACLbool, errMTPNCNotReady.Error()
178-
}
179-
req.BackendInterfaceExist = true
180-
req.BackendInterfaceMacAddresses = append(req.BackendInterfaceMacAddresses, interfaceInfo.MacAddress)
181-
182-
}
183-
if interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC {
184-
req.SecondaryInterfacesExist = true
185-
}
186-
}
187-
}
188-
logger.Printf("[SWIFTv2Middleware] pod %s has secondary interface : %v", podInfo.Name(), req.SecondaryInterfacesExist)
189-
logger.Printf("[SWIFTv2Middleware] pod %s has backend interface : %v", podInfo.Name(), req.BackendInterfaceExist)
190-
// retrieve podinfo from orchestrator context
191-
return podInfo, types.Success, defaultDenyACLbool, ""
64+
return podInfo, types.Success, ""
19265
}
19366

19467
// getIPConfig returns the pod's SWIFT V2 IP configuration.
@@ -283,3 +156,74 @@ func (k *K8sSWIFTv2Middleware) getIPConfig(ctx context.Context, podInfo cns.PodI
283156
func (k *K8sSWIFTv2Middleware) Type() cns.SWIFTV2Mode {
284157
return cns.K8sSWIFTV2
285158
}
159+
160+
// gets Pod Data
161+
func (k *K8sSWIFTv2Middleware) GetPodInfo(ctx context.Context, req *cns.IPConfigsRequest) (podInfo cns.PodInfo, k8sPod v1.Pod, respCode types.ResponseCode, message string) {
162+
// Retrieve the pod from the cluster
163+
podInfo, err := cns.UnmarshalPodInfo(req.OrchestratorContext)
164+
if err != nil {
165+
errBuf := errors.Wrapf(err, "failed to unmarshalling pod info from ipconfigs request %+v", req)
166+
return nil, v1.Pod{}, types.UnexpectedError, errBuf.Error()
167+
}
168+
logger.Printf("[SWIFTv2Middleware] validate ipconfigs request for pod %s", podInfo.Name())
169+
podNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
170+
pod := v1.Pod{}
171+
if err := k.Cli.Get(ctx, podNamespacedName, &pod); err != nil {
172+
errBuf := errors.Wrapf(err, "failed to get pod %+v", podNamespacedName)
173+
return nil, v1.Pod{}, types.UnexpectedError, errBuf.Error()
174+
}
175+
return podInfo, pod, types.Success, ""
176+
}
177+
178+
// validates if pod is multitenant by checking the pod labels, used in SWIFT V2 AKS scenario.
179+
func ValidateSwiftv2Pod(pod v1.Pod) bool {
180+
// check the pod labels for Swift V2, set the request's SecondaryInterfaceSet flag to true and check if its MTPNC CRD is ready
181+
_, swiftV2PodNetworkLabel := pod.Labels[configuration.LabelPodSwiftV2]
182+
_, swiftV2PodNetworkInstanceLabel := pod.Labels[configuration.LabelPodNetworkInstanceSwiftV2]
183+
// check if mtpnc is nil here, if not nil then proceed
184+
if swiftV2PodNetworkLabel || swiftV2PodNetworkInstanceLabel {
185+
return true
186+
}
187+
return false
188+
}
189+
190+
// checks if MTPNC is ready
191+
func (k *K8sSWIFTv2Middleware) getMTPNC(ctx context.Context, podInfo cns.PodInfo) (mtpncResource v1alpha1.MultitenantPodNetworkConfig, respCode types.ResponseCode, message string) {
192+
// Check if the MTPNC CRD exists for the pod, if not, return error
193+
mtpnc := v1alpha1.MultitenantPodNetworkConfig{}
194+
mtpncNamespacedName := k8stypes.NamespacedName{Namespace: podInfo.Namespace(), Name: podInfo.Name()}
195+
if err := k.Cli.Get(ctx, mtpncNamespacedName, &mtpnc); err != nil {
196+
return v1alpha1.MultitenantPodNetworkConfig{}, types.UnexpectedError, fmt.Errorf("failed to get pod's mtpnc from cache : %w", err).Error()
197+
}
198+
// Check if the MTPNC CRD is ready. If one of the fields is empty, return error
199+
if !mtpnc.IsReady() {
200+
return v1alpha1.MultitenantPodNetworkConfig{}, types.UnexpectedError, errMTPNCNotReady.Error()
201+
}
202+
return mtpnc, types.Success, ""
203+
}
204+
205+
// Updates Ip Config Request
206+
func (k *K8sSWIFTv2Middleware) UpdateIPConfigRequest(mtpnc v1alpha1.MultitenantPodNetworkConfig, podInfo cns.PodInfo, req *cns.IPConfigsRequest) (
207+
respCode types.ResponseCode,
208+
message string,
209+
) {
210+
interfaceInfos := mtpnc.Status.InterfaceInfos
211+
for _, interfaceInfo := range interfaceInfos {
212+
if interfaceInfo.DeviceType == v1alpha1.DeviceTypeInfiniBandNIC {
213+
if interfaceInfo.MacAddress == "" || interfaceInfo.NCID == "" {
214+
return types.UnexpectedError, errMTPNCNotReady.Error()
215+
}
216+
req.BackendInterfaceExist = true
217+
req.BackendInterfaceMacAddresses = append(req.BackendInterfaceMacAddresses, interfaceInfo.MacAddress)
218+
219+
}
220+
if interfaceInfo.DeviceType == v1alpha1.DeviceTypeVnetNIC {
221+
req.SecondaryInterfacesExist = true
222+
}
223+
}
224+
225+
logger.Printf("[SWIFTv2Middleware] pod %s has secondary interface : %v", podInfo.Name(), req.SecondaryInterfacesExist)
226+
logger.Printf("[SWIFTv2Middleware] pod %s has backend interface : %v", podInfo.Name(), req.BackendInterfaceExist)
227+
228+
return types.Success, ""
229+
}

cns/middlewares/k8sSwiftV2_linux.go

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
package middlewares
22

33
import (
4+
"context"
45
"fmt"
56
"net/netip"
67

78
"github.com/Azure/azure-container-networking/cns"
89
"github.com/Azure/azure-container-networking/cns/configuration"
910
"github.com/Azure/azure-container-networking/cns/logger"
1011
"github.com/Azure/azure-container-networking/cns/middlewares/utils"
12+
"github.com/Azure/azure-container-networking/cns/types"
1113
"github.com/Azure/azure-container-networking/crd/multitenancy/api/v1alpha1"
12-
"github.com/Azure/azure-container-networking/network/policy"
1314
"github.com/pkg/errors"
1415
)
1516

@@ -105,6 +106,66 @@ func (k *K8sSWIFTv2Middleware) assignSubnetPrefixLengthFields(_ *cns.PodIpInfo,
105106

106107
func (k *K8sSWIFTv2Middleware) addDefaultRoute(*cns.PodIpInfo, string) {}
107108

108-
func getEndpointPolicy(_, _, _ string, _ int) (policy.Policy, error) {
109-
return policy.Policy{}, nil
109+
// IPConfigsRequestHandlerWrapper is the middleware function for handling SWIFT v2 IP configs requests for AKS-SWIFT. This function wrapped the default SWIFT request
110+
// and release IP configs handlers.
111+
func (k *K8sSWIFTv2Middleware) IPConfigsRequestHandlerWrapper(defaultHandler, failureHandler cns.IPConfigsHandlerFunc) cns.IPConfigsHandlerFunc {
112+
return func(ctx context.Context, req cns.IPConfigsRequest) (*cns.IPConfigsResponse, error) {
113+
podInfo, respCode, message := k.GetPodInfoForIPConfigsRequest(ctx, &req)
114+
115+
if respCode != types.Success {
116+
return &cns.IPConfigsResponse{
117+
Response: cns.Response{
118+
ReturnCode: respCode,
119+
Message: message,
120+
},
121+
}, errors.New("failed to validate IP configs request")
122+
}
123+
ipConfigsResp, err := defaultHandler(ctx, req)
124+
// If the pod is not v2, return the response from the handler
125+
if !req.SecondaryInterfacesExist {
126+
return ipConfigsResp, err
127+
}
128+
// If the pod is v2, get the infra IP configs from the handler first and then add the SWIFTv2 IP config
129+
defer func() {
130+
// Release the default IP config if there is an error
131+
if err != nil {
132+
_, err = failureHandler(ctx, req)
133+
if err != nil {
134+
logger.Errorf("failed to release default IP config : %v", err)
135+
}
136+
}
137+
}()
138+
if err != nil {
139+
return ipConfigsResp, err
140+
}
141+
SWIFTv2PodIPInfos, err := k.getIPConfig(ctx, podInfo)
142+
if err != nil {
143+
return &cns.IPConfigsResponse{
144+
Response: cns.Response{
145+
ReturnCode: types.FailedToAllocateIPConfig,
146+
Message: fmt.Sprintf("AllocateIPConfig failed: %v, IP config request is %v", err, req),
147+
},
148+
PodIPInfo: []cns.PodIpInfo{},
149+
}, errors.Wrapf(err, "failed to get SWIFTv2 IP config : %v", req)
150+
}
151+
ipConfigsResp.PodIPInfo = append(ipConfigsResp.PodIPInfo, SWIFTv2PodIPInfos...)
152+
// Set routes for the pod
153+
for i := range ipConfigsResp.PodIPInfo {
154+
ipInfo := &ipConfigsResp.PodIPInfo[i]
155+
// Backend nics doesn't need routes to be set
156+
if ipInfo.NICType != cns.BackendNIC {
157+
err = k.setRoutes(ipInfo)
158+
if err != nil {
159+
return &cns.IPConfigsResponse{
160+
Response: cns.Response{
161+
ReturnCode: types.FailedToAllocateIPConfig,
162+
Message: fmt.Sprintf("AllocateIPConfig failed: %v, IP config request is %v", err, req),
163+
},
164+
PodIPInfo: []cns.PodIpInfo{},
165+
}, errors.Wrapf(err, "failed to set routes for pod %s", podInfo.Name())
166+
}
167+
}
168+
}
169+
return ipConfigsResp, nil
170+
}
110171
}

0 commit comments

Comments
 (0)