2016-02-15 14:09:34 +01:00
package commands
import (
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"
2018-09-25 21:31:24 +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/grafana/grafana/pkg/util/errutil"
"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 {
2020-02-26 12:27:31 +01:00
return errutil . Wrap ( "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 {
return errutil . Wrap ( "failed to initialize runner" , err )
}
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 {
return errutil . Wrap ( "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 {
return errutil . Wrap ( "failed to initialize tracer service" , err )
}
sqlStore , err := sqlstore . ProvideService ( cfg , nil , bus . GetBus ( ) , & migrations . OSSMigrations { } , tracer )
2021-08-25 15:11:22 +02:00
if err != nil {
return errutil . Wrap ( "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
}
}
2021-08-13 17:01:12 -04:00
func runCueCommand ( command func ( commandLine utils . CommandLine ) error ) func ( context * cli . Context ) error {
return func ( context * cli . Context ) error {
return command ( & utils . ContextCommandLine { Context : context } )
}
}
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>" ,
2016-06-30 23:15:47 +02:00
Action : runDbCommand ( 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 ) ,
} ,
2021-11-18 09:19:04 +01:00
} ,
} ,
2016-02-15 14:09:34 +01:00
}
2016-03-21 10:01:07 +01:00
2021-05-06 19:21:08 +03:00
var cueCommands = [ ] * cli . Command {
{
Name : "validate-schema" ,
2021-07-16 19:53:19 -04:00
Usage : "validate known *.cue files in the Grafana project" ,
2021-08-13 17:01:12 -04:00
Action : runCueCommand ( cmd . validateScuemata ) ,
2021-07-16 19:53:19 -04:00
Description : ` validate - schema checks that all CUE schema files are valid with respect
to basic standards - valid CUE , valid scuemata , etc . Note that this
command checks only paths that existed when grafana - cli was compiled ,
so must be recompiled to validate newly - added CUE files . ` ,
Flags : [ ] cli . Flag {
& cli . StringFlag {
Name : "grafana-root" ,
Usage : "path to the root of a Grafana repository to validate" ,
} ,
} ,
2021-05-06 19:21:08 +03:00
} ,
2021-05-18 10:30:13 +03:00
{
Name : "validate-resource" ,
2021-07-16 03:08:03 +03:00
Usage : "validate resource files (e.g. dashboard JSON) against schema" ,
2021-08-13 17:01:12 -04:00
Action : runCueCommand ( cmd . validateResources ) ,
2021-05-18 10:30:13 +03:00
Flags : [ ] cli . Flag {
& cli . StringFlag {
Name : "dashboard" ,
Usage : "dashboard JSON file to validate" ,
} ,
2021-07-16 03:08:03 +03:00
& cli . BoolFlag {
Name : "base-only" ,
Usage : "validate using only base schema, not dist (includes plugin schema)" ,
Value : false ,
} ,
2021-05-18 10:30:13 +03:00
} ,
} ,
2021-11-18 10:02:11 -05:00
{
Name : "trim-resource" ,
Usage : "trim schema-specified defaults from a resource" ,
Action : runCueCommand ( cmd . trimResource ) ,
Flags : [ ] cli . Flag {
& cli . StringFlag {
Name : "dashboard" ,
Usage : "path to file containing (valid) dashboard JSON" ,
} ,
& cli . BoolFlag {
Name : "apply" ,
Usage : "invert the operation: apply defaults instead of trimming them" ,
Value : false ,
} ,
} ,
} ,
2021-09-29 04:59:05 -04:00
{
Name : "gen-ts" ,
Usage : "generate TypeScript from all known CUE file types" ,
Description : ` gen - ts generates TypeScript from all CUE files at
expected positions in the filesystem tree of a Grafana repository . ` ,
Action : runCueCommand ( cmd . generateTypescript ) ,
Flags : [ ] cli . Flag {
& cli . StringFlag {
Name : "grafana-root" ,
Usage : "path to the root of a Grafana repository in which to generate TypeScript from CUE files" ,
} ,
} ,
} ,
2021-05-06 19:21:08 +03: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
} ,
2021-05-06 19:21:08 +03:00
{
Name : "cue" ,
Usage : "Cue validation commands" ,
Subcommands : cueCommands ,
} ,
2016-03-21 10:01:07 +01:00
}