@@ -117,6 +117,196 @@ func (s *ServiceVisibilityTestSuite) TestServiceUpload() {
117117 res , err := s .reconciler .Reconcile (context .Background (), req )
118118 s .Require ().NoError (err )
119119 s .Require ().Equal (ctrl.Result {}, res )
120+
121+ s .k8sClient .EXPECT ().List (gomock .Any (), gomock .Eq (& emptyList ), gomock .Eq (client .InNamespace (testNamespace ))).DoAndReturn (
122+ func (ctx context.Context , list * corev1.ServiceList , opts ... client.ListOption ) error {
123+ list .Items = []corev1.Service {service }
124+ return nil
125+ })
126+
127+ s .kubeFinder .EXPECT ().ResolveOtterizeIdentityForService (gomock .Any (), & service , gomock .Any ()).Return (serviceIdentity , true , nil )
128+
129+ // Reconcile again should not upload cause re-upload due to caching
130+ res , err = s .reconciler .Reconcile (context .Background (), req )
131+ s .Require ().NoError (err )
132+ s .Require ().Equal (ctrl.Result {}, res )
133+ }
134+
135+ func (s * ServiceVisibilityTestSuite ) TestServiceReUploadOnIdentityChange () {
136+ deploymentName := "my-server"
137+ service := corev1.Service {
138+ ObjectMeta : metav1.ObjectMeta {
139+ Name : "test-service" ,
140+ Namespace : testNamespace ,
141+ },
142+ Spec : corev1.ServiceSpec {
143+ Type : corev1 .ServiceTypeClusterIP ,
144+ Selector : map [string ]string {
145+ "app" : deploymentName ,
146+ },
147+ Ports : []corev1.ServicePort {
148+ {
149+ Port : 80 ,
150+ Protocol : corev1 .ProtocolTCP ,
151+ TargetPort : intstr .FromInt32 (8080 ),
152+ },
153+ },
154+ },
155+ }
156+
157+ emptyList := corev1.ServiceList {}
158+ s .k8sClient .EXPECT ().List (gomock .Any (), gomock .Eq (& emptyList ), gomock .Eq (client .InNamespace (testNamespace ))).DoAndReturn (
159+ func (ctx context.Context , list * corev1.ServiceList , opts ... client.ListOption ) error {
160+ list .Items = []corev1.Service {service }
161+ return nil
162+ })
163+
164+ serviceIdentity := model.OtterizeServiceIdentity {
165+ Name : deploymentName ,
166+ Namespace : testNamespace ,
167+ PodOwnerKind : nil ,
168+ KubernetesService : lo .ToPtr (service .Name ),
169+ }
170+ s .kubeFinder .EXPECT ().ResolveOtterizeIdentityForService (gomock .Any (), & service , gomock .Any ()).Return (serviceIdentity , true , nil )
171+
172+ serviceInput := cloudclient.K8sServiceInput {
173+ OtterizeServer : deploymentName ,
174+ Namespace : testNamespace ,
175+ ResourceName : service .Name ,
176+ Service : cloudclient.K8sResourceServiceInput {
177+ Spec : cloudclient.K8sResourceServiceSpecInput {
178+ Type : nilable .From (cloudclient .K8sServiceTypeClusterIp ),
179+ Ports : []cloudclient.K8sServicePort {
180+ {
181+ Port : 80 ,
182+ Protocol : nilable .From (cloudclient .K8sPortProtocolTcp ),
183+ TargetPort : nilable .From (cloudclient.IntOrStringInput {IntVal : nilable .From (8080 ), IsInt : true }),
184+ },
185+ },
186+ Selector : []cloudclient.SelectorKeyValueInput {{Key : nilable .From ("app" ), Value : nilable .From (deploymentName )}},
187+ },
188+ },
189+ }
190+ s .cloudClient .EXPECT ().ReportK8sServices (gomock .Any (), testNamespace , gomock .Any ()).DoAndReturn (
191+ func (ctx context.Context , namespace string , services []cloudclient.K8sServiceInput ) error {
192+ s .Require ().Len (services , 1 )
193+ s .Require ().Equal (serviceInput , services [0 ])
194+ return nil
195+ })
196+
197+ req := ctrl.Request {
198+ NamespacedName : client.ObjectKey {
199+ Namespace : testNamespace ,
200+ Name : "endpoint-for-service" ,
201+ },
202+ }
203+
204+ res , err := s .reconciler .Reconcile (context .Background (), req )
205+ s .Require ().NoError (err )
206+ s .Require ().Equal (ctrl.Result {}, res )
207+
208+ s .k8sClient .EXPECT ().List (gomock .Any (), gomock .Eq (& emptyList ), gomock .Eq (client .InNamespace (testNamespace ))).DoAndReturn (
209+ func (ctx context.Context , list * corev1.ServiceList , opts ... client.ListOption ) error {
210+ list .Items = []corev1.Service {service }
211+ return nil
212+ })
213+
214+ newIdentity := model.OtterizeServiceIdentity {
215+ Name : "another-server" ,
216+ Namespace : testNamespace ,
217+ PodOwnerKind : nil ,
218+ KubernetesService : lo .ToPtr (service .Name ),
219+ }
220+
221+ s .kubeFinder .EXPECT ().ResolveOtterizeIdentityForService (gomock .Any (), & service , gomock .Any ()).Return (newIdentity , true , nil )
222+
223+ newServiceInput := cloudclient.K8sServiceInput {
224+ OtterizeServer : "another-server" ,
225+ Namespace : testNamespace ,
226+ ResourceName : service .Name ,
227+ Service : cloudclient.K8sResourceServiceInput {
228+ Spec : cloudclient.K8sResourceServiceSpecInput {
229+ Type : nilable .From (cloudclient .K8sServiceTypeClusterIp ),
230+ Ports : []cloudclient.K8sServicePort {
231+ {
232+ Port : 80 ,
233+ Protocol : nilable .From (cloudclient .K8sPortProtocolTcp ),
234+ TargetPort : nilable .From (cloudclient.IntOrStringInput {IntVal : nilable .From (8080 ), IsInt : true }),
235+ },
236+ },
237+ Selector : []cloudclient.SelectorKeyValueInput {{Key : nilable .From ("app" ), Value : nilable .From (deploymentName )}},
238+ },
239+ },
240+ }
241+
242+ s .cloudClient .EXPECT ().ReportK8sServices (gomock .Any (), testNamespace , gomock .Any ()).DoAndReturn (
243+ func (ctx context.Context , namespace string , services []cloudclient.K8sServiceInput ) error {
244+ s .Require ().Len (services , 1 )
245+ s .Require ().Equal (newServiceInput , services [0 ])
246+ return nil
247+ })
248+
249+ res , err = s .reconciler .Reconcile (context .Background (), req )
250+ s .Require ().NoError (err )
251+ s .Require ().Equal (ctrl.Result {}, res )
252+
253+ nodePortService := corev1.Service {
254+ ObjectMeta : metav1.ObjectMeta {
255+ Name : "test-service" ,
256+ Namespace : testNamespace ,
257+ },
258+ Spec : corev1.ServiceSpec {
259+ Type : corev1 .ServiceTypeNodePort ,
260+ Selector : map [string ]string {
261+ "app" : deploymentName ,
262+ },
263+ Ports : []corev1.ServicePort {
264+ {
265+ Port : 80 ,
266+ Protocol : corev1 .ProtocolTCP ,
267+ TargetPort : intstr .FromInt32 (8080 ),
268+ },
269+ },
270+ },
271+ }
272+ s .k8sClient .EXPECT ().List (gomock .Any (), gomock .Eq (& emptyList ), gomock .Eq (client .InNamespace (testNamespace ))).DoAndReturn (
273+ func (ctx context.Context , list * corev1.ServiceList , opts ... client.ListOption ) error {
274+ list .Items = []corev1.Service {nodePortService }
275+ return nil
276+ })
277+
278+ s .kubeFinder .EXPECT ().ResolveOtterizeIdentityForService (gomock .Any (), & nodePortService , gomock .Any ()).Return (newIdentity , true , nil )
279+
280+ nodePortServiceInput := cloudclient.K8sServiceInput {
281+ OtterizeServer : "another-server" ,
282+ Namespace : testNamespace ,
283+ ResourceName : service .Name ,
284+ Service : cloudclient.K8sResourceServiceInput {
285+ Spec : cloudclient.K8sResourceServiceSpecInput {
286+ Type : nilable .From (cloudclient .K8sServiceTypeNodePort ),
287+ Ports : []cloudclient.K8sServicePort {
288+ {
289+ Port : 80 ,
290+ Protocol : nilable .From (cloudclient .K8sPortProtocolTcp ),
291+ TargetPort : nilable .From (cloudclient.IntOrStringInput {IntVal : nilable .From (8080 ), IsInt : true }),
292+ },
293+ },
294+ Selector : []cloudclient.SelectorKeyValueInput {{Key : nilable .From ("app" ), Value : nilable .From (deploymentName )}},
295+ },
296+ },
297+ }
298+
299+ s .cloudClient .EXPECT ().ReportK8sServices (gomock .Any (), testNamespace , gomock .Any ()).DoAndReturn (
300+ func (ctx context.Context , namespace string , services []cloudclient.K8sServiceInput ) error {
301+ s .Require ().Len (services , 1 )
302+ s .Require ().Equal (nodePortServiceInput , services [0 ])
303+ return nil
304+
305+ })
306+
307+ res , err = s .reconciler .Reconcile (context .Background (), req )
308+ s .Require ().NoError (err )
309+ s .Require ().Equal (ctrl.Result {}, res )
120310}
121311
122312func (s * ServiceVisibilityTestSuite ) TestUploadEmptyNamespaces () {
0 commit comments