@@ -30,25 +30,89 @@ const (
30
30
overlayGatewayV6 = "fe80::1234:5678:9abc"
31
31
)
32
32
33
- type SWIFTv2Middleware struct {
33
+ type K8sSWIFTv2Middleware struct {
34
34
Cli client.Client
35
35
}
36
36
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.
38
102
// 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 ) {
40
104
// Retrieve the pod from the cluster
41
105
podInfo , err := cns .UnmarshalPodInfo (req .OrchestratorContext )
42
106
if err != nil {
43
107
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 ()
45
109
}
46
110
logger .Printf ("[SWIFTv2Middleware] validate ipconfigs request for pod %s" , podInfo .Name ())
47
111
podNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
48
112
pod := v1.Pod {}
49
113
if err := m .Cli .Get (ctx , podNamespacedName , & pod ); err != nil {
50
114
errBuf := errors .Wrapf (err , "failed to get pod %+v" , podNamespacedName )
51
- return types .UnexpectedError , errBuf .Error ()
115
+ return nil , types .UnexpectedError , errBuf .Error ()
52
116
}
53
117
54
118
// 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
58
122
mtpnc := v1alpha1.MultitenantPodNetworkConfig {}
59
123
mtpncNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
60
124
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 ()
62
126
}
63
127
// Check if the MTPNC CRD is ready. If one of the fields is empty, return error
64
128
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 ()
66
130
}
67
131
}
68
132
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 , ""
70
135
}
71
136
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 ) {
74
139
// Check if the MTPNC CRD exists for the pod, if not, return error
75
140
mtpnc := v1alpha1.MultitenantPodNetworkConfig {}
76
141
mtpncNamespacedName := k8stypes.NamespacedName {Namespace : podInfo .Namespace (), Name : podInfo .Name ()}
@@ -109,8 +174,8 @@ func (m *SWIFTv2Middleware) GetIPConfig(ctx context.Context, podInfo cns.PodInfo
109
174
return podIPInfo , nil
110
175
}
111
176
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 {
114
179
logger .Printf ("[SWIFTv2Middleware] set routes for pod with nic type : %s" , podIPInfo .NICType )
115
180
podIPInfo .Routes = []cns.Route {}
116
181
switch podIPInfo .NICType {
0 commit comments