Skip to content
Open
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
2 changes: 1 addition & 1 deletion app-resource-manager/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.4
2.4.5-dev
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@ type: application
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)

version: 2.4.4
version: 2.4.5
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be -dev too like the others. But why not make a release 2.4.5 out of it?

# Default appVersion will be overwritten by the build to use {repo}/VERSION. This
# value is supplied only to enable local unbuilt deployment of default released
# content.
appVersion: 2.4.4
annotations:
revision: "30701f0"
created: "2025-05-06T21:49:13Z"
appVersion: 2.4.5-dev
annotations: {}
3 changes: 2 additions & 1 deletion app-resource-manager/internal/adm/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
"context"
"fmt"

"time"

"github.com/open-edge-platform/app-orch-deployment/app-resource-manager/internal/opa"
"github.com/open-edge-platform/orch-library/go/pkg/auth"
"google.golang.org/grpc/metadata"
"time"
)

func getCtxWithToken(ctx context.Context, vaultAuthClient auth.VaultAuth) (context.Context, error) {
Expand Down
6 changes: 3 additions & 3 deletions app-resource-manager/internal/kubernetes/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,9 @@ func (m *manager) GetAppEndpointsV2(ctx context.Context, appID string, clusterID

activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
// todo: return error after IAM is ready
log.Errorf("Failed to get active project ID: %v", err)
activeProjectID = "nil"
// Return error since ActiveProjectID is mandatory
log.Errorw("Failed to get active project ID", dazl.Error(err))
return nil, err
}

serviceEndpoints, err := getServiceAppEndpointsV2(ctx, k8sClient, activeProjectID, appID, appNamespace, clusterID)
Expand Down
4 changes: 2 additions & 2 deletions app-resource-manager/internal/kubevirt/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ func (m *manager) GetVNCAddress(ctx context.Context, appID string, clusterID str

activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Errorf("failed to get active project ID, error: %v", err)
activeProjectID = "nil"
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return "", err // Return error instead of setting to "nil" and continuing
}

if tokenString == "" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,22 @@ func (s *Server) ListAppWorkloads(ctx context.Context, req *resourceapiv2.ListAp
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("AppID", req.AppId),
dazl.String("ClusterID", req.ClusterId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

appWorkloads, err := s.sbHandler.GetAppWorkLoads(ctx, req.AppId, req.ClusterId)
if err != nil {
log.Warnw("Failed to list application workloads", dazl.Stringer("request", req), dazl.Error(err))
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like TestListVirtualMachineWorkloads is failing in tests since projectID is not present

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package resource

import (
"context"

resourceapiv2 "github.com/open-edge-platform/app-orch-deployment/app-resource-manager/api/nbi/v2/resource/v2"
"github.com/open-edge-platform/orch-library/go/pkg/errors"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -61,3 +63,21 @@ func (s *NorthboundTestSuite) TestListVirtualMachineWorkloadsError() {
assert.Error(s.T(), err)
assert.Nil(s.T(), resp)
}

func (s *NorthboundTestSuite) TestListAppWorkloads_MissingActiveProjectID() {
// Create context without ActiveProjectID
ctxWithoutProjectID := context.Background()

// Convert to a test client context
testCtx := convertToTestContext(ctxWithoutProjectID)

resp, err := s.appWorkloadServiceClient.ListAppWorkloads(testCtx, &resourceapiv2.ListAppWorkloadsRequest{
ClusterId: testCluster1,
AppId: testApp1,
})

assert.Error(s.T(), err)
assert.Nil(s.T(), resp)
assert.True(s.T(), errors.IsInvalid(errors.FromGRPC(err)))
assert.Contains(s.T(), err.Error(), "activeprojectid")
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,19 @@ func (s *Server) ListAppEndpoints(ctx context.Context, req *resourceapiv2.ListAp
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("AppID", req.AppId),
dazl.String("ClusterID", req.ClusterId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package resource

import (
"context"

resourceapiv2 "github.com/open-edge-platform/app-orch-deployment/app-resource-manager/api/nbi/v2/resource/v2"
"github.com/open-edge-platform/orch-library/go/pkg/errors"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -103,3 +105,21 @@ func (s *NorthboundTestSuite) TestAppEndpointsError() {
assert.Error(s.T(), err)

}

func (s *NorthboundTestSuite) TestListAppEndpoints_MissingActiveProjectID() {
// Create context without ActiveProjectID
ctxWithoutProjectID := context.Background()

// Convert to a test client context
testCtx := convertToTestContext(ctxWithoutProjectID)

resp, err := s.endpointServiceClient.ListAppEndpoints(testCtx, &resourceapiv2.ListAppEndpointsRequest{
ClusterId: testCluster1,
AppId: testApp1,
})

assert.Error(s.T(), err)
assert.Nil(s.T(), resp)
assert.True(s.T(), errors.IsInvalid(errors.FromGRPC(err)))
assert.Contains(s.T(), err.Error(), "activeprojectid")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package resource

import (
"context"

resourceapiv2 "github.com/open-edge-platform/app-orch-deployment/app-resource-manager/api/nbi/v2/resource/v2"
"github.com/open-edge-platform/app-orch-deployment/app-resource-manager/internal/opa"
"github.com/open-edge-platform/orch-library/go/dazl"
Expand All @@ -23,8 +24,21 @@ func (s *Server) DeletePod(ctx context.Context, req *resourceapiv2.DeletePodRequ
log.Warnw("Request validation is failed", dazl.Stringer("request", req), dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("PodName", req.PodName),
dazl.String("Namespace", req.Namespace),
dazl.String("ClusterID", req.ClusterId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
package resource

import (
"context"

resourceapiv2 "github.com/open-edge-platform/app-orch-deployment/app-resource-manager/api/nbi/v2/resource/v2"
"github.com/open-edge-platform/orch-library/go/pkg/errors"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -55,3 +57,24 @@ func (s *NorthboundTestSuite) TestInvalidPodNameDeletePod() {
assert.Error(s.T(), err)

}

// TestDeletePod_MissingActiveProjectID tests the DeletePod API handler behavior when
// the request context is missing the ActiveProjectID.
func (s *NorthboundTestSuite) TestDeletePod_MissingActiveProjectID() {
// Create context without ActiveProjectID
ctxWithoutProjectID := context.Background()

// Convert to a test client context
testCtx := convertToTestContext(ctxWithoutProjectID)

resp, err := s.podServiceClient.DeletePod(testCtx, &resourceapiv2.DeletePodRequest{
ClusterId: testCluster1,
Namespace: testNamespace,
PodName: testPodName,
})

assert.Error(s.T(), err)
assert.Nil(s.T(), resp)
assert.True(s.T(), errors.IsInvalid(errors.FromGRPC(err)))
assert.Contains(s.T(), err.Error(), "activeprojectid")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package resource

import (
"context"

resourceapiv2 "github.com/open-edge-platform/app-orch-deployment/app-resource-manager/api/nbi/v2/resource/v2"
"github.com/open-edge-platform/app-orch-deployment/app-resource-manager/internal/opa"
"github.com/open-edge-platform/orch-library/go/dazl"
Expand All @@ -25,8 +26,18 @@ func (s *Server) GetVNC(ctx context.Context, req *resourceapiv2.GetVNCRequest) (
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("AppID", req.AppId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

Expand Down Expand Up @@ -55,8 +66,18 @@ func (s *Server) RestartVirtualMachine(ctx context.Context, req *resourceapiv2.R
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("AppID", req.AppId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

Expand All @@ -83,8 +104,18 @@ func (s *Server) StartVirtualMachine(ctx context.Context, req *resourceapiv2.Sta
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("AppID", req.AppId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

Expand Down Expand Up @@ -113,8 +144,18 @@ func (s *Server) StopVirtualMachine(ctx context.Context, req *resourceapiv2.Stop
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

// Validate ActiveProjectID is present and valid
activeProjectID, err := opa.GetActiveProjectID(ctx)
if err != nil {
log.Warnw("ActiveProjectID validation failed", dazl.Error(err))
return nil, errors.Status(errors.NewInvalid(err.Error())).Err()
}

if err := opa.IsAuthorized(ctx, req, s.opaClient); err != nil {
log.Warnw("Access denied by OPA rules", dazl.Error(err))
log.Warnw("Access denied by OPA rules",
dazl.String("AppID", req.AppId),
dazl.String("ProjectID", activeProjectID),
dazl.Error(err))
return nil, errors.Status(errors.NewForbidden(err.Error())).Err()
}

Expand Down
Loading
Loading