mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 22:59:58 +00:00
TUN-3019: Remove declarative tunnel entry code
This commit is contained in:
@@ -1,205 +0,0 @@
|
||||
// Package supervisor is used by declarative tunnels to get/apply new config from the edge.
|
||||
package supervisor
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/cloudflare/cloudflared/cmd/cloudflared/updater"
|
||||
"github.com/cloudflare/cloudflared/connection"
|
||||
"github.com/cloudflare/cloudflared/edgediscovery"
|
||||
"github.com/cloudflare/cloudflared/h2mux"
|
||||
"github.com/cloudflare/cloudflared/logger"
|
||||
"github.com/cloudflare/cloudflared/streamhandler"
|
||||
"github.com/cloudflare/cloudflared/tunnelrpc/pogs"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
)
|
||||
|
||||
type Supervisor struct {
|
||||
connManager *connection.EdgeManager
|
||||
streamHandler *streamhandler.StreamHandler
|
||||
autoupdater *updater.AutoUpdater
|
||||
supportAutoupdate bool
|
||||
newConfigChan <-chan *pogs.ClientConfig
|
||||
useConfigResultChan chan<- *pogs.UseConfigurationResult
|
||||
state *state
|
||||
logger logger.Service
|
||||
metrics metrics
|
||||
}
|
||||
|
||||
type metrics struct {
|
||||
configVersion prometheus.Gauge
|
||||
}
|
||||
|
||||
func newMetrics() metrics {
|
||||
configVersion := prometheus.NewGauge(prometheus.GaugeOpts{
|
||||
Namespace: "supervisor",
|
||||
Subsystem: "supervisor",
|
||||
Name: "config_version",
|
||||
Help: "Latest configuration version received from Cloudflare",
|
||||
},
|
||||
)
|
||||
prometheus.MustRegister(
|
||||
configVersion,
|
||||
)
|
||||
return metrics{
|
||||
configVersion: configVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func NewSupervisor(
|
||||
defaultClientConfig *pogs.ClientConfig,
|
||||
userCredential []byte,
|
||||
tlsConfig *tls.Config,
|
||||
serviceDiscoverer *edgediscovery.Edge,
|
||||
cloudflaredConfig *connection.CloudflaredConfig,
|
||||
autoupdater *updater.AutoUpdater,
|
||||
supportAutoupdate bool,
|
||||
logger logger.Service,
|
||||
) (*Supervisor, error) {
|
||||
newConfigChan := make(chan *pogs.ClientConfig)
|
||||
useConfigResultChan := make(chan *pogs.UseConfigurationResult)
|
||||
streamHandler := streamhandler.NewStreamHandler(newConfigChan, useConfigResultChan, logger)
|
||||
invalidConfigs := streamHandler.UpdateConfig(defaultClientConfig.ReverseProxyConfigs)
|
||||
|
||||
if len(invalidConfigs) > 0 {
|
||||
for _, invalidConfig := range invalidConfigs {
|
||||
logger.Errorf("Tunnel %+v is invalid, reason: %s", invalidConfig.Config, invalidConfig.Reason)
|
||||
}
|
||||
return nil, fmt.Errorf("At least 1 Tunnel config is invalid")
|
||||
}
|
||||
|
||||
tunnelHostnames := make([]h2mux.TunnelHostname, len(defaultClientConfig.ReverseProxyConfigs))
|
||||
for i, reverseProxyConfig := range defaultClientConfig.ReverseProxyConfigs {
|
||||
tunnelHostnames[i] = reverseProxyConfig.TunnelHostname
|
||||
}
|
||||
defaultEdgeMgrConfigurable := &connection.EdgeManagerConfigurable{
|
||||
TunnelHostnames: tunnelHostnames,
|
||||
EdgeConnectionConfig: defaultClientConfig.EdgeConnectionConfig,
|
||||
}
|
||||
return &Supervisor{
|
||||
connManager: connection.NewEdgeManager(streamHandler, defaultEdgeMgrConfigurable, userCredential, tlsConfig,
|
||||
serviceDiscoverer, cloudflaredConfig, logger),
|
||||
streamHandler: streamHandler,
|
||||
autoupdater: autoupdater,
|
||||
supportAutoupdate: supportAutoupdate,
|
||||
newConfigChan: newConfigChan,
|
||||
useConfigResultChan: useConfigResultChan,
|
||||
state: newState(defaultClientConfig),
|
||||
logger: logger,
|
||||
metrics: newMetrics(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Supervisor) Run(ctx context.Context) error {
|
||||
errGroup, groupCtx := errgroup.WithContext(ctx)
|
||||
|
||||
errGroup.Go(func() error {
|
||||
return s.connManager.Run(groupCtx)
|
||||
})
|
||||
|
||||
errGroup.Go(func() error {
|
||||
return s.listenToNewConfig(groupCtx)
|
||||
})
|
||||
|
||||
errGroup.Go(func() error {
|
||||
return s.listenToShutdownSignal(groupCtx)
|
||||
})
|
||||
|
||||
if s.supportAutoupdate {
|
||||
errGroup.Go(func() error {
|
||||
return s.autoupdater.Run(groupCtx)
|
||||
})
|
||||
}
|
||||
|
||||
err := errGroup.Wait()
|
||||
s.logger.Errorf("Supervisor terminated, reason: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Supervisor) listenToShutdownSignal(serveCtx context.Context) error {
|
||||
signals := make(chan os.Signal, 10)
|
||||
signal.Notify(signals, syscall.SIGTERM, syscall.SIGINT)
|
||||
defer signal.Stop(signals)
|
||||
|
||||
select {
|
||||
case <-serveCtx.Done():
|
||||
return serveCtx.Err()
|
||||
case sig := <-signals:
|
||||
return fmt.Errorf("received %v signal", sig)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Supervisor) listenToNewConfig(ctx context.Context) error {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case newConfig := <-s.newConfigChan:
|
||||
s.useConfigResultChan <- s.notifySubsystemsNewConfig(newConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Supervisor) notifySubsystemsNewConfig(newConfig *pogs.ClientConfig) *pogs.UseConfigurationResult {
|
||||
s.logger.Infof("Received configuration %v", newConfig.Version)
|
||||
if s.state.hasAppliedVersion(newConfig.Version) {
|
||||
s.logger.Infof("%v has been applied", newConfig.Version)
|
||||
return &pogs.UseConfigurationResult{
|
||||
Success: true,
|
||||
}
|
||||
}
|
||||
s.metrics.configVersion.Set(float64(newConfig.Version))
|
||||
|
||||
s.state.updateConfig(newConfig)
|
||||
var tunnelHostnames []h2mux.TunnelHostname
|
||||
for _, tunnelConfig := range newConfig.ReverseProxyConfigs {
|
||||
tunnelHostnames = append(tunnelHostnames, tunnelConfig.TunnelHostname)
|
||||
}
|
||||
// Update connManager configurable
|
||||
s.connManager.UpdateConfigurable(&connection.EdgeManagerConfigurable{
|
||||
TunnelHostnames: tunnelHostnames,
|
||||
EdgeConnectionConfig: newConfig.EdgeConnectionConfig,
|
||||
})
|
||||
// Update streamHandler tunnelHostnameMapper mapping
|
||||
failedConfigs := s.streamHandler.UpdateConfig(newConfig.ReverseProxyConfigs)
|
||||
|
||||
if s.supportAutoupdate {
|
||||
s.autoupdater.Update(newConfig.SupervisorConfig.AutoUpdateFrequency)
|
||||
}
|
||||
|
||||
return &pogs.UseConfigurationResult{
|
||||
Success: len(failedConfigs) == 0,
|
||||
FailedConfigs: failedConfigs,
|
||||
}
|
||||
}
|
||||
|
||||
type state struct {
|
||||
sync.RWMutex
|
||||
currentConfig *pogs.ClientConfig
|
||||
}
|
||||
|
||||
func newState(currentConfig *pogs.ClientConfig) *state {
|
||||
return &state{
|
||||
currentConfig: currentConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *state) hasAppliedVersion(incomingVersion pogs.Version) bool {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
return s.currentConfig.Version.IsNewerOrEqual(incomingVersion)
|
||||
}
|
||||
|
||||
func (s *state) updateConfig(newConfig *pogs.ClientConfig) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.currentConfig = newConfig
|
||||
}
|
Reference in New Issue
Block a user