@rancher/shell 0.1.0 → 0.1.1
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/styles/base/_basic.scss +0 -1
- package/assets/styles/base/_variables.scss +2 -0
- package/assets/styles/global/_labeled-input.scss +6 -1
- package/assets/styles/global/_select.scss +9 -0
- package/assets/styles/vendor/vue-js-modal.scss +4 -0
- package/assets/translations/en-us.yaml +240 -16
- package/assets/translations/zh-hans.yaml +335 -111
- package/chart/example.vue +1 -1
- package/chart/istio.vue +2 -2
- package/chart/logging/index.vue +2 -2
- package/chart/monitoring/alerting/index.vue +2 -2
- package/chart/monitoring/grafana/index.vue +2 -2
- package/chart/monitoring/index.vue +2 -2
- package/chart/monitoring/prometheus/index.vue +4 -4
- package/chart/rancher-alerting-drivers.vue +17 -3
- package/chart/rancher-backup/S3.vue +37 -4
- package/chart/rancher-backup/index.vue +3 -3
- package/cloud-credential/aws.vue +1 -1
- package/cloud-credential/azure.vue +1 -1
- package/cloud-credential/digitalocean.vue +1 -1
- package/cloud-credential/gcp.vue +1 -1
- package/cloud-credential/generic.vue +1 -1
- package/cloud-credential/harvester.vue +2 -2
- package/cloud-credential/linode.vue +1 -1
- package/cloud-credential/s3.vue +2 -2
- package/cloud-credential/vmwarevsphere.vue +1 -1
- package/components/ActionMenu.vue +11 -1
- package/components/Alert.vue +1 -1
- package/components/AssignTo.vue +2 -2
- package/components/AsyncButton.vue +25 -12
- package/components/AwsComplianceBanner.vue +44 -0
- package/components/BannerGraphic.vue +11 -2
- package/components/ChartReadme.vue +10 -2
- package/components/CompoundStatusBadge.vue +50 -0
- package/components/CopyToClipboardText.vue +25 -4
- package/components/CruResource.vue +185 -16
- package/components/CruResourceFooter.vue +17 -1
- package/components/EtcdInfoBanner.vue +1 -1
- package/components/FilterLabel.vue +254 -0
- package/components/GlobalRoleBindings.vue +2 -2
- package/components/GrafanaDashboard.vue +1 -1
- package/components/GrowlManager.vue +20 -9
- package/components/HarvesterServiceAddOnConfig.vue +2 -2
- package/components/Import.vue +2 -2
- package/components/LandingPagePreference.vue +2 -2
- package/components/Markdown.vue +44 -12
- package/components/ModalWithCard.vue +2 -2
- package/components/MoveModal.vue +1 -1
- package/components/PercentageBar.vue +1 -1
- package/components/PromptChangePassword.vue +1 -1
- package/components/PromptModal.vue +13 -2
- package/components/PromptRemove.vue +64 -33
- package/components/PromptRestore.vue +3 -3
- package/components/Questions/Boolean.vue +1 -1
- package/components/Questions/Float.vue +1 -1
- package/components/Questions/Int.vue +1 -1
- package/components/Questions/Reference.vue +1 -1
- package/components/Questions/String.vue +1 -1
- package/components/RelatedResources.vue +1 -1
- package/components/RelatedWorkloadsTable.vue +3 -1
- package/components/ResourceDetail/Masthead.vue +27 -9
- package/components/ResourceDetail/index.vue +72 -7
- package/components/ResourceList/Masthead.vue +22 -0
- package/components/ResourceList/ResourceLoadingIndicator.vue +137 -0
- package/components/ResourceList/index.vue +42 -7
- package/components/ResourceTable.vue +11 -2
- package/components/ResourceYaml.vue +7 -1
- package/components/SelectIconGrid.vue +14 -1
- package/components/SortableTable/THead.vue +1 -1
- package/components/SortableTable/debug.js +117 -0
- package/components/SortableTable/index.vue +200 -43
- package/components/SortableTable/paging.js +2 -12
- package/components/SortableTable/selection.js +3 -0
- package/components/SortableTable/sorting.js +3 -1
- package/components/Tabbed/Tab.vue +25 -4
- package/components/Tabbed/index.vue +133 -119
- package/components/TypeDescription.vue +1 -1
- package/components/VMConsoleBar.vue +1 -1
- package/components/Wizard.vue +53 -14
- package/components/YamlEditor.vue +10 -0
- package/components/__tests__/CopyCode.test.ts +1 -7
- package/components/__tests__/CruResource.test.ts +1 -8
- package/components/auth/AllowedPrincipals.vue +1 -1
- package/components/auth/AuthBanner.vue +2 -1
- package/components/auth/AzureWarning.vue +69 -0
- package/components/auth/RoleDetailEdit.vue +4 -4
- package/components/auth/login/ldap.vue +1 -1
- package/components/cards/ApplicationCard.vue +140 -0
- package/components/dialog/AddClusterMemberDialog.vue +1 -1
- package/components/dialog/AddCustomBadgeDialog.vue +4 -4
- package/components/dialog/AddProjectMemberDialog.vue +2 -2
- package/components/dialog/AddonConfigConfirmationDialog.vue +1 -1
- package/components/dialog/DrainNode.vue +3 -3
- package/components/dialog/ForceMachineRemoveDialog.vue +2 -2
- package/components/dialog/GenericPrompt.vue +2 -2
- package/components/dialog/RollbackWorkloadDialog.vue +2 -2
- package/components/dialog/RotateCertificatesDialog.vue +3 -3
- package/components/dialog/RotateEncryptionKeyDialog.vue +11 -6
- package/components/dialog/SaveAsRKETemplateDialog.vue +3 -3
- package/components/dialog/harvester/AddHotplugModal.vue +3 -3
- package/components/dialog/harvester/BackupModal.vue +3 -3
- package/components/dialog/harvester/CloneTemplate.vue +3 -3
- package/components/dialog/harvester/EjectCDROMDialog.vue +3 -3
- package/components/dialog/harvester/ExportImageDialog.vue +3 -3
- package/components/dialog/harvester/MaintenanceDialog.vue +2 -2
- package/components/dialog/harvester/MigrationDialog.vue +2 -2
- package/components/dialog/harvester/RestoreDialog.vue +2 -2
- package/components/dialog/harvester/SupportBundle.vue +2 -2
- package/components/dialog/harvester/UnplugVolume.vue +2 -2
- package/components/fleet/FleetBundleResources.vue +1 -1
- package/components/fleet/FleetBundles.vue +1 -1
- package/components/fleet/FleetResources.vue +5 -3
- package/components/fleet/ForceDirectedTreeChart/chartIcons.js +17 -0
- package/components/fleet/ForceDirectedTreeChart/index.vue +553 -0
- package/components/form/ArrayList.vue +22 -3
- package/components/form/BannerSettings.vue +3 -3
- package/components/form/ChangePassword.vue +2 -2
- package/components/form/Command.vue +28 -9
- package/components/form/Error.vue +50 -0
- package/components/form/Footer.vue +2 -5
- package/components/form/HealthCheck.vue +2 -2
- package/components/form/HookOption.vue +2 -2
- package/components/form/InputWithSelect.vue +12 -2
- package/components/form/KeyValue.vue +5 -2
- package/components/form/LabeledSelect.vue +27 -14
- package/components/form/Labels.vue +12 -0
- package/components/form/MatchExpressions.vue +44 -10
- package/components/form/Members/ClusterPermissionsEditor.vue +3 -3
- package/components/form/Members/MembershipEditor.vue +10 -1
- package/components/form/Members/ProjectMembershipEditor.vue +1 -0
- package/components/form/NameNsDescription.vue +202 -79
- package/components/form/Networking.vue +1 -1
- package/components/form/NodeAffinity.vue +41 -26
- package/components/form/NodeScheduling.vue +29 -3
- package/components/form/NotificationSettings.vue +2 -2
- package/components/form/Password.vue +1 -1
- package/components/form/PodAffinity.vue +64 -6
- package/components/form/PodSecurity.vue +2 -2
- package/components/form/Ports.vue +1 -1
- package/components/form/Probe.vue +60 -17
- package/components/form/ProjectMemberEditor.vue +3 -3
- package/components/form/ResourceQuota/NamespaceRow.vue +46 -2
- package/components/form/ResourceQuota/Project.vue +4 -0
- package/components/form/ResourceTabs/index.vue +19 -7
- package/components/form/RuleSelector.vue +1 -1
- package/components/form/Security.vue +56 -14
- package/components/form/Select.vue +52 -10
- package/components/form/SelectOrCreateAuthSecret.vue +70 -31
- package/components/form/ServiceNameSelect.vue +1 -1
- package/components/form/ServicePorts.vue +10 -2
- package/components/form/ShellInput.vue +1 -1
- package/components/form/SimpleSecretSelector.vue +2 -2
- package/components/form/Tolerations.vue +1 -1
- package/components/form/UnitInput.vue +12 -3
- package/components/form/ValueFromResource.vue +1 -1
- package/components/form/WorkloadPorts.vue +1 -1
- package/components/form/__tests__/Command.test.ts +63 -0
- package/components/form/__tests__/Error.test.ts +56 -0
- package/components/form/__tests__/MatchExpressions.test.ts +79 -0
- package/components/form/__tests__/Probe.test.ts +62 -0
- package/components/form/__tests__/Security.test.ts +55 -0
- package/components/form/__tests__/UnitInput.test.ts +31 -23
- package/components/formatter/BadgeStateFormatter.vue +1 -1
- package/components/formatter/Capitalize.vue +7 -0
- package/components/formatter/ClusterLink.vue +6 -2
- package/components/formatter/ClusterProvider.vue +36 -0
- package/components/formatter/DelayedValue.vue +43 -0
- package/components/formatter/Endpoints.vue +2 -2
- package/components/formatter/HarvesterDiskState.vue +1 -1
- package/components/formatter/HarvesterIpAddress.vue +37 -18
- package/components/formatter/HarvesterMigrationState.vue +1 -1
- package/components/formatter/HarvesterVmState.vue +1 -1
- package/components/formatter/LinkDetail.vue +11 -2
- package/components/formatter/LinkName.vue +2 -2
- package/components/formatter/LiveExpiryBadgeState.vue +1 -1
- package/components/formatter/LivePodRestarts.vue +47 -0
- package/components/formatter/MachineSummaryGraph.vue +51 -5
- package/components/formatter/PodsUsage.vue +5 -3
- package/components/formatter/Weight.vue +1 -1
- package/components/formatter/WorkloadHealthScale.vue +17 -6
- package/components/nav/HarvesterUpgrade.vue +15 -5
- package/components/nav/Header.vue +15 -6
- package/components/nav/Jump.vue +1 -1
- package/components/nav/NamespaceFilter.vue +30 -10
- package/components/nav/TopLevelMenu.vue +52 -14
- package/components/nav/WindowManager/ContainerLogs.vue +14 -2
- package/components/nav/WorkspaceSwitcher.vue +1 -1
- package/components/{NovncConsole.vue → novnc/NovncConsole.vue} +0 -0
- package/components/novnc/NovncConsoleItem.vue +89 -0
- package/components/novnc/NovncConsoleWrapper.vue +243 -0
- package/config/labels-annotations.js +6 -2
- package/config/product/explorer.js +7 -3
- package/config/product/fleet.js +4 -1
- package/config/product/manager.js +5 -6
- package/config/product/settings.js +12 -1
- package/config/query-params.js +2 -0
- package/config/roles.ts +5 -0
- package/config/settings.js +60 -63
- package/config/table-headers.js +47 -18
- package/config/types.js +24 -8
- package/content/docs/en-us/whats-new.md +25 -0
- package/core/plugin.ts +12 -2
- package/creators/app/init +7 -1
- package/creators/pkg/tsconfig.json +2 -3
- package/detail/catalog.cattle.io.app.vue +1 -1
- package/detail/cis.cattle.io.clusterscan.vue +1 -1
- package/detail/fleet.cattle.io.bundle.vue +73 -21
- package/detail/fleet.cattle.io.gitrepo.vue +5 -4
- package/detail/harvesterhci.io.host/HarvesterHostBasic.vue +25 -4
- package/detail/harvesterhci.io.host/HarvesterHostDisk.vue +2 -2
- package/detail/harvesterhci.io.virtualmachinebackup/index.vue +1 -1
- package/detail/helm.cattle.io.projecthelmchart.vue +1 -1
- package/detail/networking.k8s.io.ingress.vue +10 -2
- package/detail/pod.vue +37 -1
- package/detail/provisioning.cattle.io.cluster.vue +102 -15
- package/detail/workload/index.vue +163 -15
- package/edit/auth/azuread.vue +146 -34
- package/edit/auth/github.vue +3 -3
- package/edit/auth/googleoauth.vue +3 -3
- package/edit/auth/ldap/config.vue +15 -7
- package/edit/auth/ldap/index.vue +2 -2
- package/edit/auth/oidc.vue +3 -3
- package/edit/auth/saml.vue +3 -3
- package/edit/autoscaling.horizontalpodautoscaler/index.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/metric-identifier.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/metric-object-reference.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/metric-target.vue +1 -1
- package/edit/autoscaling.horizontalpodautoscaler/metrics-row.vue +1 -1
- package/edit/catalog.cattle.io.clusterrepo.vue +2 -2
- package/edit/cis.cattle.io.clusterscan.vue +4 -4
- package/edit/cis.cattle.io.clusterscanbenchmark.vue +1 -1
- package/edit/constraints.gatekeeper.sh.constraint/index.vue +1 -1
- package/edit/fleet.cattle.io.cluster.vue +1 -0
- package/edit/fleet.cattle.io.clustergroup.vue +1 -1
- package/edit/fleet.cattle.io.gitrepo.vue +290 -157
- package/edit/harvesterhci.io.host/HarvesterDisk.vue +4 -5
- package/edit/harvesterhci.io.host/index.vue +28 -19
- package/edit/harvesterhci.io.keypair.vue +1 -1
- package/edit/harvesterhci.io.managedchart/rancher-monitoring.vue +1 -1
- package/edit/harvesterhci.io.management.cluster.vue +1 -1
- package/edit/harvesterhci.io.networkattachmentdefinition.vue +2 -2
- package/edit/harvesterhci.io.setting/additional-ca.vue +1 -1
- package/edit/harvesterhci.io.setting/backup-target.vue +1 -1
- package/edit/harvesterhci.io.setting/http-proxy.vue +1 -1
- package/edit/harvesterhci.io.setting/index.vue +3 -3
- package/edit/harvesterhci.io.setting/overcommit-config.vue +4 -1
- package/edit/harvesterhci.io.setting/ssl-parameters.vue +1 -1
- package/edit/harvesterhci.io.setting/support-bundle-image.vue +1 -1
- package/edit/harvesterhci.io.setting/vip-pools.vue +1 -1
- package/edit/harvesterhci.io.setting/vm-force-reset-policy.vue +2 -2
- package/edit/harvesterhci.io.virtualmachinebackup.vue +2 -2
- package/edit/harvesterhci.io.virtualmachineimage.vue +2 -2
- package/edit/harvesterhci.io.virtualmachinetemplateversion.vue +26 -18
- package/edit/helm.cattle.io.projecthelmchart.vue +3 -3
- package/edit/k8s.cni.cncf.io.networkattachmentdefinition.vue +2 -2
- package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/AccessCredentialsUsers.vue +1 -1
- package/edit/kubevirt.io.virtualmachine/VirtualMachineAccessCredentials/index.vue +1 -1
- package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/DataTemplate.vue +1 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig/index.vue +2 -1
- package/edit/kubevirt.io.virtualmachine/VirtualMachineCpuMemory.vue +3 -1
- package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/__tests__/HarvesterEditNetwork.test.ts +41 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineNetwork/base.vue +79 -36
- package/edit/kubevirt.io.virtualmachine/VirtualMachineReserved.vue +54 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineSSHKey.vue +1 -1
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/index.vue +2 -3
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditContainer.test.ts +40 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditExisting.test.ts +102 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVMImage.test.ts +117 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/__tests__/HarvesterEditVolume.test.ts +74 -0
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/container.vue +59 -13
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/existing.vue +72 -16
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/vmImage.vue +74 -14
- package/edit/kubevirt.io.virtualmachine/VirtualMachineVolume/type/volume.vue +35 -9
- package/edit/kubevirt.io.virtualmachine/index.vue +33 -24
- package/edit/logging-flow/index.vue +1 -1
- package/edit/logging.banzaicloud.io.output/index.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/awsElasticsearch.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/azurestorage.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/cloudwatch.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/datadog.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/elasticsearch.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/file.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/forward.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/gcs.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/gelf.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/kafka.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/kinesisStream.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/logdna.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/logz.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/loki.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/newrelic.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/s3.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/splunkHec.vue +2 -2
- package/edit/logging.banzaicloud.io.output/providers/sumologic.vue +1 -1
- package/edit/logging.banzaicloud.io.output/providers/syslog.vue +2 -2
- package/edit/management.cattle.io.clusterroletemplatebinding.vue +2 -0
- package/edit/management.cattle.io.node.vue +71 -0
- package/edit/management.cattle.io.project.vue +28 -23
- package/edit/management.cattle.io.setting.vue +14 -3
- package/edit/management.cattle.io.user.vue +1 -1
- package/edit/monitoring.coreos.com.alertmanagerconfig/index.vue +4 -4
- package/edit/monitoring.coreos.com.alertmanagerconfig/receiverConfig.vue +13 -13
- package/edit/monitoring.coreos.com.alertmanagerconfig/routeConfig.vue +18 -10
- package/edit/monitoring.coreos.com.alertmanagerconfig/tls.vue +2 -2
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/email.vue +12 -7
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/opsgenie.vue +12 -7
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/pagerduty.vue +20 -11
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/slack.vue +13 -8
- package/edit/monitoring.coreos.com.alertmanagerconfig/types/webhook.vue +25 -7
- package/edit/monitoring.coreos.com.prometheusrule/AlertingRule.vue +2 -2
- package/edit/monitoring.coreos.com.prometheusrule/GroupRules.vue +20 -7
- package/edit/monitoring.coreos.com.prometheusrule/RecordingRule.vue +1 -1
- package/edit/monitoring.coreos.com.prometheusrule/index.vue +19 -8
- package/edit/monitoring.coreos.com.receiver/auth.vue +1 -1
- package/edit/monitoring.coreos.com.receiver/index.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/tls.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/types/email.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/types/opsgenie.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/types/pagerduty.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/types/slack.vue +2 -2
- package/edit/monitoring.coreos.com.receiver/types/webhook.banner.vue +1 -1
- package/edit/monitoring.coreos.com.receiver/types/webhook.vue +3 -3
- package/edit/monitoring.coreos.com.route.vue +2 -2
- package/edit/namespace.vue +0 -8
- package/edit/network.harvesterhci.io.clusternetwork/vlan.vue +1 -1
- package/edit/networking.istio.io.destinationrule/LoadBalancer.vue +2 -2
- package/edit/networking.istio.io.destinationrule/index.vue +1 -1
- package/edit/networking.k8s.io.ingress/Certificate.vue +5 -1
- package/edit/networking.k8s.io.ingress/Certificates.vue +5 -0
- package/edit/networking.k8s.io.ingress/DefaultBackend.vue +17 -2
- package/edit/networking.k8s.io.ingress/IngressClass.vue +63 -0
- package/edit/networking.k8s.io.ingress/Rule.vue +42 -6
- package/edit/networking.k8s.io.ingress/RulePath.vue +29 -5
- package/edit/networking.k8s.io.ingress/Rules.vue +11 -0
- package/edit/networking.k8s.io.ingress/index.vue +104 -15
- package/edit/networking.k8s.io.networkpolicy/PolicyRulePort.vue +1 -1
- package/edit/networking.k8s.io.networkpolicy/PolicyRuleTarget.vue +2 -2
- package/edit/networking.k8s.io.networkpolicy/index.vue +2 -2
- package/edit/persistentvolume/index.vue +1 -1
- package/edit/persistentvolume/plugins/awsElasticBlockStore.vue +2 -2
- package/edit/persistentvolume/plugins/azureDisk.vue +2 -2
- package/edit/persistentvolume/plugins/azureFile.vue +2 -2
- package/edit/persistentvolume/plugins/cephfs.vue +4 -4
- package/edit/persistentvolume/plugins/cinder.vue +2 -2
- package/edit/persistentvolume/plugins/csi.vue +2 -2
- package/edit/persistentvolume/plugins/fc.vue +4 -4
- package/edit/persistentvolume/plugins/flexVolume.vue +2 -2
- package/edit/persistentvolume/plugins/flocker.vue +1 -1
- package/edit/persistentvolume/plugins/gcePersistentDisk.vue +2 -2
- package/edit/persistentvolume/plugins/glusterfs.vue +2 -2
- package/edit/persistentvolume/plugins/hostPath.vue +1 -1
- package/edit/persistentvolume/plugins/iscsi.vue +4 -4
- package/edit/persistentvolume/plugins/local.vue +1 -1
- package/edit/persistentvolume/plugins/longhorn.vue +2 -2
- package/edit/persistentvolume/plugins/nfs.vue +2 -2
- package/edit/persistentvolume/plugins/photonPersistentDisk.vue +1 -1
- package/edit/persistentvolume/plugins/portworxVolume.vue +2 -2
- package/edit/persistentvolume/plugins/quobyte.vue +2 -2
- package/edit/persistentvolume/plugins/rbd.vue +4 -4
- package/edit/persistentvolume/plugins/scaleIO.vue +2 -2
- package/edit/persistentvolume/plugins/storageos.vue +2 -2
- package/edit/persistentvolume/plugins/vsphereVolume.vue +1 -1
- package/edit/persistentvolumeclaim.vue +24 -8
- package/edit/provisioning.cattle.io.cluster/ACE.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/CustomCommand.vue +8 -3
- package/edit/provisioning.cattle.io.cluster/DrainOptions.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/MachinePool.vue +15 -3
- package/edit/provisioning.cattle.io.cluster/RegistryConfigs.vue +16 -3
- package/edit/provisioning.cattle.io.cluster/S3Config.vue +2 -2
- package/edit/provisioning.cattle.io.cluster/SelectCredential.vue +1 -1
- package/edit/provisioning.cattle.io.cluster/__tests__/CustomCommand.tests.ts +1 -7
- package/edit/provisioning.cattle.io.cluster/import.vue +2 -1
- package/edit/provisioning.cattle.io.cluster/index.vue +26 -7
- package/edit/provisioning.cattle.io.cluster/rke2.vue +136 -48
- package/edit/resources.cattle.io.backup.vue +26 -8
- package/edit/resources.cattle.io.restore.vue +3 -3
- package/edit/secret/basic.vue +1 -1
- package/edit/secret/index.vue +80 -2
- package/edit/secret/registry.vue +2 -2
- package/edit/secret/ssh.vue +1 -1
- package/edit/secret/tls.vue +1 -1
- package/edit/service.vue +47 -11
- package/edit/serviceaccount.vue +1 -1
- package/edit/storage.k8s.io.storageclass/index.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/aws-ebs.vue +7 -3
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/azure-disk.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/azure-file.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/cinder.vue +2 -2
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/gce-pd.vue +2 -2
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/glusterfs.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/portworx-volume.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/quobyte.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/rbd.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/scaleio.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/storageos.vue +1 -1
- package/edit/storage.k8s.io.storageclass/provisioners/kubernetes.io/vsphere-volume.vue +1 -1
- package/edit/token.vue +3 -3
- package/edit/ui.cattle.io.navlink.vue +2 -2
- package/edit/workload/Job.vue +111 -23
- package/edit/workload/Upgrading.vue +77 -22
- package/edit/workload/__tests__/Job.test.ts +72 -0
- package/edit/workload/__tests__/Upgrading.test.ts +60 -0
- package/edit/workload/index.vue +13 -1085
- package/edit/workload/mixins/workload.js +900 -0
- package/edit/workload/storage/Mount.vue +2 -2
- package/edit/workload/storage/awsElasticBlockStore.vue +1 -1
- package/edit/workload/storage/azureDisk.vue +2 -2
- package/edit/workload/storage/azureFile.vue +1 -1
- package/edit/workload/storage/ephemeralVolume/index.vue +2 -2
- package/edit/workload/storage/gcePersistentDisk.vue +1 -1
- package/edit/workload/storage/hostPath.vue +1 -1
- package/edit/workload/storage/nfs.vue +2 -2
- package/edit/workload/storage/persistentVolumeClaim/index.vue +2 -2
- package/edit/workload/storage/persistentVolumeClaim/persistentvolumeclaim.vue +3 -3
- package/edit/workload/storage/secret.vue +2 -2
- package/edit/workload/storage/vsphereVolume.vue +1 -1
- package/edit/workload/types/Deployment.vue +377 -0
- package/edit/workload/types/Generic.vue +295 -0
- package/layouts/default.vue +26 -7
- package/layouts/error.vue +3 -2
- package/layouts/home.vue +12 -2
- package/layouts/plain.vue +18 -2
- package/layouts/unauthenticated.vue +2 -1
- package/list/catalog.cattle.io.clusterrepo.vue +1 -1
- package/list/fleet.cattle.io.bundle.vue +1 -1
- package/list/fleet.cattle.io.cluster.vue +1 -1
- package/list/fleet.cattle.io.clusterregistrationtoken.vue +1 -1
- package/list/harvesterhci.io.dashboard/HarvesterUpgrade.vue +9 -8
- package/list/harvesterhci.io.dashboard/UpgradeInfo.vue +40 -0
- package/list/harvesterhci.io.dashboard/index.vue +14 -36
- package/list/harvesterhci.io.host/index.vue +24 -12
- package/list/harvesterhci.io.networkattachmentdefinition.vue +1 -1
- package/list/harvesterhci.io.setting.vue +1 -1
- package/list/harvesterhci.io.virtualmachinebackup.vue +1 -1
- package/list/harvesterhci.io.virtualmachineimage.vue +36 -3
- package/list/harvesterhci.io.virtualmachinetemplateversion.vue +1 -5
- package/list/helm.cattle.io.projecthelmchart.vue +1 -1
- package/list/kubevirt.io.virtualmachine.vue +4 -2
- package/list/management.cattle.io.feature.vue +3 -3
- package/list/management.cattle.io.setting.vue +2 -2
- package/list/monitoring.coreos.com.alertmanagerconfig.vue +1 -1
- package/list/namespace.vue +3 -1
- package/list/node.vue +10 -3
- package/list/persistentvolumeclaim.vue +42 -0
- package/list/provisioning.cattle.io.cluster.vue +22 -20
- package/list/workload.vue +31 -6
- package/machine-config/amazonec2.vue +37 -12
- package/machine-config/azure.vue +3 -3
- package/machine-config/digitalocean.vue +2 -2
- package/machine-config/generic.vue +1 -1
- package/machine-config/harvester.vue +124 -25
- package/machine-config/linode.vue +2 -2
- package/machine-config/vmwarevsphere.vue +5 -5
- package/middleware/authenticated.js +36 -6
- package/middleware/unauthenticated.js +22 -0
- package/mixins/brand.js +50 -3
- package/mixins/browser-tab-visibility.js +37 -0
- package/mixins/chart.js +36 -4
- package/mixins/{compact-input.js → compact-input.ts} +5 -3
- package/mixins/form-validation.js +122 -0
- package/mixins/harvester-vm/index.js +134 -90
- package/mixins/labeled-form-element.ts +193 -0
- package/mixins/resource-fetch.js +173 -0
- package/models/cluster.x-k8s.io.machine.js +6 -2
- package/models/etcdbackup.js +4 -0
- package/models/event.js +4 -0
- package/models/fleet.cattle.io.bundle.js +1 -1
- package/models/fleet.cattle.io.gitrepo.js +10 -0
- package/models/harvester/harvesterhci.io.virtualmachinebackup.js +5 -2
- package/models/harvester/harvesterhci.io.virtualmachineimage.js +11 -8
- package/models/harvester/harvesterhci.io.virtualmachinetemplateversion.js +11 -2
- package/models/harvester/kubevirt.io.virtualmachine.js +2 -2
- package/models/harvester/kubevirt.io.virtualmachineinstance.js +1 -1
- package/models/harvester/node.js +27 -32
- package/models/harvester/persistentvolumeclaim.js +1 -1
- package/models/management.cattle.io.cluster.js +17 -11
- package/models/management.cattle.io.clusterroletemplatebinding.js +2 -2
- package/models/management.cattle.io.globalrole.js +19 -0
- package/models/management.cattle.io.node.js +10 -11
- package/models/management.cattle.io.project.js +60 -26
- package/models/management.cattle.io.roletemplate.js +19 -0
- package/models/monitoring.coreos.com.alertmanagerconfig.js +3 -2
- package/models/monitoring.coreos.com.prometheusrule.js +9 -0
- package/models/namespace.js +9 -1
- package/models/networking.k8s.io.ingress.js +17 -5
- package/models/persistentvolumeclaim.js +47 -1
- package/models/projectroletemplatebinding.js +2 -2
- package/models/provisioning.cattle.io.cluster.js +92 -13
- package/models/rke.cattle.io.etcdsnapshot.js +4 -0
- package/models/service.js +11 -5
- package/models/storage.k8s.io.storageclass.js +14 -1
- package/models/workload.js +7 -2
- package/nuxt.config.js +27 -7
- package/package.json +10 -14
- package/pages/about.vue +15 -1
- package/pages/account/index.vue +1 -1
- package/pages/auth/login.vue +17 -5
- package/pages/auth/setup.vue +47 -9
- package/pages/c/_cluster/_product/_resource/create.vue +1 -1
- package/pages/c/_cluster/_product/members/index.vue +6 -1
- package/pages/c/_cluster/_product/projectsnamespaces.vue +113 -11
- package/pages/c/_cluster/apps/charts/chart.vue +1 -1
- package/pages/c/_cluster/apps/charts/index.vue +2 -2
- package/pages/c/_cluster/apps/charts/install.vue +197 -19
- package/pages/c/_cluster/auth/config/index.vue +1 -1
- package/pages/c/_cluster/explorer/EventsTable.vue +1 -15
- package/pages/c/_cluster/explorer/index.vue +64 -35
- package/pages/c/_cluster/explorer/tools/index.vue +1 -1
- package/pages/c/_cluster/fleet/GitRepoGraphConfig.js +249 -0
- package/pages/c/_cluster/fleet/index.vue +47 -65
- package/pages/c/_cluster/harvester/airgapupgrade/index.vue +7 -4
- package/pages/c/_cluster/harvester/console/_uid/vnc.vue +7 -1
- package/pages/c/_cluster/monitoring/alertmanagerconfig/_alertmanagerconfigid/receiver.vue +8 -14
- package/pages/c/_cluster/monitoring/index.vue +1 -1
- package/pages/c/_cluster/monitoring/route-receiver/index.vue +1 -1
- package/pages/c/_cluster/settings/banners.vue +2 -2
- package/pages/c/_cluster/settings/brand.vue +62 -7
- package/pages/c/_cluster/settings/performance.vue +167 -0
- package/pages/diagnostic.vue +468 -0
- package/pages/fail-whale.vue +17 -5
- package/pages/home.vue +36 -22
- package/pages/plugins.vue +1 -1
- package/pages/prefs.vue +20 -7
- package/pages/support/index.vue +51 -9
- package/pkg/auto-import.js +1 -1
- package/pkg/dynamic-importer.lib.js +8 -0
- package/pkg/tsconfig.json +26 -9
- package/pkg/vue.config.js +8 -0
- package/plugins/console.js +29 -0
- package/plugins/dashboard-store/actions.js +171 -28
- package/plugins/dashboard-store/getters.js +13 -1
- package/plugins/dashboard-store/index.js +5 -1
- package/plugins/dashboard-store/mutations.js +72 -22
- package/plugins/dashboard-store/resource-class.js +259 -184
- package/plugins/i18n.js +9 -3
- package/plugins/steve/actions.js +16 -1
- package/plugins/steve/getters.js +9 -1
- package/plugins/steve/index.js +6 -2
- package/plugins/steve/mutations.js +100 -5
- package/plugins/steve/norman-class.js +8 -0
- package/plugins/steve/performanceTesting.js +5 -0
- package/plugins/steve/subscribe.js +144 -12
- package/plugins/steve/web-worker.steve-sub-worker.js +129 -0
- package/promptRemove/kubevirt.io.virtualmachine.vue +3 -17
- package/promptRemove/management.cattle.io.project.vue +128 -0
- package/promptRemove/pod.vue +131 -0
- package/rancher-components/BadgeState/BadgeState.spec.ts +12 -0
- package/{components → rancher-components/BadgeState}/BadgeState.vue +18 -10
- package/rancher-components/BadgeState/index.ts +1 -0
- package/{components/__tests__ → rancher-components/Banner}/Banner.test.ts +1 -1
- package/{components → rancher-components/Banner}/Banner.vue +22 -7
- package/rancher-components/Banner/index.ts +1 -0
- package/{components → rancher-components/Card}/Card.vue +58 -12
- package/rancher-components/Card/index.ts +1 -0
- package/{components/form → rancher-components/Form/Checkbox}/Checkbox.vue +118 -25
- package/rancher-components/Form/Checkbox/index.ts +1 -0
- package/{components/form/__tests__ → rancher-components/Form/LabeledInput}/LabeledInput.test.ts +13 -2
- package/rancher-components/Form/LabeledInput/LabeledInput.vue +341 -0
- package/rancher-components/Form/LabeledInput/index.ts +1 -0
- package/{components/form → rancher-components/Form/Radio}/RadioButton.vue +50 -22
- package/{components/form → rancher-components/Form/Radio}/RadioGroup.vue +76 -28
- package/rancher-components/Form/Radio/index.ts +2 -0
- package/rancher-components/Form/TextArea/TextAreaAutoGrow.vue +169 -0
- package/rancher-components/Form/TextArea/index.ts +1 -0
- package/rancher-components/Form/index.ts +4 -0
- package/{components/form → rancher-components/LabeledTooltip}/LabeledTooltip.vue +32 -11
- package/rancher-components/LabeledTooltip/index.ts +1 -0
- package/scripts/build-pkg.sh +4 -0
- package/scripts/publish-shell.sh +37 -18
- package/scripts/test-plugins-build.sh +115 -0
- package/store/catalog.js +4 -0
- package/store/growl.js +6 -0
- package/store/i18n.js +18 -9
- package/store/index.js +190 -107
- package/store/prefs.js +8 -2
- package/store/resource-fetch.js +44 -0
- package/store/type-map.js +43 -7
- package/store/uiplugins.ts +1 -1
- package/utils/favicon.js +40 -0
- package/utils/object.js +26 -9
- package/utils/promise.js +20 -0
- package/utils/socket.js +10 -1
- package/utils/string.js +16 -0
- package/utils/validators/formRules/__tests__/index.test.ts +928 -0
- package/utils/validators/formRules/index.ts +447 -0
- package/utils/validators/prometheusrule.js +1 -1
- package/utils/validators/vm.js +12 -5
- package/utils/width.js +39 -0
- package/yarn-error.log +196 -0
- package/components/NovncConsoleWrapper.vue +0 -150
- package/components/form/Container.vue +0 -143
- package/components/form/LabeledInput.vue +0 -245
- package/components/form/Scheduling.vue +0 -115
- package/components/form/TextAreaAutoGrow.vue +0 -127
- package/mixins/labeled-form-element.js +0 -137
|
@@ -0,0 +1,928 @@
|
|
|
1
|
+
import formRulesGenerator from '@shell/utils/validators/formRules';
|
|
2
|
+
|
|
3
|
+
const mockT = (key: string, args: any) => {
|
|
4
|
+
return JSON.stringify({
|
|
5
|
+
message: key,
|
|
6
|
+
...args
|
|
7
|
+
});
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe('formRules', () => {
|
|
11
|
+
const formRules = formRulesGenerator(mockT, { displayKey: 'testDisplayKey' });
|
|
12
|
+
|
|
13
|
+
it('"required" : returns undefined when value supplied', () => {
|
|
14
|
+
const testValue = 'foo';
|
|
15
|
+
const formRuleResult = formRules.required(testValue);
|
|
16
|
+
|
|
17
|
+
expect(formRuleResult).toBeUndefined();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('"required" : returns the correct message when value undefined', () => {
|
|
21
|
+
const formRuleResult = formRules.required(undefined);
|
|
22
|
+
const expectedResult = JSON.stringify({
|
|
23
|
+
message: 'validation.required',
|
|
24
|
+
key: 'testDisplayKey'
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('"cronSchedule" : returns undefined when valid cron string value supplied', () => {
|
|
31
|
+
const testValue = '0 * * * *';
|
|
32
|
+
const formRuleResult = formRules.cronSchedule(testValue);
|
|
33
|
+
|
|
34
|
+
expect(formRuleResult).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('"cronSchedule" : returns the correct message when invalid cron string value supplied', () => {
|
|
38
|
+
// specific logic of what constitutes a cron string is in the "cronstrue" function in an external library and not tested here
|
|
39
|
+
const testValue = '0 * * **';
|
|
40
|
+
const formRuleResult = formRules.cronSchedule(testValue);
|
|
41
|
+
const expectedResult = JSON.stringify({ message: 'validation.invalidCron' });
|
|
42
|
+
|
|
43
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('"isHttps" : returns undefined when valid https url value is supplied', () => {
|
|
47
|
+
const testValue = 'https://url.com';
|
|
48
|
+
const formRuleResult = formRules.isHttps('server-url')(testValue);
|
|
49
|
+
|
|
50
|
+
expect(formRuleResult).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('"isHttps" : returns correct message when http url value is supplied', () => {
|
|
54
|
+
const testValue = 'http://url.com';
|
|
55
|
+
const formRuleResult = formRules.isHttps('server-url')(testValue);
|
|
56
|
+
const expectedResult = JSON.stringify({ message: 'validation.setting.serverUrl.https' });
|
|
57
|
+
|
|
58
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('"interval" : returns undefined when valid hour interval value is supplied', () => {
|
|
62
|
+
const testValue = '5h';
|
|
63
|
+
const formRuleResult = formRules.interval(testValue);
|
|
64
|
+
|
|
65
|
+
expect(formRuleResult).toBeUndefined();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('"interval" : returns undefined when valid minute interval value is supplied', () => {
|
|
69
|
+
const testValue = '5m';
|
|
70
|
+
const formRuleResult = formRules.interval(testValue);
|
|
71
|
+
|
|
72
|
+
expect(formRuleResult).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('"interval" : returns undefined when valid second interval value is supplied', () => {
|
|
76
|
+
const testValue = '5s';
|
|
77
|
+
const formRuleResult = formRules.interval(testValue);
|
|
78
|
+
|
|
79
|
+
expect(formRuleResult).toBeUndefined();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('"interval" : returns correct message when interval unit is supplied but not integer', () => {
|
|
83
|
+
const testValue = 's';
|
|
84
|
+
const formRuleResult = formRules.interval(testValue);
|
|
85
|
+
const expectedResult = JSON.stringify({
|
|
86
|
+
message: 'validation.monitoring.route.interval',
|
|
87
|
+
key: 'testDisplayKey'
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('"interval" : returns correct message when interval integer is supplied but not unit', () => {
|
|
94
|
+
const testValue = '5';
|
|
95
|
+
const formRuleResult = formRules.interval(testValue);
|
|
96
|
+
const expectedResult = JSON.stringify({
|
|
97
|
+
message: 'validation.monitoring.route.interval',
|
|
98
|
+
key: 'testDisplayKey'
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('"containerImage" : returns undefined when valid container with image is supplied', () => {
|
|
105
|
+
const testValue = { image: 'imageName' };
|
|
106
|
+
const formRuleResult = formRules.containerImage(testValue);
|
|
107
|
+
|
|
108
|
+
expect(formRuleResult).toBeUndefined();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('"containerImage" : returns correct message when container without image is supplied', () => {
|
|
112
|
+
const testValue = { name: 'testName' };
|
|
113
|
+
const formRuleResult = formRules.containerImage(testValue);
|
|
114
|
+
const expectedResult = JSON.stringify({
|
|
115
|
+
message: 'workload.validation.containerImage',
|
|
116
|
+
name: testValue.name
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('"containerImages" : returns undefined when valid jobTemplate value is supplied', () => {
|
|
123
|
+
const testValue = { jobTemplate: { spec: { template: { spec: { containers: [{ image: 'imageName', name: 'name' }] } } } } };
|
|
124
|
+
const formRuleResult = formRules.containerImages(testValue);
|
|
125
|
+
|
|
126
|
+
expect(formRuleResult).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('"containerImages" : returns undefined when valid non-jobTemplate value is supplied', () => {
|
|
130
|
+
const testValue = { template: { spec: { containers: [{ image: 'imageName', name: 'name' }] } } };
|
|
131
|
+
const formRuleResult = formRules.containerImages(testValue);
|
|
132
|
+
|
|
133
|
+
expect(formRuleResult).toBeUndefined();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('"containerImages" : returns correct message when supplied value contains no containers', () => {
|
|
137
|
+
const testValue = { template: { spec: { containers: [] } } };
|
|
138
|
+
const formRuleResult = formRules.containerImages(testValue);
|
|
139
|
+
const expectedResult = JSON.stringify({
|
|
140
|
+
message: 'validation.required',
|
|
141
|
+
key: JSON.stringify({ message: 'workload.container.titles.containers' })
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('"containerImages" : returns correct message when supplied value has containers but one has no image', () => {
|
|
148
|
+
const testValue = { template: { spec: { containers: [{ name: 'testName' }] } } };
|
|
149
|
+
const formRuleResult = formRules.containerImages(testValue);
|
|
150
|
+
const expectedResult = JSON.stringify({
|
|
151
|
+
message: 'workload.validation.containerImage',
|
|
152
|
+
name: 'testName'
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
it('"ruleGroups" : returns undefined when rulegroups are supplied', () => {
|
|
159
|
+
const testValue = { groups: ['group1'] };
|
|
160
|
+
const formRuleResult = formRules.ruleGroups(testValue);
|
|
161
|
+
|
|
162
|
+
expect(formRuleResult).toBeUndefined();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('"groupsAreValid" : returns undefined when valid rulegroups are supplied', () => {
|
|
166
|
+
const testValue = [
|
|
167
|
+
{
|
|
168
|
+
name: 'group',
|
|
169
|
+
rules: [
|
|
170
|
+
{
|
|
171
|
+
alert: { name: 'alertname' },
|
|
172
|
+
record: { name: 'recordname' },
|
|
173
|
+
expr: { name: 'exprname' },
|
|
174
|
+
labels: ['label1']
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
];
|
|
179
|
+
const formRuleResult = formRules.groupsAreValid(testValue);
|
|
180
|
+
|
|
181
|
+
expect(formRuleResult).toBeUndefined();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('"groupsAreValid" : returns correct message when rules are empty', () => {
|
|
185
|
+
const testValue = [
|
|
186
|
+
{
|
|
187
|
+
name: 'group',
|
|
188
|
+
rules: []
|
|
189
|
+
}
|
|
190
|
+
];
|
|
191
|
+
const formRuleResult = formRules.groupsAreValid(testValue);
|
|
192
|
+
const expectedResult = JSON.stringify({
|
|
193
|
+
message: 'validation.prometheusRule.groups.valid.singleEntry',
|
|
194
|
+
index: 1
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it('"groupsAreValid" : returns correct message when rule alert is empty', () => {
|
|
201
|
+
const testValue = [
|
|
202
|
+
{
|
|
203
|
+
name: 'group',
|
|
204
|
+
rules: [
|
|
205
|
+
{
|
|
206
|
+
alert: '',
|
|
207
|
+
record: '',
|
|
208
|
+
expr: '',
|
|
209
|
+
labels: { severity: 'none' }
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
];
|
|
214
|
+
const formRuleResult = formRules.groupsAreValid(testValue);
|
|
215
|
+
const expectedResult = JSON.stringify({
|
|
216
|
+
message: 'validation.prometheusRule.groups.valid.rule.alertName',
|
|
217
|
+
groupIndex: 1,
|
|
218
|
+
ruleIndex: 1
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('"groupsAreValid" : returns correct message when rule record is empty', () => {
|
|
225
|
+
const testValue = [
|
|
226
|
+
{
|
|
227
|
+
name: 'group',
|
|
228
|
+
rules: [
|
|
229
|
+
{
|
|
230
|
+
alert: 'name',
|
|
231
|
+
record: '',
|
|
232
|
+
expr: '',
|
|
233
|
+
labels: { severity: 'none' }
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
];
|
|
238
|
+
const formRuleResult = formRules.groupsAreValid(testValue);
|
|
239
|
+
const expectedResult = JSON.stringify({
|
|
240
|
+
message: 'validation.prometheusRule.groups.valid.rule.recordName',
|
|
241
|
+
groupIndex: 1,
|
|
242
|
+
ruleIndex: 1
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('"groupsAreValid" : returns correct message when rule expr is empty', () => {
|
|
249
|
+
const testValue = [
|
|
250
|
+
{
|
|
251
|
+
name: 'group',
|
|
252
|
+
rules: [
|
|
253
|
+
{
|
|
254
|
+
alert: 'name',
|
|
255
|
+
record: 'record',
|
|
256
|
+
expr: '',
|
|
257
|
+
labels: { severity: 'none' }
|
|
258
|
+
}
|
|
259
|
+
]
|
|
260
|
+
}
|
|
261
|
+
];
|
|
262
|
+
const formRuleResult = formRules.groupsAreValid(testValue);
|
|
263
|
+
const expectedResult = JSON.stringify({
|
|
264
|
+
message: 'validation.prometheusRule.groups.valid.rule.expr',
|
|
265
|
+
groupIndex: 1,
|
|
266
|
+
ruleIndex: 1
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it('"groupsAreValid" : returns correct message when rule labels is empty', () => {
|
|
273
|
+
const testValue = [
|
|
274
|
+
{
|
|
275
|
+
name: 'group',
|
|
276
|
+
rules: [
|
|
277
|
+
{
|
|
278
|
+
alert: 'name',
|
|
279
|
+
record: 'record',
|
|
280
|
+
expr: 'expr',
|
|
281
|
+
labels: {}
|
|
282
|
+
}
|
|
283
|
+
]
|
|
284
|
+
}
|
|
285
|
+
];
|
|
286
|
+
const formRuleResult = formRules.groupsAreValid(testValue);
|
|
287
|
+
const expectedResult = JSON.stringify({
|
|
288
|
+
message: 'validation.prometheusRule.groups.valid.rule.labels',
|
|
289
|
+
groupIndex: 1,
|
|
290
|
+
ruleIndex: 1
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('"matching" : returns undefined when is not empty and match_re is not empty', () => {
|
|
297
|
+
const testValue = { match: 'matchValue', match_re: 'match_reValue' };
|
|
298
|
+
const formRuleResult = formRules.matching(testValue);
|
|
299
|
+
|
|
300
|
+
expect(formRuleResult).toBeUndefined();
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('"matching" : returns undefined when match is empty and match_re is not empty', () => {
|
|
304
|
+
const testValue = { match: '', match_re: 'match_reValue' };
|
|
305
|
+
const formRuleResult = formRules.matching(testValue);
|
|
306
|
+
|
|
307
|
+
expect(formRuleResult).toBeUndefined();
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it('"matching" : returns undefined when match is not empty and match_re is empty', () => {
|
|
311
|
+
const testValue = { match: 'matchValue', match_re: '' };
|
|
312
|
+
const formRuleResult = formRules.matching(testValue);
|
|
313
|
+
|
|
314
|
+
expect(formRuleResult).toBeUndefined();
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
it('"matching" : returns correct message when match is empty and match_re is empty', () => {
|
|
318
|
+
const testValue = { match: '', match_re: '' };
|
|
319
|
+
const formRuleResult = formRules.matching(testValue);
|
|
320
|
+
const expectedResult = JSON.stringify({ message: 'validation.monitoring.route.match' });
|
|
321
|
+
|
|
322
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('"clusterName" : returns undefined when "isRke2" is false', () => {
|
|
326
|
+
const testValue = 'clusterName';
|
|
327
|
+
const formRuleResult = formRules.clusterName(false)(testValue);
|
|
328
|
+
|
|
329
|
+
expect(formRuleResult).toBeUndefined();
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('"clusterName" : returns undefined when "isRke2" is true and clusterName is valid', () => {
|
|
333
|
+
const testValue = 'clustername';
|
|
334
|
+
const formRuleResult = formRules.clusterName(true)(testValue);
|
|
335
|
+
|
|
336
|
+
expect(formRuleResult).toBeUndefined();
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it('"clusterName" : returns correct message when "isRke2" is true and clusterName is 5 characters long with "c-" as a prefix', () => {
|
|
340
|
+
const testValue = 'c-12345';
|
|
341
|
+
const formRuleResult = formRules.clusterName(true)(testValue);
|
|
342
|
+
const expectedResult = JSON.stringify({ message: 'validation.cluster.name' });
|
|
343
|
+
|
|
344
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it('"clusterName" : returns undefined when "isRke2" is true and clusterName is less than 5 characters long with "c-" as a prefix', () => {
|
|
348
|
+
const testValue = 'c-1234';
|
|
349
|
+
const formRuleResult = formRules.clusterName(true)(testValue);
|
|
350
|
+
|
|
351
|
+
expect(formRuleResult).toBeUndefined();
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
it('"clusterName" : returns undefined when "isRke2" is true and clusterName is more than 5 characters long with "c-" as a prefix', () => {
|
|
355
|
+
const testValue = 'c-123456';
|
|
356
|
+
const formRuleResult = formRules.clusterName(true)(testValue);
|
|
357
|
+
|
|
358
|
+
expect(formRuleResult).toBeUndefined();
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it('"roleTemplateRules" : returns undefined when type is RBAC role and value contains valid rules', () => {
|
|
362
|
+
const testValue: [{}] = [
|
|
363
|
+
{
|
|
364
|
+
verbs: ['verb1'], resources: ['resource1'], apiGroups: ['apiGroup1']
|
|
365
|
+
}
|
|
366
|
+
];
|
|
367
|
+
const formRuleResult = formRules.roleTemplateRules('rbac.authorization.k8s.io.role')(testValue);
|
|
368
|
+
|
|
369
|
+
expect(formRuleResult).toBeUndefined();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
it('"roleTemplateRules" : returns correct message when type is RBAC role and value is missing verbs', () => {
|
|
373
|
+
const testValue: [{}] = [
|
|
374
|
+
{
|
|
375
|
+
verbs: [], resources: ['resource1'], apiGroups: ['apiGroup1']
|
|
376
|
+
}
|
|
377
|
+
];
|
|
378
|
+
const formRuleResult = formRules.roleTemplateRules('rbac.authorization.k8s.io.role')(testValue);
|
|
379
|
+
const expectedResult = JSON.stringify({ message: 'validation.roleTemplate.roleTemplateRules.missingVerb' });
|
|
380
|
+
|
|
381
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it('"roleTemplateRules" : returns correct message when type is RBAC role and value is missing resources', () => {
|
|
385
|
+
const testValue: [{}] = [
|
|
386
|
+
{
|
|
387
|
+
verbs: ['verb1'], resources: [], apiGroups: ['apiGroup1']
|
|
388
|
+
}
|
|
389
|
+
];
|
|
390
|
+
const formRuleResult = formRules.roleTemplateRules('rbac.authorization.k8s.io.role')(testValue);
|
|
391
|
+
const expectedResult = JSON.stringify({ message: 'validation.roleTemplate.roleTemplateRules.missingResource' });
|
|
392
|
+
|
|
393
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('"roleTemplateRules" : returns correct message when type is RBAC role and value is missing apiGroups', () => {
|
|
397
|
+
const testValue: [{}] = [
|
|
398
|
+
{
|
|
399
|
+
verbs: ['verb1'], resources: ['resource1'], apiGroups: []
|
|
400
|
+
}
|
|
401
|
+
];
|
|
402
|
+
const formRuleResult = formRules.roleTemplateRules('rbac.authorization.k8s.io.role')(testValue);
|
|
403
|
+
const expectedResult = JSON.stringify({ message: 'validation.roleTemplate.roleTemplateRules.missingApiGroup' });
|
|
404
|
+
|
|
405
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
it('"roleTemplateRules" : returns undefined when type is not RBAC role and value contains valid rules', () => {
|
|
409
|
+
const testValue: [{}] = [
|
|
410
|
+
{
|
|
411
|
+
verbs: ['verb1'], nonResourceURLs: ['nonResourceURL1'], resources: ['resource1'], apiGroups: ['apiGroup1']
|
|
412
|
+
}
|
|
413
|
+
];
|
|
414
|
+
const formRuleResult = formRules.roleTemplateRules('nonrbactype')(testValue);
|
|
415
|
+
|
|
416
|
+
expect(formRuleResult).toBeUndefined();
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it('"roleTemplateRules" : returns undefined when type is not RBAC role and value is missing resources and nonResourceURLs and apiGroups', () => {
|
|
420
|
+
const testValue: [{}] = [
|
|
421
|
+
{
|
|
422
|
+
verbs: ['verb1'], nonResourceURLs: [], resources: [], apiGroups: []
|
|
423
|
+
}
|
|
424
|
+
];
|
|
425
|
+
const formRuleResult = formRules.roleTemplateRules('nonrbactype')(testValue);
|
|
426
|
+
const expectedResult = JSON.stringify({ message: 'validation.roleTemplate.roleTemplateRules.missingOneResource' });
|
|
427
|
+
|
|
428
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it('"servicePort" : returns undefined when servicePort is valid', () => {
|
|
432
|
+
const testValue = {
|
|
433
|
+
name: 'portName',
|
|
434
|
+
nodePort: '8081',
|
|
435
|
+
port: '8082',
|
|
436
|
+
targetPort: '8083',
|
|
437
|
+
idx: 0
|
|
438
|
+
};
|
|
439
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
440
|
+
|
|
441
|
+
expect(formRuleResult).toBeUndefined();
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it('"servicePort" : returns correct message when servicePort name is empty', () => {
|
|
445
|
+
const testValue = {
|
|
446
|
+
name: '',
|
|
447
|
+
nodePort: '8081',
|
|
448
|
+
port: '8082',
|
|
449
|
+
targetPort: '8083',
|
|
450
|
+
idx: 0
|
|
451
|
+
};
|
|
452
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
453
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.ports.name.required', position: 1 });
|
|
454
|
+
|
|
455
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it('"servicePort" : returns correct message when servicePort nodePort is not an integer', () => {
|
|
459
|
+
const testValue = {
|
|
460
|
+
name: 'portName',
|
|
461
|
+
nodePort: 'test',
|
|
462
|
+
port: '8082',
|
|
463
|
+
targetPort: '8083',
|
|
464
|
+
idx: 0
|
|
465
|
+
};
|
|
466
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
467
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.ports.nodePort.requiredInt', position: 1 });
|
|
468
|
+
|
|
469
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
it('"servicePort" : returns correct message when servicePort port is not an integer', () => {
|
|
473
|
+
const testValue = {
|
|
474
|
+
name: 'portName',
|
|
475
|
+
nodePort: '8081',
|
|
476
|
+
port: 'test',
|
|
477
|
+
targetPort: '8083',
|
|
478
|
+
idx: 0
|
|
479
|
+
};
|
|
480
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
481
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.ports.port.requiredInt', position: 1 });
|
|
482
|
+
|
|
483
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
it('"servicePort" : returns correct message when port is not provided', () => {
|
|
487
|
+
const testValue = {
|
|
488
|
+
name: 'portName',
|
|
489
|
+
nodePort: '8081',
|
|
490
|
+
targetPort: '8083',
|
|
491
|
+
idx: 0
|
|
492
|
+
};
|
|
493
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
494
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.ports.port.required', position: 1 });
|
|
495
|
+
|
|
496
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
it('"servicePort" : returns correct message when targetPort port is not an integer but is a valid dnsLabelIanaServiceName', () => {
|
|
500
|
+
const testValue = {
|
|
501
|
+
name: 'portName',
|
|
502
|
+
nodePort: '8081',
|
|
503
|
+
port: '8082',
|
|
504
|
+
targetPort: 'test',
|
|
505
|
+
idx: 0
|
|
506
|
+
};
|
|
507
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
508
|
+
|
|
509
|
+
expect(formRuleResult).toBeUndefined();
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
it('"servicePort" : returns correct message when targetPort port is not an integer but is not a valid dnsLabelIanaServiceName', () => {
|
|
513
|
+
const testValue = {
|
|
514
|
+
name: 'portName',
|
|
515
|
+
nodePort: '8081',
|
|
516
|
+
port: '8082',
|
|
517
|
+
targetPort: 'te st',
|
|
518
|
+
idx: 0
|
|
519
|
+
};
|
|
520
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
521
|
+
const expectedResult = JSON.stringify({
|
|
522
|
+
message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: 'Space'
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
526
|
+
});
|
|
527
|
+
|
|
528
|
+
it('"servicePort" : returns correct message when targetPort port is below the valid range', () => {
|
|
529
|
+
const testValue = {
|
|
530
|
+
name: 'portName',
|
|
531
|
+
nodePort: '8081',
|
|
532
|
+
port: '8082',
|
|
533
|
+
targetPort: '0',
|
|
534
|
+
idx: 0
|
|
535
|
+
};
|
|
536
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
537
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.ports.targetPort.between', position: 1 });
|
|
538
|
+
|
|
539
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
it('"servicePort" : returns correct message when targetPort port is above the valid range', () => {
|
|
543
|
+
const testValue = {
|
|
544
|
+
name: 'portName',
|
|
545
|
+
nodePort: '8081',
|
|
546
|
+
port: '8082',
|
|
547
|
+
targetPort: '65536',
|
|
548
|
+
idx: 0
|
|
549
|
+
};
|
|
550
|
+
const formRuleResult = formRules.servicePort(testValue);
|
|
551
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.ports.targetPort.between', position: 1 });
|
|
552
|
+
|
|
553
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it('"clusterIp" : always returns undefined', () => {
|
|
557
|
+
const formRuleResult = formRules.clusterIp('');
|
|
558
|
+
|
|
559
|
+
expect(formRuleResult).toBeUndefined();
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
it('"externalName" : returns undefined when value is a valid externalName', () => {
|
|
563
|
+
const testValue = 'test';
|
|
564
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
565
|
+
|
|
566
|
+
expect(formRuleResult).toBeUndefined();
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
it('"externalName" : returns expected message when value empty', () => {
|
|
570
|
+
const testValue = '';
|
|
571
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
572
|
+
const expectedResult = JSON.stringify({ message: 'validation.service.externalName.none' });
|
|
573
|
+
|
|
574
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
it('"externalName" : returns expected message when value starts with a dot', () => {
|
|
578
|
+
const testValue = '.hostname';
|
|
579
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
580
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.startDot', key: 'testDisplayKey' });
|
|
581
|
+
|
|
582
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
583
|
+
});
|
|
584
|
+
|
|
585
|
+
it('"externalName" : returns expected message when value starts is too long for a hostname', () => {
|
|
586
|
+
const testValue = 'There.are.many.variations.of.passages.of.Lorem.Ipsum.available.but.the.majority.have.suffered.alteration.in.some.form.by.injected.humour.or.randomised.words.which.dont.look.even.slightly.believable.If.you.are.going.to.use.a.passage.of.Lorem.Ipsum.you.need';
|
|
587
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
588
|
+
const expectedResult = JSON.stringify({
|
|
589
|
+
message: 'validation.dns.hostname.tooLong', key: 'testDisplayKey', max: 253
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
it('"externalName" : returns expected message when value contains invalid characters', () => {
|
|
596
|
+
const testValue = 'www.host*name.com';
|
|
597
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
598
|
+
const expectedResult = JSON.stringify({
|
|
599
|
+
message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: '"*"'
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
it('"externalName" : returns expected message when hostname label starts with a dash', () => {
|
|
606
|
+
const testValue = 'www.-hostname.com';
|
|
607
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
608
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.startHyphen', key: 'testDisplayKey' });
|
|
609
|
+
|
|
610
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
it('"externalName" : returns expected message when hostname label ends with a dash', () => {
|
|
614
|
+
const testValue = 'www.hostname-.com';
|
|
615
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
616
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.endHyphen', key: 'testDisplayKey' });
|
|
617
|
+
|
|
618
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('"externalName" : returns expected message when hostname label contains a double-dash at the third character position', () => {
|
|
622
|
+
const testValue = 'www.ho--stname.com';
|
|
623
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
624
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.doubleHyphen', key: 'testDisplayKey' });
|
|
625
|
+
|
|
626
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
it('"externalName" : returns expected message when hostname label is empty', () => {
|
|
630
|
+
const testValue = 'www..com';
|
|
631
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
632
|
+
const expectedResult = JSON.stringify({
|
|
633
|
+
message: 'validation.dns.hostname.emptyLabel', key: 'testDisplayKey', min: 1
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
it('"externalName" : returns expected message when hostname label is too long', () => {
|
|
640
|
+
const testValue = 'www.0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.com';
|
|
641
|
+
const formRuleResult = formRules.externalName(testValue);
|
|
642
|
+
const expectedResult = JSON.stringify({
|
|
643
|
+
message: 'validation.dns.hostname.tooLongLabel', key: 'testDisplayKey', max: 63
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
647
|
+
});
|
|
648
|
+
|
|
649
|
+
it('"backupTarget" : returns undefined when value is valid backupTarget', () => {
|
|
650
|
+
const testValue = JSON.stringify({ type: 'type' });
|
|
651
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
652
|
+
|
|
653
|
+
expect(formRuleResult).toBeUndefined();
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
it('"backupTarget" : returns expected message when value is backupTarget without a type', () => {
|
|
657
|
+
const testValue = JSON.stringify({});
|
|
658
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
659
|
+
const expectedResult = JSON.stringify({ message: 'validation.required', key: 'Type' });
|
|
660
|
+
|
|
661
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
it('"backupTarget" : returns expected message when value is backupTarget with a type of s3 but no accessKeyId', () => {
|
|
665
|
+
const testValue = JSON.stringify({ type: 's3' });
|
|
666
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
667
|
+
const expectedResult = JSON.stringify({ message: 'validation.required', key: 'accessKeyId' });
|
|
668
|
+
|
|
669
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
it('"backupTarget" : returns expected message when value is backupTarget with a type of s3 but no secretAccessKey', () => {
|
|
673
|
+
const testValue = JSON.stringify({ type: 's3', accessKeyId: 'id' });
|
|
674
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
675
|
+
const expectedResult = JSON.stringify({ message: 'validation.required', key: 'secretAccessKey' });
|
|
676
|
+
|
|
677
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it('"backupTarget" : returns expected message when value is backupTarget with a type of s3 but no bucketRegion', () => {
|
|
681
|
+
const testValue = JSON.stringify({
|
|
682
|
+
type: 's3', accessKeyId: 'id', secretAccessKey: 'key'
|
|
683
|
+
});
|
|
684
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
685
|
+
const expectedResult = JSON.stringify({ message: 'validation.required', key: 'bucketRegion' });
|
|
686
|
+
|
|
687
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
688
|
+
});
|
|
689
|
+
|
|
690
|
+
it('"backupTarget" : returns expected message when value is backupTarget with a type of s3 but no bucketName', () => {
|
|
691
|
+
const testValue = JSON.stringify({
|
|
692
|
+
type: 's3', accessKeyId: 'id', secretAccessKey: 'key', bucketRegion: 'region'
|
|
693
|
+
});
|
|
694
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
695
|
+
const expectedResult = JSON.stringify({ message: 'validation.required', key: 'bucketName' });
|
|
696
|
+
|
|
697
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
it('"backupTarget" : returns undefined when value is backupTarget with a type of s3 and all other values', () => {
|
|
701
|
+
const testValue = JSON.stringify({
|
|
702
|
+
type: 's3', accessKeyId: 'id', secretAccessKey: 'key', bucketRegion: 'region', bucketName: 'name'
|
|
703
|
+
});
|
|
704
|
+
const formRuleResult = formRules.backupTarget(testValue);
|
|
705
|
+
|
|
706
|
+
expect(formRuleResult).toBeUndefined();
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
it('"imageUrl" : returns undefined when value is a valid imageUrl', () => {
|
|
710
|
+
const testValue = 'https://url/image.iso';
|
|
711
|
+
const formRuleResult = formRules.imageUrl(testValue);
|
|
712
|
+
|
|
713
|
+
expect(formRuleResult).toBeUndefined();
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
it('"imageUrl" : returns expected message when value has an invalid file extension', () => {
|
|
717
|
+
const testValue = 'https://url/image.isi';
|
|
718
|
+
const formRuleResult = formRules.imageUrl(testValue);
|
|
719
|
+
const expectedResult = JSON.stringify({ message: 'harvester.validation.image.ruleTip' });
|
|
720
|
+
|
|
721
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
it('"fileRequired" : returns undefined when value has an image name key', () => {
|
|
725
|
+
const testValue = { 'harvesterhci.io/image-name': 'test' };
|
|
726
|
+
const formRuleResult = formRules.fileRequired(testValue);
|
|
727
|
+
|
|
728
|
+
expect(formRuleResult).toBeUndefined();
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
it('"fileRequired" : returns expected message when value is invalid', () => {
|
|
732
|
+
const testValue = {};
|
|
733
|
+
const formRuleResult = formRules.fileRequired(testValue);
|
|
734
|
+
const expectedResult = JSON.stringify({ message: 'validation.required', key: JSON.stringify({ message: 'harvester.image.fileName' }) });
|
|
735
|
+
|
|
736
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
it('"dnsLabel" : returns undefined when valid dnsLabel value is supplied', () => {
|
|
740
|
+
const testValue = 'bob';
|
|
741
|
+
const formRuleResult = formRules.dnsLabel(testValue);
|
|
742
|
+
|
|
743
|
+
expect(formRuleResult).toBeUndefined();
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
it('"dnsLabel" : returns correct message when dnsLabel value with invalid characters is supplied', () => {
|
|
747
|
+
const testValue = 'bob*bob';
|
|
748
|
+
const formRuleResult = formRules.dnsLabel(testValue);
|
|
749
|
+
const expectedResult = JSON.stringify({
|
|
750
|
+
message: 'validation.chars',
|
|
751
|
+
key: 'testDisplayKey',
|
|
752
|
+
count: 1,
|
|
753
|
+
chars: '"*"'
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
it('"dnsLabel" : returns correct message when dnsLabel value that starts with a dash is supplied', () => {
|
|
760
|
+
const testValue = '-bob';
|
|
761
|
+
const formRuleResult = formRules.dnsLabel(testValue);
|
|
762
|
+
const expectedResult = JSON.stringify({
|
|
763
|
+
message: 'validation.dns.label.startHyphen',
|
|
764
|
+
key: 'testDisplayKey'
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
768
|
+
});
|
|
769
|
+
|
|
770
|
+
it('"dnsLabel" : returns correct message when dnsLabel value that ends with a dash is supplied', () => {
|
|
771
|
+
const testValue = 'bob-';
|
|
772
|
+
const formRuleResult = formRules.dnsLabel(testValue);
|
|
773
|
+
const expectedResult = JSON.stringify({
|
|
774
|
+
message: 'validation.dns.label.endHyphen',
|
|
775
|
+
key: 'testDisplayKey'
|
|
776
|
+
});
|
|
777
|
+
|
|
778
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
it('"dnsLabel" : returns correct message when dnsLabel value with double-dash after first two characters is supplied', () => {
|
|
782
|
+
const testValue = 'jo--jane';
|
|
783
|
+
const formRuleResult = formRules.dnsLabel(testValue);
|
|
784
|
+
const expectedResult = JSON.stringify({
|
|
785
|
+
message: 'validation.dns.doubleHyphen',
|
|
786
|
+
key: 'testDisplayKey'
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
it('"dnsLabel" : returns correct message when dnsLabel value is too long', () => {
|
|
793
|
+
const testValue = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
|
|
794
|
+
const formRuleResult = formRules.dnsLabel(testValue);
|
|
795
|
+
const expectedResult = JSON.stringify({
|
|
796
|
+
message: 'validation.dns.label.tooLongLabel',
|
|
797
|
+
key: 'testDisplayKey',
|
|
798
|
+
max: 63
|
|
799
|
+
});
|
|
800
|
+
|
|
801
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
// this rule is pretty much identical to the standard dnsLabel other than the dnsLabel length
|
|
805
|
+
it('"dnsLabelIanaServiceName" : returns correct message when dnsLabel value is too long', () => {
|
|
806
|
+
const testValue = '0123456789abcdef';
|
|
807
|
+
const formRuleResult = formRules.dnsLabelIanaServiceName(testValue);
|
|
808
|
+
const expectedResult = JSON.stringify({
|
|
809
|
+
message: 'validation.dns.label.tooLongLabel',
|
|
810
|
+
key: 'testDisplayKey',
|
|
811
|
+
max: 15
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
815
|
+
});
|
|
816
|
+
|
|
817
|
+
// this rule is pretty much identical to the standard dnsLabel other than the startNumber test
|
|
818
|
+
it('"dnsLabelRestricted" : returns correct message when dnsLabel starts with a number', () => {
|
|
819
|
+
const testValue = '1testUrl';
|
|
820
|
+
const formRuleResult = formRules.dnsLabelRestricted(testValue);
|
|
821
|
+
const expectedResult = JSON.stringify({
|
|
822
|
+
message: 'validation.dns.label.startNumber',
|
|
823
|
+
key: 'testDisplayKey'
|
|
824
|
+
});
|
|
825
|
+
|
|
826
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
// this rule is pretty much identical to the standard dnsLabel other than the startNumber test
|
|
830
|
+
it('"hostName" : returns undefined when value is valid hostname', () => {
|
|
831
|
+
const testValue = 'www.url.com';
|
|
832
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
833
|
+
|
|
834
|
+
expect(formRuleResult).toBeUndefined();
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
it('"hostName" : returns expected message when value starts with a dot', () => {
|
|
838
|
+
const testValue = '.hostname';
|
|
839
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
840
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.startDot', key: 'testDisplayKey' });
|
|
841
|
+
|
|
842
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
it('"hostName" : returns expected message when value starts is too long for a hostname', () => {
|
|
846
|
+
const testValue = 'There.are.many.variations.of.passages.of.Lorem.Ipsum.available.but.the.majority.have.suffered.alteration.in.some.form.by.injected.humour.or.randomised.words.which.dont.look.even.slightly.believable.If.you.are.going.to.use.a.passage.of.Lorem.Ipsum.you.need';
|
|
847
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
848
|
+
const expectedResult = JSON.stringify({
|
|
849
|
+
message: 'validation.dns.hostname.tooLong', key: 'testDisplayKey', max: 253
|
|
850
|
+
});
|
|
851
|
+
|
|
852
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
it('"hostName" : returns expected message when value contains invalid characters', () => {
|
|
856
|
+
const testValue = 'www.host*name.com';
|
|
857
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
858
|
+
const expectedResult = JSON.stringify({
|
|
859
|
+
message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: '"*"'
|
|
860
|
+
});
|
|
861
|
+
|
|
862
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
863
|
+
});
|
|
864
|
+
|
|
865
|
+
it('"hostName" : returns expected message when value contains a space character', () => {
|
|
866
|
+
const testValue = 'www.host name.com';
|
|
867
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
868
|
+
const expectedResult = JSON.stringify({
|
|
869
|
+
message: 'validation.chars', key: 'testDisplayKey', count: 1, chars: 'Space'
|
|
870
|
+
});
|
|
871
|
+
|
|
872
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
873
|
+
});
|
|
874
|
+
|
|
875
|
+
it('"hostName" : returns expected message when hostname label starts with a dash', () => {
|
|
876
|
+
const testValue = 'www.-hostname.com';
|
|
877
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
878
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.startHyphen', key: 'testDisplayKey' });
|
|
879
|
+
|
|
880
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
it('"hostName" : returns expected message when hostname label ends with a dash', () => {
|
|
884
|
+
const testValue = 'www.hostname-.com';
|
|
885
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
886
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.hostname.endHyphen', key: 'testDisplayKey' });
|
|
887
|
+
|
|
888
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
it('"hostName" : returns expected message when hostname label contains a double-dash at the third character position', () => {
|
|
892
|
+
const testValue = 'www.ho--stname.com';
|
|
893
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
894
|
+
const expectedResult = JSON.stringify({ message: 'validation.dns.doubleHyphen', key: 'testDisplayKey' });
|
|
895
|
+
|
|
896
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
897
|
+
});
|
|
898
|
+
|
|
899
|
+
it('"hostName" : returns expected message when hostname label is too long', () => {
|
|
900
|
+
const testValue = 'www.0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef.com';
|
|
901
|
+
const formRuleResult = formRules.hostname(testValue);
|
|
902
|
+
const expectedResult = JSON.stringify({
|
|
903
|
+
message: 'validation.dns.hostname.tooLongLabel', key: 'testDisplayKey', max: 63
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
907
|
+
});
|
|
908
|
+
|
|
909
|
+
it('"absolutePath" : return expected message when path doesn\'t begin with a "/"', () => {
|
|
910
|
+
const formRuleResult = formRules.absolutePath('absolute_path');
|
|
911
|
+
const expectedResult = JSON.stringify({ message: 'validation.path', key: 'testDisplayKey' });
|
|
912
|
+
|
|
913
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
it('"absolutePath" : returns undefined when path begins with a "/"', () => {
|
|
917
|
+
const formRuleResult = formRules.absolutePath('/absolute_path');
|
|
918
|
+
|
|
919
|
+
expect(formRuleResult).toBeUndefined();
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
it('"testRule" : always returns the expected string', () => {
|
|
923
|
+
const formRuleResult = formRules.testRule('');
|
|
924
|
+
const expectedResult = 'This is an error returned by the testRule validator';
|
|
925
|
+
|
|
926
|
+
expect(formRuleResult).toStrictEqual(expectedResult);
|
|
927
|
+
});
|
|
928
|
+
});
|