diff --git a/.project b/.project new file mode 100644 index 0000000..a42866f --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + argo-cd + + + + + + + + diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 9da12bf..007c1e7 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -34,7 +34,7 @@ interface ApplicationDetailsState { page: number; - revision?: string; + revision?: string; // Which type of revision panelto show SYNC_STATUS_REVISION or OPERATION_STATE_REVISION groupedResources?: ResourceStatus[]; slidingPanelPage?: number; filteredGraph?: any[]; @@ -180,6 +180,233 @@ return ''; } + private getContent(application: models.Application, source: models.ApplicationSource, revisions: string[], revision: string) { + const renderCommitMessage = (message: string) => + message.split(/\s/).map(part => + urlPattern.test(part) ? ( + + {part}{' '} + + ) : ( + part + ' ' + ) + ); + + const getContentForChart = (aRevision: string, aSourceIndex: number, aVersionId: number, indx: number, aSource: models.ApplicationSource, sourceHeader?: JSX.Element) => { + return ( + ( + services.applications.revisionChartDetails(input.metadata.name, input.metadata.namespace, aRevision, aSourceIndex, aVersionId) + )}> + {(m: ChartDetails) => { + return m ? ( +
+ {sourceHeader && sourceHeader} +
+
+
Revision:
+
{aRevision}
+
+
+
Chart Source:
+
+ {aSource.repoURL} +
+
+
+
Helm Chart:
+
+ {aSource.chart}  + {m.home && ( + { + e.stopPropagation(); + window.open(m.home); + }}> + + + )} +
+
+ {m.description && ( +
+
Description:
+
{m.description}
+
+ )} + {m.maintainers && m.maintainers.length > 0 && ( +
+
Maintainers:
+
{m.maintainers.join(', ')}
+
+ )} +
+
+ ) : ( +
+
No Chart Source {indx + 1}
+
+
+
Revision:
+
{aRevision}
+
+
+
Chart Source:
+
+ {aSource.repoURL} +
+
+
+
Helm Chart:
+ +
+
+
+ ) + }} +
+ ) + } + + const getContentForNonChart = (aRevision: string, aSourceIndex: number, aVersionId: number, indx: number, aSource: models.ApplicationSource, sourceHeader?: JSX.Element) => { + return ( + + services.applications.revisionMetadata( + application.metadata.name, + application.metadata.namespace, + aRevision, + aSourceIndex, + aVersionId + ) + }> + {metadata => metadata ? ( +
+ {sourceHeader && sourceHeader} +
+
+
SHA:
+
+ +
+
+
+
+
+
Source:
+
+ {aSource.repoURL} +
+
+
+
+
+
Date:
+
+ +
+
+
+
+
+
Tags:
+
+ {((metadata.tags || []).length > 0 && metadata.tags.join(', ')) || 'No tags'} +
+
+
+
+
+
Author:
+
{metadata.author}
+
+
+
+
+
Message:
+
+
{renderCommitMessage(metadata.message)}
+
+
+
+
+ ) : ( +
+
Source {indx + 1}
+
+
+
SHA:
+
+ +
+
+
+
+
+
Source:
+
+ {aSource.repoURL} +
+
+
+
+ )} +
+ ) + } + let cont : JSX.Element[] = []; + const sources : models.ApplicationSource[] = application.spec.sources; + if (sources?.length > 0 && revisions) { + revisions.forEach((rev, indx) => { + if (sources[indx].chart) { + cont.push( + getContentForChart(rev, indx, getAppCurrentVersion(application), indx, sources[indx],
Source {indx + 1}
) + ); + } else { + cont.push( + getContentForNonChart(rev, indx, getAppCurrentVersion(application), indx, sources[indx],
Source {indx + 1}
) + ); + } + }) + return <>{cont}; + } else if (application.spec.source) { + if (source.chart) { + cont.push( + getContentForChart(revision, 0, 0, 0, source) + ); + } else { + cont.push( + getContentForNonChart(revision, 0, getAppCurrentVersion(application), 0, source) + ); + } + return <>{cont}; + } else { + return ( +
+
+
+
No more information available
+
+
+
+ ); + } + } + public render() { return ( @@ -283,17 +510,6 @@ : [] }); }; - - const renderCommitMessage = (message: string) => - message.split(/\s/).map(part => - urlPattern.test(part) ? ( - - {part}{' '} - - ) : ( - part + ' ' - ) - ); const {Tree, Pods, Network, List} = AppsDetailsViewKey; const zoomNum = (pref.zoom * 100).toFixed(0); const setZoom = (s: number) => { @@ -649,108 +865,13 @@ this.setConditionsStatusVisible(false)}> {conditions && } - this.setState({revision: null})}> - {this.state.revision && - (source.chart ? ( - - services.applications.revisionChartDetails(input.metadata.name, input.metadata.namespace, this.state.revision, 0, 0) - }> - {(m: ChartDetails) => ( -
-
-
-
Revision:
-
{this.state.revision}
-
-
-
Helm Chart:
-
- {source.chart}  - {m.home && ( - { - e.stopPropagation(); - window.open(m.home); - }}> - - - )} -
-
- {m.description && ( -
-
Description:
-
{m.description}
-
- )} - {m.maintainers && m.maintainers.length > 0 && ( -
-
Maintainers:
-
{m.maintainers.join(', ')}
-
- )} -
-
- )} -
- ) : ( - - services.applications.revisionMetadata( - application.metadata.name, - application.metadata.namespace, - this.state.revision, - 0, - getAppCurrentVersion(application) - ) - }> - {metadata => ( -
-
-
-
SHA:
-
- -
-
-
-
-
-
Date:
-
- -
-
-
-
-
-
Tags:
-
- {((metadata.tags || []).length > 0 && metadata.tags.join(', ')) || 'No tags'} -
-
-
-
-
-
Author:
-
{metadata.author}
-
-
-
-
-
Message:
-
-
{renderCommitMessage(metadata.message)}
-
-
-
-
- )} -
- ))} + this.setState({revision: null})}> + {this.state.revision === 'SYNC_STATUS_REVISION' && (application.status.sync.revisions || application.status.sync.revision) && + (this.getContent(application, source, application.status.sync.revisions, application.status.sync.revision)) + } + {this.state.revision === 'OPERATION_STATE_REVISION' && (application.status.operationState.syncResult.revisions || application.status.operationState.syncResult.revision) && + (this.getContent(application, source, application.status.operationState.syncResult.revisions, application.status.operationState.syncResult.revision)) + } +
+ {utils.getAppDefaultOperationSyncRevisionExtra(application)} +
) }); } diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx index 6945dad..0acf860 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx @@ -6,7 +6,7 @@ import * as models from '../../../shared/models'; import {services} from '../../../shared/services'; import {ApplicationSyncWindowStatusIcon, ComparisonStatusIcon, getAppDefaultSource, getAppDefaultSyncRevisionExtra, getAppOperationState} from '../utils'; -import {getConditionCategory, HealthStatusIcon, OperationState, syncStatusMessage, getAppDefaultSyncRevision} from '../utils'; +import {getConditionCategory, HealthStatusIcon, OperationState, syncStatusMessage, getAppDefaultSyncRevision, getAppDefaultOperationSyncRevision} from '../utils'; import {RevisionMetadataPanel} from './revision-metadata-panel'; import * as utils from '../utils'; @@ -37,7 +37,11 @@ return (
{sectionLabel(info)} - {onClick && + )}
); }; @@ -63,10 +67,12 @@ const statusExtensions = services.extensions.getStatusPanelExtensions(); let revision = getAppDefaultSyncRevision(application); + let operationStateRevision = getAppDefaultOperationSyncRevision(application); const infos = cntByCategory.get('info'); const warnings = cntByCategory.get('warning'); const errors = cntByCategory.get('error'); const source = getAppDefaultSource(application); + const hasMultipleSources = application.spec.sources && application.spec.sources.length > 0; return (
@@ -85,7 +91,7 @@ title: 'SYNC STATUS', helpContent: 'Whether or not the version of your app is up to date with your repo. You may wish to sync your app if it is out-of-sync.' }, - () => showMetadataInfo((revision += getAppDefaultSyncRevisionExtra(application))) + () => showMetadataInfo(application.status.sync ? 'SYNC_STATUS_REVISION' : null) )}
@@ -102,17 +108,21 @@
{application.spec.syncPolicy?.automated ? 'Auto sync is enabled.' : 'Auto sync is not enabled.'}
- {application.status && application.status.sync && application.status.sync.revision && revision && !application.spec.source.chart && ( -
- -
- )} + {application.status && + application.status.sync && + (hasMultipleSources + ? application.status.sync.revisions && application.status.sync.revisions[0] && application.spec.sources && !application.spec.sources[0].chart + : application.status.sync.revision && !application.spec.source.chart) && ( +
+ +
+ )}
{appOperationState && ( @@ -126,27 +136,27 @@ daysSinceLastSynchronized + ' days since last sync. Click for the status of that sync.' }, - () => showMetadataInfo((revision += getAppDefaultSyncRevisionExtra(application))) + () => showMetadataInfo(appOperationState.syncResult && (appOperationState.syncResult.revisions || appOperationState.syncResult.revision)? 'OPERATION_STATE_REVISION' : null) )}
showOperation && showOperation()}> {' '} - {appOperationState.syncResult && revision && ( + {appOperationState.syncResult && (appOperationState.syncResult.revision || appOperationState.syncResult.revisions) && (
- to + to {getAppDefaultSyncRevisionExtra(application)}
)}
{appOperationState.phase}
- {(appOperationState.syncResult && revision && ( + {(appOperationState.syncResult && operationStateRevision && ( )) ||
{appOperationState.message}
} diff --git a/ui/src/app/applications/components/test.yaml b/ui/src/app/applications/components/test.yaml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ui/src/app/applications/components/test.yaml diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index 46aeb3a..78513e7 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -676,8 +676,6 @@ } } - message += getAppDefaultSyncRevisionExtra(app); - switch (app.status.sync.status) { case appModels.SyncStatuses.Synced: return ( @@ -685,7 +683,7 @@ to{' '} {message} - {' '} + {getAppDefaultSyncRevisionExtra(app)}{' '} ); case appModels.SyncStatuses.OutOfSync: @@ -694,7 +692,7 @@ from{' '} {message} - {' '} + {getAppDefaultSyncRevisionExtra(app)}{' '} ); default: @@ -1077,6 +1075,15 @@ return app.status.sync.revisions && app.status.sync.revisions.length > 0 ? app.status.sync.revisions[0] : app.status.sync.revision; } +// getAppDefaultOperationSyncRevision gets the first app revisions from `status.operationState.syncResult.revisions` or, if that list is missing or empty, the `revision` +// field. +export function getAppDefaultOperationSyncRevision(app?: appModels.Application) { + if (!app || !app.status || !app.status.operationState || !app.status.operationState.syncResult) { + return ''; + } + return app.status.operationState.syncResult.revisions && app.status.operationState.syncResult.revisions.length > 0 ? app.status.operationState.syncResult.revisions[0] : app.status.operationState.syncResult.revision; +} + // getAppCurrentVersion gets the first app revisions from `status.sync.revisions` or, if that list is missing or empty, the `revision` // field. export function getAppCurrentVersion(app?: appModels.Application) { @@ -1099,6 +1106,19 @@ return ''; } +// getAppDefaultOperationSyncRevisionExtra gets the first app revisions from `status.operationState.syncResult.revisions` or, if that list is missing or empty, the `revision` +// field. +export function getAppDefaultOperationSyncRevisionExtra(app?: appModels.Application) { + if (!app || !app.status || !app.status.operationState || !app.status.operationState.syncResult || !app.status.operationState.syncResult.revisions) { + return 'Unknown'; + } + + if (app.status.operationState.syncResult.revisions.length > 0) { + return ` and (${app.status.operationState.syncResult.revisions.length - 1}) more`; + } + return ''; +} + export function getAppSpecDefaultSource(spec: appModels.ApplicationSpec) { return spec.sources && spec.sources.length > 0 ? spec.sources[0] : spec.source; } diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index bb88dcf..b8bd07b 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -103,6 +103,7 @@ export interface SyncOperationResult { resources: ResourceResult[]; revision: string; + revisions: string[]; } export type ResultCode = 'Synced' | 'SyncFailed' | 'Pruned' | 'PruneSkipped'; diff --git a/util/notification/expression/repo/repo.go b/util/notification/expression/repo/repo.go index ada7a35..177762b 100644 --- a/util/notification/expression/repo/repo.go +++ b/util/notification/expression/repo/repo.go @@ -4,7 +4,9 @@ "context" "encoding/json" "errors" + "fmt" "net/url" + "os" "regexp" "strings" @@ -49,17 +51,27 @@ } func getCommitMetadata(commitSHA string, app *unstructured.Unstructured, argocdService service.Service) (*shared.CommitMetadata, error) { + fmt.Fprintln(os.Stdout, "!!!!!!! ! About to call NestedString") repoURL, ok, err := unstructured.NestedString(app.Object, "spec", "source", "repoURL") if err != nil { + fmt.Fprintln(os.Stdout, "!!!!!!! NestedString err is ", err) return nil, err } if !ok { panic(errors.New("failed to get application source repo URL")) } + fmt.Fprintln(os.Stdout, "Context is ") + fmt.Fprintln(os.Stdout, "!!!!! ", context.Background()) + fmt.Fprintln(os.Stdout, "!!!!!!! ****** repoURL = ", repoURL) + fmt.Fprintln(os.Stdout, "!!!!!!! ****** commitSHA = ", commitSHA) + fmt.Fprintln(os.Stdout, "!!!!!!! ****** About to call repo GetCommitMetadata") meta, err := argocdService.GetCommitMetadata(context.Background(), repoURL, commitSHA) + fmt.Fprintln(os.Stdout, "!!!!!!! ****** Called repo GetCommitMetadata") if err != nil { + fmt.Fprintln(os.Stdout, "!!!!!!! getCommitMetadata err is ", err) return nil, err } + fmt.Fprintln(os.Stdout, "!!!!!!! returning metadata") return meta, nil }