github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/admin-cluster-iam-export.go (about) 1 // Copyright (c) 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 "context" 22 "fmt" 23 "io" 24 "os" 25 "path/filepath" 26 "time" 27 28 "github.com/fatih/color" 29 "github.com/minio/cli" 30 json "github.com/minio/colorjson" 31 "github.com/minio/mc/pkg/probe" 32 "github.com/minio/pkg/v2/console" 33 ) 34 35 var adminClusterIAMExportCmd = cli.Command{ 36 Name: "export", 37 Usage: "exports IAM info to zipped file", 38 Action: mainClusterIAMExport, 39 OnUsageError: onUsageError, 40 Before: setGlobalsFromContext, 41 Flags: globalFlags, 42 HideHelpCommand: true, 43 CustomHelpTemplate: `NAME: 44 {{.HelpName}} - {{.Usage}} 45 46 USAGE: 47 {{.HelpName}} [FLAGS] TARGET 48 49 FLAGS: 50 {{range .VisibleFlags}}{{.}} 51 {{end}} 52 EXAMPLES: 53 1. Download all IAM metadata for cluster into zip file. 54 {{.Prompt}} {{.HelpName}} myminio 55 `, 56 } 57 58 func checkIAMExportSyntax(ctx *cli.Context) { 59 if len(ctx.Args()) != 1 { 60 showCommandHelpAndExit(ctx, 1) // last argument is exit code 61 } 62 } 63 64 // mainClusterIAMExport - metadata export command 65 func mainClusterIAMExport(ctx *cli.Context) error { 66 // Check for command syntax 67 checkIAMExportSyntax(ctx) 68 69 // Get the alias parameter from cli 70 args := ctx.Args() 71 aliasedURL := filepath.ToSlash(args.Get(0)) 72 aliasedURL = filepath.Clean(aliasedURL) 73 74 console.SetColor("File", color.New(color.FgWhite, color.Bold)) 75 76 // Create a new MinIO Admin Client 77 client, err := newAdminClient(aliasedURL) 78 if err != nil { 79 fatalIf(err.Trace(aliasedURL), "Unable to initialize admin client.") 80 return nil 81 } 82 83 r, e := client.ExportIAM(context.Background()) 84 fatalIf(probe.NewError(e).Trace(aliasedURL), "Unable to export IAM info.") 85 86 // Create iam info zip file 87 tmpFile, e := os.CreateTemp("", fmt.Sprintf("%s-iam-info", aliasedURL)) 88 fatalIf(probe.NewError(e), "Unable to download file data.") 89 90 ext := "zip" 91 // Copy zip content to target download file 92 _, e = io.Copy(tmpFile, r) 93 fatalIf(probe.NewError(e), "Unable to download IAM info.") 94 95 // Close everything 96 r.Close() 97 tmpFile.Close() 98 99 downloadPath := fmt.Sprintf("%s-iam-info.%s", aliasedURL, ext) 100 fi, e := os.Stat(downloadPath) 101 if e == nil && !fi.IsDir() { 102 e = moveFile(downloadPath, downloadPath+"."+time.Now().Format(dateTimeFormatFilename)) 103 fatalIf(probe.NewError(e), "Unable to create a backup of "+downloadPath) 104 } else { 105 if !os.IsNotExist(e) { 106 fatal(probe.NewError(e), "Unable to download file data") 107 } 108 } 109 110 fatalIf(probe.NewError(moveFile(tmpFile.Name(), downloadPath)), "Unable to rename downloaded data, file exists at %s", tmpFile.Name()) 111 112 if !globalJSON { 113 console.Infof("IAM info successfully downloaded as %s\n", downloadPath) 114 return nil 115 } 116 117 v := struct { 118 File string `json:"file"` 119 Key string `json:"key,omitempty"` 120 }{ 121 File: downloadPath, 122 } 123 b, e := json.Marshal(v) 124 fatalIf(probe.NewError(e), "Unable to serialize data") 125 console.Println(string(b)) 126 return nil 127 }