github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/license-update.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 "os" 23 24 "github.com/fatih/color" 25 "github.com/minio/cli" 26 json "github.com/minio/colorjson" 27 "github.com/minio/mc/pkg/probe" 28 "github.com/minio/pkg/v2/console" 29 ) 30 31 var licenseUpdateCmd = cli.Command{ 32 Name: "update", 33 Usage: "update the license", 34 OnUsageError: onUsageError, 35 Action: mainLicenseUpdate, 36 Before: setGlobalsFromContext, 37 Flags: supportGlobalFlags, 38 CustomHelpTemplate: `NAME: 39 {{.HelpName}} - {{.Usage}} 40 41 USAGE: 42 {{.HelpName}} ALIAS LICENSE-FILE-PATH 43 44 FLAGS: 45 {{range .VisibleFlags}}{{.}} 46 {{end}} 47 48 EXAMPLES: 49 1. Update license for cluster with alias 'play' from the file license.key 50 {{.Prompt}} {{.HelpName}} play license.key 51 2. Update (renew) license for already registered cluster with alias 'play' 52 {{.Prompt}} {{.HelpName}} play 53 `, 54 } 55 56 const licUpdateMsgTag = "licenseUpdateMessage" 57 58 type licUpdateMessage struct { 59 Status string `json:"status"` 60 Alias string `json:"-"` 61 } 62 63 // String colorized license update message 64 func (li licUpdateMessage) String() string { 65 return console.Colorize(licUpdateMsgTag, "License updated successfully for "+li.Alias) 66 } 67 68 // JSON jsonified license update message 69 func (li licUpdateMessage) JSON() string { 70 jsonBytes, e := json.MarshalIndent(li, "", " ") 71 fatalIf(probe.NewError(e), "Unable to marshal into JSON.") 72 73 return string(jsonBytes) 74 } 75 76 func mainLicenseUpdate(ctx *cli.Context) error { 77 args := ctx.Args() 78 argsLen := len(args) 79 if argsLen > 2 || argsLen < 1 { 80 showCommandHelpAndExit(ctx, 1) // last argument is exit code 81 } 82 83 console.SetColor(licUpdateMsgTag, color.New(color.FgGreen, color.Bold)) 84 85 aliasedURL := args.Get(0) 86 alias, _ := url2Alias(aliasedURL) 87 88 if argsLen == 2 { 89 licFile := args.Get(1) 90 printMsg(performLicenseUpdate(licFile, alias)) 91 return nil 92 } 93 94 // renew the license 95 printMsg(performLicenseRenew(alias)) 96 return nil 97 } 98 99 func performLicenseRenew(alias string) licUpdateMessage { 100 apiKey, _, e := getSubnetCreds(alias) 101 fatalIf(probe.NewError(e), "Error getting subnet creds") 102 103 if len(apiKey) == 0 { 104 errMsg := fmt.Sprintf("Please register the cluster first by running 'mc license register %s'", alias) 105 fatal(errDummy().Trace(), errMsg) 106 } 107 108 renewURL := subnetLicenseRenewURL() 109 headers := SubnetAPIKeyAuthHeaders(apiKey) 110 headers.addDeploymentIDHeader(alias) 111 resp, e := SubnetPostReq(renewURL, nil, headers) 112 fatalIf(probe.NewError(e), "Error renewing license for %s", alias) 113 114 extractAndSaveSubnetCreds(alias, resp) 115 116 return licUpdateMessage{ 117 Alias: alias, 118 Status: "success", 119 } 120 } 121 122 func performLicenseUpdate(licFile, alias string) licUpdateMessage { 123 lum := licUpdateMessage{ 124 Alias: alias, 125 Status: "success", 126 } 127 128 licBytes, e := os.ReadFile(licFile) 129 fatalIf(probe.NewError(e), fmt.Sprintf("Unable to read license file %s", licFile)) 130 131 lic := string(licBytes) 132 validateAndSaveLic(lic, alias, true) 133 134 return lum 135 }