mirror of
https://github.com/gravitational/teleport.git
synced 2026-09-24 16:17:11 +08:00
* Initialize usage reporting via plugin registry after auth server setup Usage reporting was previously initialized in enterprise process constructors (cloud.NewTeleport, pro.NewTeleport), which ran after the OSS auth server completed initialization. This caused enterprise auth extensions to miss the UsageReporter service because they were initialized after the OSS auth server was created but before the usage reporting was set up. To fix the ordering, add a callback mechanism to plugin.Registry: - SetUsageReportingInitFunc registers a callback to be called once the auth server is ready. - InitUsageReporting triggers that callback from initAuthService, after setLocalAuth makes the server available to callers. Signed-off-by: Tiago Silva <tiago.silva@goteleport.com> * update comment * handle review feedback * remove dynamic function load * fix another addition --------- Signed-off-by: Tiago Silva <tiago.silva@goteleport.com>
146 lines
4.6 KiB
Go
146 lines
4.6 KiB
Go
/*
|
|
* Teleport
|
|
* Copyright (C) 2023 Gravitational, Inc.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
|
|
"github.com/gravitational/trace"
|
|
)
|
|
|
|
type getCertFunc = func() (*tls.Certificate, error)
|
|
|
|
// Plugin describes interfaces of the teleport core plugin
|
|
type Plugin interface {
|
|
// GetName returns plugin name
|
|
GetName() string
|
|
// RegisterProxyWebHandlers registers new methods with the ProxyWebHandler
|
|
RegisterProxyWebHandlers(handler any) error
|
|
// RegisterAuthWebHandlers registers new methods with the Auth Web Handler
|
|
RegisterAuthWebHandlers(service any) error
|
|
// RegisterAuthServices registers new services on the AuthServer
|
|
RegisterAuthServices(ctx context.Context, server any, getClientCert getCertFunc) error
|
|
}
|
|
|
|
// Registry is the plugin registry
|
|
type Registry interface {
|
|
// IsRegistered returns whether a plugin with the give name exists.
|
|
IsRegistered(name string) bool
|
|
// Add adds plugin to the registry
|
|
Add(plugin Plugin) error
|
|
// RegisterProxyWebHandlers registers Teleport Proxy web handlers
|
|
RegisterProxyWebHandlers(handler any) error
|
|
// RegisterAuthWebHandlers registers Teleport Auth web handlers
|
|
RegisterAuthWebHandlers(handler any) error
|
|
// RegisterAuthServices registers Teleport AuthServer services
|
|
RegisterAuthServices(ctx context.Context, server any, getClientCert getCertFunc) error
|
|
// SetUsageReportingInitFunc stores a callback that will be called once the OSS auth server is
|
|
// fully initialized. The callback receives a *service.TeleportProcess and is responsible for
|
|
// starting all usage-reporting pipelines. It must be set before service.NewTeleport is called.
|
|
SetUsageReportingInitFunc(func(process any) error)
|
|
// InitUsageReporting invokes the callback registered with SetUsageReportingInitFunc. It is
|
|
// called by initAuthService after setLocalAuth, ensuring the UsageReporter is available to
|
|
// auth-server enterprise extensions. The function process parameter is a *service.TeleportProcess
|
|
// instance.
|
|
// A no-op if no callback was registered.
|
|
InitUsageReporting(process any) error
|
|
}
|
|
|
|
// NewRegistry creates an instance of the Registry
|
|
func NewRegistry() Registry {
|
|
return ®istry{
|
|
plugins: make(map[string]Plugin),
|
|
}
|
|
}
|
|
|
|
type registry struct {
|
|
plugins map[string]Plugin
|
|
usageReportingInitFn func(process any) error
|
|
}
|
|
|
|
func (r *registry) SetUsageReportingInitFunc(f func(process any) error) {
|
|
r.usageReportingInitFn = f
|
|
}
|
|
|
|
func (r *registry) InitUsageReporting(process any) error {
|
|
if r.usageReportingInitFn != nil {
|
|
return r.usageReportingInitFn(process)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IsRegistered returns whether a plugin with the give name exists.
|
|
func (r *registry) IsRegistered(name string) bool {
|
|
_, ok := r.plugins[name]
|
|
return ok
|
|
}
|
|
|
|
// Add adds plugin to the plugin registry
|
|
func (r *registry) Add(p Plugin) error {
|
|
if p == nil {
|
|
return trace.BadParameter("missing plugin")
|
|
}
|
|
|
|
name := p.GetName()
|
|
if name == "" {
|
|
return trace.BadParameter("missing plugin name")
|
|
}
|
|
|
|
if r.IsRegistered(name) {
|
|
return trace.AlreadyExists("plugin %v already exists", name)
|
|
}
|
|
|
|
r.plugins[name] = p
|
|
|
|
return nil
|
|
}
|
|
|
|
// RegisterProxyWebHandlers registers Teleport Proxy web handlers
|
|
func (r *registry) RegisterProxyWebHandlers(handler any) error {
|
|
for _, p := range r.plugins {
|
|
if err := p.RegisterProxyWebHandlers(handler); err != nil {
|
|
return trace.Wrap(err, "plugin %v failed to register", p.GetName())
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// RegisterAuthWebHandlers registers Teleport Auth web handlers
|
|
func (r *registry) RegisterAuthWebHandlers(handler any) error {
|
|
for _, p := range r.plugins {
|
|
if err := p.RegisterAuthWebHandlers(handler); err != nil {
|
|
return trace.Wrap(err, "plugin %v failed to register", p.GetName())
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *registry) RegisterAuthServices(ctx context.Context, server any, getClientCert getCertFunc) error {
|
|
for _, p := range r.plugins {
|
|
if err := p.RegisterAuthServices(ctx, server, getClientCert); err != nil {
|
|
return trace.Wrap(err, "plugin %v failed to register", p.GetName())
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|