mirror of
https://github.com/hanzoai/deploy.git
synced 2026-10-07 08:44:50 +00:00
Signed-off-by: Antoine Veuiller <[email protected]> Signed-off-by: Michael Crenshaw <[email protected]> Co-authored-by: Michael Crenshaw <[email protected]> Co-authored-by: Cursor <[email protected]>
This commit is contained in:
committed by
GitHub
co-authored by
Michael Crenshaw
Cursor
parent
c4095370d5
commit
8259401ed4
+1
-1
@@ -37,4 +37,4 @@ cmd/argocd-server/argocd-server
|
||||
|
||||
# ignore generated `.argocd-helm-dep-up` marker file; this should not be committed to git
|
||||
reposerver/repository/testdata/**/.argocd-helm-dep-up
|
||||
.claude
|
||||
.claude
|
||||
|
||||
Generated
+4
@@ -8049,6 +8049,10 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"isAppOfApps": {
|
||||
"description": "IsAppOfApps holds true if the application has any application for child resource.",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+4
@@ -6132,6 +6132,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
Generated
+4
@@ -6132,6 +6132,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
Generated
+4
@@ -6131,6 +6131,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
Generated
+4
@@ -6132,6 +6132,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
Generated
+4
@@ -6132,6 +6132,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
Generated
+4
@@ -6132,6 +6132,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
Generated
+4
@@ -6132,6 +6132,10 @@ spec:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
isAppOfApps:
|
||||
description: IsAppOfApps holds true if the application has any
|
||||
application for child resource.
|
||||
type: boolean
|
||||
type: object
|
||||
sync:
|
||||
description: Sync contains information about the application's current
|
||||
|
||||
@@ -29,10 +29,17 @@ var appFields = map[string]func(app *v1alpha1.Application) any{
|
||||
"metadata.creationTimestamp": func(app *v1alpha1.Application) any { return app.CreationTimestamp },
|
||||
"metadata.deletionTimestamp": func(app *v1alpha1.Application) any { return app.DeletionTimestamp },
|
||||
"spec": func(app *v1alpha1.Application) any { return app.Spec },
|
||||
"spec.destination": func(app *v1alpha1.Application) any { return app.Spec.Destination },
|
||||
"spec.project": func(app *v1alpha1.Application) any { return app.Spec.Project },
|
||||
"spec.source": func(app *v1alpha1.Application) any { return app.Spec.Source },
|
||||
"spec.sources": func(app *v1alpha1.Application) any { return app.Spec.Sources },
|
||||
"spec.sourceHydrator": func(app *v1alpha1.Application) any { return app.Spec.SourceHydrator },
|
||||
"spec.syncPolicy": func(app *v1alpha1.Application) any { return app.Spec.SyncPolicy },
|
||||
"status.sourceHydrator": func(app *v1alpha1.Application) any { return app.Status.SourceHydrator },
|
||||
"status.sync.status": func(app *v1alpha1.Application) any { return app.Status.Sync.Status },
|
||||
"status.health": func(app *v1alpha1.Application) any { return app.Status.Health },
|
||||
"status.summary": func(app *v1alpha1.Application) any { return app.Status.Summary },
|
||||
"status.sync.status": func(app *v1alpha1.Application) any { return app.Status.Sync.Status },
|
||||
"status.sync.revision": func(app *v1alpha1.Application) any { return app.Status.Sync.Revision },
|
||||
"status.health": func(app *v1alpha1.Application) any { return app.Status.Health },
|
||||
"status.operationState.startedAt": func(app *v1alpha1.Application) any {
|
||||
if app.Status.OperationState != nil {
|
||||
return app.Status.OperationState.StartedAt
|
||||
|
||||
+854
-823
File diff suppressed because it is too large
Load Diff
@@ -766,6 +766,9 @@ message ApplicationSummary {
|
||||
|
||||
// Images holds all images of application child resources.
|
||||
repeated string images = 2;
|
||||
|
||||
// IsAppOfApps holds true if the application has any application for child resource.
|
||||
optional bool isAppOfApps = 3;
|
||||
}
|
||||
|
||||
// ApplicationTree represents the hierarchical structure of resources associated with an Argo CD application.
|
||||
|
||||
@@ -2104,6 +2104,8 @@ type ApplicationSummary struct {
|
||||
ExternalURLs []string `json:"externalURLs,omitempty" protobuf:"bytes,1,opt,name=externalURLs"`
|
||||
// Images holds all images of application child resources.
|
||||
Images []string `json:"images,omitempty" protobuf:"bytes,2,opt,name=images"`
|
||||
// IsAppOfApps holds true if the application has any application for child resource.
|
||||
IsAppOfApps bool `json:"isAppOfApps,omitempty" protobuf:"bytes,3,opt,name=isAppOfApps"`
|
||||
}
|
||||
|
||||
// FindNode searches for a resource node in the application tree.
|
||||
@@ -2126,11 +2128,14 @@ func (t *ApplicationTree) FindNode(group string, kind string, namespace string,
|
||||
// - It extracts container images referenced in the application's resources.
|
||||
// - Additionally, it includes links from application annotations that start with `common.AnnotationKeyLinkPrefix`.
|
||||
// - The collected URLs and images are sorted alphabetically before being returned.
|
||||
// - It also determines if the Application is managing other Applications (App of Apps pattern)
|
||||
//
|
||||
// Returns an `ApplicationSummary` containing a list of unique external URLs and container images.
|
||||
// Returns an `ApplicationSummary` containing a list of unique external URLs, container images,
|
||||
// and metadata such as app of apps pattern.
|
||||
func (t *ApplicationTree) GetSummary(app *Application) ApplicationSummary {
|
||||
urlsSet := make(map[string]bool)
|
||||
imagesSet := make(map[string]bool)
|
||||
appOfApps := false
|
||||
|
||||
// Collect external URLs and container images from application nodes
|
||||
for _, node := range t.Nodes {
|
||||
@@ -2142,6 +2147,9 @@ func (t *ApplicationTree) GetSummary(app *Application) ApplicationSummary {
|
||||
for _, image := range node.Images {
|
||||
imagesSet[image] = true
|
||||
}
|
||||
if node.Group == "argoproj.io" && node.Kind == "Application" {
|
||||
appOfApps = true
|
||||
}
|
||||
}
|
||||
|
||||
// Include application-specific links from annotations
|
||||
@@ -2163,7 +2171,7 @@ func (t *ApplicationTree) GetSummary(app *Application) ApplicationSummary {
|
||||
}
|
||||
sort.Strings(images)
|
||||
|
||||
return ApplicationSummary{ExternalURLs: urls, Images: images}
|
||||
return ApplicationSummary{ExternalURLs: urls, Images: images, IsAppOfApps: appOfApps}
|
||||
}
|
||||
|
||||
// ResourceRef includes fields which uniquely identify a resource
|
||||
|
||||
@@ -4233,6 +4233,29 @@ func TestGetSummary(t *testing.T) {
|
||||
assert.Equal(t, url, summary.ExternalURLs[0])
|
||||
}
|
||||
|
||||
func TestGetAppOfAppSummary(t *testing.T) {
|
||||
app := newTestApp()
|
||||
standardTree := &ApplicationTree{
|
||||
Nodes: []ResourceNode{
|
||||
{ResourceRef: ResourceRef{Name: "any-service", Kind: "Service"}},
|
||||
},
|
||||
}
|
||||
|
||||
summary := standardTree.GetSummary(app)
|
||||
assert.Empty(t, summary.ExternalURLs)
|
||||
assert.Empty(t, summary.Images)
|
||||
assert.False(t, summary.IsAppOfApps)
|
||||
|
||||
appOfAppsTree := &ApplicationTree{
|
||||
Nodes: []ResourceNode{
|
||||
{ResourceRef: ResourceRef{Name: "children-app", Kind: "Application", Group: "argoproj.io"}},
|
||||
{ResourceRef: ResourceRef{Name: "any-service", Kind: "Service", Group: ""}},
|
||||
},
|
||||
}
|
||||
summary = appOfAppsTree.GetSummary(app)
|
||||
assert.True(t, summary.IsAppOfApps)
|
||||
}
|
||||
|
||||
func TestApplicationSourcePluginParameters_Environ_string(t *testing.T) {
|
||||
params := ApplicationSourcePluginParameters{
|
||||
{
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app
|
||||
<Spinner show={isPending} style={{marginRight: '5px'}} />
|
||||
Synchronize
|
||||
</button>{' '}
|
||||
<button onClick={() => hide()} className='argo-button argo-button--base-o'>
|
||||
<button onClick={() => hide()} qe-id='application-sync-panel-button-cancel' className='argo-button argo-button--base-o'>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -38,17 +38,21 @@ const APP_FIELDS = [
|
||||
'metadata.labels',
|
||||
'metadata.creationTimestamp',
|
||||
'metadata.deletionTimestamp',
|
||||
'spec',
|
||||
'spec.destination',
|
||||
'spec.project',
|
||||
'spec.source',
|
||||
'spec.sources',
|
||||
'spec.sourceHydrator',
|
||||
'spec.syncPolicy',
|
||||
'operation.sync',
|
||||
'status.sourceHydrator',
|
||||
'status.summary',
|
||||
'status.sync.status',
|
||||
'status.sync.revision',
|
||||
'status.health',
|
||||
'status.operationState.phase',
|
||||
'status.operationState.finishedAt',
|
||||
'status.operationState.operation.sync',
|
||||
'status.summary',
|
||||
'status.resources'
|
||||
'status.operationState.startedAt',
|
||||
'status.operationState.finishedAt'
|
||||
];
|
||||
const APP_LIST_FIELDS = ['metadata.resourceVersion', ...APP_FIELDS.map(field => `items.${field}`)];
|
||||
const APP_WATCH_FIELDS = ['result.type', ...APP_FIELDS.map(field => `result.application.${field}`)];
|
||||
@@ -192,13 +196,8 @@ const ViewPref = ({children}: {children: (pref: AppsListPreferences & {page: num
|
||||
function filterApplications(applications: models.Application[], pref: AppsListPreferences, search: string): {filteredApps: models.Application[]; filterResults: FilteredApp[]} {
|
||||
const processedApps = applications.map(app => {
|
||||
let isAppOfAppsPattern = false;
|
||||
if (app.status?.resources) {
|
||||
for (const resource of app.status.resources) {
|
||||
if (resource.kind === 'Application') {
|
||||
isAppOfAppsPattern = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (app.status.summary?.isAppOfApps === true) {
|
||||
isAppOfAppsPattern = true;
|
||||
}
|
||||
return {...app, isAppOfAppsPattern};
|
||||
});
|
||||
|
||||
+6
-2
@@ -57,11 +57,15 @@ export const ApplicationsSyncPanel = ({show, apps, hide}: {show: boolean; apps:
|
||||
onClose={() => hide()}
|
||||
header={
|
||||
<div>
|
||||
<button className='argo-button argo-button--base' disabled={isPending} onClick={() => syncHandler(form, ctx, apps)}>
|
||||
<button
|
||||
qe-id='applications-sync-panel-button-synchronize'
|
||||
className='argo-button argo-button--base'
|
||||
disabled={isPending}
|
||||
onClick={() => syncHandler(form, ctx, apps)}>
|
||||
<Spinner show={isPending} style={{marginRight: '5px'}} />
|
||||
Sync
|
||||
</button>{' '}
|
||||
<button onClick={() => hide()} className='argo-button argo-button--base-o'>
|
||||
<button onClick={() => hide()} qe-id='applications-sync-panel-button-cancel' className='argo-button argo-button--base-o'>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -524,6 +524,7 @@ export interface ApplicationCondition {
|
||||
export interface ApplicationSummary {
|
||||
externalURLs?: string[];
|
||||
images?: string[];
|
||||
isAppOfApps?: boolean;
|
||||
}
|
||||
|
||||
export interface ApplicationStatus {
|
||||
|
||||
Reference in New Issue
Block a user