@@ -113,12 +113,12 @@ func (lbp *LBProvider) ApplyConfig(lbConfig *config.LoadBalancerConfig) error {
113113 return err
114114 }
115115
116- // 2.update with certificate if needed
117- if err = lbp .updateCertificate (lbConfig , lb ); err != nil {
116+ // 2.update lb ( if needed)
117+ if err = lbp .update (lbConfig , lb ); err != nil {
118118 return err
119119 }
120120
121- // 3.set service links
121+ // 3.set service links (if needed)
122122 if err = lbp .setServiceLinks (lb , lbConfig ); err != nil {
123123 return err
124124 }
@@ -332,24 +332,94 @@ func (lbp *LBProvider) createCertificate(cert *config.Certificate) (*client.Cert
332332 return rancherCert , nil
333333}
334334
335- func (lbp * LBProvider ) updateCertificate (lbConfig * config.LoadBalancerConfig , lb * client.LoadBalancerService ) error {
336- rancherCertID , err := lbp .getRancherCertID (lbConfig )
335+ func (lbp * LBProvider ) update (lbConfig * config.LoadBalancerConfig , lb * client.LoadBalancerService ) error {
336+ toUpdate := make (map [string ]interface {})
337+ certUpdate , err := lbp .needCertUpdate (lbConfig , lb )
337338 if err != nil {
338339 return err
339340 }
340- if lb .DefaultCertificateId != rancherCertID {
341- lb .DefaultCertificateId = rancherCertID
341+
342+ if certUpdate {
343+ rancherCertID , err := lbp .getRancherCertID (lbConfig )
342344 logrus .Infof ("Updating Rancher LB with the new cert [%s] " , rancherCertID )
343- _ , err = lbp .client .LoadBalancerService .Update (lb , map [string ]interface {}{
344- "defaultCertificateId" : rancherCertID ,
345- })
346345 if err != nil {
347- return fmt .Errorf ("Failed to update lb [%s] with a new certificate [%s]. Error: %#v" , lb .Name , rancherCertID , err )
346+ return err
347+ }
348+
349+ toUpdate ["defaultCertificateId" ] = rancherCertID
350+ }
351+
352+ newGlobal , newDefaults , err := lbp .getCustomHaproxyConfig (lbConfig )
353+ if err != nil {
354+ return err
355+ }
356+
357+ configUpdate := lbp .needConfigUpdate (lb , newGlobal , newDefaults )
358+
359+ if configUpdate {
360+ logrus .Infof ("Updating Rancher LB with the new config global:[%s], defaults:[%s]" , newGlobal , newDefaults )
361+ haproxyConfig := & client.HaproxyConfig {
362+ Defaults : newDefaults ,
363+ Global : newGlobal ,
364+ }
365+ config := & client.LoadBalancerConfig {
366+ HaproxyConfig : haproxyConfig ,
367+ }
368+ toUpdate ["loadBalancerConfig" ] = config
369+ }
370+
371+ if len (toUpdate ) > 0 {
372+ if _ , err = lbp .client .LoadBalancerService .Update (lb , toUpdate ); err != nil {
373+ return fmt .Errorf ("Failed to update lb [%s]. Error: %#v" , lb .Name , err )
374+
348375 }
349376 }
350377 return nil
351378}
352379
380+ func (lbp * LBProvider ) getCustomHaproxyConfig (lbConfig * config.LoadBalancerConfig ) (string , string , error ) {
381+ global := ""
382+ defaults := ""
383+ flag := ""
384+ for _ , c := range strings .Split (lbConfig .Config , "\n " ) {
385+ conf := strings .TrimSpace (c )
386+ if strings .HasPrefix (conf , "defaults" ) {
387+ flag = "defaults"
388+ continue
389+ } else if strings .HasPrefix (conf , "global" ) {
390+ flag = "global"
391+ continue
392+ }
393+
394+ if flag == "global" {
395+ global = fmt .Sprintf ("%s%s\n " , global , conf )
396+ } else if flag == "defaults" {
397+ defaults = fmt .Sprintf ("%s%s\n " , defaults , conf )
398+ }
399+ }
400+ return global , defaults , nil
401+ }
402+
403+ func (lbp * LBProvider ) needConfigUpdate (lb * client.LoadBalancerService , newGlobal string , newDefaults string ) bool {
404+ oldGlobal := ""
405+ oldDefaults := ""
406+ config := lb .LoadBalancerConfig
407+ if config != nil && config .HaproxyConfig != nil {
408+ oldDefaults = config .HaproxyConfig .Defaults
409+ oldGlobal = config .HaproxyConfig .Global
410+ }
411+
412+ return oldGlobal != newGlobal || oldDefaults != newDefaults
413+ }
414+
415+ func (lbp * LBProvider ) needCertUpdate (lbConfig * config.LoadBalancerConfig , lb * client.LoadBalancerService ) (bool , error ) {
416+ rancherCertID , err := lbp .getRancherCertID (lbConfig )
417+ if err != nil {
418+ return false , err
419+ }
420+ return lb .DefaultCertificateId != rancherCertID , nil
421+ }
422+
353423func (lbp * LBProvider ) cleanupLBService (lb * client.LoadBalancerService , lbConfig * config.LoadBalancerConfig ) * client.LoadBalancerService {
354424 if lb == nil {
355425 return nil
@@ -388,7 +458,7 @@ func (lbp *LBProvider) getLBServiceForConfig(lbConfigName string) (*client.LoadB
388458 }
389459 // legacy code where "-" was used as a separator
390460 fmtName = lbp .formatLBName (lbConfigName , true )
391- logrus .Infof ("Fetching service by name %v " , fmtName )
461+ logrus .Infof ("Fetching service by name [%v] " , fmtName )
392462 return lbp .getLBServiceByName (fmtName )
393463}
394464
@@ -431,6 +501,8 @@ func (lbp *LBProvider) createLBService(lbConfig *config.LoadBalancerConfig) (*cl
431501 return lb , nil
432502 }
433503
504+ logrus .Info ("Creating lb service" )
505+
434506 // private port will be overritten by ports
435507 // in hostname routing rules
436508 lbPorts := []string {}
@@ -544,7 +616,7 @@ func (lbp *LBProvider) setServiceLinks(lb *client.LoadBalancerService, lbConfig
544616 return err
545617 }
546618 serviceLinks := & client.SetLoadBalancerServiceLinksInput {}
547-
619+ var newLinks [] * client. LoadBalancerServiceLink
548620 for _ , bcknd := range lbConfig .FrontendServices [0 ].BackendServices {
549621 svc , err := lbp .getKubernetesServiceByUUID (bcknd .UUID )
550622 if err != nil {
@@ -562,6 +634,8 @@ func (lbp *LBProvider) setServiceLinks(lb *client.LoadBalancerService, lbConfig
562634 port = fmt .Sprintf ("%s=%s" , bcknd .Host , bckndPort )
563635 } else if bcknd .Path != "" {
564636 port = fmt .Sprintf ("%s=%s" , bcknd .Path , bckndPort )
637+ } else if bckndPort != "" {
638+ port = bckndPort
565639 }
566640 ports = append (ports , port )
567641
@@ -570,13 +644,62 @@ func (lbp *LBProvider) setServiceLinks(lb *client.LoadBalancerService, lbConfig
570644 Ports : ports ,
571645 }
572646 serviceLinks .ServiceLinks = append (serviceLinks .ServiceLinks , link )
573-
647+ newLinks = append ( newLinks , link )
574648 }
575649
576- _ , err = lbp .client .LoadBalancerService .ActionSetservicelinks (lb , serviceLinks )
650+ setServiceLinks := false
651+ // get existing links
652+ existingLinks , err := lbp .GetServiceLinks (lb )
577653 if err != nil {
578- return fmt .Errorf ("Failed to set service links for lb [%s]. Error: %#v" , lb .Name , err )
654+ return err
655+ }
656+ if len (existingLinks ) != len (newLinks ) {
657+ setServiceLinks = true
658+ logrus .Info ("Number of new service links is different from existing" )
659+ }
660+
661+ for _ , newLink := range newLinks {
662+ linkExists := false
663+ for _ , existingLink := range existingLinks {
664+ if newLink .ServiceId != existingLink .ConsumedServiceId {
665+ continue
666+ }
667+ linkExists = true
668+ if len (existingLink .Ports ) != len (newLink .Ports ) {
669+ logrus .Info ("Number of new service ports is different from existing" )
670+ setServiceLinks = true
671+ break
672+ }
673+ for _ , newPort := range newLink .Ports {
674+ exists := false
675+ for _ , existingPort := range existingLink .Ports {
676+ if newPort == existingPort {
677+ exists = true
678+ break
679+ }
680+ }
681+ if ! exists {
682+ logrus .Infof ("port [%v] either doesn't exist, or has different hostname routing rules" , newPort )
683+ setServiceLinks = true
684+ break
685+ }
686+ }
687+ }
688+ if ! linkExists {
689+ logrus .Infof ("Link to service id [%v] doesn't exist" , newLink .ServiceId )
690+ setServiceLinks = true
691+ break
692+ }
693+ }
694+
695+ if setServiceLinks {
696+ logrus .Info ("Resetting service links" )
697+ _ , err = lbp .client .LoadBalancerService .ActionSetservicelinks (lb , serviceLinks )
698+ if err != nil {
699+ return fmt .Errorf ("Failed to set service links for lb [%s]. Error: %#v" , lb .Name , err )
700+ }
579701 }
702+
580703 return nil
581704}
582705
@@ -625,6 +748,18 @@ func (lbp *LBProvider) reloadLBService(lb *client.LoadBalancerService) (*client.
625748 return lb , nil
626749}
627750
751+ func (lbp * LBProvider ) GetServiceLinks (lb * client.LoadBalancerService ) ([]client.ServiceConsumeMap , error ) {
752+ opts := client .NewListOpts ()
753+ opts .Filters ["removed_null" ] = "1"
754+ opts .Filters ["serviceId" ] = lb .Id
755+ links , err := lbp .client .ServiceConsumeMap .List (opts )
756+ if err != nil {
757+ return nil , fmt .Errorf ("Coudln't fetch service links. Error: %#v" , err )
758+ }
759+
760+ return links .Data , nil
761+ }
762+
628763func (lbp * LBProvider ) getAllLBServices () ([]client.LoadBalancerService , error ) {
629764 stack , err := lbp .getOrCreateSystemStack ()
630765 if err != nil {
0 commit comments