* Add config provider and integrate with wire setup * Refactor quota service to use config provider for configuration management * Enhance OSSConfigProvider to include logging and update ProvideService to return an error. Refactor server initialization to handle potential errors from config provider. Remove unnecessary wire binding for OSSConfigProvider. * Update CODEOWNERS to include the configprovider package under the grafana-backend-services-squad. * Refactor quota service initialization to include context in multiple service providers. Update tests and service implementations to ensure proper context handling during service creation.
214 lines
6.3 KiB
Go
214 lines
6.3 KiB
Go
package commands
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/datamigrations"
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/secretsconsolidation"
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/secretsmigrations"
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
|
|
"github.com/grafana/grafana/pkg/cmd/grafana-cli/utils"
|
|
"github.com/grafana/grafana/pkg/infra/db"
|
|
"github.com/grafana/grafana/pkg/server"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
func runRunnerCommand(command func(commandLine utils.CommandLine, runner server.Runner) error) func(context *cli.Context) error {
|
|
return func(context *cli.Context) error {
|
|
cmd := &utils.ContextCommandLine{Context: context}
|
|
runner, err := initializeRunner(context.Context, cmd)
|
|
if err != nil {
|
|
return fmt.Errorf("%v: %w", "failed to initialize runner", err)
|
|
}
|
|
if err := command(cmd, runner); err != nil {
|
|
return err
|
|
}
|
|
logger.Info("\n\n")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func runDbCommand(command func(commandLine utils.CommandLine, cfg *setting.Cfg, sqlStore db.DB) error) func(context *cli.Context) error {
|
|
return func(context *cli.Context) error {
|
|
cmd := &utils.ContextCommandLine{Context: context}
|
|
runner, err := initializeRunner(context.Context, cmd)
|
|
if err != nil {
|
|
return fmt.Errorf("%v: %w", "failed to initialize runner", err)
|
|
}
|
|
|
|
cfg := runner.Cfg
|
|
sqlStore := runner.SQLStore
|
|
if err := command(cmd, cfg, sqlStore); err != nil {
|
|
return err
|
|
}
|
|
|
|
logger.Info("\n\n")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func initializeRunner(ctx context.Context, cmd *utils.ContextCommandLine) (server.Runner, error) {
|
|
configOptions := strings.Split(cmd.String("configOverrides"), " ")
|
|
cfg, err := setting.NewCfgFromArgs(setting.CommandLineArgs{
|
|
Config: cmd.ConfigFile(),
|
|
HomePath: cmd.HomePath(),
|
|
// tailing arguments have precedence over the options string
|
|
Args: append(configOptions, cmd.Args().Slice()...),
|
|
})
|
|
if err != nil {
|
|
return server.Runner{}, err
|
|
}
|
|
|
|
runner, err := server.InitializeForCLI(ctx, cfg)
|
|
if err != nil {
|
|
return server.Runner{}, fmt.Errorf("%v: %w", "failed to initialize runner", err)
|
|
}
|
|
|
|
if cmd.Bool("debug") {
|
|
runner.Cfg.LogConfigSources()
|
|
}
|
|
return runner, nil
|
|
}
|
|
|
|
func runPluginCommand(command func(commandLine utils.CommandLine) error) func(context *cli.Context) error {
|
|
return func(context *cli.Context) error {
|
|
cmd := &utils.ContextCommandLine{Context: context}
|
|
if err := command(cmd); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
|
|
var pluginCommands = []*cli.Command{
|
|
{
|
|
Name: "install",
|
|
Usage: "install <plugin id> <plugin version (optional)>",
|
|
Action: runPluginCommand(installCommand),
|
|
}, {
|
|
Name: "list-remote",
|
|
Usage: "list remote available plugins",
|
|
Action: runPluginCommand(listRemoteCommand),
|
|
}, {
|
|
Name: "list-versions",
|
|
Usage: "list-versions <plugin id>",
|
|
Action: runPluginCommand(listVersionsCommand),
|
|
}, {
|
|
Name: "update",
|
|
Usage: "update <plugin id>",
|
|
Aliases: []string{"upgrade"},
|
|
Action: runPluginCommand(upgradeCommand),
|
|
}, {
|
|
Name: "update-all",
|
|
Aliases: []string{"upgrade-all"},
|
|
Usage: "update all your installed plugins",
|
|
Action: runPluginCommand(upgradeAllCommand),
|
|
}, {
|
|
Name: "ls",
|
|
Usage: "list installed plugins (excludes core plugins)",
|
|
Action: runPluginCommand(lsCommand),
|
|
}, {
|
|
Name: "uninstall",
|
|
Aliases: []string{"remove"},
|
|
Usage: "uninstall <plugin id>",
|
|
Action: runPluginCommand(removeCommand),
|
|
},
|
|
}
|
|
|
|
var adminCommands = []*cli.Command{
|
|
{
|
|
Name: "reset-admin-password",
|
|
Usage: "reset-admin-password <new password>",
|
|
Action: runRunnerCommand(resetPasswordCommand),
|
|
Flags: []cli.Flag{
|
|
&cli.BoolFlag{
|
|
Name: "password-from-stdin",
|
|
Usage: "Read the password from stdin",
|
|
Value: false,
|
|
},
|
|
&cli.IntFlag{
|
|
Name: "user-id",
|
|
Usage: "The admin user's ID",
|
|
Value: DefaultAdminUserId,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "data-migration",
|
|
Usage: "Runs a script that migrates or cleanups data in your database",
|
|
Subcommands: []*cli.Command{
|
|
{
|
|
Name: "encrypt-datasource-passwords",
|
|
Usage: "Migrates passwords from unsecured fields to secure_json_data field. Return ok unless there is an error. Safe to execute multiple times.",
|
|
Action: runDbCommand(datamigrations.EncryptDatasourcePasswords),
|
|
},
|
|
{
|
|
Name: "to-unified-storage",
|
|
Usage: "Migrates classic SQL data into unified storage",
|
|
Action: runDbCommand(datamigrations.ToUnifiedStorage),
|
|
Flags: []cli.Flag{
|
|
&cli.BoolFlag{
|
|
Name: "non-interactive",
|
|
Usage: "Non interactive mode. Just run the migration.",
|
|
Value: false,
|
|
},
|
|
&cli.StringFlag{
|
|
Name: "namespace",
|
|
Usage: "That's the Unified Storage Namespace.",
|
|
Value: "default",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "secrets-migration",
|
|
Usage: "Runs a script that migrates secrets in your database",
|
|
Subcommands: []*cli.Command{
|
|
{
|
|
Name: "re-encrypt",
|
|
Usage: "Re-encrypts secrets by decrypting and re-encrypting them with the currently configured encryption. Returns ok unless there is an error. Safe to execute multiple times.",
|
|
Action: runRunnerCommand(secretsmigrations.ReEncryptSecrets),
|
|
},
|
|
{
|
|
Name: "rollback",
|
|
Usage: "Rolls back secrets to legacy encryption. Returns ok unless there is an error. Safe to execute multiple times.",
|
|
Action: runRunnerCommand(secretsmigrations.RollBackSecrets),
|
|
},
|
|
{
|
|
Name: "re-encrypt-data-keys",
|
|
Usage: "Rotates persisted data encryption keys. Returns ok unless there is an error. Safe to execute multiple times.",
|
|
Action: runRunnerCommand(secretsmigrations.ReEncryptDEKS),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Name: "secrets-consolidation",
|
|
Usage: "Runs an operation that re-encrypts all encrypted values in your database with new data keys",
|
|
Subcommands: []*cli.Command{
|
|
{
|
|
Name: "consolidate",
|
|
Usage: "Re-encrypts all encrypted values with new data keys and deletes the old deactivated data keys. Returns ok unless there is an error. Safe to execute multiple times.",
|
|
Action: runRunnerCommand(secretsconsolidation.ConsolidateSecrets),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var Commands = []*cli.Command{
|
|
{
|
|
Name: "plugins",
|
|
Usage: "Manage plugins for grafana",
|
|
Subcommands: pluginCommands,
|
|
},
|
|
{
|
|
Name: "admin",
|
|
Usage: "Grafana admin commands",
|
|
Subcommands: adminCommands,
|
|
},
|
|
}
|