@@ -30,25 +30,89 @@ const (
3030 overlayGatewayV6 = "fe80::1234:5678:9abc"
3131)
3232
33- type SWIFTv2Middleware struct {
33+ type K8sSWIFTv2Middleware struct {
3434 Cli client.Client
3535}
3636
37- // ValidateIPConfigsRequest validates if pod is multitenant by checking the pod labels, used in SWIFT V2 scenario.
37+ // Verify interface compliance at compile time
38+ var _ cns.IPConfigsHandlerMiddleware = (* K8sSWIFTv2Middleware )(nil )
39+
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 (m * K8sSWIFTv2Middleware ) IPConfigsRequestHandlerWrapper (defaultHandler , failureHandler cns.IPConfigsHandlerFunc ) cns.IPConfigsHandlerFunc {
43+ return func (ctx context.Context , req cns.IPConfigsRequest ) (* cns.IPConfigsResponse , error ) {
44+ podInfo , respCode , message := m .validateIPConfigsRequest (ctx , & req )
45+
46+ if respCode != types .Success {
47+ return & cns.IPConfigsResponse {
48+ Response : cns.Response {
49+ ReturnCode : respCode ,
50+ Message : message ,
51+ },
52+ }, errors .New ("failed to validate ip configs request" )
53+ }
54+ ipConfigsResp , err := defaultHandler (ctx , req )
55+ // If the pod is not v2, return the response from the handler
56+ if ! req .SecondaryInterfacesExist {
57+ return ipConfigsResp , err
58+ }
59+ // If the pod is v2, get the infra IP configs from the handler first and then add the SWIFTv2 IP config
60+ defer func () {
61+ // Release the default IP config if there is an error
62+ if err != nil {
63+ _ , err = failureHandler (ctx , req )
64+ if err != nil {
65+ logger .Errorf ("failed to release default IP config : %v" , err )
66+ }
67+ }
68+ }()
69+ if err != nil {
70+ return ipConfigsResp , err
71+ }
72+ SWIFTv2PodIPInfo , err := m .getIPConfig (ctx , podInfo )
73+ if err != nil {
74+ return & cns.IPConfigsResponse {
75+ Response : cns.Response {
76+ ReturnCode : types .FailedToAllocateIPConfig ,
77+ Message : fmt .Sprintf ("AllocateIPConfig failed: %v, IP config request is %v" , err , req ),
78+ },
79+ PodIPInfo : []cns.PodIpInfo {},
80+ }, errors .Wrapf (err , "failed to get SWIFTv2 IP config : %v" , req )
81+ }
82+ ipConfigsResp .PodIPInfo = append (ipConfigsResp .PodIPInfo , SWIFTv2PodIPInfo )
83+ // Set routes for the pod
84+ for i := range ipConfigsResp .PodIPInfo {
85+ ipInfo := & ipConfigsResp .PodIPInfo [i ]
86+ err = m .setRoutes (ipInfo )
87+ if err != nil {
88+ return & cns.IPConfigsResponse {
89+ Response : cns.Response {
90+ ReturnCode : types .FailedToAllocateIPConfig ,
91+ Message : fmt .Sprintf ("AllocateIPConfig failed: %v, IP config request is %v" , err , req ),
92+ },
93+ PodIPInfo : []cns.PodIpInfo {},
94+ }, errors .Wrapf (err , "failed to set routes for pod %s" , podInfo .Name ())
95+ }
96+ }
97+ return ipConfigsResp , nil
98+ }
99+ }
100+
101+ // validateIPConfigsRequest validates if pod is multitenant by checking the pod labels, used in SWIFT V2 AKS scenario.
38102// nolint
39- func (m * SWIFTv2Middleware ) ValidateIPConfigsRequest (ctx context.Context , req * cns.IPConfigsRequest ) (respCode types.ResponseCode , message string ) {
103+ func (m * K8sSWIFTv2Middleware ) validateIPConfigsRequest (ctx context.Context , req * cns.IPConfigsRequest ) (podInfo cns. PodInfo , respCode types.ResponseCode , message string ) {
40104 // Retrieve the pod from the cluster
41105 podInfo , err := cns .UnmarshalPodInfo (req .OrchestratorContext )
42106 if err != nil {
43107 errBuf := errors .Wrapf (err , "failed to unmarshalling pod info from ipconfigs request %+v" , req )
44- return types .UnexpectedError , errBuf .Error ()
108+ return nil , types .UnexpectedError , errBuf .Error ()
45109 }
46110 logger .Printf ("[SWIFTv2Middleware] validate ipconfigs request for pod %s" , podInfo .Name ())
47111 podNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
48112 pod := v1.Pod {}
49113 if err := m .Cli .Get (ctx , podNamespacedName , & pod ); err != nil {
50114 errBuf := errors .Wrapf (err , "failed to get pod %+v" , podNamespacedName )
51- return types .UnexpectedError , errBuf .Error ()
115+ return nil , types .UnexpectedError , errBuf .Error ()
52116 }
53117
54118 // check the pod labels for Swift V2, set the request's SecondaryInterfaceSet flag to true and check if its MTPNC CRD is ready
@@ -58,19 +122,20 @@ func (m *SWIFTv2Middleware) ValidateIPConfigsRequest(ctx context.Context, req *c
58122 mtpnc := v1alpha1.MultitenantPodNetworkConfig {}
59123 mtpncNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
60124 if err := m .Cli .Get (ctx , mtpncNamespacedName , & mtpnc ); err != nil {
61- return types .UnexpectedError , fmt .Errorf ("failed to get pod's mtpnc from cache : %w" , err ).Error ()
125+ return nil , types .UnexpectedError , fmt .Errorf ("failed to get pod's mtpnc from cache : %w" , err ).Error ()
62126 }
63127 // Check if the MTPNC CRD is ready. If one of the fields is empty, return error
64128 if mtpnc .Status .PrimaryIP == "" || mtpnc .Status .MacAddress == "" || mtpnc .Status .NCID == "" || mtpnc .Status .GatewayIP == "" {
65- return types .UnexpectedError , errMTPNCNotReady .Error ()
129+ return nil , types .UnexpectedError , errMTPNCNotReady .Error ()
66130 }
67131 }
68132 logger .Printf ("[SWIFTv2Middleware] pod %s has secondary interface : %v" , podInfo .Name (), req .SecondaryInterfacesExist )
69- return types .Success , ""
133+ // retrieve podinfo from orchestrator context
134+ return podInfo , types .Success , ""
70135}
71136
72- // GetIPConfig returns the pod's SWIFT V2 IP configuration.
73- func (m * SWIFTv2Middleware ) GetIPConfig (ctx context.Context , podInfo cns.PodInfo ) (cns.PodIpInfo , error ) {
137+ // getIPConfig returns the pod's SWIFT V2 IP configuration.
138+ func (m * K8sSWIFTv2Middleware ) getIPConfig (ctx context.Context , podInfo cns.PodInfo ) (cns.PodIpInfo , error ) {
74139 // Check if the MTPNC CRD exists for the pod, if not, return error
75140 mtpnc := v1alpha1.MultitenantPodNetworkConfig {}
76141 mtpncNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
@@ -109,8 +174,8 @@ func (m *SWIFTv2Middleware) GetIPConfig(ctx context.Context, podInfo cns.PodInfo
109174 return podIPInfo , nil
110175}
111176
112- // SetRoutes sets the routes for podIPInfo used in SWIFT V2 scenario.
113- func (m * SWIFTv2Middleware ) SetRoutes (podIPInfo * cns.PodIpInfo ) error {
177+ // setRoutes sets the routes for podIPInfo used in SWIFT V2 scenario.
178+ func (m * K8sSWIFTv2Middleware ) setRoutes (podIPInfo * cns.PodIpInfo ) error {
114179 logger .Printf ("[SWIFTv2Middleware] set routes for pod with nic type : %s" , podIPInfo .NICType )
115180 podIPInfo .Routes = []cns.Route {}
116181 switch podIPInfo .NICType {
0 commit comments