@rancher/shell 3.0.9-rc.3 → 3.0.9-rc.5
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/assets/brand/suse/metadata.json +2 -1
- package/assets/translations/en-us.yaml +105 -5
- package/components/ActionMenuShell.vue +1 -1
- package/components/Inactivity.vue +2 -2
- package/components/Resource/Detail/Card/ExtrasCard.vue +49 -15
- package/components/Resource/Detail/Card/__tests__/ExtrasCard.test.ts +111 -0
- package/components/Resource/Detail/Masthead/__tests__/index.test.ts +0 -17
- package/components/Resource/Detail/Masthead/index.vue +11 -4
- package/components/Resource/Detail/Metadata/IdentifyingInformation/index.vue +3 -1
- package/components/Resource/Detail/Metadata/index.vue +1 -1
- package/components/Resource/Detail/ResourceRow.vue +1 -1
- package/components/ResourceDetail/Masthead/latest.vue +12 -2
- package/components/ResourceList/index.vue +9 -0
- package/components/ResourceTable.vue +38 -4
- package/components/Tabbed/Tab.vue +4 -0
- package/components/Tabbed/index.vue +4 -1
- package/components/__tests__/ProjectRow.test.ts +60 -0
- package/components/form/ChangePassword.vue +41 -35
- package/components/form/ResourceQuota/Project.vue +42 -1
- package/components/form/ResourceQuota/ProjectRow.vue +71 -4
- package/components/form/ResourceQuota/__tests__/Project.test.ts +63 -0
- package/components/form/SelectOrCreateAuthSecret.vue +6 -1
- package/components/form/__tests__/SelectOrCreateAuthSecret.test.ts +35 -0
- package/components/formatter/KubeconfigClusters.vue +74 -0
- package/components/formatter/MachineSummaryGraph.vue +10 -2
- package/components/formatter/__tests__/KubeconfigClusters.test.ts +125 -0
- package/components/nav/TopLevelMenu.helper.ts +50 -2
- package/components/nav/TopLevelMenu.vue +14 -0
- package/components/nav/Type.vue +5 -0
- package/components/nav/__tests__/TopLevelMenu.test.ts +3 -3
- package/components/nav/__tests__/Type.test.ts +6 -4
- package/config/product/explorer.js +4 -3
- package/config/product/manager.js +47 -3
- package/config/router/navigation-guards/authentication.js +8 -9
- package/config/router/routes.js +4 -1
- package/config/types.js +10 -2
- package/detail/auditlog.cattle.io.auditpolicy.vue +19 -0
- package/detail/management.cattle.io.user.vue +1 -2
- package/detail/node.vue +0 -1
- package/detail/provisioning.cattle.io.cluster.vue +2 -1
- package/dialog/ChangePasswordDialog.vue +8 -0
- package/dialog/GenericPrompt.vue +20 -3
- package/dialog/ScaleMachineDownDialog.vue +65 -15
- package/dialog/SearchDialog.vue +10 -2
- package/dialog/__tests__/ScaleMachineDownDialog.test.ts +184 -0
- package/edit/__tests__/fleet.cattle.io.gitrepo.test.ts +89 -0
- package/edit/__tests__/management.cattle.io.project.test.js +56 -1
- package/edit/auditlog.cattle.io.auditpolicy/AdditionalRedactions.vue +114 -0
- package/edit/auditlog.cattle.io.auditpolicy/Filters.vue +119 -0
- package/edit/auditlog.cattle.io.auditpolicy/General.vue +180 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/AdditionalRedactions.test.ts +327 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/Filters.test.ts +449 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/General.test.ts +472 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/AdditionalRedactions.test.ts.snap +27 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/Filters.test.ts.snap +39 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/General.test.ts.snap +174 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/__snapshots__/index.test.ts.snap +29 -0
- package/edit/auditlog.cattle.io.auditpolicy/__tests__/index.test.ts +215 -0
- package/edit/auditlog.cattle.io.auditpolicy/index.vue +104 -0
- package/edit/auditlog.cattle.io.auditpolicy/types.ts +28 -0
- package/edit/fleet.cattle.io.gitrepo.vue +16 -1
- package/edit/management.cattle.io.project.vue +8 -2
- package/edit/management.cattle.io.user.vue +29 -34
- package/edit/provisioning.cattle.io.cluster/__tests__/rke2.test.ts +178 -0
- package/edit/provisioning.cattle.io.cluster/rke2.vue +22 -2
- package/edit/provisioning.cattle.io.cluster/shared.ts +4 -0
- package/edit/provisioning.cattle.io.cluster/tabs/Basics.vue +1 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/S3Config.vue +57 -2
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/__tests__/S3Config.test.ts +109 -0
- package/edit/provisioning.cattle.io.cluster/tabs/etcd/index.vue +1 -0
- package/list/auditlog.cattle.io.auditpolicy.vue +63 -0
- package/list/ext.cattle.io.kubeconfig.vue +118 -0
- package/list/group.principal.vue +11 -15
- package/list/management.cattle.io.user.vue +11 -21
- package/machine-config/azure.vue +14 -0
- package/mixins/__tests__/chart.test.ts +147 -0
- package/mixins/browser-tab-visibility.js +5 -4
- package/mixins/chart.js +10 -8
- package/mixins/fetch.client.js +6 -0
- package/models/__tests__/auditlog.cattle.io.auditpolicy.test.ts +117 -0
- package/models/__tests__/ext.cattle.io.kubeconfig.test.ts +364 -0
- package/models/__tests__/secret.test.ts +55 -0
- package/models/__tests__/workload.test.ts +49 -6
- package/models/auditlog.cattle.io.auditpolicy.js +46 -0
- package/models/cluster.x-k8s.io.machine.js +1 -1
- package/models/cluster.x-k8s.io.machinedeployment.js +5 -5
- package/models/event.js +5 -0
- package/models/ext.cattle.io.groupmembershiprefreshrequest.js +15 -0
- package/models/ext.cattle.io.kubeconfig.ts +97 -0
- package/models/ext.cattle.io.passwordchangerequest.js +15 -0
- package/models/ext.cattle.io.selfuser.js +15 -0
- package/models/fleet-application.js +17 -7
- package/models/management.cattle.io.user.js +28 -31
- package/models/schema.js +18 -0
- package/models/secret.js +28 -25
- package/models/steve-schema.ts +39 -2
- package/models/workload.js +3 -2
- package/package.json +2 -2
- package/pages/about.vue +3 -2
- package/pages/account/index.vue +23 -16
- package/pages/auth/login.vue +15 -8
- package/pages/auth/setup.vue +52 -15
- package/pages/c/_cluster/apps/charts/AppChartCardFooter.vue +38 -14
- package/pages/c/_cluster/apps/charts/index.vue +1 -0
- package/pages/home.vue +9 -3
- package/plugins/dashboard-store/__tests__/resource-class.test.ts +1 -3
- package/plugins/dashboard-store/actions.js +7 -0
- package/plugins/dashboard-store/getters.js +23 -1
- package/plugins/dashboard-store/index.js +3 -2
- package/plugins/dashboard-store/mutations.js +4 -0
- package/plugins/dashboard-store/resource-class.js +12 -5
- package/plugins/steve/__tests__/steve-class.test.ts +167 -0
- package/plugins/steve/schema.d.ts +5 -0
- package/plugins/steve/steve-class.js +19 -0
- package/plugins/steve/steve-pagination-utils.ts +2 -1
- package/rancher-components/RcItemCard/RcItemCard.test.ts +4 -2
- package/rancher-components/RcItemCard/RcItemCard.vue +27 -10
- package/store/auth.js +57 -19
- package/store/notifications.ts +1 -1
- package/store/type-map.js +12 -1
- package/types/shell/index.d.ts +24 -15
- package/types/store/dashboard-store.types.ts +7 -0
- package/utils/__tests__/chart.test.ts +96 -0
- package/utils/__tests__/version.test.ts +1 -19
- package/utils/chart.js +64 -0
- package/utils/pagination-wrapper.ts +11 -3
- package/utils/version.js +5 -17
- package/vue.config.js +26 -13
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`component: General rendering & initial state should render with default props (snapshot) 1`] = `
|
|
4
|
+
<div>
|
|
5
|
+
<div
|
|
6
|
+
class="row"
|
|
7
|
+
>
|
|
8
|
+
<div
|
|
9
|
+
class="col span-6"
|
|
10
|
+
>
|
|
11
|
+
<fieldset>
|
|
12
|
+
<h3>
|
|
13
|
+
auditPolicy.general.enabled.title
|
|
14
|
+
</h3>
|
|
15
|
+
<checkbox-stub
|
|
16
|
+
componenttestid="checkbox"
|
|
17
|
+
data-testid="auditPolicy-enabled"
|
|
18
|
+
disabled="false"
|
|
19
|
+
id="test-id-123"
|
|
20
|
+
indeterminate="false"
|
|
21
|
+
labelkey="auditPolicy.general.enabled.checkbox"
|
|
22
|
+
mode="create"
|
|
23
|
+
primary="false"
|
|
24
|
+
value="false"
|
|
25
|
+
valuewhentrue="true"
|
|
26
|
+
/>
|
|
27
|
+
</fieldset>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
<div
|
|
31
|
+
class="spacer"
|
|
32
|
+
/>
|
|
33
|
+
<div
|
|
34
|
+
class="row"
|
|
35
|
+
>
|
|
36
|
+
<div
|
|
37
|
+
class="col span-6"
|
|
38
|
+
>
|
|
39
|
+
<fieldset>
|
|
40
|
+
<h3>
|
|
41
|
+
auditPolicy.general.verbosity.title
|
|
42
|
+
</h3>
|
|
43
|
+
<banner-stub
|
|
44
|
+
class="mt-0"
|
|
45
|
+
closable="false"
|
|
46
|
+
color="info"
|
|
47
|
+
disabled="false"
|
|
48
|
+
labelkey="auditPolicy.general.verbosity.banner"
|
|
49
|
+
stacked="false"
|
|
50
|
+
/>
|
|
51
|
+
<h4>
|
|
52
|
+
auditPolicy.general.verbosity.level.title
|
|
53
|
+
<i
|
|
54
|
+
class="icon icon-info has-clean-tooltip"
|
|
55
|
+
/>
|
|
56
|
+
</h4>
|
|
57
|
+
<div
|
|
58
|
+
class="row"
|
|
59
|
+
>
|
|
60
|
+
<div
|
|
61
|
+
class="col span-12"
|
|
62
|
+
>
|
|
63
|
+
<labeled-select-stub
|
|
64
|
+
appendtobody="true"
|
|
65
|
+
clearable="false"
|
|
66
|
+
closeonselect="true"
|
|
67
|
+
disabled="false"
|
|
68
|
+
hovertooltip="true"
|
|
69
|
+
label="auditPolicy.general.verbosity.level.label"
|
|
70
|
+
loading="false"
|
|
71
|
+
localizedlabel="false"
|
|
72
|
+
mode="create"
|
|
73
|
+
nooptionslabelkey="labelSelect.noOptions.empty"
|
|
74
|
+
optionlabel="label"
|
|
75
|
+
options="[object Object],[object Object],[object Object],[object Object]"
|
|
76
|
+
reduce="[Function]"
|
|
77
|
+
required="false"
|
|
78
|
+
selectable="[Function]"
|
|
79
|
+
value="0"
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
<div
|
|
84
|
+
class="spacer-small"
|
|
85
|
+
/>
|
|
86
|
+
<div
|
|
87
|
+
class="row"
|
|
88
|
+
>
|
|
89
|
+
<div
|
|
90
|
+
class="col span-6"
|
|
91
|
+
>
|
|
92
|
+
<h4>
|
|
93
|
+
auditPolicy.general.verbosity.request.title
|
|
94
|
+
<i
|
|
95
|
+
class="icon icon-info has-clean-tooltip"
|
|
96
|
+
/>
|
|
97
|
+
</h4>
|
|
98
|
+
<div
|
|
99
|
+
class="row"
|
|
100
|
+
>
|
|
101
|
+
<checkbox-stub
|
|
102
|
+
componenttestid="checkbox"
|
|
103
|
+
disabled="false"
|
|
104
|
+
id="test-id-123"
|
|
105
|
+
indeterminate="false"
|
|
106
|
+
label="auditPolicy.general.verbosity.request.requestHeaders"
|
|
107
|
+
mode="create"
|
|
108
|
+
primary="false"
|
|
109
|
+
value="false"
|
|
110
|
+
valuewhentrue="true"
|
|
111
|
+
/>
|
|
112
|
+
</div>
|
|
113
|
+
<div
|
|
114
|
+
class="row"
|
|
115
|
+
>
|
|
116
|
+
<checkbox-stub
|
|
117
|
+
componenttestid="checkbox"
|
|
118
|
+
disabled="false"
|
|
119
|
+
id="test-id-123"
|
|
120
|
+
indeterminate="false"
|
|
121
|
+
label="auditPolicy.general.verbosity.request.requestBody"
|
|
122
|
+
mode="create"
|
|
123
|
+
primary="false"
|
|
124
|
+
value="false"
|
|
125
|
+
valuewhentrue="true"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
<div
|
|
130
|
+
class="col span-6"
|
|
131
|
+
>
|
|
132
|
+
<h4>
|
|
133
|
+
auditPolicy.general.verbosity.response.title
|
|
134
|
+
<i
|
|
135
|
+
class="icon icon-info has-clean-tooltip"
|
|
136
|
+
/>
|
|
137
|
+
</h4>
|
|
138
|
+
<div
|
|
139
|
+
class="row"
|
|
140
|
+
>
|
|
141
|
+
<checkbox-stub
|
|
142
|
+
componenttestid="checkbox"
|
|
143
|
+
disabled="false"
|
|
144
|
+
id="test-id-123"
|
|
145
|
+
indeterminate="false"
|
|
146
|
+
label="auditPolicy.general.verbosity.response.responseHeaders"
|
|
147
|
+
mode="create"
|
|
148
|
+
primary="false"
|
|
149
|
+
value="false"
|
|
150
|
+
valuewhentrue="true"
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
<div
|
|
154
|
+
class="row"
|
|
155
|
+
>
|
|
156
|
+
<checkbox-stub
|
|
157
|
+
componenttestid="checkbox"
|
|
158
|
+
disabled="false"
|
|
159
|
+
id="test-id-123"
|
|
160
|
+
indeterminate="false"
|
|
161
|
+
label="auditPolicy.general.verbosity.response.responseBody"
|
|
162
|
+
mode="create"
|
|
163
|
+
primary="false"
|
|
164
|
+
value="false"
|
|
165
|
+
valuewhentrue="true"
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
</fieldset>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
`;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`component: CRUAuditPolicy (index) rendering & initial state should render with default props (snapshot) 1`] = `
|
|
4
|
+
<div
|
|
5
|
+
data-v-app=""
|
|
6
|
+
>
|
|
7
|
+
|
|
8
|
+
<!--v-if-->
|
|
9
|
+
<cru-resource-stub
|
|
10
|
+
cancelevent="false"
|
|
11
|
+
canyaml="true"
|
|
12
|
+
componenttestid="form"
|
|
13
|
+
description=""
|
|
14
|
+
errors=""
|
|
15
|
+
finishmode="finish"
|
|
16
|
+
minheight=""
|
|
17
|
+
mode="create"
|
|
18
|
+
namespacekey="metadata.namespace"
|
|
19
|
+
prevententersubmit="false"
|
|
20
|
+
resource="[object Object]"
|
|
21
|
+
showcancel="true"
|
|
22
|
+
steps=""
|
|
23
|
+
stepsoptions="[object Object]"
|
|
24
|
+
subtypes=""
|
|
25
|
+
validationpassed="true"
|
|
26
|
+
/>
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
`;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { shallowMount, VueWrapper } from '@vue/test-utils';
|
|
2
|
+
import CRUAuditPolicy from '../index.vue';
|
|
3
|
+
import { ComponentPublicInstance } from 'vue';
|
|
4
|
+
|
|
5
|
+
// Mock the ID generation to have consistent snapshots
|
|
6
|
+
jest.mock('@shell/utils/string', () => ({ generateRandomAlphaString: () => 'test-id-123' }));
|
|
7
|
+
|
|
8
|
+
// Type definitions for component
|
|
9
|
+
interface AuditPolicyComponent extends ComponentPublicInstance {
|
|
10
|
+
mode: string;
|
|
11
|
+
value: Record<string, any>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const defaultProps = {
|
|
15
|
+
value: {
|
|
16
|
+
id: 'test-policy',
|
|
17
|
+
type: 'auditlog.cattle.io.auditpolicy',
|
|
18
|
+
metadata: { name: 'test-policy' },
|
|
19
|
+
spec: { enabled: false }
|
|
20
|
+
},
|
|
21
|
+
mode: 'create'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const globalMocks = {
|
|
25
|
+
global: {
|
|
26
|
+
mocks: {
|
|
27
|
+
$t: (key: string) => key,
|
|
28
|
+
t: (key: string) => key,
|
|
29
|
+
$store: {
|
|
30
|
+
getters: {
|
|
31
|
+
'i18n/t': (key: string) => key,
|
|
32
|
+
currentStore: () => 'cluster',
|
|
33
|
+
'cluster/schemaFor': () => ({
|
|
34
|
+
attributes: { namespaced: true },
|
|
35
|
+
id: 'auditlog.cattle.io.auditpolicy'
|
|
36
|
+
})
|
|
37
|
+
},
|
|
38
|
+
dispatch: jest.fn()
|
|
39
|
+
},
|
|
40
|
+
$route: {
|
|
41
|
+
params: {},
|
|
42
|
+
query: {}
|
|
43
|
+
},
|
|
44
|
+
$router: {
|
|
45
|
+
push: jest.fn(),
|
|
46
|
+
replace: jest.fn()
|
|
47
|
+
},
|
|
48
|
+
$fetchState: { pending: false }
|
|
49
|
+
},
|
|
50
|
+
provide: {
|
|
51
|
+
store: {
|
|
52
|
+
getters: { 'i18n/t': (key: string) => key },
|
|
53
|
+
dispatch: jest.fn()
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
stubs: {
|
|
57
|
+
Loading: true,
|
|
58
|
+
CruResource: true,
|
|
59
|
+
NameNsDescription: true,
|
|
60
|
+
Error: true,
|
|
61
|
+
Tabbed: true,
|
|
62
|
+
Tab: true,
|
|
63
|
+
General: true,
|
|
64
|
+
Filters: true,
|
|
65
|
+
AdditionalRedactions: true,
|
|
66
|
+
Labels: true
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
function factory(props: Record<string, any> = {}, options: Record<string, any> = {}): VueWrapper<AuditPolicyComponent> {
|
|
72
|
+
return shallowMount(CRUAuditPolicy, {
|
|
73
|
+
props: { ...defaultProps, ...props },
|
|
74
|
+
...globalMocks,
|
|
75
|
+
global: {
|
|
76
|
+
...globalMocks.global,
|
|
77
|
+
// Prevent directive conflicts by using shallow mounting without plugins
|
|
78
|
+
plugins: [],
|
|
79
|
+
...(options.global || {})
|
|
80
|
+
},
|
|
81
|
+
...options
|
|
82
|
+
}) as VueWrapper<AuditPolicyComponent>;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
describe('component: CRUAuditPolicy (index)', () => {
|
|
86
|
+
describe('rendering & initial state', () => {
|
|
87
|
+
it('should render with default props (snapshot)', () => {
|
|
88
|
+
const wrapper = factory();
|
|
89
|
+
|
|
90
|
+
expect(wrapper.element).toMatchSnapshot();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should mount successfully', () => {
|
|
94
|
+
const wrapper = factory();
|
|
95
|
+
|
|
96
|
+
expect(wrapper.exists()).toBe(true);
|
|
97
|
+
expect(wrapper.vm).toBeDefined();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should render with different modes', () => {
|
|
101
|
+
const modes = ['create', 'edit', 'view'];
|
|
102
|
+
|
|
103
|
+
modes.forEach((mode) => {
|
|
104
|
+
const wrapper = factory({ mode });
|
|
105
|
+
|
|
106
|
+
expect(wrapper.exists()).toBe(true);
|
|
107
|
+
expect(wrapper.vm.mode).toBe(mode);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('component initialization', () => {
|
|
113
|
+
it('should initialize with provided value', () => {
|
|
114
|
+
const wrapper = factory();
|
|
115
|
+
|
|
116
|
+
expect(wrapper.vm.value).toBeDefined();
|
|
117
|
+
expect(wrapper.vm.value.spec).toBeDefined();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should handle different value configurations', () => {
|
|
121
|
+
const customValue = {
|
|
122
|
+
id: 'custom-policy',
|
|
123
|
+
type: 'auditlog.cattle.io.auditpolicy',
|
|
124
|
+
metadata: { name: 'custom' },
|
|
125
|
+
spec: { enabled: true }
|
|
126
|
+
};
|
|
127
|
+
const wrapper = factory({ value: customValue });
|
|
128
|
+
|
|
129
|
+
expect(wrapper.vm.value.id).toBe('custom-policy');
|
|
130
|
+
expect(wrapper.vm.value.spec.enabled).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should handle spec initialization lifecycle', () => {
|
|
134
|
+
const valueWithoutSpec = {
|
|
135
|
+
...defaultProps.value,
|
|
136
|
+
spec: undefined
|
|
137
|
+
};
|
|
138
|
+
// The component created() hook should initialize spec when missing
|
|
139
|
+
const wrapper = factory({ value: valueWithoutSpec });
|
|
140
|
+
|
|
141
|
+
// After mounting, spec should be initialized
|
|
142
|
+
expect(wrapper.vm.value.spec).toBeDefined();
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('component structure', () => {
|
|
147
|
+
it('should have the correct component name', () => {
|
|
148
|
+
const wrapper = factory();
|
|
149
|
+
|
|
150
|
+
expect(wrapper.vm.$options.name).toBe('CRUAuditPolicy');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should use CreateEditView and FormValidation mixins', () => {
|
|
154
|
+
const wrapper = factory();
|
|
155
|
+
|
|
156
|
+
// Check that mixins are applied by testing for their properties/methods
|
|
157
|
+
expect(typeof wrapper.vm.mode).toBe('string');
|
|
158
|
+
expect(wrapper.vm.value).toBeDefined();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('should render main template elements', () => {
|
|
162
|
+
const wrapper = factory();
|
|
163
|
+
|
|
164
|
+
expect(wrapper.html()).toContain('cru-resource-stub');
|
|
165
|
+
expect(wrapper.findComponent({ name: 'CruResource' })).toBeTruthy();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('props and configuration', () => {
|
|
170
|
+
it('should handle different modes correctly', () => {
|
|
171
|
+
const modes = ['create', 'edit', 'view'];
|
|
172
|
+
|
|
173
|
+
modes.forEach((mode) => {
|
|
174
|
+
const wrapper = factory({ mode });
|
|
175
|
+
|
|
176
|
+
expect(wrapper.vm.mode).toBe(mode);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should handle different value objects', () => {
|
|
181
|
+
const customValue = {
|
|
182
|
+
id: 'test-policy',
|
|
183
|
+
type: 'auditlog.cattle.io.auditpolicy',
|
|
184
|
+
metadata: { name: 'test' },
|
|
185
|
+
spec: { enabled: true, verbosity: { level: 2 } }
|
|
186
|
+
};
|
|
187
|
+
const wrapper = factory({ value: customValue });
|
|
188
|
+
|
|
189
|
+
expect(wrapper.vm.value.spec.enabled).toBe(true);
|
|
190
|
+
expect(wrapper.vm.value.spec.verbosity.level).toBe(2);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe('edge cases', () => {
|
|
195
|
+
it('should handle empty value object', () => {
|
|
196
|
+
const wrapper = factory({ value: {} });
|
|
197
|
+
|
|
198
|
+
// The created() hook initializes spec, so empty object gets spec added
|
|
199
|
+
expect(wrapper.vm.value).toStrictEqual({ spec: { enabled: false } });
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should handle component updates', async() => {
|
|
203
|
+
const wrapper = factory();
|
|
204
|
+
|
|
205
|
+
await wrapper.setProps({
|
|
206
|
+
value: {
|
|
207
|
+
...defaultProps.value,
|
|
208
|
+
spec: { enabled: true }
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
expect(wrapper.vm.value.spec.enabled).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// Shared AuditPolicy interface for all audit log policy components
|
|
3
|
+
import CreateEditView from '@shell/mixins/create-edit-view';
|
|
4
|
+
import FormValidation from '@shell/mixins/form-validation';
|
|
5
|
+
import CruResource from '@shell/components/CruResource.vue';
|
|
6
|
+
import NameNsDescription from '@shell/components/form/NameNsDescription.vue';
|
|
7
|
+
import Labels from '@shell/components/form/Labels.vue';
|
|
8
|
+
import Tabbed from '@shell/components/Tabbed/index.vue';
|
|
9
|
+
import Tab from '@shell/components/Tabbed/Tab.vue';
|
|
10
|
+
import Loading from '@shell/components/Loading.vue';
|
|
11
|
+
import General from '@shell/edit/auditlog.cattle.io.auditpolicy/General.vue';
|
|
12
|
+
import Filters from '@shell/edit/auditlog.cattle.io.auditpolicy/Filters.vue';
|
|
13
|
+
import AdditionalRedactions from '@shell/edit/auditlog.cattle.io.auditpolicy/AdditionalRedactions.vue';
|
|
14
|
+
|
|
15
|
+
export default {
|
|
16
|
+
name: 'CRUAuditPolicy',
|
|
17
|
+
components: {
|
|
18
|
+
CruResource,
|
|
19
|
+
General,
|
|
20
|
+
Labels,
|
|
21
|
+
Loading,
|
|
22
|
+
NameNsDescription,
|
|
23
|
+
Filters,
|
|
24
|
+
AdditionalRedactions,
|
|
25
|
+
Tab,
|
|
26
|
+
Tabbed,
|
|
27
|
+
},
|
|
28
|
+
mixins: [CreateEditView, FormValidation],
|
|
29
|
+
|
|
30
|
+
created() {
|
|
31
|
+
if ( !this.value.spec ) {
|
|
32
|
+
this.value.spec = { enabled: false };
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
</script>
|
|
37
|
+
|
|
38
|
+
<template>
|
|
39
|
+
<Loading v-if="$fetchState.pending" />
|
|
40
|
+
<CruResource
|
|
41
|
+
:done-route="doneRoute"
|
|
42
|
+
:mode="mode"
|
|
43
|
+
:resource="value"
|
|
44
|
+
:subtypes="[]"
|
|
45
|
+
:validation-passed="fvFormIsValid"
|
|
46
|
+
:errors="errors"
|
|
47
|
+
@error="e=>errors = e"
|
|
48
|
+
@finish="save"
|
|
49
|
+
@cancel="done"
|
|
50
|
+
>
|
|
51
|
+
<NameNsDescription
|
|
52
|
+
v-if="!isView"
|
|
53
|
+
:value="value"
|
|
54
|
+
:mode="mode"
|
|
55
|
+
:namespaced="schema.attributes.namespaced"
|
|
56
|
+
:nameRequired="false"
|
|
57
|
+
:register-before-hook="registerBeforeHook"
|
|
58
|
+
/>
|
|
59
|
+
<Tabbed :side-tabs="true">
|
|
60
|
+
<Tab
|
|
61
|
+
name="general"
|
|
62
|
+
:label="t('auditPolicy.general.title')"
|
|
63
|
+
:weight="3"
|
|
64
|
+
>
|
|
65
|
+
<General
|
|
66
|
+
v-model:value="value.spec"
|
|
67
|
+
:mode="mode"
|
|
68
|
+
/>
|
|
69
|
+
</Tab>
|
|
70
|
+
<Tab
|
|
71
|
+
name="filters"
|
|
72
|
+
:label="t('auditPolicy.filters.title')"
|
|
73
|
+
:weight="2"
|
|
74
|
+
>
|
|
75
|
+
<Filters
|
|
76
|
+
v-model:value="value.spec"
|
|
77
|
+
:mode="mode"
|
|
78
|
+
/>
|
|
79
|
+
</Tab>
|
|
80
|
+
<Tab
|
|
81
|
+
name="additional-redactions"
|
|
82
|
+
:label="t('auditPolicy.additionalRedactions.title')"
|
|
83
|
+
:weight="1"
|
|
84
|
+
>
|
|
85
|
+
<AdditionalRedactions
|
|
86
|
+
v-model:value="value.spec"
|
|
87
|
+
:mode="mode"
|
|
88
|
+
/>
|
|
89
|
+
</Tab>
|
|
90
|
+
<Tab
|
|
91
|
+
name="labels-and-annotations"
|
|
92
|
+
label-key="generic.labelsAndAnnotations"
|
|
93
|
+
:weight="0"
|
|
94
|
+
>
|
|
95
|
+
<Labels
|
|
96
|
+
default-container-class="labels-and-annotations-container"
|
|
97
|
+
:value="value"
|
|
98
|
+
:mode="mode"
|
|
99
|
+
:display-side-by-side="false"
|
|
100
|
+
/>
|
|
101
|
+
</Tab>
|
|
102
|
+
</Tabbed>
|
|
103
|
+
</CruResource>
|
|
104
|
+
</template>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Types & Interfaces
|
|
2
|
+
export interface FilterRule {
|
|
3
|
+
action: string;
|
|
4
|
+
requestURI: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface RedactionRule {
|
|
8
|
+
headers?: string[];
|
|
9
|
+
paths?: string[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface VerbosityDetails {
|
|
13
|
+
headers?: boolean;
|
|
14
|
+
body?: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface Verbosity {
|
|
18
|
+
level: number;
|
|
19
|
+
request?: VerbosityDetails;
|
|
20
|
+
response?: VerbosityDetails;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface AuditPolicy {
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
verbosity?: Verbosity;
|
|
26
|
+
filters?: FilterRule[];
|
|
27
|
+
additionalRedactions?: RedactionRule[];
|
|
28
|
+
}
|
|
@@ -122,6 +122,15 @@ export default {
|
|
|
122
122
|
return _SPECIFY;
|
|
123
123
|
},
|
|
124
124
|
|
|
125
|
+
isGitHubDotComRepository() {
|
|
126
|
+
// It needs to be specifically https://github.com, if different it could have something like https://company-intranet.github.com/ or https://company.com/github.com/
|
|
127
|
+
return this.value.spec.repo?.toLowerCase().includes('https://github.com');
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
isBasicAuthSelected() {
|
|
131
|
+
return this.tempCachedValues.clientSecretName?.selected === AUTH_TYPE._BASIC;
|
|
132
|
+
},
|
|
133
|
+
|
|
125
134
|
steps() {
|
|
126
135
|
return [
|
|
127
136
|
{
|
|
@@ -189,7 +198,6 @@ export default {
|
|
|
189
198
|
handler: 'updateTls',
|
|
190
199
|
immediate: true
|
|
191
200
|
},
|
|
192
|
-
|
|
193
201
|
workspace(neu) {
|
|
194
202
|
if ( this.isCreate ) {
|
|
195
203
|
set(this.value, 'metadata.namespace', neu);
|
|
@@ -502,6 +510,12 @@ export default {
|
|
|
502
510
|
|
|
503
511
|
<h2 v-t="'fleet.gitRepo.auth.title'" />
|
|
504
512
|
|
|
513
|
+
<Banner
|
|
514
|
+
v-if="isGitHubDotComRepository && isBasicAuthSelected"
|
|
515
|
+
color="warning"
|
|
516
|
+
label-key="fleet.gitRepo.auth.githubdotcomPasswordBanner"
|
|
517
|
+
data-testid="gitrepo-githubdotcom-password-warning"
|
|
518
|
+
/>
|
|
505
519
|
<SelectOrCreateAuthSecret
|
|
506
520
|
data-testid="gitrepo-git-auth"
|
|
507
521
|
:value="value.spec.clientSecretName"
|
|
@@ -515,6 +529,7 @@ export default {
|
|
|
515
529
|
label-key="fleet.gitRepo.auth.git"
|
|
516
530
|
:cache-secrets="true"
|
|
517
531
|
:show-ssh-known-hosts="true"
|
|
532
|
+
:is-github-dot-com-repository="isGitHubDotComRepository"
|
|
518
533
|
@update:value="updateAuth($event, 'clientSecretName')"
|
|
519
534
|
@inputauthval="updateCachedAuthVal($event, 'clientSecretName')"
|
|
520
535
|
/>
|
|
@@ -50,6 +50,7 @@ export default {
|
|
|
50
50
|
RANCHER_TYPES,
|
|
51
51
|
fvFormRuleSets: [{ path: 'spec.displayName', rules: ['required'] }],
|
|
52
52
|
resourceQuotaKey: 0,
|
|
53
|
+
isQuotasValid: true,
|
|
53
54
|
};
|
|
54
55
|
},
|
|
55
56
|
computed: {
|
|
@@ -110,6 +111,9 @@ export default {
|
|
|
110
111
|
}
|
|
111
112
|
},
|
|
112
113
|
methods: {
|
|
114
|
+
validateQuotas(isValid) {
|
|
115
|
+
this.isQuotasValid = isValid;
|
|
116
|
+
},
|
|
113
117
|
async save(saveCb) {
|
|
114
118
|
try {
|
|
115
119
|
this.errors = [];
|
|
@@ -158,7 +162,7 @@ export default {
|
|
|
158
162
|
},
|
|
159
163
|
|
|
160
164
|
removeQuota(key) {
|
|
161
|
-
const isExtended = key.startsWith(`${ TYPES.EXTENDED }
|
|
165
|
+
const isExtended = key.startsWith(`${ TYPES.EXTENDED }`);
|
|
162
166
|
let resourceKey = key;
|
|
163
167
|
|
|
164
168
|
if (isExtended) {
|
|
@@ -176,6 +180,7 @@ export default {
|
|
|
176
180
|
delete limit.extended;
|
|
177
181
|
}
|
|
178
182
|
}
|
|
183
|
+
|
|
179
184
|
if (usedLimit?.extended && typeof usedLimit.extended[resourceKey] !== 'undefined') {
|
|
180
185
|
delete usedLimit.extended[resourceKey];
|
|
181
186
|
if (Object.keys(usedLimit.extended).length === 0) {
|
|
@@ -207,7 +212,7 @@ export default {
|
|
|
207
212
|
:resource="value"
|
|
208
213
|
:subtypes="[]"
|
|
209
214
|
:can-yaml="false"
|
|
210
|
-
:validation-passed="fvFormIsValid"
|
|
215
|
+
:validation-passed="fvFormIsValid && isQuotasValid"
|
|
211
216
|
@error="e=>errors = e"
|
|
212
217
|
@finish="save"
|
|
213
218
|
@cancel="done"
|
|
@@ -258,6 +263,7 @@ export default {
|
|
|
258
263
|
:mode="canEditTabElements"
|
|
259
264
|
:types="isStandaloneHarvester ? HARVESTER_TYPES : RANCHER_TYPES"
|
|
260
265
|
@remove="removeQuota"
|
|
266
|
+
@validationChanged="validateQuotas"
|
|
261
267
|
/>
|
|
262
268
|
</Tab>
|
|
263
269
|
<Tab
|