<commit_before>// 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"
	"github.com/minio/mc/pkg/probe"
	"github.com/minio/pkg/console"
)

const licRegisterMsgTag = "licenseRegisterMessage"

var licenseRegisterFlags = append([]cli.Flag{
	cli.StringFlag{
		Name:  "name",
		Usage: "Specify the name to associate to this MinIO cluster in SUBNET",
	},
}, subnetCommonFlags...)

var licenseRegisterCmd = cli.Command{
	Name:         "register",
	Usage:        "register with MinIO Subscription Network",
	OnUsageError: onUsageError,
	Action:       mainLicenseRegister,
	Before:       setGlobalsFromContext,
	Flags:        append(licenseRegisterFlags, supportGlobalFlags...),
	CustomHelpTemplate: `NAME:
  {{.HelpName}} - {{.Usage}}

USAGE:
  {{.HelpName}} TARGET

FLAGS:
  {{range .VisibleFlags}}{{.}}
  {{end}}
EXAMPLES:
  1. Register MinIO cluster at alias 'play' on SUBNET, using api key for auth
     {{.Prompt}} {{.HelpName}} play --api-key <KEY>

  2. Register MinIO cluster at alias 'play' on SUBNET, using api key for auth,
     and "play-cluster" as the preferred name for the cluster on SUBNET.
     {{.Prompt}} {{.HelpName}} play --api-key <KEY> --name play-cluster

  3. Register MinIO cluster at alias 'play' on SUBNET in an airgapped environment
     {{.Prompt}} {{.HelpName}} play --airgap

  4. Register MinIO cluster at alias 'play' on SUBNET, using alias as the cluster name.
     This asks for SUBNET credentials if the cluster is not already registered.
     {{.Prompt}} {{.HelpName}} play
`,
}

type licRegisterMessage struct {
	Status string `json:"status"`
	Alias  string `json:"-"`
	Action string `json:"action,omitempty"`
	Type   string `json:"type"`
	URL    string `json:"url,omitempty"`
}

// String colorized license register message
func (li licRegisterMessage) String() string {
	var msg string
	switch li.Type {
	case "online":
		msg = fmt.Sprintf("%s %s successfully.", li.Alias, li.Action)
	case "offline":
		msg = fmt.Sprintln("Open the following URL in the browser to register", li.Alias, "on SUBNET:")
		msg += li.URL
	}
	return console.Colorize(licRegisterMsgTag, msg)
}

// JSON jsonified license register message
func (li licRegisterMessage) JSON() string {
	jsonBytes, e := json.MarshalIndent(li, "", " ")
	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")

	return string(jsonBytes)
}

// checkLicenseRegisterSyntax - validate arguments passed by a user
func checkLicenseRegisterSyntax(ctx *cli.Context) {
	if len(ctx.Args()) == 0 || len(ctx.Args()) > 1 {
		showCommandHelpAndExit(ctx, "register", 1) // last argument is exit code
	}
}

// ClusterRegistrationReq - JSON payload of the subnet api for cluster registration
// Contains a registration token created by base64 encoding  of the registration info
type ClusterRegistrationReq struct {
	Token string `json:"token"`
}

// ClusterRegistrationInfo - Information stored in the cluster registration token
type ClusterRegistrationInfo struct {
	DeploymentID string      `json:"deployment_id"`
	ClusterName  string      `json:"cluster_name"`
	UsedCapacity uint64      `json:"used_capacity"`
	Info         ClusterInfo `json:"info"`
}

// ClusterInfo - The "info" sub-node of the cluster registration information struct
// Intended to be extensible i.e. more fields will be added as and when required
type ClusterInfo struct {
	MinioVersion    string `json:"minio_version"`
	NoOfServerPools int    `json:"no_of_server_pools"`
	NoOfServers     int    `json:"no_of_servers"`
	NoOfDrives      int    `json:"no_of_drives"`
	NoOfBuckets     uint64 `json:"no_of_buckets"`
	NoOfObjects     uint64 `json:"no_of_objects"`
	TotalDriveSpace uint64 `json:"total_drive_space"`
	UsedDriveSpace  uint64 `json:"used_drive_space"`
}

// SubnetLoginReq - JSON payload of the SUBNET login api
type SubnetLoginReq struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

// SubnetMFAReq - JSON payload of the SUBNET mfa api
type SubnetMFAReq struct {
	Username string `json:"username"`
	OTP      string `json:"otp"`
	Token    string `json:"token"`
}

func mainLicenseRegister(ctx *cli.Context) error {
	console.SetColor(licRegisterMsgTag, color.New(color.FgGreen, color.Bold))<commit_msg>Show airgapped registration link in different color (#4282)<commit_after>// 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"
	"github.com/minio/mc/pkg/probe"
	"github.com/minio/pkg/console"
)

const (
	licRegisterMsgTag  = "licenseRegisterMessage"
	licRegisterLinkTag = "licenseRegisterLink"
)

var licenseRegisterFlags = append([]cli.Flag{
	cli.StringFlag{
		Name:  "name",
		Usage: "Specify the name to associate to this MinIO cluster in SUBNET",
	},
}, subnetCommonFlags...)

var licenseRegisterCmd = cli.Command{
	Name:         "register",
	Usage:        "register with MinIO Subscription Network",
	OnUsageError: onUsageError,
	Action:       mainLicenseRegister,
	Before:       setGlobalsFromContext,
	Flags:        append(licenseRegisterFlags, supportGlobalFlags...),
	CustomHelpTemplate: `NAME:
  {{.HelpName}} - {{.Usage}}

USAGE:
  {{.HelpName}} TARGET

FLAGS:
  {{range .VisibleFlags}}{{.}}
  {{end}}
EXAMPLES:
  1. Register MinIO cluster at alias 'play' on SUBNET, using api key for auth
     {{.Prompt}} {{.HelpName}} play --api-key <KEY>

  2. Register MinIO cluster at alias 'play' on SUBNET, using api key for auth,
     and "play-cluster" as the preferred name for the cluster on SUBNET.
     {{.Prompt}} {{.HelpName}} play --api-key <KEY> --name play-cluster

  3. Register MinIO cluster at alias 'play' on SUBNET in an airgapped environment
     {{.Prompt}} {{.HelpName}} play --airgap

  4. Register MinIO cluster at alias 'play' on SUBNET, using alias as the cluster name.
     This asks for SUBNET credentials if the cluster is not already registered.
     {{.Prompt}} {{.HelpName}} play
`,
}

type licRegisterMessage struct {
	Status string `json:"status"`
	Alias  string `json:"-"`
	Action string `json:"action,omitempty"`
	Type   string `json:"type"`
	URL    string `json:"url,omitempty"`
}

// String colorized license register message
func (li licRegisterMessage) String() string {
	var msg string
	switch li.Type {
	case "online":
		msg = console.Colorize(licRegisterMsgTag, fmt.Sprintf("%s %s successfully.", li.Alias, li.Action))
	case "offline":
		msg = fmt.Sprintln("Open the following URL in the browser to register", li.Alias, "on SUBNET:")
		msg = console.Colorize(licRegisterMsgTag, msg) + console.Colorize(licRegisterLinkTag, li.URL)
	}
	return msg
}

// JSON jsonified license register message
func (li licRegisterMessage) JSON() string {
	jsonBytes, e := json.MarshalIndent(li, "", " ")
	fatalIf(probe.NewError(e), "Unable to marshal into JSON.")

	return string(jsonBytes)
}

// checkLicenseRegisterSyntax - validate arguments passed by a user
func checkLicenseRegisterSyntax(ctx *cli.Context) {
	if len(ctx.Args()) == 0 || len(ctx.Args()) > 1 {
		showCommandHelpAndExit(ctx, "register", 1) // last argument is exit code
	}
}

// ClusterRegistrationReq - JSON payload of the subnet api for cluster registration
// Contains a registration token created by base64 encoding  of the registration info
type ClusterRegistrationReq struct {
	Token string `json:"token"`
}

// ClusterRegistrationInfo - Information stored in the cluster registration token
type ClusterRegistrationInfo struct {
	DeploymentID string      `json:"deployment_id"`
	ClusterName  string      `json:"cluster_name"`
	UsedCapacity uint64      `json:"used_capacity"`
	Info         ClusterInfo `json:"info"`
}

// ClusterInfo - The "info" sub-node of the cluster registration information struct
// Intended to be extensible i.e. more fields will be added as and when required
type ClusterInfo struct {
	MinioVersion    string `json:"minio_version"`
	NoOfServerPools int    `json:"no_of_server_pools"`
	NoOfServers     int    `json:"no_of_servers"`
	NoOfDrives      int    `json:"no_of_drives"`
	NoOfBuckets     uint64 `json:"no_of_buckets"`
	NoOfObjects     uint64 `json:"no_of_objects"`
	TotalDriveSpace uint64 `json:"total_drive_space"`
	UsedDriveSpace  uint64 `json:"used_drive_space"`
}

// SubnetLoginReq - JSON payload of the SUBNET login api
type SubnetLoginReq struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

// SubnetMFAReq - JSON payload of the SUBNET mfa api
type SubnetMFAReq struct {
	Username string `json:"username"`
	OTP      string `json:"otp"`
	Token    string `json:"token"`
}

func mainLicenseRegister(ctx *cli.Context) error {
	console.SetColor(licRegisterMsgTag, color.New(color.FgGreen, color.Bold))
	console.SetColor(licRegisterLinkTag, color.New(color.FgWhite, color.Bold))
{'fraction_non_alphanumeric': 0.10919651500484027, 'fraction_numerical': 0.005808325266214908, 'mean_word_length': 4.069185475956821, 'pattern_counts': {'":': 4, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '201779', 'n_tokens_mistral': 3192, 'n_tokens_neox': 3079, 'n_words': 1076}