utils

package
v0.5.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2026 License: MPL-2.0 Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultProvisionTimeout is the default wait time for provisioning operations
	// (buy, update commands that wait for the resource to become ready).
	DefaultProvisionTimeout = 10 * time.Minute

	// DefaultMutationTimeout is the default context timeout for buy/update/delete
	// commands that may take longer than the standard request timeout.
	DefaultMutationTimeout = 15 * time.Minute
)
View Source
const (
	FormatTable = "table"
	FormatJSON  = "json"
	FormatCSV   = "csv"
	FormatXML   = "xml"

	// StatusDecommissioning is used for filtering inactive resources. The SDK
	// exports STATUS_CANCELLED and STATUS_DECOMMISSIONED but not this one.
	StatusDecommissioning = "DECOMMISSIONING"
)

Variables

View Source
var (
	// Env is the target environment (prod, dev, staging). Set once via flag
	// binding before command execution; read during login. Not protected by
	// a mutex because cobra flag parsing and command execution are sequential
	// on the main goroutine.
	Env string

	// ProfileOverride is the config profile name. Same set-once semantics as Env.
	ProfileOverride string

	ValidFormats = []string{FormatTable, FormatJSON, FormatCSV, FormatXML}
)
View Source
var BuyConfirmPrompt = func(resourceType string, details []BuyConfirmDetail, noColor bool) bool {
	fmt.Println()
	if !noColor {
		fmt.Println(color.New(color.FgHiWhite, color.Bold).Sprint("Purchase Summary:"))
	} else {
		fmt.Println("Purchase Summary:")
	}
	fmt.Printf("  Resource Type: %s\n", resourceType)
	for _, d := range details {
		if d.Value != "" {
			fmt.Printf("  %s: %s\n", d.Key, d.Value)
		}
	}
	fmt.Println()
	return ConfirmPrompt("Proceed with purchase?", noColor)
}

BuyConfirmPrompt displays a resource purchase summary and asks for confirmation.

View Source
var ConfirmPrompt = func(question string, noColor bool) bool {
	var response string

	if !noColor {

		fmt.Print(color.New(color.FgHiRed).Sprint("⚠️  " + question + " "))
		fmt.Print(color.New(color.FgHiWhite, color.Bold).Sprint("[y/N]") + " ")
	} else {
		fmt.Printf("⚠️  %s [y/N] ", question)
	}

	_, err := fmt.Scanln(&response)
	if err != nil {

		if err.Error() == "unexpected newline" {
			return false
		}
		return false
	}

	response = strings.ToLower(strings.TrimSpace(response))
	return response == "y" || response == "yes"
}
View Source
var Prompt = func(msg string, noColor bool) (string, error) {
	if !noColor {

		fmt.Print(color.New(color.FgHiRed, color.Bold).Sprint("❯ " + msg + " "))
	} else {
		fmt.Print("❯ " + msg + " ")
	}

	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(input), nil
}
View Source
var ResourcePrompt = func(resourceType string, msg string, noColor bool) (string, error) {

	icon := "❯"
	switch strings.ToLower(resourceType) {
	case "port":
		icon = "🔌"
	case "mve":
		icon = "🌐"
	case "mcr":
		icon = "🛰️"
	case "vxc":
		icon = "🔗"
	case "location":
		icon = "📍"
	}

	if !noColor {
		fmt.Print(color.New(color.FgHiRed, color.Bold).Sprint(icon + " " + msg + " "))
	} else {
		fmt.Print(icon + " " + msg + " ")
	}

	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(input), nil
}
View Source
var ResourceTagsPrompt = func(noColor bool) (map[string]string, error) {
	addTags := ConfirmPrompt("Would you like to add resource tags?", noColor)
	if !addTags {
		return nil, nil
	}

	tags := make(map[string]string)
	fmt.Println("Enter tags (key and value). Enter empty key to finish.")

	for {

		key, err := Prompt("Tag key:", noColor)
		if err != nil {
			return nil, err
		}

		if key == "" {
			break
		}

		value, err := Prompt("Tag value for '"+key+"':", noColor)
		if err != nil {
			return nil, err
		}

		tags[key] = value
	}

	if len(tags) > 0 {
		fmt.Println("Tags added:")
		for k, v := range tags {
			fmt.Printf("  %s: %s\n", k, v)
		}
	}

	return tags, nil
}
View Source
var UpdateResourceTagsPrompt = func(existingTags map[string]string, noColor bool) (map[string]string, error) {

	if !noColor {
		fmt.Println(color.New(color.FgHiYellow).Sprint("⚠️  Warning: This operation will replace all existing tags with the new set of tags you define."))
	} else {
		fmt.Println("⚠️  Warning: This operation will replace all existing tags with the new set of tags you define.")
	}

	if len(existingTags) > 0 {
		fmt.Println("Current tags:")
		for k, v := range existingTags {
			fmt.Printf("  %s: %s\n", k, v)
		}
	} else {
		fmt.Println("No existing tags found.")
	}

	proceed := ConfirmPrompt("Do you want to continue with updating tags?", noColor)
	if !proceed {
		return nil, fmt.Errorf("tag update cancelled by user")
	}

	if len(existingTags) > 0 {
		fmt.Println("\nChoose how you want to update tags:")
		fmt.Println("1. Start with a clean slate (remove all existing tags)")
		fmt.Println("2. Start with existing tags and modify them")

		choice, err := Prompt("Enter choice (1 or 2):", noColor)
		if err != nil {
			return nil, err
		}

		tags := make(map[string]string)
		if choice == "2" {

			for k, v := range existingTags {
				tags[k] = v
			}

			fmt.Println("\nYou can now modify, add, or remove tags.")
			fmt.Println("To remove a tag, enter its key and an empty value.")
		} else if choice != "1" {
			return nil, fmt.Errorf("invalid choice: %s", choice)
		}

		fmt.Println("\nEnter tags (key and value). Enter empty key to finish.")
		for {

			key, err := Prompt("Tag key:", noColor)
			if err != nil {
				return nil, err
			}

			if key == "" {
				break
			}

			value, err := Prompt(fmt.Sprintf("Tag value for '%s':", key), noColor)
			if err != nil {
				return nil, err
			}

			if value == "" && tags[key] != "" {
				delete(tags, key)
				fmt.Printf("  Removed tag: %s\n", key)
			} else if value != "" {
				tags[key] = value
				fmt.Printf("  Updated tag: %s: %s\n", key, value)
			}
		}

		fmt.Println("\nFinal tags that will be applied:")
		if len(tags) > 0 {
			for k, v := range tags {
				fmt.Printf("  %s: %s\n", k, v)
			}
		} else {
			fmt.Println("  No tags - all existing tags will be removed")
		}

		confirmApply := ConfirmPrompt("Apply these changes?", noColor)
		if !confirmApply {
			return nil, fmt.Errorf("tag update cancelled by user")
		}

		return tags, nil
	} else {

		return ResourceTagsPrompt(noColor)
	}
}

Functions

func ApplyLimitAndPrint added in v0.5.9

func ApplyLimitAndPrint[T any](
	items []T,
	limit int,
	outputFormat string,
	noColor bool,
	emptyMessage string,
	printFunc func([]T, string, bool) error,
) error

ApplyLimitAndPrint handles the common post-filter pipeline for all List commands: validate and apply --limit, check for empty results, and print.

Returns nil (no error) when items is empty. If outputFormat is table, it also prints an informational message.

func ContextFromCmd added in v0.5.8

func ContextFromCmd(cmd *cobra.Command) (context.Context, context.CancelFunc)

ContextFromCmd creates a context with timeout from the command's --timeout flag. If no timeout flag is set or the duration is zero or negative, defaults to 90 seconds.

func ContextFromCmdWithDefault added in v0.5.8

func ContextFromCmdWithDefault(cmd *cobra.Command, defaultTimeout time.Duration) (context.Context, context.CancelFunc)

ContextFromCmdWithDefault creates a context with timeout from the command's --timeout flag, falling back to defaultTimeout when the flag is not set or is zero or negative. Use this for long-running operations (e.g. provisioning) where the operation-appropriate default differs from the global 90-second default.

func Filter added in v0.5.8

func Filter[T any](items []T, predicate func(T) bool) []T

Filter returns a new slice containing only the elements of items for which predicate returns true. Returns nil (not an empty slice) when no elements match, consistent with the existing filter functions across this codebase. Callers need not special-case a nil result: len(nil) == 0 in Go.

func GetCurrentEnv

func GetCurrentEnv() string

func ListResourceTags added in v0.5.1

func ListResourceTags(resourceType, uid string, noColor bool, outputFormat string, listFunc TagListerFunc) error

ListResourceTags handles the common pattern of listing resource tags: setting output format, calling the list function, converting to ResourceTag slice, sorting, and printing output.

func ParseResourceTagsInput added in v0.5.1

func ParseResourceTagsInput(cmd *cobra.Command) (map[string]string, error)

ParseResourceTagsInput reads resource tags from --json or --json-file flags.

func ResolveInput added in v0.5.9

func ResolveInput[T any](cfg InputConfig[T]) (T, error)

ResolveInput determines which input mode the user chose (JSON, flags, or interactive) and delegates to the appropriate builder function.

Precedence: JSON > flags > interactive > error.

func ShouldDisableColors added in v0.3.2

func ShouldDisableColors() bool

func UpdateResourceTags added in v0.5.1

func UpdateResourceTags(opts UpdateTagsOptions) error

UpdateResourceTags handles the common pattern of updating resource tags: fetching existing tags, parsing input (interactive/JSON/JSON file), calling the update function, and printing results.

func WatchLoop added in v0.5.8

func WatchLoop(ctx context.Context, cfg WatchConfig, pollFn func(ctx context.Context) (string, error)) error

WatchLoop runs pollFn repeatedly at the configured interval until interrupted. pollFn should fetch and print its output, returning the current status string for transition tracking.

func WrapAPIError added in v0.5.5

func WrapAPIError(err error, resourceType, resourceUID string) error

WrapAPIError wraps a megaport SDK error with an actionable message based on the HTTP status code. Falls back to the original error if the type cannot be extracted.

func WrapColorAwareRunE

func WrapColorAwareRunE(fn func(cmd *cobra.Command, args []string, noColor bool) error) func(cmd *cobra.Command, args []string) error

WrapColorAwareRunE combines WrapRunE and WrapCommandFunc to handle both error formatting and passing the noColor flag to command functions.

func WrapOutputFormatRunE

func WrapOutputFormatRunE(fn func(cmd *cobra.Command, args []string, noColor bool, format string) error) func(cmd *cobra.Command, args []string) error

WrapOutputFormatRunE handles both output format and color settings in command functions. This wrapper takes a function that needs both output format and noColor parameters.

func WrapRunE

func WrapRunE(runE func(cmd *cobra.Command, args []string) error) func(cmd *cobra.Command, args []string) error

WrapRunE wraps a RunE function to set SilenceUsage to true if an error occurs and formats the error message.

Types

type BuyConfirmDetail added in v0.5.4

type BuyConfirmDetail struct {
	Key   string
	Value string
}

BuyConfirmDetail represents a key-value detail line in the purchase summary.

type InputConfig added in v0.5.9

type InputConfig[T any] struct {
	// ResourceName is used in the fallback error message (e.g. "port", "MCR").
	ResourceName string

	// Cmd is the cobra command whose flags are inspected.
	Cmd *cobra.Command

	// NoColor disables colored output.
	NoColor bool

	// FlagsProvided should return true when any resource-specific CLI flags
	// have been explicitly set by the user.
	FlagsProvided func() bool

	// FromJSON builds the request from --json or --json-file input.
	FromJSON func(jsonStr, jsonFile string) (T, error)

	// FromFlags builds the request from CLI flags.
	FromFlags func() (T, error)

	// FromPrompt builds the request via interactive prompts.
	// May be nil if the command does not support interactive mode.
	FromPrompt func() (T, error)
}

InputConfig configures how ResolveInput resolves the request object from one of the three input modes (JSON, flags, interactive prompts).

type TagListerFunc added in v0.5.1

type TagListerFunc func(ctx context.Context, uid string) (map[string]string, error)

TagListerFunc is a function that lists resource tags for a given UID.

type TagUpdaterFunc added in v0.5.1

type TagUpdaterFunc func(ctx context.Context, uid string, tags map[string]string) error

TagUpdaterFunc is a function that updates resource tags for a given UID.

type UpdateTagsOptions added in v0.5.1

type UpdateTagsOptions struct {
	ResourceType  string
	UID           string
	NoColor       bool
	Cmd           *cobra.Command
	ListFunc      TagListerFunc
	UpdateFunc    TagUpdaterFunc
	ExtraTagFlags bool // When true, also check --tags, --tags-file, --resource-tags flags
}

UpdateTagsOptions contains the options for UpdateResourceTags.

type WatchConfig added in v0.5.8

type WatchConfig struct {
	Interval     time.Duration
	NoColor      bool
	OutputFormat string
	ResourceType string // "Port", "VXC", "MCR", "MVE"
	ResourceUID  string
}

WatchConfig holds configuration for the watch loop.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL