diff --git a/cypress/e2e/po/components/unit-input.po.ts b/cypress/e2e/po/components/unit-input.po.ts index ad383387f37..d2348e69384 100644 --- a/cypress/e2e/po/components/unit-input.po.ts +++ b/cypress/e2e/po/components/unit-input.po.ts @@ -5,4 +5,8 @@ export default class UnitInputPo extends ComponentPo { setValue(value: string): Cypress.Chainable { return new LabeledInputPo(this.self().find('input')).set(value); } + + clear() { + return this.self().clear(); + } } diff --git a/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po.ts b/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po.ts index 12d14ee5f67..9af81e6cffa 100644 --- a/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po.ts +++ b/cypress/e2e/po/edit/catalog.cattle.io.clusterrepo.po.ts @@ -3,6 +3,7 @@ import NameNsDescription from '@/cypress/e2e/po/components/name-ns-description.p import ResourceDetailPo from '@/cypress/e2e/po/edit/resource-detail.po'; import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po'; import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po'; +import UnitInputPo from '@/cypress/e2e/po/components/unit-input.po'; import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po'; import CheckboxInputPo from '@/cypress/e2e/po/components/checkbox-input.po'; import SelectOrCreateAuthPo from '@/cypress/e2e/po/components/select-or-create-auth.po'; @@ -92,19 +93,19 @@ export default class AppClusterRepoEditPo extends PagePo { } ociMinWait() { - return this.self().get('[data-testid="clusterrepo-oci-min-wait-input"]').invoke('val'); + return this.self().get('[data-testid="clusterrepo-oci-min-wait-input"] input').invoke('val'); } enterOciMinWait(value: string) { - return new LabeledInputPo('[data-testid="clusterrepo-oci-min-wait-input"]').set(value); + return new UnitInputPo('[data-testid="clusterrepo-oci-min-wait-input"]').setValue(value); } ociMaxWait() { - return this.self().get('[data-testid="clusterrepo-oci-max-wait-input"]').invoke('val'); + return this.self().get('[data-testid="clusterrepo-oci-max-wait-input"] input').invoke('val'); } enterOciMaxWait(value: string) { - return new LabeledInputPo('[data-testid="clusterrepo-oci-max-wait-input"]').set(value); + return new UnitInputPo('[data-testid="clusterrepo-oci-max-wait-input"]').setValue(value); } ociMaxRetries() { diff --git a/cypress/e2e/po/edit/chart-repositories.po.ts b/cypress/e2e/po/edit/chart-repositories.po.ts index 955c23ffd1e..09526572a9d 100644 --- a/cypress/e2e/po/edit/chart-repositories.po.ts +++ b/cypress/e2e/po/edit/chart-repositories.po.ts @@ -1,5 +1,6 @@ import PagePo from '@/cypress/e2e/po/pages/page.po'; import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po'; +import UnitInputPo from '@/cypress/e2e/po/components/unit-input.po'; import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po'; import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po'; import RadioGroupInputPo from '@/cypress/e2e/po/components/radio-group-input.po'; @@ -38,11 +39,11 @@ export default class ChartRepositoriesCreateEditPo extends PagePo { } ociMinWaitInput() { - return new LabeledInputPo('[data-testid="clusterrepo-oci-min-wait-input"]'); + return new UnitInputPo('[data-testid="clusterrepo-oci-min-wait-input"]'); } ociMaxWaitInput() { - return new LabeledInputPo('[data-testid="clusterrepo-oci-max-wait-input"]'); + return new UnitInputPo('[data-testid="clusterrepo-oci-max-wait-input"]'); } authentication(): LabeledSelectPo { @@ -65,6 +66,10 @@ export default class ChartRepositoriesCreateEditPo extends PagePo { return this.authSelectOrCreate('[data-testid="clusterrepo-auth-secret"]'); } + refreshIntervalInput() { + return new UnitInputPo('[data-testid="clusterrepo-refresh-interval"]'); + } + saveAndWaitForRequests(method: string, url: string) { cy.intercept(method, url).as('request'); this.saveCreateForm().click(); diff --git a/cypress/e2e/tests/pages/manager/repositories.spec.ts b/cypress/e2e/tests/pages/manager/repositories.spec.ts index 5ef408325aa..e6b8d7b91c9 100644 --- a/cypress/e2e/tests/pages/manager/repositories.spec.ts +++ b/cypress/e2e/tests/pages/manager/repositories.spec.ts @@ -207,17 +207,18 @@ describe('Cluster Management Helm Repositories', { testIsolation: 'off', tags: [ repositoriesPage.createEditRepositories().waitForPage(); const ociUrl = 'oci://test.rancher.io/charts/mychart'; const ociMinWait = '2'; - const expectedOciMinWaitInPayload = 2; const ociMaxWait = '7'; + const refreshInterval = '12'; repositoriesPage.createEditRepositories().nameNsDescription().name().set(this.repoName); repositoriesPage.createEditRepositories().nameNsDescription().description().set(`${ this.repoName }-description`); repositoriesPage.createEditRepositories().repoRadioBtn().set(2); repositoriesPage.createEditRepositories().ociUrl().set(ociUrl); + repositoriesPage.createEditRepositories().refreshIntervalInput().setValue(refreshInterval); repositoriesPage.createEditRepositories().clusterRepoAuthSelectOrCreate().createBasicAuth('test', 'test'); - repositoriesPage.createEditRepositories().ociMinWaitInput().set(ociMinWait); + repositoriesPage.createEditRepositories().ociMinWaitInput().setValue(ociMinWait); // setting a value and removing it so in the intercept we test that the key(e.g. maxWait) is not included in the request - repositoriesPage.createEditRepositories().ociMaxWaitInput().set(ociMaxWait); + repositoriesPage.createEditRepositories().ociMaxWaitInput().setValue(ociMaxWait); repositoriesPage.createEditRepositories().ociMaxWaitInput().clear(); cy.intercept('POST', '/v1/catalog.cattle.io.clusterrepos').as('createRepository'); @@ -227,10 +228,12 @@ describe('Cluster Management Helm Repositories', { testIsolation: 'off', tags: [ cy.wait('@createRepository', { requestTimeout: 10000 }).then((req) => { expect(req.response?.statusCode).to.equal(201); expect(req.request?.body?.spec.url).to.equal(ociUrl); - expect(req.request?.body?.spec.exponentialBackOffValues.minWait).to.equal(expectedOciMinWaitInPayload); + expect(req.request?.body?.spec.exponentialBackOffValues.minWait).to.equal(Number(ociMinWait)); expect(req.request?.body?.spec.exponentialBackOffValues.maxWait).to.equal(undefined); // insecurePlainHttp should always be included in the payload for oci repo creation expect(req.request?.body?.spec.insecurePlainHttp).to.equal(false); + // check refreshInterval + expect(req.request?.body?.spec.refreshInterval).to.equal(Number(refreshInterval)); }); repositoriesPage.waitForPage(); diff --git a/shell/assets/translations/en-us.yaml b/shell/assets/translations/en-us.yaml index 69983df09da..15bdebfda0d 100644 --- a/shell/assets/translations/en-us.yaml +++ b/shell/assets/translations/en-us.yaml @@ -1079,14 +1079,17 @@ catalog: exponentialBackOff: label: Exponential Back Off minWait: - label: Min Wait Time (in Seconds) - placeholder: 1 (default) + label: Min Wait Time + placeholder: 'default: 1' maxWait: - label: Max Wait Time (in Seconds) - placeholder: 5 (default) + label: Max Wait Time + placeholder: 'default: 5' maxRetries: label: Max Number of Retries - placeholder: 5 (default) + placeholder: 'default: 5' + refreshInterval: + label: Refresh Interval + placeholder: 'default: {hours}' tools: header: Cluster Tools noTools: "No Cluster Tools found" diff --git a/shell/edit/catalog.cattle.io.clusterrepo.vue b/shell/edit/catalog.cattle.io.clusterrepo.vue index e24fc79cfd8..cfab9254144 100644 --- a/shell/edit/catalog.cattle.io.clusterrepo.vue +++ b/shell/edit/catalog.cattle.io.clusterrepo.vue @@ -9,6 +9,7 @@ import SelectOrCreateAuthSecret from '@shell/components/form/SelectOrCreateAuthS import InfoBox from '@shell/components/InfoBox'; import { Checkbox } from '@components/Form/Checkbox'; import { MANAGEMENT, NAMESPACE, CLUSTER_REPO_TYPES } from '@shell/config/types'; +import UnitInput from '@shell/components/form/UnitInput.vue'; export default { name: 'CruCatalogRepo', @@ -23,7 +24,8 @@ export default { Labels, SelectOrCreateAuthSecret, InfoBox, - Checkbox + Checkbox, + UnitInput }, mixins: [CreateEditView], @@ -83,7 +85,7 @@ export default { this.value.spec['exponentialBackOffValues'] = {}; } // when user removes the value we remove the key too, backend will set the default value - if (newVal === '') { + if (newVal === '' || newVal === null) { delete this.value.spec.exponentialBackOffValues[key]; return; @@ -91,15 +93,27 @@ export default { this.value.spec.exponentialBackOffValues[key] = Number(newVal); }, + updateRefreshInterval(newVal) { + // when user removes the value we don't send refreshInterval along with the payload + if (newVal === null) { + delete this.value.spec.refreshInterval; + + return; + } + + this.value.spec.refreshInterval = newVal; + }, resetGitRepoValues() { delete this.value.spec['gitRepo']; delete this.value.spec['gitBranch']; + delete this.value.spec['refreshInterval']; }, resetOciValues() { delete this.value.spec['url']; delete this.value.spec['insecurePlainHttp']; delete this.value.spec['insecureSkipTLSVerify']; delete this.value.spec['caBundle']; + delete this.value.spec['refreshInterval']; delete this.value.spec['exponentialBackOffValues']; this.ociMinWait = undefined; this.ociMaxWait = undefined; @@ -139,55 +153,80 @@ export default { -