@@ -20,6 +20,7 @@ import (
20
20
"net/http"
21
21
"os"
22
22
"strconv"
23
+ "strings"
23
24
"time"
24
25
25
26
"github.com/alecthomas/kingpin/v2"
@@ -145,8 +146,6 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
145
146
serve .Flag ("envoy-service-https-port" , "Kubernetes Service port for HTTPS requests." ).PlaceHolder ("<port>" ).IntVar (& ctx .httpsPort )
146
147
serve .Flag ("envoy-service-name" , "Name of the Envoy service to inspect for Ingress status details." ).PlaceHolder ("<name>" ).StringVar (& ctx .Config .EnvoyServiceName )
147
148
serve .Flag ("envoy-service-namespace" , "Envoy Service Namespace." ).PlaceHolder ("<namespace>" ).StringVar (& ctx .Config .EnvoyServiceNamespace )
148
- serve .Flag ("envoy-ingress-name" , "Name of the Envoy ingress to inspect for Ingress status details." ).PlaceHolder ("<name>" ).StringVar (& ctx .Config .EnvoyIngressName )
149
- serve .Flag ("envoy-ingress-namespace" , "Envoy Ingress Namespace." ).PlaceHolder ("<namespace>" ).StringVar (& ctx .Config .EnvoyIngressNamespace )
150
149
151
150
serve .Flag ("health-address" , "Address the health HTTP endpoint will bind to." ).PlaceHolder ("<ipaddr>" ).StringVar (& ctx .healthAddr )
152
151
serve .Flag ("health-port" , "Port the health HTTP endpoint will bind to." ).PlaceHolder ("<port>" ).IntVar (& ctx .healthPort )
@@ -169,6 +168,8 @@ func registerServe(app *kingpin.Application) (*kingpin.CmdClause, *serveContext)
169
168
serve .Flag ("leader-election-resource-namespace" , "The namespace of the resource (Lease) leader election will lease." ).Default (config .GetenvOr ("CONTOUR_NAMESPACE" , "projectcontour" )).StringVar (& ctx .LeaderElection .Namespace )
170
169
serve .Flag ("leader-election-retry-period" , "The interval which Contour will attempt to acquire leadership lease." ).Default ("2s" ).DurationVar (& ctx .LeaderElection .RetryPeriod )
171
170
171
+ serve .Flag ("load-balancer-status" , "Address to set or the source to inspect for ingress status." ).PlaceHolder ("<kind:namespace/name|address>" ).StringVar (& ctx .Config .LoadBalancerStatus )
172
+
172
173
serve .Flag ("root-namespaces" , "Restrict contour to searching these namespaces for root ingress routes." ).PlaceHolder ("<ns,ns>" ).StringVar (& ctx .rootNamespaces )
173
174
174
175
serve .Flag ("stats-address" , "Envoy /stats interface address." ).PlaceHolder ("<ipaddr>" ).StringVar (& ctx .statsAddr )
@@ -673,87 +674,162 @@ func (s *Server) doServe() error {
673
674
}
674
675
675
676
// Set up ingress load balancer status writer.
677
+ if err := s .setupIngressLoadBalancerStatusWriter (contourConfiguration , ingressClassNames , gatewayControllerName , gatewayRef , sh .Writer ()); err != nil {
678
+ return err
679
+ }
680
+
681
+ xdsServer := & xdsServer {
682
+ log : s .log ,
683
+ registry : s .registry ,
684
+ config : * contourConfiguration .XDSServer ,
685
+ snapshotHandler : snapshotHandler ,
686
+ resources : resources ,
687
+ initialDagBuilt : contourHandler .HasBuiltInitialDag ,
688
+ }
689
+ if err := s .mgr .Add (xdsServer ); err != nil {
690
+ return err
691
+ }
692
+
693
+ notifier := & leadership.Notifier {
694
+ ToNotify : append ([]leadership.NeedLeaderElectionNotification {
695
+ contourHandler ,
696
+ observer ,
697
+ }, needsNotification ... ),
698
+ }
699
+ if err := s .mgr .Add (notifier ); err != nil {
700
+ return err
701
+ }
702
+
703
+ // GO!
704
+ return s .mgr .Start (signals .SetupSignalHandler ())
705
+ }
706
+
707
+ func (s * Server ) setupIngressLoadBalancerStatusWriter (
708
+ contourConfiguration contour_api_v1alpha1.ContourConfigurationSpec ,
709
+ ingressClassNames []string ,
710
+ gatewayControllerName string ,
711
+ gatewayRef * types.NamespacedName ,
712
+ statusUpdater k8s.StatusUpdater ) error {
676
713
lbsw := & loadBalancerStatusWriter {
677
714
log : s .log .WithField ("context" , "loadBalancerStatusWriter" ),
678
715
cache : s .mgr .GetCache (),
679
716
lbStatus : make (chan corev1.LoadBalancerStatus , 1 ),
680
717
ingressClassNames : ingressClassNames ,
681
718
gatewayControllerName : gatewayControllerName ,
682
719
gatewayRef : gatewayRef ,
683
- statusUpdater : sh . Writer () ,
720
+ statusUpdater : statusUpdater ,
684
721
}
685
722
if err := s .mgr .Add (lbsw ); err != nil {
686
723
return err
687
724
}
688
725
689
- // Register an informer to watch envoy's service if we haven't been given static details.
726
+ elbs := & envoyLoadBalancerStatus {}
690
727
if lbAddress := contourConfiguration .Ingress .StatusAddress ; len (lbAddress ) > 0 {
691
- s .log .WithField ("loadbalancer-address" , lbAddress ).Info ("Using supplied information for Ingress status" )
692
- lbsw .lbStatus <- parseStatusFlag (lbAddress )
728
+ elbs .Kind = "hostname"
729
+ elbs .FQDNs = lbAddress
730
+ } else if contourConfiguration .Envoy .LoadBalancer != "" {
731
+ status , err := parseEnvoyLoadBalancerStatus (contourConfiguration .Envoy .LoadBalancer )
732
+ if err != nil {
733
+ return err
734
+ }
735
+ elbs = status
693
736
} else {
737
+ elbs .Kind = "service"
738
+ elbs .Namespace = contourConfiguration .Envoy .Service .Namespace
739
+ elbs .Name = contourConfiguration .Envoy .Service .Name
740
+ }
741
+ switch strings .ToLower (elbs .Kind ) {
742
+ case "hostname" :
743
+ s .log .WithField ("loadbalancer-fqdns" , lbAddress ).Info ("Using supplied hostname for Ingress status" )
744
+ lbsw .lbStatus <- parseStatusFlag (elbs .FQDNs )
745
+ case "service" :
746
+ // Register an informer to watch supplied service
694
747
serviceHandler := & k8s.ServiceStatusLoadBalancerWatcher {
695
- ServiceName : contourConfiguration . Envoy . Service .Name ,
748
+ ServiceName : elbs .Name ,
696
749
LBStatus : lbsw .lbStatus ,
697
750
Log : s .log .WithField ("context" , "serviceStatusLoadBalancerWatcher" ),
698
751
}
699
752
700
753
var handler cache.ResourceEventHandler = serviceHandler
701
- if contourConfiguration . Envoy . Service .Namespace != "" {
702
- handler = k8s .NewNamespaceFilter ([]string {contourConfiguration . Envoy . Service .Namespace }, handler )
754
+ if elbs .Namespace != "" {
755
+ handler = k8s .NewNamespaceFilter ([]string {elbs .Namespace }, handler )
703
756
}
704
757
705
758
if err := s .informOnResource (& corev1.Service {}, handler ); err != nil {
706
- s .log .WithError (err ).WithField ("resource" , "services" ).Fatal ("failed to create informer" )
759
+ s .log .WithError (err ).WithField ("resource" , "services" ).Fatal ("failed to create services informer" )
707
760
}
708
-
761
+ s .log .Infof ("Watching %s for Ingress status" , elbs )
762
+ case "ingress" :
763
+ // Register an informer to watch supplied ingress
709
764
ingressHandler := & k8s.IngressStatusLoadBalancerWatcher {
710
- ServiceName : contourConfiguration . Envoy . Service .Name ,
765
+ IngressName : elbs .Name ,
711
766
LBStatus : lbsw .lbStatus ,
712
767
Log : s .log .WithField ("context" , "ingressStatusLoadBalancerWatcher" ),
713
768
}
714
769
715
- var ingressEventHandler cache.ResourceEventHandler = ingressHandler
716
- if contourConfiguration . Envoy . Ingress .Namespace != "" {
717
- handler = k8s .NewNamespaceFilter ([]string {contourConfiguration . Envoy . Ingress .Namespace }, handler )
770
+ var handler cache.ResourceEventHandler = ingressHandler
771
+ if elbs .Namespace != "" {
772
+ handler = k8s .NewNamespaceFilter ([]string {elbs .Namespace }, handler )
718
773
}
719
774
720
- if err := informOnResource (& networking_v1.Ingress {}, ingressEventHandler , s . mgr . GetCache () ); err != nil {
775
+ if err := s . informOnResource (& networking_v1.Ingress {}, handler ); err != nil {
721
776
s .log .WithError (err ).WithField ("resource" , "ingresses" ).Fatal ("failed to create ingresses informer" )
722
777
}
778
+ s .log .Infof ("Watching %s for Ingress status" , elbs )
779
+ default :
780
+ return fmt .Errorf ("unsupported ingress kind: %s" , elbs .Kind )
781
+ }
723
782
724
- s .log .WithField ("envoy-service-name" , contourConfiguration .Envoy .Service .Name ).
725
- WithField ("envoy-service-namespace" , contourConfiguration .Envoy .Service .Namespace ).
726
- Info ("Watching Service for Ingress status" )
783
+ return nil
784
+ }
727
785
728
- s .log .WithField ("envoy-ingress-name" , contourConfiguration .Envoy .Ingress .Name ).
729
- WithField ("envoy-ingress-namespace" , contourConfiguration .Envoy .Ingress .Namespace ).
730
- Info ("Watching Ingress for Ingress status" )
731
- }
786
+ type envoyLoadBalancerStatus struct {
787
+ Kind string
788
+ FQDNs string
789
+ config.NamespacedName
790
+ }
732
791
733
- xdsServer := & xdsServer {
734
- log : s .log ,
735
- registry : s .registry ,
736
- config : * contourConfiguration .XDSServer ,
737
- snapshotHandler : snapshotHandler ,
738
- resources : resources ,
739
- initialDagBuilt : contourHandler .HasBuiltInitialDag ,
792
+ func (elbs * envoyLoadBalancerStatus ) String () string {
793
+ if elbs .Kind == "hostname" {
794
+ return fmt .Sprintf ("%s:%s" , elbs .Kind , elbs .FQDNs )
740
795
}
741
- if err := s .mgr .Add (xdsServer ); err != nil {
742
- return err
796
+ return fmt .Sprintf ("%s:%s/%s" , elbs .Kind , elbs .Namespace , elbs .Name )
797
+ }
798
+
799
+ func parseEnvoyLoadBalancerStatus (s string ) (* envoyLoadBalancerStatus , error ) {
800
+ parts := strings .SplitN (s , ":" , 2 )
801
+ if len (parts ) != 2 {
802
+ return nil , fmt .Errorf ("invalid load-balancer-status: %s" , s )
743
803
}
744
804
745
- notifier := & leadership.Notifier {
746
- ToNotify : append ([]leadership.NeedLeaderElectionNotification {
747
- contourHandler ,
748
- observer ,
749
- }, needsNotification ... ),
805
+ if parts [1 ] == "" {
806
+ return nil , fmt .Errorf ("invalid load-balancer-status: empty object reference" )
750
807
}
751
- if err := s .mgr .Add (notifier ); err != nil {
752
- return err
808
+
809
+ elbs := envoyLoadBalancerStatus {}
810
+
811
+ elbs .Kind = strings .ToLower (parts [0 ])
812
+ switch elbs .Kind {
813
+ case "ingress" , "service" :
814
+ parts = strings .Split (parts [1 ], "/" )
815
+ if len (parts ) != 2 {
816
+ return nil , fmt .Errorf ("invalid load-balancer-status: %s is not in the format of <namespace>/<name>" , s )
817
+ }
818
+
819
+ if parts [0 ] == "" || parts [1 ] == "" {
820
+ return nil , fmt .Errorf ("invalid load-balancer-status: <namespace> or <name> is empty" )
821
+ }
822
+ elbs .Namespace = parts [0 ]
823
+ elbs .Name = parts [1 ]
824
+ case "hostname" :
825
+ elbs .FQDNs = parts [1 ]
826
+ case "" :
827
+ return nil , fmt .Errorf ("invalid load-balancer-status: kind is empty" )
828
+ default :
829
+ return nil , fmt .Errorf ("invalid load-balancer-status: unsupported kind: %s" , elbs .Kind )
753
830
}
754
831
755
- // GO!
756
- return s .mgr .Start (signals .SetupSignalHandler ())
832
+ return & elbs , nil
757
833
}
758
834
759
835
func (s * Server ) getExtensionSvcConfig (name string , namespace string ) (xdscache_v3.ExtensionServiceConfig , error ) {
0 commit comments