233 lines
6.7 KiB
Go
233 lines
6.7 KiB
Go
package multiclustermanager
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"os"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/rancher/rancher/pkg/agent/clean/adunmigration"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/rancher/norman/types"
|
|
"github.com/sirupsen/logrus"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"github.com/rancher/rancher/pkg/auth/providerrefresh"
|
|
"github.com/rancher/rancher/pkg/auth/providers/common"
|
|
"github.com/rancher/rancher/pkg/auth/tokens"
|
|
"github.com/rancher/rancher/pkg/catalog/manager"
|
|
"github.com/rancher/rancher/pkg/clustermanager"
|
|
managementController "github.com/rancher/rancher/pkg/controllers/management"
|
|
"github.com/rancher/rancher/pkg/controllers/management/clusterupstreamrefresher"
|
|
managementcrds "github.com/rancher/rancher/pkg/crds/management"
|
|
"github.com/rancher/rancher/pkg/cron"
|
|
managementdata "github.com/rancher/rancher/pkg/data/management"
|
|
"github.com/rancher/rancher/pkg/dialer"
|
|
"github.com/rancher/rancher/pkg/jailer"
|
|
"github.com/rancher/rancher/pkg/metrics"
|
|
"github.com/rancher/rancher/pkg/namespace"
|
|
"github.com/rancher/rancher/pkg/systemtokens"
|
|
"github.com/rancher/rancher/pkg/telemetry"
|
|
"github.com/rancher/rancher/pkg/tunnelserver/mcmauthorizer"
|
|
"github.com/rancher/rancher/pkg/types/config"
|
|
"github.com/rancher/rancher/pkg/wrangler"
|
|
)
|
|
|
|
type Options struct {
|
|
LocalClusterEnabled bool
|
|
RemoveLocalCluster bool
|
|
Embedded bool
|
|
HTTPSListenPort int
|
|
Debug bool
|
|
Trace bool
|
|
}
|
|
|
|
type mcm struct {
|
|
ScaledContext *config.ScaledContext
|
|
clusterManager *clustermanager.Manager
|
|
router func(http.Handler) http.Handler
|
|
wranglerContext *wrangler.Context
|
|
localClusterEnabled bool
|
|
removeLocalCluster bool
|
|
embedded bool
|
|
httpsListenPort int
|
|
|
|
startedChan chan struct{}
|
|
startLock sync.Mutex
|
|
}
|
|
|
|
func BuildScaledContext(ctx context.Context, wranglerContext *wrangler.Context, cfg *Options) (*config.ScaledContext,
|
|
*clustermanager.Manager, *mcmauthorizer.Authorizer, error) {
|
|
scaledContext, err := config.NewScaledContext(*wranglerContext.RESTConfig, &config.ScaleContextOptions{
|
|
ControllerFactory: wranglerContext.ControllerFactory,
|
|
})
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
|
|
scaledContext.Wrangler = wranglerContext
|
|
|
|
scaledContext.CatalogManager = manager.New(scaledContext.Management, scaledContext.Project, scaledContext.Core)
|
|
|
|
if err := managementcrds.Create(ctx, wranglerContext.RESTConfig); err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
|
|
dialerFactory, err := dialer.NewFactory(scaledContext, wranglerContext)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
scaledContext.Dialer = dialerFactory
|
|
|
|
userManager, err := common.NewUserManager(scaledContext)
|
|
if err != nil {
|
|
return nil, nil, nil, err
|
|
}
|
|
|
|
scaledContext.UserManager = userManager
|
|
scaledContext.RunContext = ctx
|
|
|
|
systemTokens := systemtokens.NewSystemTokensFromScale(scaledContext)
|
|
scaledContext.SystemTokens = systemTokens
|
|
|
|
manager := clustermanager.NewManager(cfg.HTTPSListenPort, scaledContext, wranglerContext.ASL)
|
|
|
|
scaledContext.AccessControl = manager
|
|
scaledContext.ClientGetter = manager
|
|
|
|
authorizer := mcmauthorizer.NewAuthorizer(scaledContext)
|
|
wranglerContext.TunnelAuthorizer.Add(authorizer.AuthorizeTunnel)
|
|
scaledContext.PeerManager = wranglerContext.PeerManager
|
|
|
|
return scaledContext, manager, authorizer, nil
|
|
}
|
|
|
|
func newMCM(ctx context.Context, wranglerContext *wrangler.Context, cfg *Options) (*mcm, error) {
|
|
scaledContext, clusterManager, tunnelAuthorizer, err := BuildScaledContext(ctx, wranglerContext, cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
router, err := router(ctx, cfg.LocalClusterEnabled, tunnelAuthorizer, scaledContext, clusterManager)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if os.Getenv("CATTLE_PROMETHEUS_METRICS") == "true" {
|
|
metrics.Register(ctx, scaledContext)
|
|
}
|
|
|
|
mcm := &mcm{
|
|
router: router,
|
|
ScaledContext: scaledContext,
|
|
clusterManager: clusterManager,
|
|
wranglerContext: wranglerContext,
|
|
localClusterEnabled: cfg.LocalClusterEnabled,
|
|
removeLocalCluster: cfg.RemoveLocalCluster,
|
|
embedded: cfg.Embedded,
|
|
httpsListenPort: cfg.HTTPSListenPort,
|
|
startedChan: make(chan struct{}),
|
|
}
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
mcm.started(ctx)
|
|
}()
|
|
|
|
return mcm, nil
|
|
}
|
|
|
|
func (m *mcm) started(ctx context.Context) {
|
|
m.startLock.Lock()
|
|
defer m.startLock.Unlock()
|
|
select {
|
|
case <-m.startedChan:
|
|
default:
|
|
close(m.startedChan)
|
|
}
|
|
}
|
|
|
|
func (m *mcm) Wait(ctx context.Context) {
|
|
select {
|
|
case <-m.startedChan:
|
|
for {
|
|
if _, err := m.wranglerContext.Core.Namespace().Get(namespace.GlobalNamespace, metav1.GetOptions{}); err == nil {
|
|
return
|
|
}
|
|
logrus.Infof("Waiting for initial data to be populated")
|
|
time.Sleep(2 * time.Second)
|
|
}
|
|
case <-ctx.Done():
|
|
}
|
|
}
|
|
|
|
func (m *mcm) NormanSchemas() *types.Schemas {
|
|
<-m.startedChan
|
|
return m.ScaledContext.Schemas
|
|
}
|
|
|
|
func (m *mcm) Middleware(next http.Handler) http.Handler {
|
|
return m.router(next)
|
|
}
|
|
|
|
func (m *mcm) Start(ctx context.Context) error {
|
|
var (
|
|
management *config.ManagementContext
|
|
)
|
|
|
|
if dm := os.Getenv("CATTLE_DEV_MODE"); dm == "" {
|
|
if err := jailer.CreateJail("driver-jail"); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := cron.StartJailSyncCron(m.ScaledContext); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
m.wranglerContext.OnLeader(func(ctx context.Context) error {
|
|
err := m.wranglerContext.StartWithTransaction(ctx, func(ctx context.Context) error {
|
|
var (
|
|
err error
|
|
)
|
|
|
|
management, err = m.ScaledContext.NewManagementContext()
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create management context")
|
|
}
|
|
|
|
if err := managementdata.Add(ctx, m.wranglerContext, management); err != nil {
|
|
return errors.Wrap(err, "failed to add management data")
|
|
}
|
|
|
|
managementController.Register(ctx, management, m.ScaledContext.ClientGetter.(*clustermanager.Manager), m.wranglerContext)
|
|
if err := managementController.RegisterWrangler(ctx, m.wranglerContext, management, m.ScaledContext.ClientGetter.(*clustermanager.Manager)); err != nil {
|
|
return errors.Wrap(err, "failed to register wrangler controllers")
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := telemetry.Start(ctx, m.httpsListenPort, m.ScaledContext); err != nil {
|
|
return errors.Wrap(err, "failed to telemetry")
|
|
}
|
|
|
|
go adunmigration.UnmigrateAdGUIDUsersOnce(m.ScaledContext)
|
|
tokens.StartPurgeDaemon(ctx, management)
|
|
providerrefresh.StartRefreshDaemon(ctx, m.ScaledContext, management)
|
|
managementdata.CleanupOrphanedSystemUsers(ctx, management)
|
|
clusterupstreamrefresher.MigrateEksRefreshCronSetting(m.wranglerContext)
|
|
go managementdata.CleanupDuplicateBindings(m.ScaledContext, m.wranglerContext)
|
|
go managementdata.CleanupOrphanBindings(m.ScaledContext, m.wranglerContext)
|
|
|
|
logrus.Infof("Rancher startup complete")
|
|
return nil
|
|
})
|
|
|
|
return nil
|
|
}
|