From 7b9b7cef115a96098a63204f760815eac5eb2bb2 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Mon, 27 Jun 2022 03:58:25 -0700 Subject: [PATCH] add license banner for GNU AGPLv3 (#15178) Bonus: rewrite subnet re-use of Transport --- cmd/callhome.go | 14 ++++ cmd/config-current.go | 4 +- cmd/iam.go | 2 +- cmd/main.go | 2 +- cmd/server-startup-msg.go | 17 ++-- .../config/subnet/{api-key.go => config.go} | 27 +++++- .../config/subnet/subnet.go | 82 +++++++------------ 7 files changed, 80 insertions(+), 68 deletions(-) rename internal/config/subnet/{api-key.go => config.go} (70%) rename cmd/subnet-utils.go => internal/config/subnet/subnet.go (51%) diff --git a/cmd/callhome.go b/cmd/callhome.go index 08a13f8ff..e2c294786 100644 --- a/cmd/callhome.go +++ b/cmd/callhome.go @@ -134,3 +134,17 @@ func performCallhome(ctx context.Context) { logger.LogIf(ctx, fmt.Errorf("Unable to perform callhome: %w", err)) } } + +const ( + callhomeURL = "https://subnet.min.io/api/callhome" + callhomeURLDev = "http://localhost:9000/api/callhome" +) + +func sendCallhomeInfo(ch CallhomeInfo) error { + url := callhomeURL + if globalIsCICD { + url = callhomeURLDev + } + _, err := globalSubnetConfig.Post(url, ch) + return err +} diff --git a/cmd/config-current.go b/cmd/config-current.go index 7b65a5f53..86ed07063 100644 --- a/cmd/config-current.go +++ b/cmd/config-current.go @@ -364,7 +364,7 @@ func validateSubSysConfig(s config.Config, subSys string, objAPI ObjectLayer) er return err } case config.SubnetSubSys: - if _, err := subnet.LookupConfig(s[config.SubnetSubSys][config.Default]); err != nil { + if _, err := subnet.LookupConfig(s[config.SubnetSubSys][config.Default], nil); err != nil { return err } case config.CallhomeSubSys: @@ -599,7 +599,7 @@ func lookupConfigs(s config.Config, objAPI ObjectLayer) { setGlobalAuthZPlugin(polplugin.New(authZPluginCfg)) - globalSubnetConfig, err = subnet.LookupConfig(s[config.SubnetSubSys][config.Default]) + globalSubnetConfig, err = subnet.LookupConfig(s[config.SubnetSubSys][config.Default], globalProxyTransport) if err != nil { logger.LogIf(ctx, fmt.Errorf("Unable to parse subnet configuration: %w", err)) } diff --git a/cmd/iam.go b/cmd/iam.go index 13a5fa0aa..384189eab 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -372,7 +372,7 @@ func (sys *IAMSys) Init(ctx context.Context, objAPI ObjectLayer, etcdClient *etc sys.printIAMRoles() now := time.Now() - logger.Info("Finished loading IAM sub-system (took %.1fs of %.1fs to load data).", now.Sub(iamLoadStart).Seconds(), now.Sub(iamInitStart).Seconds()) + logger.Info("Finished loading IAM sub-system (took %.1fs of %.1fs).", now.Sub(iamLoadStart).Seconds(), now.Sub(iamInitStart).Seconds()) } func (sys *IAMSys) validateAndAddRolePolicyMappings(ctx context.Context, m map[arn.ARN]string) { diff --git a/cmd/main.go b/cmd/main.go index 3981e9748..dc5861631 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -167,7 +167,7 @@ func printMinIOVersion(c *cli.Context) { fmt.Fprintln(c.App.Writer, color.Greenf("%s version %s (commit-id=%s)", c.App.Name, c.App.Version, CommitID)) fmt.Fprintln(c.App.Writer, color.Greenf("Runtime: %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)) fmt.Fprintln(c.App.Writer, color.Greenf("Copyright (c) 2015-%s MinIO, Inc.", CopyrightYear)) - fmt.Fprintln(c.App.Writer, color.Red("Licence AGPLv3 ")) + fmt.Fprintln(c.App.Writer, color.Red("Licence GNU AGPLv3 ")) } // Main main for minio server. diff --git a/cmd/server-startup-msg.go b/cmd/server-startup-msg.go index e4b9f7a98..e30478fa7 100644 --- a/cmd/server-startup-msg.go +++ b/cmd/server-startup-msg.go @@ -50,6 +50,11 @@ func printStartupMessage(apiEndpoints []string, err error) { } } + if len(globalSubnetConfig.APIKey) == 0 && err == nil { + logger.Info(color.Blue("\nLicense:") + " GNU AGPLv3 ") + logger.Info(color.Yellow("Detected a deployment not registered with SUBNET. Please register your deployment via 'mc support register ALIAS'\n")) + } + strippedAPIEndpoints := stripStandardPorts(apiEndpoints, globalMinioHost) // If cache layer is enabled, print cache capacity. cachedObjAPI := newCachedObjectLayerFn() @@ -72,12 +77,6 @@ func printStartupMessage(apiEndpoints []string, err error) { // Prints documentation message. printObjectAPIMsg() - - if globalMinioConsolePortAuto && globalBrowserEnabled { - msg := fmt.Sprintf("\nWARNING: Console endpoint is listening on a dynamic port (%s), please use --console-address \":PORT\" to choose a static port.", - globalMinioConsolePort) - logger.Info(color.RedBold(msg)) - } } // Returns true if input is IPv6 @@ -141,9 +140,13 @@ func printServerCommonMsg(apiEndpoints []string) { } printEventNotifiers() + if globalMinioConsolePortAuto && globalBrowserEnabled { + logger.Info(color.RedBold("\nWARNING: Console endpoint is listening on a dynamic port (%s), please use --console-address \":PORT\" to choose a static port.", + globalMinioConsolePort)) + } if globalBrowserEnabled { consoleEndpointStr := strings.Join(stripStandardPorts(getConsoleEndpoints(), globalMinioConsoleHost), " ") - logger.Info(color.Blue("\nConsole: ") + color.Bold(fmt.Sprintf("%s ", consoleEndpointStr))) + logger.Info(color.Blue("Console: ") + color.Bold(fmt.Sprintf("%s ", consoleEndpointStr))) if color.IsTerminal() && (!globalCLIContext.Anonymous && !globalCLIContext.JSON) { logger.Info(color.Blue("RootUser: ") + color.Bold(fmt.Sprintf("%s ", cred.AccessKey))) logger.Info(color.Blue("RootPass: ") + color.Bold(fmt.Sprintf("%s ", cred.SecretKey))) diff --git a/internal/config/subnet/api-key.go b/internal/config/subnet/config.go similarity index 70% rename from internal/config/subnet/api-key.go rename to internal/config/subnet/config.go index f1bb1859c..67bccfe2f 100644 --- a/internal/config/subnet/api-key.go +++ b/internal/config/subnet/config.go @@ -18,6 +18,10 @@ package subnet import ( + "net/http" + "net/url" + "strings" + "github.com/minio/minio/internal/config" "github.com/minio/pkg/env" xnet "github.com/minio/pkg/net" @@ -49,10 +53,13 @@ type Config struct { // The HTTP(S) proxy URL to use for connecting to SUBNET ProxyURL *xnet.URL `json:"proxy_url"` + + // Transport configured with proxy_url if set optionally. + transport *http.Transport } // LookupConfig - lookup config and override with valid environment settings if any. -func LookupConfig(kvs config.KVS) (cfg Config, err error) { +func LookupConfig(kvs config.KVS, transport http.RoundTripper) (cfg Config, err error) { if err = config.CheckValidKeys(config.SubnetSubSys, kvs, DefaultKVS); err != nil { return cfg, err } @@ -63,10 +70,24 @@ func LookupConfig(kvs config.KVS) (cfg Config, err error) { if err != nil { return cfg, err } + } - cfg.License = env.Get(config.EnvMinIOSubnetLicense, kvs.Get(config.License)) - cfg.APIKey = env.Get(config.EnvMinIOSubnetAPIKey, kvs.Get(config.APIKey)) + cfg.License = strings.TrimSpace(env.Get(config.EnvMinIOSubnetLicense, kvs.Get(config.License))) + cfg.APIKey = strings.TrimSpace(env.Get(config.EnvMinIOSubnetAPIKey, kvs.Get(config.APIKey))) + + if transport == nil { + // when transport is nil, it means we are just validating the + // inputs not performing any network calls. + return cfg, nil + } + + // Make sure to clone the transport before editing the ProxyURL + ctransport := transport.(*http.Transport).Clone() + if cfg.ProxyURL != nil { + ctransport.Proxy = http.ProxyURL((*url.URL)(cfg.ProxyURL)) + } + cfg.transport = ctransport return cfg, nil } diff --git a/cmd/subnet-utils.go b/internal/config/subnet/subnet.go similarity index 51% rename from cmd/subnet-utils.go rename to internal/config/subnet/subnet.go index cdcf90342..eecacb55c 100644 --- a/cmd/subnet-utils.go +++ b/internal/config/subnet/subnet.go @@ -15,7 +15,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -package cmd +package subnet import ( "bytes" @@ -25,58 +25,20 @@ import ( "io" "io/ioutil" "net/http" - "net/url" "time" xhttp "github.com/minio/minio/internal/http" ) const ( - subnetRespBodyLimit = 1 << 20 // 1 MiB - callhomeURL = "https://subnet.min.io/api/callhome" - callhomeURLDev = "http://localhost:9000/api/callhome" + respBodyLimit = 1 << 20 // 1 MiB ) -func httpClient(timeout time.Duration) *http.Client { - return &http.Client{ - Timeout: timeout, - Transport: globalProxyTransport, +// Post submit 'payload' to specified URL +func (c Config) Post(reqURL string, payload interface{}) (string, error) { + if len(c.APIKey) == 0 { + return "", errors.New("Deployment is not registered with SUBNET. Please register the deployment via 'mc support register ALIAS'") } -} - -func subnetHTTPDo(req *http.Request) (*http.Response, error) { - client := httpClient(10 * time.Second) - if globalSubnetConfig.ProxyURL != nil { - client.Transport.(*http.Transport).Proxy = http.ProxyURL((*url.URL)(globalSubnetConfig.ProxyURL)) - } - return client.Do(req) -} - -func subnetReqDo(r *http.Request, authToken string) (string, error) { - r.Header.Set("Authorization", authToken) - r.Header.Set("Content-Type", "application/json") - - resp, err := subnetHTTPDo(r) - if resp != nil { - defer xhttp.DrainBody(resp.Body) - } - if err != nil { - return "", err - } - - respBytes, err := ioutil.ReadAll(io.LimitReader(resp.Body, subnetRespBodyLimit)) - if err != nil { - return "", err - } - respStr := string(respBytes) - - if resp.StatusCode == http.StatusOK { - return respStr, nil - } - return respStr, fmt.Errorf("SUBNET request failed with code %d and error: %s", resp.StatusCode, respStr) -} - -func subnetPostReq(reqURL string, payload interface{}, authToken string) (string, error) { body, err := json.Marshal(payload) if err != nil { return "", err @@ -85,18 +47,30 @@ func subnetPostReq(reqURL string, payload interface{}, authToken string) (string if err != nil { return "", err } - return subnetReqDo(r, authToken) -} -func sendCallhomeInfo(ch CallhomeInfo) error { - if len(globalSubnetConfig.APIKey) == 0 { - return errors.New("Cluster is not registered with SUBNET. Please register by running 'mc support register ALIAS'") + r.Header.Set("Authorization", c.APIKey) + r.Header.Set("Content-Type", "application/json") + + client := &http.Client{ + Timeout: 10 * time.Second, + Transport: c.transport, } - url := callhomeURL - if globalIsCICD { - url = callhomeURLDev + resp, err := client.Do(r) + if err != nil { + return "", err } - _, err := subnetPostReq(url, ch, globalSubnetConfig.APIKey) - return err + defer xhttp.DrainBody(resp.Body) + + respBytes, err := ioutil.ReadAll(io.LimitReader(resp.Body, respBodyLimit)) + if err != nil { + return "", err + } + respStr := string(respBytes) + + if resp.StatusCode == http.StatusOK { + return respStr, nil + } + + return respStr, fmt.Errorf("SUBNET request failed with code %d and error: %s", resp.StatusCode, respStr) }