1
0
mirror of https://github.com/minio/mc.git synced 2025-04-19 21:02:15 +03:00
mc/cmd/support.go
2025-03-28 01:05:40 -07:00

189 lines
5.2 KiB
Go

// Copyright (c) 2015-2022 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package cmd
import (
"fmt"
"github.com/fatih/color"
"github.com/minio/cli"
json "github.com/minio/colorjson"
"github.com/minio/madmin-go/v3"
"github.com/minio/mc/pkg/probe"
"github.com/minio/minio-go/v7/pkg/set"
"github.com/minio/pkg/v3/console"
)
const (
supportSuccessMsgTag = "SupportSuccessMessage"
supportErrorMsgTag = "SupportErrorMessage"
)
var supportGlobalFlags = append(globalFlags,
cli.BoolFlag{
Name: "dev",
Usage: "Development mode",
Hidden: true,
},
cli.BoolFlag{
Name: "airgap",
Usage: "use in environments without network access to SUBNET (e.g. airgapped, firewalled, etc.)",
},
)
var supportSubcommands = []cli.Command{
supportRegisterCmd,
supportCallhomeCmd,
supportDiagCmd,
supportPerfCmd,
supportInspectCmd,
supportProfileCmd,
supportTopCmd,
supportProxyCmd,
supportUploadCmd,
}
var supportCmd = cli.Command{
Name: "support",
Usage: "support related commands",
Action: mainSupport,
Before: setGlobalsFromContext,
Flags: globalFlags,
Subcommands: supportSubcommands,
HideHelpCommand: true,
}
func toggleCmdArgs() set.StringSet {
return set.CreateStringSet("enable", "disable", "status")
}
func validateToggleCmdArg(arg string) error {
valid := toggleCmdArgs()
if !valid.Contains(arg) {
return fmt.Errorf("Invalid argument '%s'. Must be one of %v", arg, valid)
}
return nil
}
func checkToggleCmdSyntax(ctx *cli.Context) (string, string) {
if len(ctx.Args()) != 2 {
showCommandHelpAndExit(ctx, 1) // last argument is exit code
}
arg := ctx.Args().Get(0)
aliasedURL := ctx.Args().Get(1)
fatalIf(probe.NewError(validateToggleCmdArg(arg)), "Invalid arguments.")
alias, _ := url2Alias(aliasedURL)
return alias, arg
}
func setSuccessMessageColor() {
console.SetColor(supportSuccessMsgTag, color.New(color.FgGreen, color.Bold))
}
func setErrorMessageColor() {
console.SetColor(supportErrorMsgTag, color.New(color.FgYellow, color.Italic))
}
func featureStatusStr(enabled bool) string {
if enabled {
return "enabled"
}
return "disabled"
}
func validateClusterRegistered(alias string, cmdTalksToSubnet bool) string {
// Non-registered execution allowed only in following scenarios
// command doesn't talk to subnet: dev mode (`--dev` passed)
// command talks to subnet: dev+airgapped mode (both `--dev` and `--airgap` passed)
requireRegistration := !GlobalDevMode
if cmdTalksToSubnet {
requireRegistration = !GlobalDevMode || !globalAirgapped
}
apiKey, e := getSubnetAPIKey(alias)
if requireRegistration {
fatalIf(probe.NewError(e), "")
}
return apiKey
}
// isFeatureEnabled - checks if a feature is enabled in MinIO config
// To be used with configs that can be switched on/off using the `enable` key
// e.g. subSys = logger_webhook, target = logger_webhook:subnet
// Returns true if any of the following is true
// - `enable` is set to `on`
// - `enable` key is not found
// Returns false if any of the following is true
// - given subsystem is not supported by the version of MinIO
// - the given target doesn't exist in the config
// - `enable` is set to `off`
func isFeatureEnabled(alias, subSys, target string) bool {
client, err := newAdminClient(alias)
// Create a new MinIO Admin Client
fatalIf(err, "Unable to initialize admin connection.")
if !minioConfigSupportsSubSys(client, subSys) {
return false
}
scfgs, e := getMinIOSubSysConfig(client, subSys)
if e != nil {
// Ignore error if the given target doesn't exist
// e.g. logger_webhook:subnet doesn't exist when
// pushing logs to SUBNET has not been enabled
if e.Error() == fmt.Sprintf("sub-system target '%s' doesn't exist", target) {
return false
}
fatalIf(probe.NewError(e), fmt.Sprintf("Unable to get server config for '%s'", subSys))
}
if target == madmin.Default {
target = ""
}
for _, scfg := range scfgs {
if scfg.Target == target {
enable, found := scfg.Lookup(madmin.EnableKey)
if !found {
// if `enable` key is not found, it means that `enable=on`
return true
}
return enable == madmin.EnableOn
}
}
return false
}
func toJSON(obj interface{}) string {
jsonBytes, e := json.MarshalIndent(obj, "", " ")
fatalIf(probe.NewError(e), "Unable to marshal into JSON.")
return string(jsonBytes)
}
// mainSupport is the handle for "mc support" command.
func mainSupport(ctx *cli.Context) error {
commandNotFound(ctx, supportSubcommands)
return nil
// Sub-commands like "register", "callhome", "diagnostics" have their own main.
}