@@ -48,21 +48,24 @@ func withMgmtx[T any](d *Deployer, ctx context.Context, clusterID string, fn fun
4848}
4949
5050type Deployer struct {
51- logger * zap.Logger
52- client * caocontrol.Controller
51+ logger * zap.Logger
52+ client * caocontrol.Controller
53+ sharedGateway string
5354}
5455
5556var _ deployment.Deployer = (* Deployer )(nil )
5657
5758type NewDeployerOptions struct {
58- Logger * zap.Logger
59- Client * caocontrol.Controller
59+ Logger * zap.Logger
60+ Client * caocontrol.Controller
61+ SharedGateway string
6062}
6163
6264func NewDeployer (opts * NewDeployerOptions ) (* Deployer , error ) {
6365 return & Deployer {
64- logger : opts .Logger ,
65- client : opts .Client ,
66+ logger : opts .Logger ,
67+ client : opts .Client ,
68+ sharedGateway : opts .SharedGateway ,
6669 }, nil
6770}
6871
@@ -553,6 +556,104 @@ func (d *Deployer) RemoveAll(ctx context.Context) error {
553556 return nil
554557}
555558
559+ func (d * Deployer ) getSharedGatewayBaseDomain (ctx context.Context ) (string , error ) {
560+ baseDomain , err := d .client .GetIstioGatewayAnnotation (ctx , d .sharedGateway , "cbdc.couchbase.com/base-domain" )
561+ if err != nil {
562+ return "" , errors .Wrap (err , "failed to get shared gateway base domain" )
563+ }
564+ if baseDomain == "" {
565+ return "" , errors .New ("shared gateway is missing cbdc.couchbase.com/base-domain annotation" )
566+ }
567+ return baseDomain , nil
568+ }
569+
570+ func (d * Deployer ) enableIngressesViaVirtualService (ctx context.Context , clusterID string , namespace string ) error {
571+ baseDomain , err := d .getSharedGatewayBaseDomain (ctx )
572+ if err != nil {
573+ return err
574+ }
575+
576+ cngHost := fmt .Sprintf ("cng-%s.%s" , clusterID , baseDomain )
577+
578+ _ , err = d .client .GetService (ctx , namespace , CngServiceName )
579+ if err != nil {
580+ d .logger .Info ("no cng service detected, skipping cng virtual service" )
581+ } else {
582+ d .logger .Info ("creating cng virtual service" , zap .String ("host" , cngHost ))
583+
584+ err = d .client .CreateVirtualService (ctx , namespace , "cng" , map [string ]interface {}{
585+ "hosts" : []interface {}{cngHost },
586+ "gateways" : []interface {}{d .sharedGateway },
587+ "http" : []interface {}{
588+ map [string ]interface {}{
589+ "route" : []interface {}{
590+ map [string ]interface {}{
591+ "destination" : map [string ]interface {}{
592+ "host" : CngServiceName ,
593+ "port" : map [string ]interface {}{
594+ "number" : 443 ,
595+ },
596+ },
597+ },
598+ },
599+ },
600+ },
601+ })
602+ if err != nil {
603+ return errors .Wrap (err , "failed to create cng virtual service" )
604+ }
605+
606+ // CNG expects TLS connections, but the gateway terminates TLS.
607+ // Create a DestinationRule to originate TLS to CNG.
608+ d .logger .Info ("creating cng destination rule for TLS origination" )
609+
610+ err = d .client .CreateDestinationRule (ctx , namespace , "cng-tls" , map [string ]interface {}{
611+ "host" : CngServiceName ,
612+ "trafficPolicy" : map [string ]interface {}{
613+ "connectionPool" : map [string ]interface {}{
614+ "http" : map [string ]interface {}{
615+ "useClientProtocol" : true ,
616+ },
617+ },
618+ "tls" : map [string ]interface {}{
619+ "mode" : "SIMPLE" ,
620+ "insecureSkipVerify" : true ,
621+ },
622+ },
623+ })
624+ if err != nil {
625+ return errors .Wrap (err , "failed to create cng destination rule" )
626+ }
627+ }
628+
629+ uiHost := fmt .Sprintf ("ui-%s.%s" , clusterID , baseDomain )
630+ d .logger .Info ("creating ui virtual service" , zap .String ("host" , uiHost ))
631+
632+ err = d .client .CreateVirtualService (ctx , namespace , "ui" , map [string ]interface {}{
633+ "hosts" : []interface {}{uiHost },
634+ "gateways" : []interface {}{d .sharedGateway },
635+ "http" : []interface {}{
636+ map [string ]interface {}{
637+ "route" : []interface {}{
638+ map [string ]interface {}{
639+ "destination" : map [string ]interface {}{
640+ "host" : UiServiceName ,
641+ "port" : map [string ]interface {}{
642+ "number" : 8091 ,
643+ },
644+ },
645+ },
646+ },
647+ },
648+ },
649+ })
650+ if err != nil {
651+ return errors .Wrap (err , "failed to create ui virtual service" )
652+ }
653+
654+ return nil
655+ }
656+
556657func (d * Deployer ) EnableIngresses (ctx context.Context , clusterID string ) error {
557658 isOpenShift , err := d .client .IsOpenShift (ctx )
558659 if err != nil {
@@ -568,6 +669,10 @@ func (d *Deployer) EnableIngresses(ctx context.Context, clusterID string) error
568669 return err
569670 }
570671
672+ if d .sharedGateway != "" {
673+ return d .enableIngressesViaVirtualService (ctx , clusterID , namespace )
674+ }
675+
571676 _ , err = d .client .GetRouteHost (ctx , namespace , "ui" )
572677 if err != nil {
573678 d .logger .Info ("creating ui route" )
@@ -630,6 +735,37 @@ func (d *Deployer) DisableIngresses(ctx context.Context, clusterID string) error
630735 return err
631736 }
632737
738+ if d .sharedGateway != "" {
739+ allDeletesFailed := true
740+
741+ err = d .client .DeleteVirtualService (ctx , namespace , "cng" )
742+ if err != nil {
743+ d .logger .Debug ("failed to delete cng virtual service" , zap .Error (err ))
744+ } else {
745+ allDeletesFailed = false
746+ }
747+
748+ err = d .client .DeleteVirtualService (ctx , namespace , "ui" )
749+ if err != nil {
750+ d .logger .Debug ("failed to delete ui virtual service" , zap .Error (err ))
751+ } else {
752+ allDeletesFailed = false
753+ }
754+
755+ err = d .client .DeleteDestinationRule (ctx , namespace , "cng-tls" )
756+ if err != nil {
757+ d .logger .Debug ("failed to delete cng destination rule" , zap .Error (err ))
758+ } else {
759+ allDeletesFailed = false
760+ }
761+
762+ if allDeletesFailed {
763+ return errors .New ("virtual service deletions failed" )
764+ }
765+
766+ return nil
767+ }
768+
633769 allDeletesFailed := true
634770
635771 err = d .client .DeleteRoute (ctx , namespace , "ui" )
@@ -742,6 +878,24 @@ func (d *Deployer) GetConnectInfo(ctx context.Context, clusterID string) (*deplo
742878}
743879
744880func (d * Deployer ) GetIngressConnectInfo (ctx context.Context , clusterID string ) (* deployment.ConnectInfo , error ) {
881+ if d .sharedGateway != "" {
882+ baseDomain , err := d .getSharedGatewayBaseDomain (ctx )
883+ if err != nil {
884+ return nil , err
885+ }
886+
887+ cngHost := fmt .Sprintf ("cng-%s.%s" , clusterID , baseDomain )
888+ uiHost := fmt .Sprintf ("ui-%s.%s" , clusterID , baseDomain )
889+
890+ return & deployment.ConnectInfo {
891+ ConnStr : "" ,
892+ ConnStrTls : "" ,
893+ ConnStrCb2 : fmt .Sprintf ("couchbase2://%s:443" , cngHost ),
894+ Mgmt : "" ,
895+ MgmtTls : fmt .Sprintf ("https://%s:443" , uiHost ),
896+ }, nil
897+ }
898+
745899 namespaceName , err := d .getClusterNamespace (ctx , clusterID )
746900 if err != nil {
747901 return nil , err
0 commit comments