@flightctl/ui-components 1.1.0-rc1 → 1.1.0-rc2
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/dist/src/components/Repository/CreateRepository/CreateRepositoryForm.css +5 -1
- package/dist/types/imagebuilder/index.d.ts +1 -0
- package/dist/types/imagebuilder/index.d.ts.map +1 -1
- package/dist/types/imagebuilder/models/Status.d.ts +30 -0
- package/dist/types/imagebuilder/models/Status.d.ts.map +1 -0
- package/dist/types/imagebuilder/models/Status.js +3 -0
- package/dist/types/imagebuilder/models/Status.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/models/ApplicationProviderBase.d.ts +12 -0
- package/dist/types/models/ApplicationProviderBase.d.ts.map +1 -0
- package/dist/types/models/ApplicationProviderBase.js +3 -0
- package/dist/types/models/ApplicationProviderBase.js.map +1 -0
- package/dist/types/models/ApplicationProviderSpec.d.ts +5 -15
- package/dist/types/models/ApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/ApplicationUser.d.ts +7 -0
- package/dist/types/models/ApplicationUser.d.ts.map +1 -0
- package/dist/types/models/ApplicationUser.js +3 -0
- package/dist/types/models/ApplicationUser.js.map +1 -0
- package/dist/types/models/ComposeApplication.d.ts +7 -0
- package/dist/types/models/ComposeApplication.d.ts.map +1 -0
- package/dist/types/models/ComposeApplication.js +3 -0
- package/dist/types/models/ComposeApplication.js.map +1 -0
- package/dist/types/models/ContainerApplication.d.ts +18 -0
- package/dist/types/models/ContainerApplication.d.ts.map +1 -0
- package/dist/types/models/ContainerApplication.js +3 -0
- package/dist/types/models/ContainerApplication.js.map +1 -0
- package/dist/types/models/ContainerApplicationProperties.d.ts +13 -0
- package/dist/types/models/ContainerApplicationProperties.d.ts.map +1 -0
- package/dist/types/models/ContainerApplicationProperties.js +3 -0
- package/dist/types/models/ContainerApplicationProperties.js.map +1 -0
- package/dist/types/models/HelmApplication.d.ts +20 -0
- package/dist/types/models/HelmApplication.d.ts.map +1 -0
- package/dist/types/models/HelmApplication.js +3 -0
- package/dist/types/models/HelmApplication.js.map +1 -0
- package/dist/types/models/ImageApplicationProviderSpec.d.ts +2 -22
- package/dist/types/models/ImageApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/InlineApplicationProviderSpec.d.ts +2 -3
- package/dist/types/models/InlineApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/QuadletApplication.d.ts +8 -0
- package/dist/types/models/QuadletApplication.d.ts.map +1 -0
- package/dist/types/models/QuadletApplication.js +3 -0
- package/dist/types/models/QuadletApplication.js.map +1 -0
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.js +1 -1
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.js.map +1 -1
- package/dist/ui-components/src/components/DetailsPage/Tables/ApplicationsTable.js +1 -1
- package/dist/ui-components/src/components/DetailsPage/Tables/ApplicationsTable.js.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.js +5 -4
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.js +308 -363
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.js +18 -19
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.js +4 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.js +2 -2
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.d.ts +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.js +20 -23
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.js +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js +25 -45
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.d.ts +8 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.d.ts.map +1 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.js +37 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.js.map +1 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.js +5 -8
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/utils.d.ts +18 -18
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.js +2 -2
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.js.map +1 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.d.ts.map +1 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js +3 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.d.ts +7 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.d.ts.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.js +40 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.js.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.d.ts +8 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.d.ts.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.js +30 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.js.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.js +2 -2
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.js +22 -11
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.js +103 -36
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.d.ts +5 -2
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.js +22 -12
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.js +17 -8
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.d.ts +10 -9
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.js +109 -25
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.js.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.js +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.js.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.js +3 -3
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.js.map +1 -1
- package/dist/ui-components/src/components/form/validations.d.ts +20 -18
- package/dist/ui-components/src/components/form/validations.d.ts.map +1 -1
- package/dist/ui-components/src/components/form/validations.js +40 -11
- package/dist/ui-components/src/components/form/validations.js.map +1 -1
- package/dist/ui-components/src/constants.d.ts +7 -6
- package/dist/ui-components/src/constants.d.ts.map +1 -1
- package/dist/ui-components/src/constants.js +19 -11
- package/dist/ui-components/src/constants.js.map +1 -1
- package/dist/ui-components/src/types/deviceSpec.d.ts +44 -76
- package/dist/ui-components/src/types/deviceSpec.d.ts.map +1 -1
- package/dist/ui-components/src/types/deviceSpec.js +13 -26
- package/dist/ui-components/src/types/deviceSpec.js.map +1 -1
- package/dist/ui-components/src/types/extraTypes.d.ts +1 -7
- package/dist/ui-components/src/types/extraTypes.d.ts.map +1 -1
- package/dist/ui-components/src/types/extraTypes.js.map +1 -1
- package/dist/ui-components/src/types/rbac.d.ts +7 -1
- package/dist/ui-components/src/types/rbac.d.ts.map +1 -1
- package/dist/ui-components/src/types/rbac.js +6 -0
- package/dist/ui-components/src/types/rbac.js.map +1 -1
- package/dist/ui-components/src/utils/imageBuilds.d.ts +1 -0
- package/dist/ui-components/src/utils/imageBuilds.d.ts.map +1 -1
- package/dist/ui-components/src/utils/imageBuilds.js +7 -1
- package/dist/ui-components/src/utils/imageBuilds.js.map +1 -1
- package/dist/ui-components/src/utils/search.js +1 -1
- package/dist/ui-components/src/utils/search.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AuthProvider/CreateAuthProvider/utils.ts +2 -2
- package/src/components/DetailsPage/Tables/ApplicationsTable.tsx +2 -2
- package/src/components/Device/DeviceDetails/DeviceDetailsPage.tsx +10 -4
- package/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts +359 -425
- package/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.tsx +19 -29
- package/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.tsx +4 -12
- package/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.tsx +2 -16
- package/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.tsx +8 -7
- package/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.tsx +5 -5
- package/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsx +29 -101
- package/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.tsx +87 -0
- package/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.tsx +5 -10
- package/src/components/Fleet/CreateFleet/utils.ts +4 -4
- package/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.tsx +11 -8
- package/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.tsx +81 -0
- package/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.tsx +48 -0
- package/src/components/ImageBuilds/CreateImageBuildWizard/utils.ts +3 -3
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.tsx +35 -16
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.tsx +120 -42
- package/src/components/ImageBuilds/ImageBuildRow.tsx +41 -20
- package/src/components/ImageBuilds/ImageBuildsPage.tsx +34 -15
- package/src/components/ImageBuilds/ImageExportCards.tsx +176 -77
- package/src/components/Repository/CreateRepository/CreateRepositoryForm.css +5 -1
- package/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx +1 -0
- package/src/components/Repository/CreateRepository/utils.ts +4 -4
- package/src/components/form/validations.ts +112 -82
- package/src/constants.ts +19 -6
- package/src/types/deviceSpec.ts +68 -108
- package/src/types/extraTypes.ts +2 -12
- package/src/types/rbac.ts +6 -0
- package/src/utils/imageBuilds.ts +8 -0
- package/src/utils/search.ts +2 -2
|
@@ -10,31 +10,25 @@ import {
|
|
|
10
10
|
AppSpecType,
|
|
11
11
|
BatchForm,
|
|
12
12
|
BatchLimitType,
|
|
13
|
-
|
|
14
|
-
ComposeInlineAppForm,
|
|
13
|
+
ComposeAppForm,
|
|
15
14
|
DisruptionBudgetForm,
|
|
16
15
|
GitConfigTemplate,
|
|
17
|
-
|
|
16
|
+
HelmAppForm,
|
|
18
17
|
HttpConfigTemplate,
|
|
19
18
|
InlineConfigTemplate,
|
|
19
|
+
InlineFileForm,
|
|
20
20
|
KubeSecretTemplate,
|
|
21
21
|
PortMapping,
|
|
22
|
-
|
|
23
|
-
QuadletInlineAppForm,
|
|
22
|
+
QuadletAppForm,
|
|
24
23
|
RolloutPolicyForm,
|
|
25
24
|
SpecConfigTemplate,
|
|
26
25
|
SystemdUnitFormValue,
|
|
27
26
|
UpdatePolicyForm,
|
|
28
27
|
getAppIdentifier,
|
|
29
|
-
isComposeImageAppForm,
|
|
30
28
|
isGitConfigTemplate,
|
|
31
|
-
isHelmImageAppForm,
|
|
32
29
|
isHttpConfigTemplate,
|
|
33
30
|
isInlineConfigTemplate,
|
|
34
31
|
isKubeSecretTemplate,
|
|
35
|
-
isQuadletImageAppForm,
|
|
36
|
-
isQuadletInlineAppForm,
|
|
37
|
-
isSingleContainerAppForm,
|
|
38
32
|
} from '../../types/deviceSpec';
|
|
39
33
|
import { labelToString } from '../../utils/labels';
|
|
40
34
|
import { UpdateScheduleMode } from '../../utils/time';
|
|
@@ -74,6 +68,9 @@ const relativePathRegex = /^(?!\.\.\/|\.\.\$|\.\/)(\.\/)*[\w.-]+(?:\/[\w.-]+)*\/
|
|
|
74
68
|
export const MAX_TARGET_REVISION_LENGTH = 244;
|
|
75
69
|
const MAX_FILE_PATH_LENGTH = 253;
|
|
76
70
|
|
|
71
|
+
const HELM_NAMESPACE_MAX_LENGTH = 63;
|
|
72
|
+
const HELM_VALUES_FILE_EXT_REGEXP = /\.(yaml|yml)$/i;
|
|
73
|
+
|
|
77
74
|
const isInteger = (val: number | undefined) => val === undefined || Number.isInteger(val);
|
|
78
75
|
|
|
79
76
|
const validComposeFileNames = [
|
|
@@ -265,6 +262,48 @@ export const validOsImage = (t: TFunction, { isFleet }: { isFleet: boolean }) =>
|
|
|
265
262
|
},
|
|
266
263
|
);
|
|
267
264
|
|
|
265
|
+
export const validHelmNamespace = (t: TFunction) =>
|
|
266
|
+
Yup.string()
|
|
267
|
+
.max(
|
|
268
|
+
HELM_NAMESPACE_MAX_LENGTH,
|
|
269
|
+
t('Namespace must not exceed {{ max }} characters.', { max: HELM_NAMESPACE_MAX_LENGTH }),
|
|
270
|
+
)
|
|
271
|
+
.test(
|
|
272
|
+
'helm-namespace-format',
|
|
273
|
+
t(
|
|
274
|
+
'Namespace must only include lowercase letters, numbers, and hyphens. It must start and end with a letter or number.',
|
|
275
|
+
),
|
|
276
|
+
(value) => {
|
|
277
|
+
return !value || APPLICATION_NAME_REGEXP.test(value);
|
|
278
|
+
},
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
export const validHelmValuesFile = (t: TFunction) =>
|
|
282
|
+
Yup.string().test('helm-values-file', function (filename) {
|
|
283
|
+
if (!filename) {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
if (filename.length > MAX_FILE_PATH_LENGTH) {
|
|
287
|
+
return this.createError({
|
|
288
|
+
message: t('Values file path must not exceed {{ max }} characters.', {
|
|
289
|
+
max: MAX_FILE_PATH_LENGTH,
|
|
290
|
+
}),
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
if (filename.startsWith('/') || filename.includes('..')) {
|
|
294
|
+
return this.createError({
|
|
295
|
+
message: t('Values file path must be relative and cannot contain parent directory references (..).'),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (!HELM_VALUES_FILE_EXT_REGEXP.test(filename)) {
|
|
300
|
+
return this.createError({
|
|
301
|
+
message: t('Values file must have .yaml or .yml extension.'),
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
return true;
|
|
305
|
+
});
|
|
306
|
+
|
|
268
307
|
export const validLabelsSchema = (t: TFunction, forbiddenLabels?: string[]) =>
|
|
269
308
|
Yup.array()
|
|
270
309
|
.of(
|
|
@@ -370,11 +409,7 @@ const inlineAppFileSchema = (t: TFunction) =>
|
|
|
370
409
|
|
|
371
410
|
// Common test for unique file paths in inline applications
|
|
372
411
|
const uniqueFilePathsTest =
|
|
373
|
-
(t: TFunction) =>
|
|
374
|
-
(
|
|
375
|
-
files: (QuadletInlineAppForm | ComposeInlineAppForm)['files'] | undefined,
|
|
376
|
-
testContext: Yup.TestContext<Yup.AnyObject>,
|
|
377
|
-
) => {
|
|
412
|
+
(t: TFunction) => (files: InlineFileForm[] | undefined, testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
378
413
|
if (!files || files.length === 0) {
|
|
379
414
|
return true;
|
|
380
415
|
}
|
|
@@ -412,34 +447,33 @@ const uniqueFilePathsTest =
|
|
|
412
447
|
});
|
|
413
448
|
};
|
|
414
449
|
|
|
415
|
-
const composeFileName =
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (!file.path) {
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
|
-
// Extract filename from relative path (get last part after slash, or use whole path if no slash)
|
|
423
|
-
const fileName = file.path.includes('/') ? file.path.split('/').pop() || file.path : file.path;
|
|
424
|
-
if (!validComposeFileNames.includes(fileName)) {
|
|
425
|
-
return index;
|
|
426
|
-
}
|
|
450
|
+
const composeFileName = (t: TFunction) => (files: InlineFileForm[], testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
451
|
+
const invalidFiles = files
|
|
452
|
+
.map((file, index) => {
|
|
453
|
+
if (!file.path) {
|
|
427
454
|
return null;
|
|
428
|
-
}
|
|
429
|
-
|
|
455
|
+
}
|
|
456
|
+
// Extract filename from relative path (get last part after slash, or use whole path if no slash)
|
|
457
|
+
const fileName = file.path.includes('/') ? file.path.split('/').pop() || file.path : file.path;
|
|
458
|
+
if (!validComposeFileNames.includes(fileName)) {
|
|
459
|
+
return index;
|
|
460
|
+
}
|
|
461
|
+
return null;
|
|
462
|
+
})
|
|
463
|
+
.filter((index): index is number => index !== null);
|
|
430
464
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
465
|
+
if (invalidFiles.length > 0) {
|
|
466
|
+
const firstInvalidIndex = invalidFiles[0];
|
|
467
|
+
return testContext.createError({
|
|
468
|
+
path: `${testContext.path}[${firstInvalidIndex}].path`,
|
|
469
|
+
message: () =>
|
|
470
|
+
t('File name must be one of: {{ allowedFileNames }}', {
|
|
471
|
+
allowedFileNames: validComposeFileNameDisplay,
|
|
472
|
+
}),
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
return true;
|
|
476
|
+
};
|
|
443
477
|
|
|
444
478
|
// Helper to extract file extension from a path
|
|
445
479
|
const getFileExtension = (path: string): string => {
|
|
@@ -454,7 +488,7 @@ const isAtRoot = (path: string): boolean => {
|
|
|
454
488
|
|
|
455
489
|
// Validation for quadlet applications: checks for unsupported types first, then requires at least one supported type
|
|
456
490
|
const quadletFileTypesValidation =
|
|
457
|
-
(t: TFunction) => (files:
|
|
491
|
+
(t: TFunction) => (files: InlineFileForm[], testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
458
492
|
if (!files || files.length === 0) {
|
|
459
493
|
return true; // This is handled by the min(1) requirement
|
|
460
494
|
}
|
|
@@ -512,36 +546,35 @@ const quadletFileTypesValidation =
|
|
|
512
546
|
};
|
|
513
547
|
|
|
514
548
|
// Validation for quadlet applications: quadlet files must be at root level
|
|
515
|
-
const quadletFilesAtRoot =
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
549
|
+
const quadletFilesAtRoot = (t: TFunction) => (files: InlineFileForm[], testContext: Yup.TestContext<Yup.AnyObject>) => {
|
|
550
|
+
if (!files || files.length === 0) {
|
|
551
|
+
return true;
|
|
552
|
+
}
|
|
520
553
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
return null;
|
|
525
|
-
}
|
|
526
|
-
const ext = getFileExtension(file.path);
|
|
527
|
-
// Only check files with supported quadlet extensions
|
|
528
|
-
if (supportedQuadletExtensions.includes(ext) && !isAtRoot(file.path)) {
|
|
529
|
-
return index;
|
|
530
|
-
}
|
|
554
|
+
const invalidFiles = files
|
|
555
|
+
.map((file, index) => {
|
|
556
|
+
if (!file.path) {
|
|
531
557
|
return null;
|
|
532
|
-
}
|
|
533
|
-
|
|
558
|
+
}
|
|
559
|
+
const ext = getFileExtension(file.path);
|
|
560
|
+
// Only check files with supported quadlet extensions
|
|
561
|
+
if (supportedQuadletExtensions.includes(ext) && !isAtRoot(file.path)) {
|
|
562
|
+
return index;
|
|
563
|
+
}
|
|
564
|
+
return null;
|
|
565
|
+
})
|
|
566
|
+
.filter((index): index is number => index !== null);
|
|
534
567
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
568
|
+
if (invalidFiles.length > 0) {
|
|
569
|
+
const firstInvalidIndex = invalidFiles[0];
|
|
570
|
+
return testContext.createError({
|
|
571
|
+
path: `${testContext.path}[${firstInvalidIndex}].path`,
|
|
572
|
+
message: () => t('Quadlet files must be at root level (no subdirectories)'),
|
|
573
|
+
});
|
|
574
|
+
}
|
|
542
575
|
|
|
543
|
-
|
|
544
|
-
|
|
576
|
+
return true;
|
|
577
|
+
};
|
|
545
578
|
|
|
546
579
|
const PORT_NUMBER_REGEXP = /^\d+$/;
|
|
547
580
|
const MAX_PORT = 65535;
|
|
@@ -670,13 +703,13 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
670
703
|
.of(
|
|
671
704
|
Yup.lazy((value: AppForm) => {
|
|
672
705
|
// Container applications (image-based with ports and resources)
|
|
673
|
-
if (
|
|
706
|
+
if (value.appType === AppType.AppTypeContainer) {
|
|
674
707
|
return Yup.object().shape({
|
|
675
708
|
specType: Yup.string()
|
|
676
709
|
.oneOf([AppSpecType.OCI_IMAGE])
|
|
677
710
|
.required(t('Definition source must be image for this type of applications')),
|
|
678
711
|
appType: Yup.string().oneOf([AppType.AppTypeContainer]).required(t('Application type is required')),
|
|
679
|
-
name: validApplicationAndVolumeName(t)
|
|
712
|
+
name: validApplicationAndVolumeName(t),
|
|
680
713
|
image: Yup.string()
|
|
681
714
|
.required(t('Image is required.'))
|
|
682
715
|
.matches(APPLICATION_IMAGE_REGEXP, t('Application image includes invalid characters.')),
|
|
@@ -709,8 +742,8 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
709
742
|
}
|
|
710
743
|
|
|
711
744
|
// Helm applications
|
|
712
|
-
if (
|
|
713
|
-
return Yup.object<
|
|
745
|
+
if (value.appType === AppType.AppTypeHelm) {
|
|
746
|
+
return Yup.object<HelmAppForm>().shape({
|
|
714
747
|
specType: Yup.string()
|
|
715
748
|
.oneOf([AppSpecType.OCI_IMAGE])
|
|
716
749
|
.required(t('Definition source must be image for this type of applications')),
|
|
@@ -719,7 +752,7 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
719
752
|
image: Yup.string()
|
|
720
753
|
.required(t('Image is required.'))
|
|
721
754
|
.matches(APPLICATION_IMAGE_REGEXP, t('Application image includes invalid characters.')),
|
|
722
|
-
namespace:
|
|
755
|
+
namespace: validHelmNamespace(t),
|
|
723
756
|
valuesYaml: Yup.string().test('valid-yaml', t('YAML content is invalid.'), (value) => {
|
|
724
757
|
if (!value || value.trim() === '') {
|
|
725
758
|
return true;
|
|
@@ -731,16 +764,13 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
731
764
|
}
|
|
732
765
|
return true;
|
|
733
766
|
}),
|
|
734
|
-
|
|
735
|
-
// Since the UX design has the first field added by default, we will ignore all empty values files.
|
|
736
|
-
// The user can't add more values files if any is empty (though they can clear existing ones).
|
|
737
|
-
valuesFiles: Yup.array().of(Yup.string()),
|
|
767
|
+
valuesFiles: Yup.array().of(validHelmValuesFile(t)),
|
|
738
768
|
});
|
|
739
769
|
}
|
|
740
770
|
|
|
741
771
|
// Image applications (Quadlet or Compose)
|
|
742
|
-
if (
|
|
743
|
-
return Yup.object<
|
|
772
|
+
if (value.specType === AppSpecType.OCI_IMAGE) {
|
|
773
|
+
return Yup.object<QuadletAppForm | ComposeAppForm>().shape({
|
|
744
774
|
specType: Yup.string()
|
|
745
775
|
.oneOf([AppSpecType.OCI_IMAGE])
|
|
746
776
|
.required(t('Definition source must be image for this type of applications')),
|
|
@@ -757,8 +787,8 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
757
787
|
}
|
|
758
788
|
|
|
759
789
|
// Inline quadlet applications
|
|
760
|
-
if (
|
|
761
|
-
return Yup.object<
|
|
790
|
+
if (value.appType === AppType.AppTypeQuadlet && value.specType === AppSpecType.INLINE) {
|
|
791
|
+
return Yup.object<QuadletAppForm>().shape({
|
|
762
792
|
specType: appSpecTypeSchema(t),
|
|
763
793
|
appType: Yup.string().oneOf([AppType.AppTypeQuadlet]).required(t('Application type is required')),
|
|
764
794
|
name: validApplicationAndVolumeName(t).required(t('Name is required for quadlet applications.')),
|
|
@@ -772,7 +802,7 @@ export const validApplicationsSchema = (t: TFunction) => {
|
|
|
772
802
|
}
|
|
773
803
|
|
|
774
804
|
// Inline compose applications
|
|
775
|
-
return Yup.object<
|
|
805
|
+
return Yup.object<ComposeAppForm>().shape({
|
|
776
806
|
specType: appSpecTypeSchema(t),
|
|
777
807
|
appType: Yup.string().oneOf([AppType.AppTypeCompose]).required(t('Application type is required')),
|
|
778
808
|
name: validApplicationAndVolumeName(t).required(t('Name is required for compose applications.')),
|
package/src/constants.ts
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
|
-
const APP_TITLE = 'Edge Manager';
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const EVENT_PAGE_SIZE = 200; // It's 500 in OCP console
|
|
5
|
-
const CERTIFICATE_VALIDITY_IN_YEARS = 1;
|
|
1
|
+
export const APP_TITLE = 'Edge Manager';
|
|
2
|
+
export const CORE_API_VERSION = 'v1beta1';
|
|
3
|
+
export const IMAGEBUILDER_API_VERSION = 'v1alpha1';
|
|
6
4
|
|
|
7
|
-
export
|
|
5
|
+
export const PAGE_SIZE = 15;
|
|
6
|
+
export const EVENT_PAGE_SIZE = 200; // It's 500 in OCP console
|
|
7
|
+
|
|
8
|
+
export const CERTIFICATE_VALIDITY_IN_YEARS = 1;
|
|
9
|
+
|
|
10
|
+
export const getApiVersion = (api: 'flightctl' | 'imagebuilder' | 'alerts'): string | undefined => {
|
|
11
|
+
switch (api) {
|
|
12
|
+
case 'flightctl':
|
|
13
|
+
return CORE_API_VERSION;
|
|
14
|
+
case 'imagebuilder':
|
|
15
|
+
return IMAGEBUILDER_API_VERSION;
|
|
16
|
+
case 'alerts':
|
|
17
|
+
default:
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
};
|
package/src/types/deviceSpec.ts
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
ApplicationProviderSpec,
|
|
3
|
+
ComposeApplication,
|
|
4
4
|
ConfigProviderSpec,
|
|
5
|
+
ContainerApplication,
|
|
5
6
|
DisruptionBudget,
|
|
6
7
|
GitConfigProviderSpec,
|
|
8
|
+
HelmApplication,
|
|
7
9
|
HttpConfigProviderSpec,
|
|
8
10
|
ImageApplicationProviderSpec,
|
|
9
11
|
ImagePullPolicy,
|
|
12
|
+
InlineApplicationProviderSpec,
|
|
10
13
|
InlineConfigProviderSpec,
|
|
11
14
|
KubernetesSecretProviderSpec,
|
|
15
|
+
QuadletApplication,
|
|
12
16
|
} from '@flightctl/types';
|
|
13
|
-
import {
|
|
17
|
+
import { FlightCtlLabel } from './extraTypes';
|
|
14
18
|
import { UpdateScheduleMode } from '../utils/time';
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
// At the moment the "root" user is the default user when no user is specified.
|
|
17
21
|
export const RUN_AS_ROOT_USER = 'root';
|
|
22
|
+
export const RUN_AS_FLIGHTCTL_USER = 'flightctl';
|
|
18
23
|
|
|
19
24
|
export enum ConfigType {
|
|
20
25
|
GIT = 'git',
|
|
@@ -35,77 +40,12 @@ export type GitConfigTemplate = ConfigTemplate & {
|
|
|
35
40
|
path: string;
|
|
36
41
|
};
|
|
37
42
|
|
|
43
|
+
/** Used when adding a Compose/Quadlet app to choose image vs inline source. */
|
|
38
44
|
export enum AppSpecType {
|
|
39
45
|
OCI_IMAGE = 'image',
|
|
40
46
|
INLINE = 'inline',
|
|
41
47
|
}
|
|
42
48
|
|
|
43
|
-
type InlineContent = {
|
|
44
|
-
content?: string;
|
|
45
|
-
path: string;
|
|
46
|
-
base64?: boolean;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
type AppBase = {
|
|
50
|
-
appType: AppType;
|
|
51
|
-
specType: AppSpecType;
|
|
52
|
-
name?: string;
|
|
53
|
-
variables: { name: string; value: string }[];
|
|
54
|
-
volumes?: ApplicationVolumeForm[];
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
export type PortMapping = {
|
|
58
|
-
hostPort: string;
|
|
59
|
-
containerPort: string;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export type SingleContainerAppForm = AppBase & {
|
|
63
|
-
appType: AppType.AppTypeContainer;
|
|
64
|
-
specType: AppSpecType.OCI_IMAGE;
|
|
65
|
-
name: string;
|
|
66
|
-
image: string;
|
|
67
|
-
ports?: PortMapping[];
|
|
68
|
-
limits?: ApplicationResourceLimits;
|
|
69
|
-
runAs?: string;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
export type QuadletImageAppForm = AppBase & {
|
|
73
|
-
appType: AppType.AppTypeQuadlet;
|
|
74
|
-
specType: AppSpecType.OCI_IMAGE;
|
|
75
|
-
image: string;
|
|
76
|
-
runAs?: string;
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export type QuadletInlineAppForm = AppBase & {
|
|
80
|
-
appType: AppType.AppTypeQuadlet;
|
|
81
|
-
specType: AppSpecType.INLINE;
|
|
82
|
-
name: string; // transforms the field in required
|
|
83
|
-
files: InlineContent[];
|
|
84
|
-
runAs?: string;
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export type ComposeImageAppForm = AppBase & {
|
|
88
|
-
appType: AppType.AppTypeCompose;
|
|
89
|
-
specType: AppSpecType.OCI_IMAGE;
|
|
90
|
-
image: string;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export type ComposeInlineAppForm = AppBase & {
|
|
94
|
-
appType: AppType.AppTypeCompose;
|
|
95
|
-
specType: AppSpecType.INLINE;
|
|
96
|
-
name: string;
|
|
97
|
-
files: InlineContent[];
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
export type HelmImageAppForm = Omit<AppBase, 'variables' | 'volumes'> & {
|
|
101
|
-
appType: AppType.AppTypeHelm;
|
|
102
|
-
specType: AppSpecType.OCI_IMAGE;
|
|
103
|
-
image: string;
|
|
104
|
-
namespace?: string;
|
|
105
|
-
valuesFiles: Array<string>;
|
|
106
|
-
valuesYaml?: string;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
49
|
export const isGitConfigTemplate = (configTemplate: ConfigTemplate): configTemplate is GitConfigTemplate =>
|
|
110
50
|
configTemplate.type === ConfigType.GIT;
|
|
111
51
|
|
|
@@ -123,50 +63,70 @@ export type RepoConfig = GitConfigProviderSpec | HttpConfigProviderSpec;
|
|
|
123
63
|
export const isRepoConfig = (config: ConfigSourceProvider): config is RepoConfig =>
|
|
124
64
|
isGitProviderSpec(config) || isHttpProviderSpec(config);
|
|
125
65
|
|
|
126
|
-
export
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
| HelmImageAppForm;
|
|
133
|
-
|
|
134
|
-
export const isImageAppProvider = (
|
|
135
|
-
app: ApplicationProviderSpecFixed,
|
|
136
|
-
): app is ApplicationProviderSpecFixed & ImageApplicationProviderSpec => 'image' in app;
|
|
137
|
-
|
|
138
|
-
// Type guards for the 5 explicit types
|
|
139
|
-
export const isQuadletImageAppForm = (app: AppForm): app is QuadletImageAppForm =>
|
|
140
|
-
app.appType === AppType.AppTypeQuadlet && app.specType === AppSpecType.OCI_IMAGE;
|
|
141
|
-
export const isQuadletInlineAppForm = (app: AppForm): app is QuadletInlineAppForm =>
|
|
142
|
-
app.appType === AppType.AppTypeQuadlet && app.specType === AppSpecType.INLINE;
|
|
143
|
-
export const isComposeImageAppForm = (app: AppForm): app is ComposeImageAppForm =>
|
|
144
|
-
app.appType === AppType.AppTypeCompose && app.specType === AppSpecType.OCI_IMAGE;
|
|
145
|
-
export const isComposeInlineAppForm = (app: AppForm): app is ComposeInlineAppForm =>
|
|
146
|
-
app.appType === AppType.AppTypeCompose && app.specType === AppSpecType.INLINE;
|
|
147
|
-
export const isSingleContainerAppForm = (app: AppForm): app is SingleContainerAppForm =>
|
|
148
|
-
app.appType === AppType.AppTypeContainer;
|
|
149
|
-
export const isHelmImageAppForm = (app: AppForm): app is HelmImageAppForm =>
|
|
150
|
-
app.appType === AppType.AppTypeHelm && app.specType === AppSpecType.OCI_IMAGE;
|
|
66
|
+
export const isImageVariantApp = (
|
|
67
|
+
app: ApplicationProviderSpec,
|
|
68
|
+
): app is ApplicationProviderSpec & ImageApplicationProviderSpec => 'image' in app;
|
|
69
|
+
export const isInlineVariantApp = (
|
|
70
|
+
app: ApplicationProviderSpec,
|
|
71
|
+
): app is ApplicationProviderSpec & InlineApplicationProviderSpec => 'inline' in app;
|
|
151
72
|
|
|
152
73
|
export type ApplicationVolumeForm = {
|
|
153
74
|
name: string;
|
|
154
|
-
imageRef
|
|
155
|
-
imagePullPolicy
|
|
156
|
-
mountPath
|
|
75
|
+
imageRef: string;
|
|
76
|
+
imagePullPolicy: ImagePullPolicy;
|
|
77
|
+
mountPath: string;
|
|
157
78
|
};
|
|
158
79
|
|
|
80
|
+
export type PortMapping = {
|
|
81
|
+
hostPort: string;
|
|
82
|
+
containerPort: string;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type VariablesForm = { name: string; value: string }[];
|
|
86
|
+
|
|
87
|
+
export type InlineFileForm = { path: string; content?: string; base64?: boolean };
|
|
88
|
+
|
|
89
|
+
type InlineOrImageVariantForm = {
|
|
90
|
+
specType: AppSpecType;
|
|
91
|
+
image: string;
|
|
92
|
+
files: InlineFileForm[];
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type SingleContainerAppForm = Omit<ContainerApplication, 'ports' | 'resources' | 'envVars' | 'volumes'> & {
|
|
96
|
+
specType: AppSpecType.OCI_IMAGE;
|
|
97
|
+
ports: PortMapping[];
|
|
98
|
+
cpuLimit: string;
|
|
99
|
+
memoryLimit: string;
|
|
100
|
+
variables: VariablesForm;
|
|
101
|
+
volumes: ApplicationVolumeForm[];
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export type HelmAppForm = Omit<HelmApplication, 'values'> & {
|
|
105
|
+
specType: AppSpecType.OCI_IMAGE;
|
|
106
|
+
valuesYaml?: string;
|
|
107
|
+
valuesFiles: string[];
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export type QuadletAppForm = Omit<QuadletApplication, 'envVars' | 'volumes' | 'image' | 'inline'> &
|
|
111
|
+
InlineOrImageVariantForm & {
|
|
112
|
+
variables: VariablesForm;
|
|
113
|
+
volumes: ApplicationVolumeForm[];
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
export type ComposeAppForm = Omit<ComposeApplication, 'envVars' | 'volumes' | 'image' | 'inline'> &
|
|
117
|
+
InlineOrImageVariantForm & {
|
|
118
|
+
variables: VariablesForm;
|
|
119
|
+
volumes: ApplicationVolumeForm[];
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type AppForm = SingleContainerAppForm | HelmAppForm | QuadletAppForm | ComposeAppForm;
|
|
123
|
+
|
|
159
124
|
const hasTemplateVariables = (str: string) => /{{.+?}}/.test(str);
|
|
160
125
|
|
|
161
|
-
export const getAppIdentifier = (app: AppForm) => {
|
|
162
|
-
if (
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (isQuadletImageAppForm(app) || isComposeImageAppForm(app)) {
|
|
166
|
-
return app.name || app.image;
|
|
167
|
-
}
|
|
168
|
-
// Name is mandatory for inline applications
|
|
169
|
-
return app.name;
|
|
126
|
+
export const getAppIdentifier = (app: AppForm | ApplicationProviderSpec): string => {
|
|
127
|
+
if (app.name) return app.name;
|
|
128
|
+
if ('image' in app && app.image) return app.image;
|
|
129
|
+
return '';
|
|
170
130
|
};
|
|
171
131
|
|
|
172
132
|
const removeSlashes = (url: string | undefined) => (url || '').replace(/^\/+|\/+$/g, '');
|
|
@@ -214,7 +174,7 @@ export const isKubeProviderSpec = (providerSpec: ConfigProviderSpec): providerSp
|
|
|
214
174
|
|
|
215
175
|
export type InlineConfigTemplate = ConfigTemplate & {
|
|
216
176
|
type: ConfigType.INLINE;
|
|
217
|
-
files: Array<
|
|
177
|
+
files: Array<InlineFileForm & { permissions?: string; user?: string; group?: string }>;
|
|
218
178
|
};
|
|
219
179
|
|
|
220
180
|
export const isInlineConfigTemplate = (configTemplate: ConfigTemplate): configTemplate is InlineConfigTemplate =>
|
package/src/types/extraTypes.ts
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
AppType,
|
|
3
|
-
ApplicationEnvVars,
|
|
4
|
-
ApplicationVolumeProviderSpec,
|
|
5
2
|
AuthProvider,
|
|
6
3
|
Condition,
|
|
7
4
|
ConditionType,
|
|
@@ -9,7 +6,6 @@ import {
|
|
|
9
6
|
EnrollmentRequest,
|
|
10
7
|
FileContent,
|
|
11
8
|
Fleet,
|
|
12
|
-
ImageApplicationProviderSpec,
|
|
13
9
|
OAuth2ProviderSpec,
|
|
14
10
|
OIDCProviderSpec,
|
|
15
11
|
RelativePath,
|
|
@@ -55,16 +51,10 @@ export type AnnotationType = DeviceAnnotation; // Add more types when they are a
|
|
|
55
51
|
|
|
56
52
|
export const isFleet = (resource: ResourceSync | Fleet): resource is Fleet => resource.kind === 'Fleet';
|
|
57
53
|
|
|
58
|
-
// ApplicationProviderSpec's definition for inline files adds a Record<string, any>.
|
|
54
|
+
// ApplicationProviderSpec's definition for inline files adds a Record<string, any>.
|
|
55
|
+
// We use the fixed type to get proper Typescript checks for the field
|
|
59
56
|
export type InlineApplicationFileFixed = FileContent & RelativePath;
|
|
60
57
|
|
|
61
|
-
// "FixedApplicationProviderSpec" will need to be manually adjusted whenever the API definition changes
|
|
62
|
-
export type ApplicationProviderSpecFixed = ApplicationEnvVars &
|
|
63
|
-
ApplicationVolumeProviderSpec & {
|
|
64
|
-
name?: string;
|
|
65
|
-
appType: AppType;
|
|
66
|
-
} & (ImageApplicationProviderSpec | { inline: InlineApplicationFileFixed[] });
|
|
67
|
-
|
|
68
58
|
type CliArtifact = {
|
|
69
59
|
os: string;
|
|
70
60
|
arch: string;
|
package/src/types/rbac.ts
CHANGED
|
@@ -21,4 +21,10 @@ export enum RESOURCE {
|
|
|
21
21
|
ALERTS = 'alerts',
|
|
22
22
|
AUTH_PROVIDER = 'authproviders',
|
|
23
23
|
IMAGE_BUILD = 'imagebuilds',
|
|
24
|
+
IMAGE_BUILD_LOG = 'imagebuilds/log',
|
|
25
|
+
IMAGE_BUILD_CANCEL = 'imagebuilds/cancel',
|
|
26
|
+
IMAGE_EXPORT = 'imageexports',
|
|
27
|
+
IMAGE_EXPORT_LOG = 'imageexports/log',
|
|
28
|
+
IMAGE_EXPORT_CANCEL = 'imageexports/cancel',
|
|
29
|
+
IMAGE_EXPORT_DOWNLOAD = 'imageexports/download',
|
|
24
30
|
}
|
package/src/utils/imageBuilds.ts
CHANGED
|
@@ -99,6 +99,14 @@ export const isImageBuildActiveReason = (reason: ImageBuildConditionReason): boo
|
|
|
99
99
|
);
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
+
export const isImageBuildCancelable = (reason: ImageBuildConditionReason): boolean => {
|
|
103
|
+
return (
|
|
104
|
+
reason === ImageBuildConditionReason.ImageBuildConditionReasonPending ||
|
|
105
|
+
reason === ImageBuildConditionReason.ImageBuildConditionReasonBuilding ||
|
|
106
|
+
reason === ImageBuildConditionReason.ImageBuildConditionReasonPushing
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
|
|
102
110
|
export const isImageExportActiveReason = (reason: ImageExportConditionReason): boolean => {
|
|
103
111
|
return (
|
|
104
112
|
reason === ImageExportConditionReason.ImageExportConditionReasonPending ||
|
package/src/utils/search.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fuzzy from 'fuzzysearch';
|
|
2
|
-
import {
|
|
2
|
+
import { CORE_API_VERSION } from '../constants';
|
|
3
3
|
|
|
4
4
|
// Must be an even number for "getSearchResultsCount" to work
|
|
5
5
|
export const MAX_TOTAL_SEARCH_RESULTS = 10;
|
|
@@ -26,7 +26,7 @@ export const getSearchResultsCount = (labelCount: number, fleetCount: number) =>
|
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export const getEmptyFleetSearch = () => ({
|
|
29
|
-
apiVersion:
|
|
29
|
+
apiVersion: CORE_API_VERSION,
|
|
30
30
|
kind: 'Fleet',
|
|
31
31
|
metadata: {},
|
|
32
32
|
items: [],
|