Skip to content

Commit a94f162

Browse files
committed
Expose installationID and serverURL to deep link and API contexts
Signed-off-by: Atif Ali <[email protected]>
1 parent d1ccd57 commit a94f162

File tree

6 files changed

+94
-11
lines changed

6 files changed

+94
-11
lines changed

server/application/application.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,7 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *v1alpha1.Appl
13171317
return status.Errorf(codes.InvalidArgument, "application spec for %s is invalid: %s", app.Name, argo.FormatAppConditions(conditions))
13181318
}
13191319

1320+
app.Spec = *argo.NormalizeApplicationSpec(&app.Spec)
13201321
return nil
13211322
}
13221323

@@ -2164,8 +2165,19 @@ func (s *Server) ListLinks(ctx context.Context, req *application.ListAppLinksReq
21642165
return nil, err
21652166
}
21662167

2168+
// Create deep links object with managed-by URL
21672169
deepLinksObject := deeplinks.CreateDeepLinksObject(nil, obj, clstObj, nil)
21682170

2171+
// If no managed-by URL is set, use the current instance's URL
2172+
if deepLinksObject[deeplinks.ManagedByURLKey] == nil {
2173+
settings, err := s.settingsMgr.GetSettings()
2174+
if err != nil {
2175+
log.Warnf("Failed to get settings: %v", err)
2176+
} else if settings.URL != "" {
2177+
deepLinksObject[deeplinks.ManagedByURLKey] = settings.URL
2178+
}
2179+
}
2180+
21692181
finalList, errorList := deeplinks.EvaluateDeepLinksResponse(deepLinksObject, obj.GetName(), deepLinks)
21702182
if len(errorList) > 0 {
21712183
log.Errorf("errorList while evaluating application deep links, %v", strings.Join(errorList, ", "))

server/cluster/cluster.go

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"fmt"
66
"net/url"
7+
"strings"
78
"time"
89

910
"github.com/argoproj/gitops-engine/pkg/utils/kube"
@@ -15,30 +16,39 @@ import (
1516
"k8s.io/client-go/kubernetes"
1617

1718
"github.com/argoproj/argo-cd/v3/common"
19+
"github.com/argoproj/argo-cd/v3/pkg/apiclient/application"
1820
"github.com/argoproj/argo-cd/v3/pkg/apiclient/cluster"
1921
appv1 "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
2022
servercache "github.com/argoproj/argo-cd/v3/server/cache"
23+
"github.com/argoproj/argo-cd/v3/server/deeplinks"
2124
"github.com/argoproj/argo-cd/v3/util/argo"
2225
"github.com/argoproj/argo-cd/v3/util/clusterauth"
2326
"github.com/argoproj/argo-cd/v3/util/db"
2427
"github.com/argoproj/argo-cd/v3/util/rbac"
28+
"github.com/argoproj/argo-cd/v3/util/settings"
29+
)
30+
31+
const (
32+
ClusterDeepLinks = "cluster.deepLinks"
2533
)
2634

2735
// Server provides a Cluster service
2836
type Server struct {
29-
db db.ArgoDB
30-
enf *rbac.Enforcer
31-
cache *servercache.Cache
32-
kubectl kube.Kubectl
37+
db db.ArgoDB
38+
enf *rbac.Enforcer
39+
cache *servercache.Cache
40+
kubectl kube.Kubectl
41+
settingsMgr *settings.SettingsManager
3342
}
3443

3544
// NewServer returns a new instance of the Cluster service
36-
func NewServer(db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache, kubectl kube.Kubectl) *Server {
45+
func NewServer(db db.ArgoDB, enf *rbac.Enforcer, cache *servercache.Cache, kubectl kube.Kubectl, settingsMgr *settings.SettingsManager) *Server {
3746
return &Server{
38-
db: db,
39-
enf: enf,
40-
cache: cache,
41-
kubectl: kubectl,
47+
db: db,
48+
enf: enf,
49+
cache: cache,
50+
kubectl: kubectl,
51+
settingsMgr: settingsMgr,
4252
}
4353
}
4454

@@ -506,3 +516,31 @@ func (s *Server) InvalidateCache(ctx context.Context, q *cluster.ClusterQuery) (
506516
}
507517
return s.toAPIResponse(cls), nil
508518
}
519+
520+
func (s *Server) ListLinks(ctx context.Context, req *cluster.ListClusterLinksRequest) (*application.LinksResponse, error) {
521+
clst, err := s.getClusterAndVerifyAccess(ctx, &cluster.ClusterQuery{
522+
Name: req.GetName(),
523+
Server: req.GetServer(),
524+
}, rbac.ActionGet)
525+
if err != nil {
526+
return nil, err
527+
}
528+
529+
obj, err := kube.ToUnstructured(clst)
530+
if err != nil {
531+
return nil, fmt.Errorf("error getting cluster: %w", err)
532+
}
533+
534+
deepLinks, err := s.settingsMgr.GetDeepLinks(ClusterDeepLinks)
535+
if err != nil {
536+
return nil, fmt.Errorf("failed to read cluster deep links from configmap: %w", err)
537+
}
538+
539+
deeplinksObj := deeplinks.CreateDeepLinksObject(nil, nil, nil, obj)
540+
finalList, errorList := deeplinks.EvaluateDeepLinksResponse(deeplinksObj, obj.GetName(), deepLinks)
541+
if len(errorList) > 0 {
542+
log.Errorf("errorList while evaluating cluster deep links, %v", strings.Join(errorList, ", "))
543+
}
544+
545+
return finalList, nil
546+
}

server/cluster/cluster.proto

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ message ClusterQuery {
2626

2727
message ClusterResponse {}
2828

29+
message ListClusterLinksRequest {
30+
string name = 1;
31+
string server = 2;
32+
}
33+
2934
message ClusterCreateRequest {
3035
github.zerozr99.workers.dev.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster cluster = 1;
3136
bool upsert = 2;
@@ -80,5 +85,9 @@ service ClusterService {
8085
rpc InvalidateCache(ClusterQuery) returns (github.com.argoproj.argo_cd.v3.pkg.apis.application.v1alpha1.Cluster) {
8186
option (google.api.http).post = "/api/v1/clusters/{id.value}/invalidate-cache";
8287
}
83-
88+
89+
// ListLinks returns list of links for a cluster
90+
rpc ListLinks(ListClusterLinksRequest) returns (github.com.argoproj.argo_cd.v3.pkg.apiclient.application.LinksResponse) {
91+
option (google.api.http).get = "/api/v1/clusters/{name}/links";
92+
}
8493
}

server/deeplinks/deeplinks.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const (
3131
AppDeepLinkShortKey = "app"
3232
ClusterDeepLinkKey = "cluster"
3333
ProjectDeepLinkKey = "project"
34+
ManagedByURLKey = "managedByURL"
3435
)
3536

3637
type ClusterLinksData struct {
@@ -70,6 +71,17 @@ func CreateDeepLinksObject(resourceObj *unstructured.Unstructured, app *unstruct
7071
if app != nil {
7172
deeplinkObj[AppDeepLinkKey] = app.Object
7273
deeplinkObj[AppDeepLinkShortKey] = app.Object
74+
75+
// Add managed-by URL if present in annotations
76+
if app.Object["metadata"] != nil {
77+
if metadata, ok := app.Object["metadata"].(map[string]interface{}); ok {
78+
if annotations, ok := metadata["annotations"].(map[string]interface{}); ok {
79+
if managedByURL, ok := annotations["argocd.argoproj.io/managed-by-url"].(string); ok {
80+
deeplinkObj[ManagedByURLKey] = managedByURL
81+
}
82+
}
83+
}
84+
}
7385
}
7486
if cluster != nil {
7587
deeplinkObj[ClusterDeepLinkKey] = cluster.Object

server/project/project.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,15 @@ func (s *Server) NormalizeProjs() error {
563563
}
564564
return nil
565565
}
566+
567+
func (s *Server) getProjectEnforceRBAC(ctx context.Context, action string, name string) (*v1alpha1.AppProject, error) {
568+
if err := s.enf.EnforceErr(ctx.Value("claims"), rbac.ResourceProjects, action, name); err != nil {
569+
return nil, err
570+
}
571+
proj, err := s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Get(ctx, name, metav1.GetOptions{})
572+
if err != nil {
573+
return nil, err
574+
}
575+
proj.NormalizeJWTTokens()
576+
return proj, nil
577+
}

server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ type ArgoCDServiceSet struct {
10091009

10101010
func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet {
10111011
kubectl := kubeutil.NewKubectl()
1012-
clusterService := cluster.NewServer(a.db, a.enf, a.Cache, kubectl)
1012+
clusterService := cluster.NewServer(a.db, a.enf, a.Cache, kubectl, a.settingsMgr)
10131013
repoService := repository.NewServer(a.RepoClientset, a.db, a.enf, a.Cache, a.appLister, a.projInformer, a.Namespace, a.settingsMgr, a.HydratorEnabled)
10141014
repoCredsService := repocreds.NewServer(a.RepoClientset, a.db, a.enf, a.settingsMgr)
10151015
var loginRateLimiter func() (utilio.Closer, error)

0 commit comments

Comments
 (0)