Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions pkg/cli/cmd/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,14 @@ func (r *Runner) Validate(cmd *cobra.Command, args []string) error {
return err
}
if envResult == nil {
return clierrors.Message("The environment %q does not exist in scope %q. Run `rad env create` first. You could also provide the environment ID if the environment exists in a different group.", r.EnvironmentNameOrID, r.Workspace.Scope)
// If a full environment ID was provided (or came from the workspace default),
// report the scope encoded in that ID rather than the possibly-different
// --group scope, since that's the scope that was actually checked.
errScope := r.Workspace.Scope
if envID, parseErr := resources.Parse(r.EnvironmentNameOrID); parseErr == nil {
errScope = envID.RootScope()
}
return clierrors.Message("The environment %q does not exist in scope %q. Run `rad env create` first. You could also provide the environment ID if the environment exists in a different group.", r.EnvironmentNameOrID, errScope)
}
r.EnvResult = envResult
}
Expand Down Expand Up @@ -551,7 +558,7 @@ func (r *Runner) getApplicationsCoreEnvironment(ctx context.Context, id string)
}

// getRadiusCoreEnvironment retrieves environment using Radius Core client and returns as Applications.Core format
func (r *Runner) getRadiusCoreEnvironment(ctx context.Context, name string) (*v20250801preview.EnvironmentResource, error) {
func (r *Runner) getRadiusCoreEnvironment(ctx context.Context, scope, name string) (*v20250801preview.EnvironmentResource, error) {
if r.RadiusCoreClientFactory == nil {
clientFactory, err := cmd.InitializeRadiusCoreClientFactory(ctx, r.Workspace)
if err != nil {
Expand All @@ -561,7 +568,7 @@ func (r *Runner) getRadiusCoreEnvironment(ctx context.Context, name string) (*v2
}

environmentClient := r.RadiusCoreClientFactory.NewEnvironmentsClient()
env, err := environmentClient.Get(ctx, r.Workspace.Scope, name, nil)
env, err := environmentClient.Get(ctx, scope, name, nil)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -629,14 +636,20 @@ func (r *Runner) FetchEnvironment(ctx context.Context, envNameOrID string) (*Env
}
}
if fetchRadiusCoreEnv {
// If it's a full ID, look it up in the scope encoded in the ID itself (which may
// differ from the workspace/--group scope, e.g. when the environment lives in a
// different resource group than the one being deployed into). Otherwise, resolve
// the name within the current workspace scope.
var radCoreEnvName string
radCoreScope := r.Workspace.Scope
if isID {
radCoreEnvName = envID.Name()
radCoreScope = envID.RootScope()
} else {
radCoreEnvName = envNameOrID
}

radiusCoreEnv, err := r.getRadiusCoreEnvironment(ctx, radCoreEnvName)
radiusCoreEnv, err := r.getRadiusCoreEnvironment(ctx, radCoreScope, radCoreEnvName)
if err != nil {
if !clients.Is404Error(err) {
return nil, err
Expand Down
72 changes: 70 additions & 2 deletions pkg/cli/cmd/deploy/deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
"github.com/radius-project/radius/pkg/corerp/api/v20250801preview"
corerpfake "github.com/radius-project/radius/pkg/corerp/api/v20250801preview/fake"
"github.com/radius-project/radius/pkg/to"
"github.com/radius-project/radius/pkg/ucp/resources"
"github.com/radius-project/radius/test/radcli"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -1922,7 +1923,7 @@ func Test_getRadiusCoreEnvironment(t *testing.T) {
command: &cobra.Command{},
args: []string{"template.bicep"},
expectedEnv: &v20250801preview.EnvironmentResource{
Name: new("/planes/radius/local/resourceGroups/test/providers/Radius.Core/environments/myenv"),
Name: new("myenv"),
},
shouldError: false,
},
Expand All @@ -1942,7 +1943,15 @@ func Test_getRadiusCoreEnvironment(t *testing.T) {
},
}

env, err := runner.getRadiusCoreEnvironment(t.Context(), tc.environmentName)
// The Radius Core EnvironmentsClient.Get API takes (scope, environmentName), not a
// full resource ID. Callers (e.g. FetchEnvironment) extract scope/name from a full
// ID before calling getRadiusCoreEnvironment, so mirror that here.
callScope, callName := scope, tc.environmentName
if parsedID, parseErr := resources.Parse(tc.environmentName); parseErr == nil {
callScope, callName = parsedID.RootScope(), parsedID.Name()
}

env, err := runner.getRadiusCoreEnvironment(t.Context(), callScope, callName)

if tc.shouldError {
require.Error(t, err)
Expand All @@ -1961,6 +1970,65 @@ func Test_getRadiusCoreEnvironment(t *testing.T) {
}
}

// Test_FetchEnvironment_RadiusCoreEnvironmentUsesOwnGroup is a regression test for
// https://github.com/radius-project/radius/issues/12573: a Radius.Core environment
// referenced by full ID (e.g. the workspace's stored default environment) must be looked
// up in the resource group encoded in that ID, not in the (possibly different)
// --group-overridden workspace scope used for the deployment itself.
func Test_FetchEnvironment_RadiusCoreEnvironmentUsesOwnGroup(t *testing.T) {
envScope := "/planes/radius/local/resourceGroups/default"
envID := envScope + "/providers/Radius.Core/environments/default"
deployScope := "/planes/radius/local/resourceGroups/test"

// Only succeed when queried in the environment's own scope; 404 for any other scope
// (such as the --group-overridden deploy scope) to catch a regression.
envServer := corerpfake.EnvironmentsServer{
Get: func(
_ context.Context,
rootScope string,
environmentName string,
_ *v20250801preview.EnvironmentsClientGetOptions,
) (resp azfake.Responder[v20250801preview.EnvironmentsClientGetResponse], errResp azfake.ErrorResponder) {
// The fake HTTP transport strips the leading slash from the rootScope path
// segment, so compare against the trimmed form.
if rootScope != strings.TrimPrefix(envScope, "/") {
errResp.SetError(fmt.Errorf("environment not found"))
errResp.SetResponseError(404, "Not Found")
return
}
resp.SetResponse(200, v20250801preview.EnvironmentsClientGetResponse{
EnvironmentResource: v20250801preview.EnvironmentResource{
Name: to.Ptr(environmentName),
ID: to.Ptr(envID),
},
}, nil)
return
},
}

factory, err := test_client_factory.NewRadiusCoreTestClientFactory(
deployScope,
func() corerpfake.EnvironmentsServer { return envServer },
nil,
)
require.NoError(t, err)

runner := &Runner{
RadiusCoreClientFactory: factory,
Workspace: &workspaces.Workspace{
// Simulates `-g test` overriding the deploy scope while the workspace's
// default environment still lives in the "default" resource group.
Scope: deployScope,
},
}

result, err := runner.FetchEnvironment(t.Context(), envID)
require.NoError(t, err)
require.NotNil(t, result, "environment should resolve using the ID's own resource group, not the --group-overridden workspace scope")
require.False(t, result.UseApplicationsCore)
require.Equal(t, envID, runner.EnvironmentNameOrID)
}

func Test_constructApplicationsCoreEnvironmentID(t *testing.T) {
runner := &Runner{
Workspace: &workspaces.Workspace{
Expand Down
Loading