@@ -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
3837var _ 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
283156func (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+ }
0 commit comments