Help us shape the future of Go! Take the 2026 Go Developer Survey

cmd

package
v0.62.0-rc.1 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

README

CLI Commands

This package pkg/cli/cmd is the root for our CLI commands. Commands are organized according to their hierarchy of sub-commands. For example rad resource show would be located in pkg/cli/cmd/resource/show/show.go.

Some of our command names are reserved words in Go and so they can't be used as package names. When this happens add a prefix from the parent command. eg: switch -> appswitch.

Each command is its own package to discourage accidentally sharing code between commands. Any functionality that needs to be shared should be moved to another location outside of pkg/cli/cmd.

Make sure to run make test-validate-cli to get the test coverage for the file you have added tests.

Template

Here's a useful template for a new (blank) command.

/*
Copyright 2023 The Radius Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package list

import (
	"context"

	"github.com/radius-project/radius/pkg/cli"
	"github.com/radius-project/radius/pkg/cli/cmd/commonflags"
	"github.com/radius-project/radius/pkg/cli/framework"
	"github.com/radius-project/radius/pkg/cli/output"
	"github.com/radius-project/radius/pkg/cli/workspaces"
	"github.com/spf13/cobra"
)

// NewCommand creates an instance of the `rad <fill in the blank>` command and runner.
func NewCommand(factory framework.Factory) (*cobra.Command, framework.Runner) {
	runner := NewRunner(factory)

	cmd := &cobra.Command{
		Use:     "",
		Short:   "",
		Long:    "",
		Example: ``,
		Args:    cobra.ExactArgs(2),
		RunE:    framework.RunCommand(runner),
	}

	// Define your flags here
	commonflags.AddOutputFlag(cmd)
	cmd.Flags().StringP("flagName", "k (flag's shorthand notation like w for workspace)", "", "What does the flag ask for")

	return cmd, runner
}

// Runner is the Runner implementation for the `rad <fill in the blank>` command.
type Runner struct {
	ConfigHolder *framework.ConfigHolder
	Output       output.Interface
	Format       string
	Workspace    *workspaces.Workspace
}

// NewRunner creates an instance of the runner for the `rad <fill in the blank>` command.
func NewRunner(factory framework.Factory) *Runner {
	return &Runner{
		ConfigHolder: factory.GetConfigHolder(),
		Output:       factory.GetOutput(),
	}
}

// Validate runs validation for the `rad <fill in the blank>` command.
func (r *Runner) Validate(cmd *cobra.Command, args []string) error {
	// Validate command line args and
	workspace, err := cli.RequireWorkspace(cmd, r.ConfigHolder.Config, r.ConfigHolder.DirectoryConfig)
	if err != nil {
		return err
	}
	r.Workspace = workspace

	format, err := cli.RequireOutput(cmd)
	if err != nil {
		return err
	}
	r.Format = format

	return nil
}

// Run runs the `rad <fill in the blank>` command.
func (r *Runner) Run(ctx context.Context) error {
	// Implement your command here
	return nil
}

Here's a useful template for testing the new command.

/*
Copyright 2023 The Radius Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0
    
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package show

import (
	"testing"

	"github.com/radius-project/radius/pkg/cli/framework"
	"github.com/radius-project/radius/test/radcli"
)

func Test_CommandValidation(t *testing.T) {
	radcli.SharedCommandValidation(t, NewCommand)
}

func Test_Validate(t *testing.T) {
	config := radcli.LoadConfigWithWorkspace(t)
	testcases := []radcli.ValidateInput{
		{
			Name:          "example validation test",
			Input:         []string{"show", "-s", "cool-value"},
			ExpectedValid: true,
			ConfigHolder:  framework.ConfigHolder{Config: config},
		},
	}
	radcli.SharedValidateValidation(t, NewCommand, testcases)
}

func Test_Run(t *testing.T) {
	t.Run("Validate Scenario 1", func(t *testing.T) {
		
	})
	t.Run("Validate Scenario 2", func(t *testing.T) {
		
	})
	t.Run("Validate Scenario 3", func(t *testing.T) {
		
	})
	t.Run("Validate Scenario i", func(t *testing.T) {
		
	})
}

Documentation

Index

Constants

View Source
const MsgDeletingResource = "  Deleting %s..."

MsgDeletingResource is logged for each resource before its deletion is started.

View Source
const MsgSkippingResource = "  Warning: skipping %s because its resource ID or type is missing. It must be deleted manually."

MsgSkippingResource is logged for each resource the cascade cannot delete, so the count shown in the confirmation prompt cannot quietly disagree with what was actually deleted.

Variables

This section is empty.

Functions

func ApplicationID added in v0.62.0

func ApplicationID(scope string, applicationName string) string

ApplicationID builds a fully qualified Radius.Core application ID.

func CheckIfRecipeExists

func CheckIfRecipeExists(ctx context.Context, client clients.ApplicationsManagementClient, environmentName string, recipeName string, resourceType string) (corerp.EnvironmentResource, map[string]map[string]corerp.RecipePropertiesClassification, error)

CheckIfRecipeExists checks if a given recipe exists in a given environment and returns the environment resource, recipe properties and an error if the recipe does not exist.

func DeleteOrderedResourceTypes added in v0.62.0

func DeleteOrderedResourceTypes() []string

DeleteOrderedResourceTypes returns every resource type with an explicit tier, ordered by tier and then alphabetically. It exists so that tests and documentation can describe the ordering without duplicating the table.

func DeleteResourcesInParallel added in v0.61.0

func DeleteResourcesInParallel(ctx context.Context, client clients.ApplicationsManagementClient, out output.Interface, selected []generated.GenericResource, force bool) error

DeleteResourcesInParallel deletes the given resources concurrently, tolerating resources that have already been deleted. The ID of each resource is logged before its deletion is started, because output.Interface implementations are not guaranteed to be thread-safe and logging up front keeps the output deterministic.

A managed secret selected together with its producer is deleted by the server, not separately by the CLI. After deleting the producers, this helper verifies that those secrets disappear before returning, so callers can safely remove the application or environment. If a producer is already absent, an inactive remaining secret is deleted directly.

A resource missing an ID or type cannot be addressed and is skipped with a warning rather than silently dropped, so the caller's reported count cannot disagree with what was deleted.

Deletions are limited to maxParallelDeletes at a time. On the first failure errgroup cancels the shared context, which abandons every other delete. Those deletes are left in mixed states: some were already accepted by the server and are still running there, some were canceled before the request was sent, and some queued behind the concurrency limit may never have started. The command reports a single error, so the outcome of the rest is unknown. Re-running the command is the way to converge, which is safe because deleting an already-deleted resource is treated as success.

func DeleteResourcesInTiers added in v0.62.0

func DeleteResourcesInTiers(ctx context.Context, client clients.ApplicationsManagementClient, out output.Interface, tiers [][]generated.GenericResource, force bool) error

DeleteResourcesInTiers deletes resources in dependency order, one tier at a time. A tier is only started once every delete in the previous tier has finished, so that a recipe running in an earlier tier can still resolve the environment, settings and secrets it needs.

Within a tier, deletes run concurrently up to maxParallelDeletes because nothing in a tier depends on anything else in it.

Unlike DeleteResourcesInParallel, a failure does not abandon the deletes running alongside it. Every delete in the tier is allowed to finish and all of their errors are reported together. A destructive command that stops partway through leaves the user unable to tell which resources were deleted, and re-running it is the only way to converge; reporting the full set of failures makes that outcome legible. Deleting an already-deleted resource succeeds, so re-running is safe.

Later tiers are skipped once a tier has failed, because the resources that failed to delete may still depend on them.

func DescribeResources added in v0.62.0

func DescribeResources(resources []generated.GenericResource) string

DescribeResources renders resources as a human-readable list for use in error messages, naming at most maxDescribedResources of them and summarizing the rest as a count. It returns the empty string when there are no resources, so callers must only use it when there is something to describe.

func EnvironmentID added in v0.62.0

func EnvironmentID(scope string, environmentName string) string

EnvironmentID builds a fully qualified Radius.Core environment ID.

func GetNamespace

func GetNamespace(envResource corerp.EnvironmentResource) string

GetNamespace takes in an EnvironmentResource object and returns a string representing the namespace associated with the KubernetesCompute object, or an empty string if the Compute property is not a KubernetesCompute object.

func GroupResourcesByDeleteTier added in v0.62.0

func GroupResourcesByDeleteTier(resources []generated.GenericResource) [][]generated.GenericResource

GroupResourcesByDeleteTier partitions resources into the tiers they must be deleted in, ordered from the first tier to delete to the last. The returned slice always has one entry per tier, so callers can iterate it directly; tiers with no resources are empty.

A resource missing a type cannot be classified and is placed in the first tier. Such a resource cannot be addressed for deletion at all, and is reported by the delete itself rather than dropped here, so that the set shown to the user stays consistent with the set that was acted on.

func InitializeClientFactory added in v0.48.0

func InitializeClientFactory(ctx context.Context, workspace *workspaces.Workspace) (*v20231001preview.ClientFactory, error)

InitializeClientFactory initializes a new v20231001preview.ClientFactory using the provided workspace context. It connects to the workspace and creates a new client factory with anonymous credentials. If the connection fails, it returns an error.

func InitializeRadiusCoreClientFactory added in v0.54.0

func InitializeRadiusCoreClientFactory(ctx context.Context, workspace *workspaces.Workspace) (*v20250801preview.ClientFactory, error)

InitializeRadiusCoreClientFactory initializes a new v20250801preview.ClientFactory using the provided workspace context. It connects to the workspace and creates a new client factory with anonymous credentials. If the connection fails, it returns an error.

func ListApplicationsInEnvironment added in v0.62.0

func ListApplicationsInEnvironment(ctx context.Context, client *corerpv20250801.ApplicationsClient, workspace *workspaces.Workspace, environmentID string) ([]corerpv20250801.ApplicationResource, error)

ListApplicationsInEnvironment lists the Radius.Core applications in the workspace scope whose properties.environment references the given environment ID.

func PopulateRecipePackClients added in v0.58.0

func PopulateRecipePackClients(
	ctx context.Context,
	workspace *workspaces.Workspace,
	clientsByScope map[string]*v20250801preview.RecipePacksClient,
	packIDs []string,
) error

PopulateRecipePackClients adds a RecipePacksClient to clientsByScope for every scope referenced by packIDs that is not already in the map. Callers seed the map with workspace-scope and default-scope clients before calling this function.

func ResourceID added in v0.62.0

func ResourceID(scope string, resourceType string, name string) string

ResourceID builds a fully qualified resource ID from a workspace scope, resource type and resource name.

Types

type DeleteTier added in v0.62.0

type DeleteTier int

DeleteTier identifies a stage in an ordered delete. Lower tiers are deleted first, so a resource is always deleted before the resources it depends on.

const (
	// DeleteTierWorkload covers ordinary workloads such as containers, gateways, extenders and
	// user-defined types. These are recipe-driven and depend on everything in the later tiers.
	DeleteTierWorkload DeleteTier = iota

	// DeleteTierSecuritySecret covers Radius.Security/secrets. A secret may itself be recipe-driven,
	// so it cannot be deleted alongside the workloads in the first tier. It may also supply
	// credentials to a settings resource in the final tier, so it cannot be deleted with those
	// either. It therefore needs a tier of its own between the two.
	//
	// Known limitation: secrets within this tier are deleted concurrently, and a type cannot be
	// ordered against itself. This only matters when a secret holds credentials that Radius has to
	// resolve in order to run another secret's delete recipe: deleting a resource runs its recipe,
	// and engine deleteCore resolves the credentials named by the environment's Bicep
	// authentication or Terraform settings before invoking the driver. If that credential secret is
	// deleted first, the recipe can no longer run and the remaining secret cannot be deleted.
	//
	// The secret's own data is never read for this, so ordering is irrelevant whenever the
	// environment configures no credentials at all. A public recipe registry is not on its own
	// enough to guarantee that: the Bicep driver gathers every secret named by
	// RecipeConfig.Bicep.Authentication, and the Terraform driver additionally resolves the secrets
	// backing its provider configuration and environment variables. Closing the gap entirely needs
	// ordering derived from the references between individual resources rather than their types.
	DeleteTierSecuritySecret

	// DeleteTierSecretStore covers the legacy Applications.Core/secretStores, which plays the same
	// credential-supplying role as a Radius.Security/secrets but is resolved through a separate
	// code path. It is deleted after Radius.Security/secrets so that a secret store backing a
	// secret is still resolvable while that secret is being deleted.
	DeleteTierSecretStore

	// DeleteTierApplication covers applications in both the Applications.Core and Radius.Core
	// namespaces. Applications own the workloads deleted in the earlier tiers.
	DeleteTierApplication

	// DeleteTierEnvironment covers environments in both namespaces along with the configuration
	// they reference: recipe packs, Terraform settings and Bicep settings. Every recipe-driven
	// delete in an earlier tier has to load this configuration in order to run, so it must survive
	// until all of those deletes have finished.
	DeleteTierEnvironment
)

func DeleteTierForResourceType added in v0.62.0

func DeleteTierForResourceType(resourceType string) DeleteTier

DeleteTierForResourceType returns the tier a resource type is deleted in, matching the type case-insensitively. An unrecognized type is treated as a workload.

Directories

Path Synopsis
app
bicep
env
namespace
Package namespace is a generated GoMock package.
Package namespace is a generated GoMock package.
recipepack
resource
resourceprovider
resourcetype
Package shutdown implements the `rad shutdown` command, which backs up all durable Radius state (PostgreSQL control-plane databases and Terraform state Secrets) for the current workspace to a state archive.
Package shutdown implements the `rad shutdown` command, which backs up all durable Radius state (PostgreSQL control-plane databases and Terraform state Secrets) for the current workspace to a state archive.
Package startup implements the `rad startup` command, which restores durable Radius state (PostgreSQL control-plane databases and Terraform state Secrets) previously saved by `rad shutdown` into the current workspace's running control plane.
Package startup implements the `rad startup` command, which restores durable Radius state (PostgreSQL control-plane databases and Terraform state Secrets) previously saved by `rad shutdown` into the current workspace's running control plane.
workspace

Jump to

Keyboard shortcuts

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