diff --git a/cmd/admin-main.go b/cmd/admin-main.go index 131ba523..a0b1683f 100644 --- a/cmd/admin-main.go +++ b/cmd/admin-main.go @@ -42,6 +42,7 @@ var adminCmd = cli.Command{ adminTopCmd, adminTraceCmd, adminConsoleCmd, + adminPrometheusCmd, }, } diff --git a/cmd/admin-prometheus-generate.go b/cmd/admin-prometheus-generate.go new file mode 100644 index 00000000..8b008e8d --- /dev/null +++ b/cmd/admin-prometheus-generate.go @@ -0,0 +1,190 @@ +/* + * MinIO Client (C) 2019 MinIO, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import ( + "fmt" + "net/url" + "time" + + "github.com/fatih/color" + "github.com/minio/cli" + "github.com/minio/mc/pkg/console" + "github.com/minio/mc/pkg/probe" + + jwtgo "github.com/dgrijalva/jwt-go" + json "github.com/minio/mc/pkg/colorjson" + yaml "gopkg.in/yaml.v2" +) + +const ( + defaultJobName = "minio-job" + defaultMetricsPath = "/minio/prometheus/metrics" +) + +var adminPrometheusGenerateCmd = cli.Command{ + Name: "generate", + Usage: "generates prometheus config", + Action: mainAdminPrometheusGenerate, + Before: setGlobalsFromContext, + Flags: globalFlags, + HideHelpCommand: true, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} TARGET + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +EXAMPLES: + 1. Generate a default prometheus config. + $ {{.HelpName}} myminio + +`, +} + +// PrometheusConfig - container to hold the top level scrape config. +type PrometheusConfig struct { + ScrapeConfigs []ScrapeConfig `yaml:"scrape_configs,omitempty"` +} + +// String colorized prometheus config yaml. +func (c PrometheusConfig) String() string { + b, err := yaml.Marshal(c) + if err != nil { + return fmt.Sprintf("error creating config string: %s", err) + } + return console.Colorize("yaml", string(b)) +} + +// JSON jsonified prometheus config. +func (c PrometheusConfig) JSON() string { + jsonMessageBytes, e := json.MarshalIndent(c.ScrapeConfigs[0], "", " ") + fatalIf(probe.NewError(e), "Unable to marshal into JSON.") + return string(jsonMessageBytes) +} + +// StatConfig - container to hold the targets config. +type StatConfig struct { + Targets []string `yaml:",flow" json:"targets"` +} + +// String colorized stat config yaml. +func (t StatConfig) String() string { + b, err := yaml.Marshal(t) + if err != nil { + return fmt.Sprintf("error creating config string: %s", err) + } + return console.Colorize("yaml", string(b)) +} + +// JSON jsonified stat config. +func (t StatConfig) JSON() string { + jsonMessageBytes, e := json.MarshalIndent(t.Targets, "", " ") + fatalIf(probe.NewError(e), "Unable to marshal into JSON.") + return string(jsonMessageBytes) +} + +// ScrapeConfig configures a scraping unit for Prometheus. +type ScrapeConfig struct { + JobName string `yaml:"job_name" json:"jobName"` + BearerToken string `yaml:"bearer_token" json:"bearerToken"` + MetricsPath string `yaml:"metrics_path,omitempty" json:"metricsPath"` + Scheme string `yaml:"scheme,omitempty" json:"scheme"` + StaticConfigs []StatConfig `yaml:"static_configs,omitempty" json:"staticConfigs"` +} + +const ( + defaultPrometheusJWTExpiry = 100 * 365 * 24 * time.Hour +) + +var defaultConfig = PrometheusConfig{ + ScrapeConfigs: []ScrapeConfig{ + { + JobName: defaultJobName, + MetricsPath: defaultMetricsPath, + StaticConfigs: []StatConfig{ + { + Targets: []string{""}, + }, + }, + }, + }, +} + +// checkAdminPrometheusSyntax - validate all the passed arguments +func checkAdminPrometheusSyntax(ctx *cli.Context) { + if len(ctx.Args()) != 1 { + cli.ShowCommandHelpAndExit(ctx, "generate", 1) // last argument is exit code + } +} + +func generatePrometheusConfig(ctx *cli.Context) error { + // Get the alias parameter from cli + args := ctx.Args() + alias := args.Get(0) + + if !isValidAlias(alias) { + fatalIf(errInvalidAlias(alias), "Invalid alias.") + } + + hostConfig := mustGetHostConfig(alias) + if hostConfig == nil { + fatalIf(errInvalidAliasedURL(alias), "No such alias `"+alias+"` found.") + } + + u, err := url.Parse(hostConfig.URL) + if err != nil { + return err + } + + jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.StandardClaims{ + ExpiresAt: UTCNow().Add(defaultPrometheusJWTExpiry).Unix(), + Subject: hostConfig.AccessKey, + Issuer: "prometheus", + }) + + token, err := jwt.SignedString([]byte(hostConfig.SecretKey)) + if err != nil { + return err + } + + // Setting the values + defaultConfig.ScrapeConfigs[0].BearerToken = token + defaultConfig.ScrapeConfigs[0].Scheme = u.Scheme + defaultConfig.ScrapeConfigs[0].StaticConfigs[0].Targets[0] = u.Host + + printMsg(defaultConfig) + + return nil +} + +// mainAdminPrometheus is the handle for "mc admin prometheus generate" sub-command. +func mainAdminPrometheusGenerate(ctx *cli.Context) error { + + console.SetColor("yaml", color.New(color.FgGreen)) + + checkAdminPrometheusSyntax(ctx) + + if err := generatePrometheusConfig(ctx); err != nil { + return nil + } + + return nil +} diff --git a/cmd/admin-prometheus.go b/cmd/admin-prometheus.go new file mode 100644 index 00000000..c251d446 --- /dev/null +++ b/cmd/admin-prometheus.go @@ -0,0 +1,47 @@ +/* + * MinIO Client (C) 2019 MinIO, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cmd + +import "github.com/minio/cli" + +var adminPrometheusCmd = cli.Command{ + Name: "prometheus", + Usage: "manages prometheus config", + Action: mainAdminPrometheus, + Before: setGlobalsFromContext, + Flags: globalFlags, + HideHelpCommand: true, + Subcommands: []cli.Command{ + adminPrometheusGenerateCmd, + }, + CustomHelpTemplate: `NAME: + {{.HelpName}} - {{.Usage}} + +USAGE: + {{.HelpName}} TARGET + +FLAGS: + {{range .VisibleFlags}}{{.}} + {{end}} +`, +} + +// mainAdminPrometheus is the handle for "mc admin prometheus" command. +func mainAdminPrometheus(ctx *cli.Context) error { + cli.ShowCommandHelp(ctx, ctx.Args().First()) + return nil +} diff --git a/docs/minio-admin-complete-guide.md b/docs/minio-admin-complete-guide.md index e74dc087..39d42dc0 100644 --- a/docs/minio-admin-complete-guide.md +++ b/docs/minio-admin-complete-guide.md @@ -15,6 +15,7 @@ profile generate profile data for debugging purposes top provide top like statistics for MinIO trace show http trace for minio server console show console logs for MinIO server +prometheus manages prometheus config settings ``` ## 1. Download MinIO Client @@ -277,7 +278,7 @@ Skip SSL certificate verification. | [**top** - provide top like statistics for MinIO](#top) | | [**trace** - show http trace for MinIO server](#trace) | | [**console** - show console logs for MinIO server](#console) | - +| [**prometheus** - manages prometheus config settings](#prometheus) | ### Command `update` - updates all MinIO servers @@ -691,3 +692,33 @@ mc admin console myminio 2: cmd/notification.go:815:cmd.(*NotificationSys).Init() 1: cmd/server-main.go:375:cmd.serverMain() ``` + + + +### Command `prometheus` - Manages prometheus config settings + +`generate` command generates the prometheus config (To be pasted in `prometheus.yml`) + +```sh +NAME: + mc admin prometheus - manages prometheus config + +USAGE: + mc admin prometheus COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...] + +COMMANDS: + generate generates prometheus config + +``` + +_Example: Generates prometheus config for an ._ + +```sh +mc admin prometheus generate +- job_name: minio-job + bearer_token: + metrics_path: /minio/prometheus/metrics + scheme: http + static_configs: + - targets: ['localhost:9000'] +``` diff --git a/go.mod b/go.mod index 03473276..7107f700 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,8 @@ go 1.13 require ( github.com/cheggaaa/pb v1.0.28 + github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect + github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dustin/go-humanize v1.0.0 github.com/fatih/color v1.7.0 github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf @@ -23,6 +25,7 @@ require ( golang.org/x/text v0.3.2 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 gopkg.in/h2non/filetype.v1 v1.0.5 + gopkg.in/yaml.v2 v2.2.2 ) replace github.com/gorilla/rpc v1.2.0+incompatible => github.com/gorilla/rpc v1.2.0