@@ -366,77 +366,18 @@ func (c *Cluster) createService(role PostgresRole) (*v1.Service, error) {
366
366
}
367
367
368
368
func (c * Cluster ) updateService (role PostgresRole , newService * v1.Service ) error {
369
+ var (
370
+ svc * v1.Service
371
+ err error
372
+ )
373
+
369
374
c .setProcessName ("updating %v service" , role )
370
375
371
376
if c .Services [role ] == nil {
372
377
return fmt .Errorf ("there is no service in the cluster" )
373
378
}
374
379
375
380
serviceName := util .NameFromMeta (c .Services [role ].ObjectMeta )
376
- endpointName := util .NameFromMeta (c .Endpoints [role ].ObjectMeta )
377
- // TODO: check if it possible to change the service type with a patch in future versions of Kubernetes
378
- if newService .Spec .Type != c .Services [role ].Spec .Type {
379
- // service type has changed, need to replace the service completely.
380
- // we cannot use just patch the current service, since it may contain attributes incompatible with the new type.
381
- var (
382
- currentEndpoint * v1.Endpoints
383
- err error
384
- )
385
-
386
- if role == Master {
387
- // for the master service we need to re-create the endpoint as well. Get the up-to-date version of
388
- // the addresses stored in it before the service is deleted (deletion of the service removes the endpoint)
389
- currentEndpoint , err = c .KubeClient .Endpoints (c .Namespace ).Get (c .endpointName (role ), metav1.GetOptions {})
390
- if err != nil {
391
- return fmt .Errorf ("could not get current cluster %s endpoints: %v" , role , err )
392
- }
393
- }
394
- err = c .KubeClient .Services (serviceName .Namespace ).Delete (serviceName .Name , c .deleteOptions )
395
- if err != nil {
396
- return fmt .Errorf ("could not delete service %q: %v" , serviceName , err )
397
- }
398
-
399
- // wait until the service is truly deleted
400
- c .logger .Debugf ("waiting for service to be deleted" )
401
-
402
- err = retryutil .Retry (c .OpConfig .ResourceCheckInterval , c .OpConfig .ResourceCheckTimeout ,
403
- func () (bool , error ) {
404
- _ , err2 := c .KubeClient .Services (serviceName .Namespace ).Get (serviceName .Name , metav1.GetOptions {})
405
- if err2 == nil {
406
- return false , nil
407
- }
408
- if k8sutil .ResourceNotFound (err2 ) {
409
- return true , nil
410
- }
411
- return false , err2
412
- })
413
- if err != nil {
414
- return fmt .Errorf ("could not delete service %q: %v" , serviceName , err )
415
- }
416
-
417
- // make sure we clear the stored service and endpoint status if the subsequent create fails.
418
- c .Services [role ] = nil
419
- c .Endpoints [role ] = nil
420
- if role == Master {
421
- // create the new endpoint using the addresses obtained from the previous one
422
- endpointSpec := c .generateEndpoint (role , currentEndpoint .Subsets )
423
- ep , err := c .KubeClient .Endpoints (endpointSpec .Namespace ).Create (endpointSpec )
424
- if err != nil {
425
- return fmt .Errorf ("could not create endpoint %q: %v" , endpointName , err )
426
- }
427
-
428
- c .Endpoints [role ] = ep
429
- }
430
-
431
- svc , err := c .KubeClient .Services (serviceName .Namespace ).Create (newService )
432
- if err != nil {
433
- return fmt .Errorf ("could not create service %q: %v" , serviceName , err )
434
- }
435
-
436
- c .Services [role ] = svc
437
-
438
- return nil
439
- }
440
381
441
382
// update the service annotation in order to propagate ELB notation.
442
383
if len (newService .ObjectMeta .Annotations ) > 0 {
@@ -454,18 +395,30 @@ func (c *Cluster) updateService(role PostgresRole, newService *v1.Service) error
454
395
}
455
396
}
456
397
457
- patchData , err := specPatch (newService .Spec )
458
- if err != nil {
459
- return fmt .Errorf ("could not form patch for the service %q: %v" , serviceName , err )
460
- }
398
+ // now, patch the service spec, but when disabling LoadBalancers do update instead
399
+ // patch does not work because of LoadBalancerSourceRanges field (even if set to nil)
400
+ oldServiceType := c .Services [role ].Spec .Type
401
+ newServiceType := newService .Spec .Type
402
+ if newServiceType == "ClusterIP" && newServiceType != oldServiceType {
403
+ newService .ResourceVersion = c .Services [role ].ResourceVersion
404
+ newService .Spec .ClusterIP = c .Services [role ].Spec .ClusterIP
405
+ svc , err = c .KubeClient .Services (serviceName .Namespace ).Update (newService )
406
+ if err != nil {
407
+ return fmt .Errorf ("could not update service %q: %v" , serviceName , err )
408
+ }
409
+ } else {
410
+ patchData , err := specPatch (newService .Spec )
411
+ if err != nil {
412
+ return fmt .Errorf ("could not form patch for the service %q: %v" , serviceName , err )
413
+ }
461
414
462
- // update the service spec
463
- svc , err := c . KubeClient . Services ( serviceName .Namespace ). Patch (
464
- serviceName . Name ,
465
- types . MergePatchType ,
466
- patchData , "" )
467
- if err != nil {
468
- return fmt . Errorf ( "could not patch service %q: %v" , serviceName , err )
415
+ svc , err = c . KubeClient . Services ( serviceName . Namespace ). Patch (
416
+ serviceName .Name ,
417
+ types . MergePatchType ,
418
+ patchData , "" )
419
+ if err != nil {
420
+ return fmt . Errorf ( "could not patch service %q: %v" , serviceName , err )
421
+ }
469
422
}
470
423
c .Services [role ] = svc
471
424
0 commit comments