github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/admin-kms-key-status.go (about)

     1  // Copyright (c) 2015-2022 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"fmt"
    22  
    23  	"github.com/fatih/color"
    24  	"github.com/minio/cli"
    25  	json "github.com/minio/colorjson"
    26  	"github.com/minio/mc/pkg/probe"
    27  	"github.com/minio/pkg/v2/console"
    28  )
    29  
    30  var adminKMSKeyStatusCmd = cli.Command{
    31  	Name:         "status",
    32  	Usage:        "request status information for a KMS master key",
    33  	Action:       mainAdminKMSKeyStatus,
    34  	OnUsageError: onUsageError,
    35  	Before:       setGlobalsFromContext,
    36  	Flags:        globalFlags,
    37  	CustomHelpTemplate: `NAME:
    38    {{.HelpName}} - {{.Usage}}
    39  
    40  USAGE:
    41    {{.HelpName}} TARGET [KEY_NAME]
    42  
    43  FLAGS:
    44    {{range .VisibleFlags}}{{.}}
    45    {{end}}
    46  EXAMPLES:
    47    1. Get default master key and its status from a MinIO server/cluster.
    48       $ {{.HelpName}} play
    49    2. Get the status of one particular master key from a MinIO server/cluster.
    50       $ {{.HelpName}} play my-master-key
    51  `,
    52  }
    53  
    54  // adminKMSKeyCmd is the handle for the "mc admin kms key" command.
    55  func mainAdminKMSKeyStatus(ctx *cli.Context) error {
    56  	if len(ctx.Args()) == 0 || len(ctx.Args()) > 2 {
    57  		showCommandHelpAndExit(ctx, 1) // last argument is exit code
    58  	}
    59  
    60  	console.SetColor("StatusSuccess", color.New(color.FgGreen, color.Bold))
    61  	console.SetColor("StatusError", color.New(color.FgRed, color.Bold))
    62  	console.SetColor("StatusUnknown", color.New(color.FgYellow, color.Bold))
    63  
    64  	client, err := newAdminClient(ctx.Args().Get(0))
    65  	fatalIf(err, "Unable to get a configured admin connection.")
    66  
    67  	var keyID string
    68  	if len(ctx.Args()) == 2 {
    69  		keyID = ctx.Args().Get(1)
    70  	}
    71  	status, e := client.GetKeyStatus(globalContext, keyID)
    72  	fatalIf(probe.NewError(e), "Failed to get status information")
    73  
    74  	printMsg(kmsKeyStatusMsg{
    75  		KeyID:         status.KeyID,
    76  		EncryptionErr: status.EncryptionErr,
    77  		DecryptionErr: status.DecryptionErr,
    78  	})
    79  	return nil
    80  }
    81  
    82  type kmsKeyStatusMsg struct {
    83  	KeyID         string `json:"keyId"`
    84  	EncryptionErr string `json:"encryptionError,omitempty"`
    85  	DecryptionErr string `json:"decryptionError,omitempty"`
    86  	Status        string `json:"status"`
    87  }
    88  
    89  func (s kmsKeyStatusMsg) JSON() string {
    90  	s.Status = "success"
    91  	kmsBytes, e := json.MarshalIndent(s, "", "    ")
    92  	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")
    93  
    94  	return string(kmsBytes)
    95  }
    96  
    97  func (s kmsKeyStatusMsg) String() string {
    98  	msg := fmt.Sprintf("Key: %s\n", s.KeyID)
    99  
   100  	success := console.Colorize("StatusSuccess", "✔")
   101  	failure := console.Colorize("StatusError", "✗")
   102  	dunno := console.Colorize("StatusUnknown", "?")
   103  
   104  	formatStatus := func(name string, unknown bool, err string) string {
   105  		st := ""
   106  		switch {
   107  		case !unknown && err == "":
   108  			st = success
   109  		case unknown:
   110  			st = dunno
   111  		case err != "":
   112  			st = fmt.Sprintf("%s (%s)", failure, err)
   113  		}
   114  		return fmt.Sprintf("   - %s %s\n", name, st)
   115  	}
   116  
   117  	msg += formatStatus("Encryption", false, s.EncryptionErr)
   118  	msg += formatStatus("Decryption", s.EncryptionErr != "", s.DecryptionErr)
   119  	return msg
   120  }