mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-19 04:59:56 +00:00
152 lines
4.9 KiB
Go
152 lines
4.9 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/dexidp/dex/storage"
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/netbirdio/netbird/formatter/hook"
|
|
admincmd "github.com/netbirdio/netbird/management/cmd/admin"
|
|
tokencmd "github.com/netbirdio/netbird/management/cmd/token"
|
|
nbconfig "github.com/netbirdio/netbird/management/internals/server/config"
|
|
"github.com/netbirdio/netbird/management/server/activity"
|
|
activitystore "github.com/netbirdio/netbird/management/server/activity/store"
|
|
"github.com/netbirdio/netbird/management/server/store"
|
|
"github.com/netbirdio/netbird/management/server/types"
|
|
"github.com/netbirdio/netbird/util"
|
|
)
|
|
|
|
// newAdminCommands creates the admin command tree with combined-specific resource openers.
|
|
func newAdminCommands() *cobra.Command {
|
|
return admincmd.NewCommands(admincmd.Openers{
|
|
Resources: withAdminResources,
|
|
Store: withAdminStoreOnly,
|
|
IDP: withAdminIDPOnly,
|
|
})
|
|
}
|
|
|
|
func newLegacyTokenCommand() *cobra.Command {
|
|
cmd := tokencmd.NewCommands(tokencmd.StoreOpener(withAdminStoreOnly))
|
|
cmd.Deprecated = "use 'admin token' instead"
|
|
return cmd
|
|
}
|
|
|
|
// withAdminResources loads the combined YAML config, initializes stores, and calls fn.
|
|
func withAdminResources(cmd *cobra.Command, fn func(ctx context.Context, resources admincmd.Resources) error) error {
|
|
return withAdminConfig(cmd, func(ctx context.Context, cfg *CombinedConfig) error {
|
|
mgmtConfig, err := adminManagementConfig(cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
managementStore, err := openAdminStore(ctx, cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer admincmd.CloseStore(ctx, managementStore)
|
|
|
|
idpStorage, idpStorageFile, err := admincmd.OpenIDPStorage(mgmtConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer admincmd.CloseIDPStorage(idpStorage)
|
|
|
|
eventStore, esErr := openAdminEventStore(ctx, cfg, mgmtConfig)
|
|
if esErr != nil {
|
|
_, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Warning: audit events will not be recorded: %v\n", esErr)
|
|
}
|
|
if eventStore != nil {
|
|
defer func() {
|
|
if err := eventStore.Close(ctx); err != nil {
|
|
log.Debugf("close activity event store: %v", err)
|
|
}
|
|
}()
|
|
}
|
|
|
|
return fn(ctx, admincmd.Resources{Store: managementStore, IDPStorage: idpStorage, IDPStorageFile: idpStorageFile, EventStore: eventStore})
|
|
})
|
|
}
|
|
|
|
// withAdminStoreOnly opens only the management store for admin subcommands that do not
|
|
// need embedded IdP storage.
|
|
func withAdminStoreOnly(cmd *cobra.Command, fn func(ctx context.Context, s store.Store) error) error {
|
|
return withAdminConfig(cmd, func(ctx context.Context, cfg *CombinedConfig) error {
|
|
managementStore, err := openAdminStore(ctx, cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer admincmd.CloseStore(ctx, managementStore)
|
|
|
|
return fn(ctx, managementStore)
|
|
})
|
|
}
|
|
|
|
func withAdminIDPOnly(cmd *cobra.Command, fn func(ctx context.Context, idpStorage storage.Storage, storageFile string) error) error {
|
|
return withAdminConfig(cmd, func(ctx context.Context, cfg *CombinedConfig) error {
|
|
mgmtConfig, err := adminManagementConfig(cfg)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
idpStorage, idpStorageFile, err := admincmd.OpenIDPStorage(mgmtConfig)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer admincmd.CloseIDPStorage(idpStorage)
|
|
|
|
return fn(ctx, idpStorage, idpStorageFile)
|
|
})
|
|
}
|
|
|
|
func withAdminConfig(cmd *cobra.Command, fn func(ctx context.Context, cfg *CombinedConfig) error) error {
|
|
if err := util.InitLog("error", "console"); err != nil {
|
|
return fmt.Errorf("init log: %w", err)
|
|
}
|
|
|
|
ctx := context.WithValue(cmd.Context(), hook.ExecutionContextKey, hook.SystemSource) //nolint:staticcheck
|
|
|
|
cfg, err := LoadConfig(configPath)
|
|
if err != nil {
|
|
return fmt.Errorf("load config: %w", err)
|
|
}
|
|
cfg.ApplyAdminDefaults()
|
|
applyServerStoreEnv(cfg.Server.Store)
|
|
|
|
return fn(ctx, cfg)
|
|
}
|
|
|
|
func adminManagementConfig(cfg *CombinedConfig) (*nbconfig.Config, error) {
|
|
mgmtConfig, err := cfg.ToManagementConfig()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create management config: %w", err)
|
|
}
|
|
return mgmtConfig, nil
|
|
}
|
|
|
|
func openAdminStore(ctx context.Context, cfg *CombinedConfig) (store.Store, error) {
|
|
managementStore, err := store.NewStore(ctx, types.Engine(cfg.Management.Store.Engine), cfg.Management.DataDir, nil, true)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create store: %w", err)
|
|
}
|
|
return managementStore, nil
|
|
}
|
|
|
|
func openAdminEventStore(ctx context.Context, cfg *CombinedConfig, config *nbconfig.Config) (activity.Store, error) {
|
|
if config.DataStoreEncryptionKey == "" {
|
|
return nil, fmt.Errorf("data store encryption key is not configured")
|
|
}
|
|
if err := applyActivityStoreEnv(cfg.Server.ActivityStore); err != nil {
|
|
return nil, fmt.Errorf("configure activity event store: %w", err)
|
|
}
|
|
eventStore, err := activitystore.NewSqlStore(ctx, config.Datadir, config.DataStoreEncryptionKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open activity event store: %w", err)
|
|
}
|
|
if eventStore == nil {
|
|
return nil, fmt.Errorf("open activity event store: returned nil store")
|
|
}
|
|
return eventStore, nil
|
|
}
|