2016-02-15 14:09:34 +01:00
package commands
import (
2022-06-03 03:24:24 -04:00
"fmt"
2019-06-24 20:20:21 +01:00
"strings"
2016-04-11 18:05:28 -04:00
2021-04-26 16:13:40 +02:00
"github.com/fatih/color"
2022-06-14 16:07:41 +02:00
"github.com/grafana/grafana/pkg/bus"
2019-05-27 10:47:21 +02:00
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/datamigrations"
2021-11-18 09:19:04 +01:00
"github.com/grafana/grafana/pkg/cmd/grafana-cli/commands/secretsmigrations"
2016-06-03 12:19:04 +02:00
"github.com/grafana/grafana/pkg/cmd/grafana-cli/logger"
2021-11-17 20:43:09 +01:00
"github.com/grafana/grafana/pkg/cmd/grafana-cli/runner"
2020-02-26 12:27:31 +01:00
"github.com/grafana/grafana/pkg/cmd/grafana-cli/services"
2019-05-27 10:47:21 +02:00
"github.com/grafana/grafana/pkg/cmd/grafana-cli/utils"
2022-01-20 11:10:12 +01:00
"github.com/grafana/grafana/pkg/infra/tracing"
2016-06-30 23:15:47 +02:00
"github.com/grafana/grafana/pkg/services/sqlstore"
2021-08-25 15:11:22 +02:00
"github.com/grafana/grafana/pkg/services/sqlstore/migrations"
2016-06-30 23:15:47 +02:00
"github.com/grafana/grafana/pkg/setting"
2020-02-26 12:27:31 +01:00
"github.com/urfave/cli/v2"
2016-02-15 14:09:34 +01:00
)
2021-11-17 20:43:09 +01:00
func runRunnerCommand ( command func ( commandLine utils . CommandLine , runner runner . Runner ) error ) func ( context * cli . Context ) error {
2020-02-26 12:27:31 +01:00
return func ( context * cli . Context ) error {
2019-05-27 10:47:21 +02:00
cmd := & utils . ContextCommandLine { Context : context }
2021-11-17 20:43:09 +01:00
cfg , err := initCfg ( cmd )
2021-08-25 15:11:22 +02:00
if err != nil {
2022-06-03 03:24:24 -04:00
return fmt . Errorf ( "%v: %w" , "failed to load configuration" , err )
2019-10-15 16:44:15 +02:00
}
2016-06-30 23:15:47 +02:00
2021-11-17 20:43:09 +01:00
r , err := runner . Initialize ( cfg )
if err != nil {
2022-06-03 03:24:24 -04:00
return fmt . Errorf ( "%v: %w" , "failed to initialize runner" , err )
2021-11-17 20:43:09 +01:00
}
if err := command ( cmd , r ) ; err != nil {
return err
}
logger . Info ( "\n\n" )
return nil
}
}
func runDbCommand ( command func ( commandLine utils . CommandLine , sqlStore * sqlstore . SQLStore ) error ) func ( context * cli . Context ) error {
return func ( context * cli . Context ) error {
cmd := & utils . ContextCommandLine { Context : context }
cfg , err := initCfg ( cmd )
if err != nil {
2022-06-03 03:24:24 -04:00
return fmt . Errorf ( "%v: %w" , "failed to load configuration" , err )
2019-06-24 20:20:21 +01:00
}
2019-06-17 11:27:26 +01:00
2022-01-20 11:10:12 +01:00
tracer , err := tracing . ProvideService ( cfg )
if err != nil {
2022-06-03 03:24:24 -04:00
return fmt . Errorf ( "%v: %w" , "failed to initialize tracer service" , err )
2022-01-20 11:10:12 +01:00
}
2022-02-15 18:54:27 +02:00
2022-06-14 16:07:41 +02:00
bus := bus . ProvideBus ( tracer )
sqlStore , err := sqlstore . ProvideService ( cfg , nil , & migrations . OSSMigrations { } , bus , tracer )
2021-08-25 15:11:22 +02:00
if err != nil {
2022-06-03 03:24:24 -04:00
return fmt . Errorf ( "%v: %w" , "failed to initialize SQL store" , err )
2019-10-15 16:44:15 +02:00
}
2016-06-30 23:15:47 +02:00
2021-08-25 15:11:22 +02:00
if err := command ( cmd , sqlStore ) ; err != nil {
2020-02-26 12:27:31 +01:00
return err
2016-06-30 23:15:47 +02:00
}
2019-03-27 17:53:49 +01:00
logger . Info ( "\n\n" )
2020-02-26 12:27:31 +01:00
return nil
2016-06-30 23:15:47 +02:00
}
}
2021-11-17 20:43:09 +01:00
func initCfg ( cmd * utils . ContextCommandLine ) ( * setting . Cfg , error ) {
configOptions := strings . Split ( cmd . String ( "configOverrides" ) , " " )
cfg , err := setting . NewCfgFromArgs ( setting . CommandLineArgs {
Config : cmd . ConfigFile ( ) ,
HomePath : cmd . HomePath ( ) ,
Args : append ( configOptions , cmd . Args ( ) . Slice ( ) ... ) , // tailing arguments have precedence over the options string
} )
if err != nil {
return nil , err
}
if cmd . Bool ( "debug" ) {
cfg . LogConfigSources ( )
}
return cfg , nil
}
2020-02-26 12:27:31 +01:00
func runPluginCommand ( command func ( commandLine utils . CommandLine ) error ) func ( context * cli . Context ) error {
return func ( context * cli . Context ) error {
2019-05-27 10:47:21 +02:00
cmd := & utils . ContextCommandLine { Context : context }
2016-02-15 14:09:34 +01:00
if err := command ( cmd ) ; err != nil {
2020-02-26 12:27:31 +01:00
return err
2016-02-15 14:09:34 +01:00
}
2019-03-27 17:53:49 +01:00
2021-04-26 16:13:40 +02:00
logger . Info ( color . GreenString ( "Please restart Grafana after installing plugins. Refer to Grafana documentation for instructions if necessary.\n\n" ) )
2020-02-26 12:27:31 +01:00
return nil
2016-02-15 14:09:34 +01:00
}
}
2020-02-26 12:27:31 +01:00
// Command contains command state.
type Command struct {
Client utils . ApiClient
}
var cmd Command = Command {
Client : & services . GrafanaComClient { } ,
}
var pluginCommands = [ ] * cli . Command {
2016-02-15 14:09:34 +01:00
{
Name : "install" ,
2016-07-27 03:41:33 -04:00
Usage : "install <plugin id> <plugin version (optional)>" ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . installCommand ) ,
2016-02-15 14:09:34 +01:00
} , {
Name : "list-remote" ,
Usage : "list remote available plugins" ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . listRemoteCommand ) ,
2016-07-27 03:41:33 -04:00
} , {
Name : "list-versions" ,
Usage : "list-versions <plugin id>" ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . listVersionsCommand ) ,
2016-02-15 14:09:34 +01:00
} , {
2016-04-11 18:05:28 -04:00
Name : "update" ,
Usage : "update <plugin id>" ,
Aliases : [ ] string { "upgrade" } ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . upgradeCommand ) ,
2016-02-15 14:09:34 +01:00
} , {
2016-04-11 18:05:28 -04:00
Name : "update-all" ,
Aliases : [ ] string { "upgrade-all" } ,
Usage : "update all your installed plugins" ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . upgradeAllCommand ) ,
2016-02-15 14:09:34 +01:00
} , {
Name : "ls" ,
Usage : "list all installed plugins" ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . lsCommand ) ,
2016-04-11 14:49:12 +02:00
} , {
2016-06-23 08:21:55 +02:00
Name : "uninstall" ,
Aliases : [ ] string { "remove" } ,
Usage : "uninstall <plugin id>" ,
2020-02-26 12:27:31 +01:00
Action : runPluginCommand ( cmd . removeCommand ) ,
2016-06-30 23:15:47 +02:00
} ,
}
2020-02-26 12:27:31 +01:00
var adminCommands = [ ] * cli . Command {
2016-06-30 23:15:47 +02:00
{
2016-12-09 15:25:02 +01:00
Name : "reset-admin-password" ,
Usage : "reset-admin-password <new password>" ,
2022-08-02 16:58:05 +02:00
Action : runRunnerCommand ( resetPasswordCommand ) ,
2020-07-02 18:29:10 +04:00
Flags : [ ] cli . Flag {
& cli . BoolFlag {
Name : "password-from-stdin" ,
Usage : "Read the password from stdin" ,
Value : false ,
} ,
} ,
2016-02-15 14:09:34 +01:00
} ,
2019-05-27 10:47:21 +02:00
{
Name : "data-migration" ,
2021-11-18 09:19:04 +01:00
Usage : "Runs a script that migrates or cleanups data in your database" ,
2020-02-26 12:27:31 +01:00
Subcommands : [ ] * cli . Command {
2019-05-27 10:47:21 +02:00
{
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." ,
2020-06-01 17:11:25 +02:00
Action : runDbCommand ( datamigrations . EncryptDatasourcePasswords ) ,
2019-05-27 10:47:21 +02:00
} ,
} ,
} ,
2021-11-18 09:19:04 +01:00
{
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 ) ,
} ,
2022-02-03 07:19:18 +01:00
{
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 ) ,
} ,
2022-02-03 09:15:38 +01:00
{
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 ) ,
} ,
2021-11-18 09:19:04 +01:00
} ,
} ,
2022-08-12 14:47:31 +01:00
{
Name : "user-manager" ,
Usage : "Runs different helpful user commands" ,
Subcommands : [ ] * cli . Command {
// TODO: reset password for user
{
Name : "conflicts" ,
Usage : "runs a conflict resolution to find users with multiple entries" ,
Subcommands : [ ] * cli . Command {
{
Name : "list" ,
Usage : "returns a list of users with more than one entry in the database" ,
Action : runListConflictUsers ( ) ,
} ,
{
Name : "generate-file" ,
2022-09-29 14:26:24 +02:00
Usage : "creates a conflict users file. Safe to execute multiple times." ,
2022-08-12 14:47:31 +01:00
Action : runGenerateConflictUsersFile ( ) ,
} ,
2022-09-29 14:26:24 +02:00
{
Name : "validate-file" ,
Usage : "validates the conflict users file. Safe to execute multiple times." ,
Action : runValidateConflictUsersFile ( ) ,
} ,
{
Name : "ingest-file" ,
Usage : "ingests the conflict users file" ,
Action : runIngestConflictUsersFile ( ) ,
} ,
2022-08-12 14:47:31 +01:00
} ,
} ,
} ,
} ,
2016-02-15 14:09:34 +01:00
}
2016-03-21 10:01:07 +01:00
2020-02-26 12:27:31 +01:00
var Commands = [ ] * cli . Command {
2016-03-21 10:01:07 +01:00
{
Name : "plugins" ,
Usage : "Manage plugins for grafana" ,
Subcommands : pluginCommands ,
} ,
2016-06-30 23:15:47 +02:00
{
2016-12-09 15:25:02 +01:00
Name : "admin" ,
Usage : "Grafana admin commands" ,
Subcommands : adminCommands ,
2016-06-30 23:15:47 +02:00
} ,
2016-03-21 10:01:07 +01:00
}