fix: syncPolicy.automated.enabled=false does not disable automated sync (#24254)

Signed-off-by: downfa11 <downfa11@naver.com>
This commit is contained in:
downfa11 2025-09-04 01:03:59 +09:00 committed by GitHub
parent f2233ccd67
commit 4c9291152b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 879 additions and 782 deletions

2
assets/swagger.json generated
View file

@ -10540,7 +10540,7 @@
"type": "boolean",
"title": "AllowEmpty allows apps have zero live resources (default: false)"
},
"enable": {
"enabled": {
"type": "boolean",
"title": "Enable allows apps to explicitly control automated sync"
},

File diff suppressed because it is too large Load diff

View file

@ -2626,7 +2626,7 @@ message SyncPolicyAutomated {
optional bool allowEmpty = 3;
// Enable allows apps to explicitly control automated sync
optional bool enable = 4;
optional bool enabled = 4;
}
// SyncSource specifies a location from which hydrated manifests may be synced. RepoURL is assumed based on the

View file

@ -1532,7 +1532,7 @@ type SyncPolicyAutomated struct {
// AllowEmpty allows apps have zero live resources (default: false)
AllowEmpty bool `json:"allowEmpty,omitempty" protobuf:"bytes,3,opt,name=allowEmpty"`
// Enable allows apps to explicitly control automated sync
Enabled *bool `json:"enabled,omitempty" protobuf:"bytes,4,opt,name=enable"`
Enabled *bool `json:"enabled,omitempty" protobuf:"bytes,4,opt,name=enabled"`
}
// SyncStrategy controls the manner in which a sync is performed

View file

@ -221,7 +221,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh
<div className='application-status-panel__item-value__revision show-for-large'>{syncStatusMessage(application)}</div>
</div>
<div className='application-status-panel__item-name' style={{marginBottom: '0.5em'}}>
{application.spec.syncPolicy?.automated ? 'Auto sync is enabled.' : 'Auto sync is not enabled.'}
{application.spec.syncPolicy?.automated && application.spec.syncPolicy.automated.enabled !== false ? 'Auto sync is enabled.' : 'Auto sync is not enabled.'}
</div>
{application.status &&
application.status.sync &&

View file

@ -0,0 +1,47 @@
import { Application } from '../../../shared/models';
function isAutoSyncEnabled(app: Application): boolean {
return !!(app.spec.syncPolicy?.automated && app.spec.syncPolicy.automated.enabled !== false);
}
test('automated.enabled is true, return to `true`.', () => {
const enabledApp = {
spec: {
syncPolicy: {
automated: { enabled: true }
}
}
} as Application;
expect(isAutoSyncEnabled(enabledApp)).toBe(true);
});
test('automated.enabled is undefined, return to `true`.', () => {
const enabledApp = {
spec: {
syncPolicy: { automated: {} }
}
} as Application;
expect(isAutoSyncEnabled(enabledApp)).toBe(true);
});
test('automated.enabled is false, return to `false`.', () => {
const disabledApp = {
spec: {
syncPolicy: { automated: { enabled: false } }
}
} as Application;
expect(isAutoSyncEnabled(disabledApp)).toBe(false);
});
test('syncPolicy is nil, return to `false`', () => {
const noSyncPolicyApp = { spec: {} } as Application;
expect(isAutoSyncEnabled(noSyncPolicyApp)).toBe(false);
});
test('automated is nil, return to `false`.', () => {
const noAutomatedApp = { spec: { syncPolicy: {} } } as Application;
expect(isAutoSyncEnabled(noAutomatedApp)).toBe(false);
});

View file

@ -515,9 +515,13 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => {
<div className='white-box__details'>
<p>SYNC POLICY</p>
<div className='row white-box__details-row'>
<div className='columns small-3'>{(app.spec.syncPolicy && app.spec.syncPolicy.automated && <span>AUTOMATED</span>) || <span>NONE</span>}</div>
<div className='columns small-3'>
{(app.spec.syncPolicy && app.spec.syncPolicy.automated && app.spec.syncPolicy.automated.enabled !== false && <span>AUTOMATED</span>) || (
<span>NONE</span>
)}
</div>
<div className='columns small-9'>
{(app.spec.syncPolicy && app.spec.syncPolicy.automated && (
{(app.spec.syncPolicy && app.spec.syncPolicy.automated && app.spec.syncPolicy.automated.enabled !== false && (
<button className='argo-button argo-button--base' onClick={() => unsetAutoSync(ctx)}>
<Spinner show={changeSync} style={{marginRight: '5px'}} />
Disable Auto-Sync

View file

@ -0,0 +1,46 @@
import { getAutoSyncStatus } from './applications-filter';
import { SyncPolicy } from '../../../shared/models';
const AUTO_SYNC_ENABLED = 'Enabled';
const AUTO_SYNC_DISABLED = 'Disabled';
test('automated.enabled is true, return to `Enabled`.', () => {
const syncPolicy = {
automated: {
enabled: true,
prune: false,
selfHeal: false
}
} as SyncPolicy;
expect(getAutoSyncStatus(syncPolicy)).toBe(AUTO_SYNC_ENABLED);
});
test('automated.enabled is undefined, return to `Enabled`.', () => {
const syncPolicy = {
automated: {}
} as unknown as SyncPolicy;
expect(getAutoSyncStatus(syncPolicy)).toBe(AUTO_SYNC_ENABLED);
});
test('automated.enabled is false, return to `Disabled`.', () => {
const syncPolicy = {
automated: {
enabled: false,
prune: false,
selfHeal: false
}
} as SyncPolicy;
expect(getAutoSyncStatus(syncPolicy)).toBe(AUTO_SYNC_DISABLED);
});
test('syncPolicy is nil, return to `Disabled`', () => {
expect(getAutoSyncStatus(undefined)).toBe(AUTO_SYNC_DISABLED);
});
test('automated is nil, return to `Disabled`.', () => {
const syncPolicy = {} as SyncPolicy;
expect(getAutoSyncStatus(syncPolicy)).toBe(AUTO_SYNC_DISABLED);
});

View file

@ -25,8 +25,8 @@ export interface FilteredApp extends Application {
filterResult: FilterResult;
}
function getAutoSyncStatus(syncPolicy?: SyncPolicy) {
if (!syncPolicy || !syncPolicy.automated) {
export function getAutoSyncStatus(syncPolicy?: SyncPolicy) {
if (!syncPolicy || !syncPolicy.automated || syncPolicy.automated.enabled === false) {
return 'Disabled';
}
return 'Enabled';