@rancher/shell 3.0.12-rc.4 → 3.0.12-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/intf/resources-api/resource-base.ts +42 -2
- package/apis/intf/resources-api/resource-instance.ts +101 -0
- package/apis/intf/resources-api/resources-api.ts +177 -23
- package/apis/intf/resources.ts +8 -6
- package/apis/resources/__tests__/resources-api-class.test.ts +309 -28
- package/apis/resources/resources-api-class.ts +232 -43
- package/assets/images/providers/traefik.png +0 -0
- package/assets/styles/global/_button.scss +1 -1
- package/assets/translations/en-us.yaml +49 -14
- package/chart/__tests__/rancher-monitoring-dashboards-index.test.ts +269 -0
- package/chart/rancher-monitoring-dashboards/index.vue +155 -0
- package/cloud-credential/__tests__/generic.test.ts +132 -0
- package/cloud-credential/generic.vue +33 -3
- package/components/ActionDropdownShell.vue +5 -3
- package/components/ButtonGroup.vue +26 -1
- package/components/CruResource.vue +51 -2
- package/components/EtcdInfoBanner.vue +2 -12
- package/components/GrafanaDashboard.vue +2 -8
- package/components/PromptRestore.vue +93 -32
- package/components/Questions/index.vue +1 -0
- package/components/Resource/Detail/Masthead/__tests__/index.test.ts +68 -14
- package/components/Resource/Detail/Masthead/index.vue +8 -3
- package/components/ResourceTable.vue +1 -0
- package/components/SortableTable/index.vue +4 -3
- package/components/Wizard.vue +14 -1
- package/components/__tests__/ButtonGroup.test.ts +56 -0
- package/components/__tests__/PromptRestore.test.ts +169 -19
- package/components/fleet/GitRepoAdvancedTab.vue +1 -0
- package/components/fleet/GitRepoMetadataTab.vue +5 -0
- package/components/fleet/HelmOpAppCoConfigTab.vue +4 -0
- package/components/fleet/HelmOpMetadataTab.vue +5 -0
- package/components/form/FileSelector.vue +39 -1
- package/components/form/PrivateRegistry.constants.ts +7 -0
- package/components/form/PrivateRegistry.vue +253 -18
- package/components/form/Security.vue +1 -1
- package/components/form/SelectOrCreateAuthSecret.vue +140 -17
- package/components/form/__tests__/FileSelector.test.ts +23 -0
- package/components/form/__tests__/PrivateRegistry.test.ts +463 -73
- package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +122 -0
- package/components/formatter/EtcdSnapshotName.vue +73 -0
- package/components/formatter/Translate.vue +22 -1
- package/components/nav/Group.vue +5 -10
- package/components/nav/Header.vue +8 -1
- package/components/nav/TopLevelMenu.vue +1 -30
- package/components/nav/__tests__/Group.test.ts +61 -0
- package/components/templates/default.vue +7 -0
- package/config/features.js +1 -0
- package/config/labels-annotations.js +3 -0
- package/config/product/manager.js +6 -0
- package/config/secret.ts +10 -0
- package/config/settings.ts +6 -2
- package/config/table-headers.js +5 -2
- package/config/types.js +7 -0
- package/core/__tests__/plugin-products-apply.test.ts +787 -0
- package/core/__tests__/plugin-products-extend.test.ts +189 -0
- package/core/__tests__/plugin-products-helpers.test.ts +81 -78
- package/core/__tests__/plugin-products-new.test.ts +389 -0
- package/core/__tests__/plugin-products-scenarios.test.ts +980 -0
- package/core/__tests__/plugin-products-side-menu.test.ts +1935 -0
- package/core/plugin-products-base.ts +201 -93
- package/core/plugin-products-extending.ts +1 -1
- package/core/plugin-products-external.ts +380 -0
- package/core/plugin-products-helpers.ts +28 -24
- package/core/plugin-products-internal.ts +207 -0
- package/core/plugin-products-top-level.ts +10 -5
- package/core/plugin-products-type-guards.ts +17 -6
- package/core/plugin-products.ts +5 -7
- package/core/plugin-types.ts +1 -389
- package/core/plugin.ts +10 -11
- package/core/types.ts +6 -202
- package/detail/__tests__/provisioning.cattle.io.cluster.test.ts +52 -0
- package/detail/pod.vue +1 -1
- package/detail/provisioning.cattle.io.cluster.vue +79 -5
- package/dialog/RotateEncryptionKeyDialog.vue +33 -9
- package/dialog/__tests__/RotateEncryptionKeyDialog.test.ts +78 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +92 -0
- package/edit/__tests__/fleet.cattle.io.helmop.test.ts +101 -0
- package/edit/__tests__/management.cattle.io.setting.test.ts +2 -1
- package/edit/auth/AuthProviderWarningBanners.vue +12 -0
- package/edit/auth/__tests__/AuthProviderWarningBanners.test.ts +10 -1
- package/edit/auth/__tests__/azuread.test.ts +1 -0
- package/edit/auth/__tests__/github.test.ts +1 -0
- package/edit/auth/__tests__/oidc.test.ts +1 -0
- package/edit/auth/__tests__/saml.test.ts +1 -0
- package/edit/auth/ldap/__tests__/index.test.ts +1 -0
- package/edit/compliance.cattle.io.clusterscanprofile.vue +39 -41
- package/edit/fleet.cattle.io.gitrepo.vue +70 -16
- package/edit/fleet.cattle.io.helmop.vue +51 -5
- package/edit/helm.cattle.io.projecthelmchart.vue +1 -0
- package/edit/{management.cattle.io.setting.vue → management.cattle.io.setting/index.vue} +32 -9
- package/edit/management.cattle.io.setting/system-default-registry-pull-secrets.vue +81 -0
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +3 -12
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +18 -0
- package/edit/provisioning.cattle.io.cluster/index.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/rke2.vue +6 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +0 -1
- package/edit/provisioning.cattle.io.cluster/tabs/networking/index.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/tabs/registries/index.vue +14 -55
- package/list/management.cattle.io.user.vue +24 -5
- package/list/utils/management.cattle.io.cluster.utils.ts +1 -1
- package/machine-config/__tests__/generic.test.ts +163 -0
- package/machine-config/components/EC2Networking.vue +31 -7
- package/machine-config/components/__tests__/EC2Networking.test.ts +38 -15
- package/machine-config/generic.vue +32 -5
- package/mixins/resource-fetch.js +1 -1
- package/models/__tests__/provisioning.cattle.io.cluster.test.ts +156 -0
- package/models/__tests__/rke-machine.cattle.io.vmwarevspheremachinetemplate.test.ts +22 -0
- package/models/__tests__/secret.test.ts +68 -1
- package/models/management.cattle.io.cluster.js +21 -3
- package/models/pod.js +25 -12
- package/models/provisioning.cattle.io.cluster.js +59 -9
- package/models/rke-machine.cattle.io.vmwarevspheremachinetemplate.js +9 -0
- package/models/rke.cattle.io.etcdsnapshot.js +17 -9
- package/models/secret.js +19 -0
- package/models/workload.js +12 -7
- package/package.json +1 -1
- package/pages/auth/login.vue +1 -1
- package/pages/c/_cluster/apps/charts/__tests__/install.test.ts +569 -81
- package/pages/c/_cluster/apps/charts/install.vue +143 -28
- package/pages/c/_cluster/auth/config/index.vue +11 -4
- package/pages/c/_cluster/monitoring/index.vue +6 -1
- package/pkg/require-asset.lib.js +25 -0
- package/pkg/vue.config.js +7 -0
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +84 -0
- package/plugins/dashboard-store/getters.js +0 -1
- package/plugins/dashboard-store/resource-class.js +62 -15
- package/plugins/steve/__tests__/steve-class-resource-api.test.ts +147 -0
- package/plugins/steve/steve-class.js +43 -0
- package/plugins/steve/subscribe.js +11 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.test.ts +115 -0
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +83 -3
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +30 -0
- package/rancher-components/Form/TextArea/__tests__/TextAreaAutoGrow.test.ts +95 -0
- package/rancher-components/RcButton/index.ts +1 -1
- package/rancher-components/RcDropdown/RcDropdownTrigger.vue +6 -1
- package/store/__tests__/auth.test.ts +18 -0
- package/store/__tests__/features.test.ts +131 -0
- package/store/__tests__/growl.test.ts +374 -0
- package/store/__tests__/modal.test.ts +131 -0
- package/store/__tests__/notifications.test.ts +466 -1
- package/store/__tests__/slideInPanel.test.ts +88 -0
- package/store/__tests__/type-map.utils.test.ts +433 -0
- package/store/__tests__/ui-context.test.ts +255 -0
- package/store/auth.js +11 -1
- package/store/features.js +5 -0
- package/store/plugins.js +6 -0
- package/types/rancher/steve.api.ts +2 -2
- package/types/shell/index.d.ts +120 -0
- package/types/store/dashboard-store.types.ts +2 -2
- package/types/store/type-map.ts +262 -1
- package/utils/__tests__/operation-cr.test.ts +34 -0
- package/utils/async.ts +2 -0
- package/utils/grafana.js +2 -17
- package/utils/monitoring.js +38 -1
- package/utils/operation-cr.js +19 -0
- package/utils/require-asset.ts +7 -0
- package/utils/validators/__tests__/private-registry.test.ts +27 -15
- package/utils/validators/private-registry.ts +15 -4
- package/core/__tests__/plugin-products.test.ts +0 -4694
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
2
|
import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
|
|
3
3
|
import { AUTH_TYPE } from '@shell/config/types';
|
|
4
|
+
import { base64Encode } from '@shell/utils/crypto';
|
|
4
5
|
import GitRepo from '@shell/models/fleet.cattle.io.gitrepo';
|
|
5
6
|
import GitRepoComponent from '@shell/edit/fleet.cattle.io.gitrepo.vue';
|
|
6
7
|
|
|
@@ -327,3 +328,94 @@ describe('view: fleet.cattle.io.gitrepo, GitHub password banner - should', () =>
|
|
|
327
328
|
expect(githubBanner.exists()).toBe(shouldShowBanner);
|
|
328
329
|
});
|
|
329
330
|
});
|
|
331
|
+
|
|
332
|
+
describe('view: fleet.cattle.io.gitrepo, GitHub App auth - should', () => {
|
|
333
|
+
const originalDispatch = mockStore.dispatch;
|
|
334
|
+
|
|
335
|
+
afterEach(() => {
|
|
336
|
+
mockStore.dispatch = originalDispatch;
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('create an Opaque secret with the GitHub App data keys on doCreate', async() => {
|
|
340
|
+
const fakeSecret: any = {
|
|
341
|
+
metadata: { name: 'gitrepo-auth-abc' },
|
|
342
|
+
save: jest.fn().mockResolvedValue(undefined),
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
mockStore.dispatch = jest.fn().mockResolvedValue(fakeSecret);
|
|
346
|
+
|
|
347
|
+
const wrapper = mount(GitRepoComponent, initGitRepo({ mode: _CREATE }));
|
|
348
|
+
|
|
349
|
+
await (wrapper.vm as any).doCreate('clientSecretName', {
|
|
350
|
+
selected: AUTH_TYPE._GITHUB_APP,
|
|
351
|
+
githubAppId: 'app-id',
|
|
352
|
+
githubAppInstallationId: 'install-id',
|
|
353
|
+
githubAppPrivateKey: 'private-key',
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
expect(fakeSecret._type).toBe('Opaque');
|
|
357
|
+
expect(fakeSecret.data).toStrictEqual({
|
|
358
|
+
github_app_id: base64Encode('app-id'),
|
|
359
|
+
github_app_installation_id: base64Encode('install-id'),
|
|
360
|
+
github_app_private_key: base64Encode('private-key'),
|
|
361
|
+
});
|
|
362
|
+
expect(fakeSecret.save).toHaveBeenCalledWith();
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
describe('view: fleet.cattle.io.gitrepo, beforeNext dryRun validation', () => {
|
|
367
|
+
it('should call dryRunCreate when leaving stepMetadata in create mode', async() => {
|
|
368
|
+
const wrapper = mount(GitRepoComponent, initGitRepo({ mode: _CREATE }));
|
|
369
|
+
const vm = wrapper.vm as any;
|
|
370
|
+
|
|
371
|
+
vm.value.dryRunCreate = jest.fn().mockResolvedValue({});
|
|
372
|
+
|
|
373
|
+
await vm.beforeNext({ name: 'stepMetadata' });
|
|
374
|
+
|
|
375
|
+
expect(vm.value.dryRunCreate).toHaveBeenCalledWith(expect.objectContaining({
|
|
376
|
+
type: 'fleet.cattle.io.gitrepo',
|
|
377
|
+
metadata: expect.objectContaining({
|
|
378
|
+
name: 'test',
|
|
379
|
+
namespace: 'test',
|
|
380
|
+
}),
|
|
381
|
+
spec: expect.objectContaining({ repo: 'https://example.com/placeholder' }),
|
|
382
|
+
}));
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
it('should not call dryRunCreate for non-metadata steps', async() => {
|
|
386
|
+
const wrapper = mount(GitRepoComponent, initGitRepo({ mode: _CREATE }));
|
|
387
|
+
const vm = wrapper.vm as any;
|
|
388
|
+
|
|
389
|
+
vm.value.dryRunCreate = jest.fn();
|
|
390
|
+
|
|
391
|
+
await vm.beforeNext({ name: 'stepRepo' });
|
|
392
|
+
|
|
393
|
+
expect(vm.value.dryRunCreate).not.toHaveBeenCalled();
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('should not call dryRunCreate in edit mode', async() => {
|
|
397
|
+
const wrapper = mount(GitRepoComponent, initGitRepo({ mode: _EDIT }));
|
|
398
|
+
const vm = wrapper.vm as any;
|
|
399
|
+
|
|
400
|
+
vm.value.dryRunCreate = jest.fn();
|
|
401
|
+
|
|
402
|
+
await vm.beforeNext({ name: 'stepMetadata' });
|
|
403
|
+
|
|
404
|
+
expect(vm.value.dryRunCreate).not.toHaveBeenCalled();
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it('should reject with API errors when dryRunCreate fails', async() => {
|
|
408
|
+
const apiError = {
|
|
409
|
+
_status: 409,
|
|
410
|
+
message: 'gitrepos.fleet.cattle.io "test" already exists',
|
|
411
|
+
statusText: 'Conflict',
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
const wrapper = mount(GitRepoComponent, initGitRepo({ mode: _CREATE }));
|
|
415
|
+
const vm = wrapper.vm as any;
|
|
416
|
+
|
|
417
|
+
vm.value.dryRunCreate = jest.fn().mockRejectedValue(apiError);
|
|
418
|
+
|
|
419
|
+
await expect(vm.beforeNext({ name: 'stepMetadata' })).rejects.toStrictEqual(apiError);
|
|
420
|
+
});
|
|
421
|
+
});
|
|
@@ -421,6 +421,12 @@ describe.each([
|
|
|
421
421
|
expect(wrapper.vm.value.spec.downstreamResources).toStrictEqual([{ name: 'configMap2', kind: 'ConfigMap' }, { name: 'configMap3', kind: 'ConfigMap' }]);
|
|
422
422
|
});
|
|
423
423
|
|
|
424
|
+
it('should have a beforeNext method', () => {
|
|
425
|
+
const wrapper = mount(HelmOpComponent, initHelmOp({ mode }));
|
|
426
|
+
|
|
427
|
+
expect(typeof wrapper.vm.beforeNext).toBe('function');
|
|
428
|
+
});
|
|
429
|
+
|
|
424
430
|
if (mode === _CREATE) {
|
|
425
431
|
it('should set created-by-user-id label when updateBeforeSave is called in CREATE mode', () => {
|
|
426
432
|
const mockCurrentUser = { id: 'user-123' };
|
|
@@ -475,3 +481,98 @@ describe.each([
|
|
|
475
481
|
});
|
|
476
482
|
}
|
|
477
483
|
});
|
|
484
|
+
|
|
485
|
+
describe('view: fleet.cattle.io.helmop, beforeNext dryRun validation', () => {
|
|
486
|
+
const initHelmOpWithMetadata = (props: any) => {
|
|
487
|
+
const value = new HelmOp({
|
|
488
|
+
...mockHelmOp,
|
|
489
|
+
metadata: {
|
|
490
|
+
name: 'test-helmop',
|
|
491
|
+
namespace: 'fleet-default',
|
|
492
|
+
},
|
|
493
|
+
}, {
|
|
494
|
+
getters: { schemaFor: () => ({ linkFor: jest.fn() }) },
|
|
495
|
+
dispatch: jest.fn(),
|
|
496
|
+
rootGetters: { 'i18n/t': jest.fn() },
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
value.applyDefaults = () => {};
|
|
500
|
+
|
|
501
|
+
return {
|
|
502
|
+
props: {
|
|
503
|
+
value,
|
|
504
|
+
...props
|
|
505
|
+
},
|
|
506
|
+
provide: {
|
|
507
|
+
store: createStore({
|
|
508
|
+
getters: {
|
|
509
|
+
currentStore: () => 'current_store',
|
|
510
|
+
'management/paginationEnabled': () => () => false
|
|
511
|
+
}
|
|
512
|
+
})
|
|
513
|
+
},
|
|
514
|
+
computed: mockComputed,
|
|
515
|
+
global: { mocks },
|
|
516
|
+
};
|
|
517
|
+
};
|
|
518
|
+
|
|
519
|
+
it('should call dryRunCreate when leaving basics step in create mode', async() => {
|
|
520
|
+
const wrapper = mount(HelmOpComponent, initHelmOpWithMetadata({ mode: _CREATE }));
|
|
521
|
+
const vm = wrapper.vm as any;
|
|
522
|
+
|
|
523
|
+
vm.value.dryRunCreate = jest.fn().mockResolvedValue({});
|
|
524
|
+
|
|
525
|
+
await vm.beforeNext({ name: 'basics' });
|
|
526
|
+
|
|
527
|
+
expect(vm.value.dryRunCreate).toHaveBeenCalledWith(expect.objectContaining({
|
|
528
|
+
type: 'fleet.cattle.io.helmop',
|
|
529
|
+
metadata: expect.objectContaining({
|
|
530
|
+
name: 'test-helmop',
|
|
531
|
+
namespace: 'fleet-default',
|
|
532
|
+
}),
|
|
533
|
+
spec: expect.objectContaining({
|
|
534
|
+
helm: expect.objectContaining({
|
|
535
|
+
chart: 'placeholder',
|
|
536
|
+
repo: 'https://example.com',
|
|
537
|
+
}),
|
|
538
|
+
}),
|
|
539
|
+
}));
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('should not call dryRunCreate for non-basics steps', async() => {
|
|
543
|
+
const wrapper = mount(HelmOpComponent, initHelmOpWithMetadata({ mode: _CREATE }));
|
|
544
|
+
const vm = wrapper.vm as any;
|
|
545
|
+
|
|
546
|
+
vm.value.dryRunCreate = jest.fn();
|
|
547
|
+
|
|
548
|
+
await vm.beforeNext({ name: 'chart' });
|
|
549
|
+
|
|
550
|
+
expect(vm.value.dryRunCreate).not.toHaveBeenCalled();
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it('should not call dryRunCreate in edit mode', async() => {
|
|
554
|
+
const wrapper = mount(HelmOpComponent, initHelmOpWithMetadata({ mode: _EDIT }));
|
|
555
|
+
const vm = wrapper.vm as any;
|
|
556
|
+
|
|
557
|
+
vm.value.dryRunCreate = jest.fn();
|
|
558
|
+
|
|
559
|
+
await vm.beforeNext({ name: 'basics' });
|
|
560
|
+
|
|
561
|
+
expect(vm.value.dryRunCreate).not.toHaveBeenCalled();
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
it('should reject with API errors when dryRunCreate fails', async() => {
|
|
565
|
+
const apiError = {
|
|
566
|
+
_status: 409,
|
|
567
|
+
message: 'helmops.fleet.cattle.io "test-helmop" already exists',
|
|
568
|
+
statusText: 'Conflict',
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
const wrapper = mount(HelmOpComponent, initHelmOpWithMetadata({ mode: _CREATE }));
|
|
572
|
+
const vm = wrapper.vm as any;
|
|
573
|
+
|
|
574
|
+
vm.value.dryRunCreate = jest.fn().mockRejectedValue(apiError);
|
|
575
|
+
|
|
576
|
+
await expect(vm.beforeNext({ name: 'basics' })).rejects.toStrictEqual(apiError);
|
|
577
|
+
});
|
|
578
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { mount } from '@vue/test-utils';
|
|
2
|
-
import Settings from '@shell/edit/management.cattle.io.setting.vue';
|
|
2
|
+
import Settings from '@shell/edit/management.cattle.io.setting/index.vue';
|
|
3
3
|
import { SETTING } from '@shell/config/settings';
|
|
4
4
|
|
|
5
5
|
const requiredSetup = () => ({
|
|
@@ -18,6 +18,7 @@ const requiredSetup = () => ({
|
|
|
18
18
|
},
|
|
19
19
|
$route: { query: { AS: '' } },
|
|
20
20
|
$router: { applyQuery: jest.fn() },
|
|
21
|
+
t: (key: string) => key,
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
24
|
});
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { defineComponent } from 'vue';
|
|
3
3
|
import { Banner } from '@components/Banner';
|
|
4
|
+
import { HIDE_LOCAL_AUTH_PROVIDER } from '@shell/store/features';
|
|
4
5
|
|
|
5
6
|
export default defineComponent({
|
|
6
7
|
name: 'AuthProviderWarningBanners',
|
|
7
8
|
|
|
8
9
|
components: { Banner },
|
|
9
10
|
|
|
11
|
+
data() {
|
|
12
|
+
return { disableLocalAuth: this.$store.getters['features/get'](HIDE_LOCAL_AUTH_PROVIDER) };
|
|
13
|
+
},
|
|
14
|
+
|
|
10
15
|
props: {
|
|
11
16
|
tArgs: {
|
|
12
17
|
type: Object,
|
|
@@ -24,6 +29,13 @@ export default defineComponent({
|
|
|
24
29
|
color="warning"
|
|
25
30
|
data-testid="auth-provider-disabled-warning-banner"
|
|
26
31
|
/>
|
|
32
|
+
<Banner
|
|
33
|
+
v-if="disableLocalAuth"
|
|
34
|
+
color="warning"
|
|
35
|
+
data-testid="auth-provider-disable-local-auth-banner"
|
|
36
|
+
>
|
|
37
|
+
<span v-clean-html="t('authConfig.bannerEnableAuthProvider', {}, true)" />
|
|
38
|
+
</Banner>
|
|
27
39
|
<Banner
|
|
28
40
|
color="warning"
|
|
29
41
|
data-testid="auth-provider-admin-permissions-warning-banner"
|
|
@@ -4,7 +4,16 @@ import { mount } from '@vue/test-utils';
|
|
|
4
4
|
describe('component: AuthProviderWarningBanners.vue', () => {
|
|
5
5
|
const wrapper = mount(AuthProviderWarningBanners, {
|
|
6
6
|
props: { tArgs: { provider: 'Any Provider', username: 'username' } },
|
|
7
|
-
global: {
|
|
7
|
+
global: {
|
|
8
|
+
mocks: {
|
|
9
|
+
$store: {
|
|
10
|
+
getters: {
|
|
11
|
+
'i18n/t': (text: string) => text,
|
|
12
|
+
'features/get': () => false,
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
8
17
|
});
|
|
9
18
|
|
|
10
19
|
it('should render properly', () => {
|
|
@@ -103,48 +103,46 @@ export default {
|
|
|
103
103
|
</script>
|
|
104
104
|
|
|
105
105
|
<template>
|
|
106
|
-
<
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
<div class="
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/>
|
|
125
|
-
</div>
|
|
106
|
+
<CruResource
|
|
107
|
+
:validation-passed="!!name && !!value.spec.benchmarkVersion"
|
|
108
|
+
:done-route="doneRoute"
|
|
109
|
+
:resource="value"
|
|
110
|
+
:mode="mode"
|
|
111
|
+
:errors="errors"
|
|
112
|
+
@finish="save"
|
|
113
|
+
@error="e=>errors = e"
|
|
114
|
+
>
|
|
115
|
+
<div class="spacer" />
|
|
116
|
+
<div class="row">
|
|
117
|
+
<div class="col span-12">
|
|
118
|
+
<NameNsDescription
|
|
119
|
+
:mode="mode"
|
|
120
|
+
:value="value"
|
|
121
|
+
:namespaced="false"
|
|
122
|
+
@change="name=value.metadata.name"
|
|
123
|
+
/>
|
|
126
124
|
</div>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
125
|
+
</div>
|
|
126
|
+
<div class="row">
|
|
127
|
+
<div class="col span-6">
|
|
128
|
+
<LabeledSelect
|
|
129
|
+
v-model:value="value.spec.benchmarkVersion"
|
|
130
|
+
:mode="mode"
|
|
131
|
+
:label="t('compliance.benchmarkVersion')"
|
|
132
|
+
:options="compatibleBenchmarkNames"
|
|
133
|
+
/>
|
|
136
134
|
</div>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
135
|
+
</div>
|
|
136
|
+
<div class="spacer" />
|
|
137
|
+
<div class="row">
|
|
138
|
+
<div class="col span-6">
|
|
139
|
+
<ArrayList
|
|
140
|
+
v-model:value="value.spec.skipTests"
|
|
141
|
+
:title="t('compliance.testsToSkip')"
|
|
142
|
+
:value-placeholder="t('compliance.testID')"
|
|
143
|
+
:mode="mode"
|
|
144
|
+
/>
|
|
147
145
|
</div>
|
|
148
|
-
</
|
|
149
|
-
</
|
|
146
|
+
</div>
|
|
147
|
+
</CruResource>
|
|
150
148
|
</template>
|
|
@@ -8,7 +8,7 @@ import Loading from '@shell/components/Loading';
|
|
|
8
8
|
import { base64Decode, base64Encode } from '@shell/utils/crypto';
|
|
9
9
|
import { _CREATE, _EDIT, _VIEW } from '@shell/config/query-params';
|
|
10
10
|
import { CATALOG, FLEET as FLEET_LABELS } from '@shell/config/labels-annotations';
|
|
11
|
-
import { SECRET_TYPES } from '@shell/config/secret';
|
|
11
|
+
import { SECRET_TYPES, GITHUB_APP_SECRET_KEYS } from '@shell/config/secret';
|
|
12
12
|
import FormValidation from '@shell/mixins/form-validation';
|
|
13
13
|
import { toSeconds } from '@shell/utils/duration';
|
|
14
14
|
import Tab from '@shell/components/Tabbed/Tab.vue';
|
|
@@ -97,10 +97,19 @@ export default {
|
|
|
97
97
|
refValue,
|
|
98
98
|
displayHelmRepoUrlRegex: false,
|
|
99
99
|
targetsCreated: '',
|
|
100
|
-
fvFormRuleSets: [
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
fvFormRuleSets: [
|
|
101
|
+
{
|
|
102
|
+
step: 'stepMetadata',
|
|
103
|
+
path: 'metadata.name',
|
|
104
|
+
rules: ['subDomain'],
|
|
105
|
+
translationKey: 'nameNsDescription.name.label'
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
step: 'stepRepo',
|
|
109
|
+
path: 'spec.repo',
|
|
110
|
+
rules: ['urlRepository'],
|
|
111
|
+
},
|
|
112
|
+
],
|
|
104
113
|
touched: null,
|
|
105
114
|
};
|
|
106
115
|
},
|
|
@@ -129,7 +138,7 @@ export default {
|
|
|
129
138
|
label: this.t('fleet.gitRepo.add.steps.metadata.label'),
|
|
130
139
|
subtext: this.t('fleet.gitRepo.add.steps.metadata.subtext'),
|
|
131
140
|
descriptionKey: 'fleet.gitRepo.add.steps.metadata.description',
|
|
132
|
-
ready: this.isView || !!this.value.metadata.name,
|
|
141
|
+
ready: this.isView || (!!this.value.metadata.name && this.stepPathErrors('stepMetadata').length === 0),
|
|
133
142
|
weight: 1
|
|
134
143
|
},
|
|
135
144
|
{
|
|
@@ -206,6 +215,15 @@ export default {
|
|
|
206
215
|
},
|
|
207
216
|
|
|
208
217
|
methods: {
|
|
218
|
+
stepPathErrors(stepName) {
|
|
219
|
+
// Helper is used to check which validations is for each step
|
|
220
|
+
const paths = this.fvFormRuleSets
|
|
221
|
+
.filter((rule) => rule.step === stepName)
|
|
222
|
+
.map((rule) => rule.path);
|
|
223
|
+
|
|
224
|
+
return this.fvGetPathErrors(paths);
|
|
225
|
+
},
|
|
226
|
+
|
|
209
227
|
updatePaths(value) {
|
|
210
228
|
const { paths, bundles } = value;
|
|
211
229
|
|
|
@@ -283,10 +301,13 @@ export default {
|
|
|
283
301
|
selected,
|
|
284
302
|
publicKey,
|
|
285
303
|
privateKey,
|
|
286
|
-
sshKnownHosts
|
|
304
|
+
sshKnownHosts,
|
|
305
|
+
githubAppId,
|
|
306
|
+
githubAppInstallationId,
|
|
307
|
+
githubAppPrivateKey,
|
|
287
308
|
} = credentials;
|
|
288
309
|
|
|
289
|
-
if ( ![AUTH_TYPE._SSH, AUTH_TYPE._BASIC, AUTH_TYPE._S3].includes(selected) ) {
|
|
310
|
+
if ( ![AUTH_TYPE._SSH, AUTH_TYPE._BASIC, AUTH_TYPE._S3, AUTH_TYPE._GITHUB_APP].includes(selected) ) {
|
|
290
311
|
return;
|
|
291
312
|
}
|
|
292
313
|
|
|
@@ -323,19 +344,31 @@ export default {
|
|
|
323
344
|
publicField = 'username';
|
|
324
345
|
privateField = 'password';
|
|
325
346
|
break;
|
|
347
|
+
case AUTH_TYPE._GITHUB_APP:
|
|
348
|
+
type = SECRET_TYPES.OPAQUE;
|
|
349
|
+
break;
|
|
326
350
|
default:
|
|
327
351
|
throw new Error('Unknown type');
|
|
328
352
|
}
|
|
329
353
|
|
|
330
354
|
secret._type = type;
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
355
|
+
|
|
356
|
+
if (selected === AUTH_TYPE._GITHUB_APP) {
|
|
357
|
+
secret.data = {
|
|
358
|
+
[GITHUB_APP_SECRET_KEYS.APP_ID]: base64Encode(githubAppId),
|
|
359
|
+
[GITHUB_APP_SECRET_KEYS.INSTALLATION_ID]: base64Encode(githubAppInstallationId),
|
|
360
|
+
[GITHUB_APP_SECRET_KEYS.PRIVATE_KEY]: base64Encode(githubAppPrivateKey),
|
|
361
|
+
};
|
|
362
|
+
} else {
|
|
363
|
+
secret.data = {
|
|
364
|
+
[publicField]: base64Encode(publicKey),
|
|
365
|
+
[privateField]: base64Encode(privateKey),
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// Add ssh known hosts
|
|
369
|
+
if (selected === AUTH_TYPE._SSH && sshKnownHosts) {
|
|
370
|
+
secret.data.known_hosts = base64Encode(sshKnownHosts);
|
|
371
|
+
}
|
|
339
372
|
}
|
|
340
373
|
}
|
|
341
374
|
|
|
@@ -413,6 +446,25 @@ export default {
|
|
|
413
446
|
}
|
|
414
447
|
},
|
|
415
448
|
|
|
449
|
+
async beforeNext(activeStep) {
|
|
450
|
+
if (activeStep.name !== 'stepMetadata' || !this.isCreate) {
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
await this.value.dryRunCreate({
|
|
455
|
+
type: this.value.type,
|
|
456
|
+
metadata: {
|
|
457
|
+
name: this.value.metadata.name,
|
|
458
|
+
namespace: this.value.metadata.namespace,
|
|
459
|
+
},
|
|
460
|
+
spec: {
|
|
461
|
+
repo: 'https://example.com/placeholder',
|
|
462
|
+
branch: 'master',
|
|
463
|
+
paths: [],
|
|
464
|
+
}
|
|
465
|
+
});
|
|
466
|
+
},
|
|
467
|
+
|
|
416
468
|
durationSeconds(value) {
|
|
417
469
|
return `${ value }s`;
|
|
418
470
|
}
|
|
@@ -432,6 +484,7 @@ export default {
|
|
|
432
484
|
:errors="errors"
|
|
433
485
|
:steps="!isView ? steps : undefined"
|
|
434
486
|
:finish-mode="'finish'"
|
|
487
|
+
:before-next="beforeNext"
|
|
435
488
|
class="wizard"
|
|
436
489
|
@cancel="done"
|
|
437
490
|
@error="e=>errors = e"
|
|
@@ -442,6 +495,7 @@ export default {
|
|
|
442
495
|
:value="value"
|
|
443
496
|
:mode="mode"
|
|
444
497
|
:is-view="isView"
|
|
498
|
+
:name-rules="fvGetAndReportPathRules('metadata.name')"
|
|
445
499
|
@input="$emit('input', $event)"
|
|
446
500
|
/>
|
|
447
501
|
</template>
|