@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
package/mixins/chart.js
CHANGED
|
@@ -118,6 +118,7 @@ export default {
|
|
|
118
118
|
return out;
|
|
119
119
|
},
|
|
120
120
|
|
|
121
|
+
// Conditionally filter out prerelease versions of the chart.
|
|
121
122
|
filteredVersions() {
|
|
122
123
|
return this.showPreRelease ? this.mappedVersions : this.mappedVersions.filter(v => !v.isPre);
|
|
123
124
|
},
|
|
@@ -144,12 +145,18 @@ export default {
|
|
|
144
145
|
return this.$route.query[HIDDEN] === _FLAGGED;
|
|
145
146
|
},
|
|
146
147
|
|
|
148
|
+
// If the user is installing the app for the first time,
|
|
149
|
+
// warn them about CPU and memory requirements.
|
|
147
150
|
warnings() {
|
|
148
151
|
const warnings = [];
|
|
149
152
|
|
|
150
153
|
if ( this.existing ) {
|
|
151
154
|
// Ignore the limits on upgrade (or if asked by query) and don't show any warnings
|
|
152
155
|
} else {
|
|
156
|
+
// The UI will show warnings about CPU and memory if
|
|
157
|
+
// these annotations are added to Helm chart:
|
|
158
|
+
// - catalog.cattle.io/requests-cpu
|
|
159
|
+
// - catalog.cattle.io/requests-memory
|
|
153
160
|
const needCpu = parseSi(this.version?.annotations?.[CATALOG_ANNOTATIONS.REQUESTS_CPU] || '0');
|
|
154
161
|
const needMemory = parseSi(this.version?.annotations?.[CATALOG_ANNOTATIONS.REQUESTS_MEMORY] || '0');
|
|
155
162
|
|
|
@@ -238,7 +245,10 @@ export default {
|
|
|
238
245
|
await this.$store.dispatch('catalog/load');
|
|
239
246
|
|
|
240
247
|
if ( this.query.appNamespace && this.query.appName ) {
|
|
241
|
-
//
|
|
248
|
+
// First check the URL query for an app name and namespace.
|
|
249
|
+
// Use those values to check for a catalog app resource.
|
|
250
|
+
// If found, set the form to edit mode. If not, set the
|
|
251
|
+
// form to create mode.
|
|
242
252
|
|
|
243
253
|
try {
|
|
244
254
|
this.existing = await this.$store.dispatch('cluster/find', {
|
|
@@ -252,8 +262,11 @@ export default {
|
|
|
252
262
|
this.existing = null;
|
|
253
263
|
}
|
|
254
264
|
} else if ( this.chart?.targetNamespace && this.chart?.targetName ) {
|
|
255
|
-
//
|
|
256
|
-
//
|
|
265
|
+
// If the app name and namespace values are not provided in the
|
|
266
|
+
// query, fall back on target values defined in the Helm chart itself.
|
|
267
|
+
|
|
268
|
+
// Ask to install a special chart with fixed namespace/name
|
|
269
|
+
// or edit it if there's an existing install.
|
|
257
270
|
|
|
258
271
|
try {
|
|
259
272
|
this.existing = await this.$store.dispatch('cluster/find', {
|
|
@@ -275,6 +288,9 @@ export default {
|
|
|
275
288
|
return;
|
|
276
289
|
}
|
|
277
290
|
|
|
291
|
+
// If no version is given in the URL query,
|
|
292
|
+
// use the first version provided by the Helm chart
|
|
293
|
+
// as the default.
|
|
278
294
|
if ( !this.query.versionName && this.chart.versions?.length ) {
|
|
279
295
|
this.query.versionName = this.chart.versions[0].version;
|
|
280
296
|
}
|
|
@@ -304,10 +320,26 @@ export default {
|
|
|
304
320
|
chartName: this.query.chartName,
|
|
305
321
|
versionName: this.query.versionName
|
|
306
322
|
});
|
|
323
|
+
// Here we set us versionInfo. The returned
|
|
324
|
+
// object contains everything all info
|
|
325
|
+
// about a currently installed app, and it has the
|
|
326
|
+
// following keys:
|
|
327
|
+
//
|
|
328
|
+
// - appReadme: A short overview of what the app does. This
|
|
329
|
+
// forms the first few paragraphs of the chart info when
|
|
330
|
+
// you install a Helm chart app through Rancher.
|
|
331
|
+
// - chart: Metadata about the Helm chart, including the
|
|
332
|
+
// name and version.
|
|
333
|
+
// - readme: This is more detailed information that appears
|
|
334
|
+
// under the heading "Chart Information (Helm README)" when
|
|
335
|
+
// you install or upgrade a Helm chart app through Rancher,
|
|
336
|
+
// below the app README.
|
|
337
|
+
// - values: All Helm chart values for the currently installed
|
|
338
|
+
// app.
|
|
307
339
|
} catch (e) {
|
|
308
340
|
console.error('Unable to fetch VersionInfo: ', e); // eslint-disable-line no-console
|
|
309
341
|
}
|
|
310
|
-
},
|
|
342
|
+
}, // End of fetchChart
|
|
311
343
|
|
|
312
344
|
selectVersion({ id: version }) {
|
|
313
345
|
this.$router.applyQuery({ [VERSION]: version });
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import Vue from 'vue';
|
|
2
|
+
|
|
3
|
+
export default Vue.extend({
|
|
2
4
|
props: {
|
|
3
5
|
compact: {
|
|
4
6
|
type: Boolean,
|
|
@@ -16,9 +18,9 @@ export default {
|
|
|
16
18
|
},
|
|
17
19
|
|
|
18
20
|
computed: {
|
|
19
|
-
isCompact() {
|
|
21
|
+
isCompact(): boolean {
|
|
20
22
|
// Compact if explicitly set - otherwise compact if there is no label
|
|
21
23
|
return this.compact !== null ? this.compact : !(this.label || this.labelKey);
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
|
-
};
|
|
26
|
+
});
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { getAllValues } from '@shell/utils/object';
|
|
2
|
+
import formRulesGenerator from '@shell/utils/validators/formRules';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
data() {
|
|
6
|
+
return {
|
|
7
|
+
fvFormRuleSets: [
|
|
8
|
+
/* fvFormRuleSets define the validation rules for the entire form. These should almost always be overridden in the form-component using the mixin
|
|
9
|
+
example:
|
|
10
|
+
{
|
|
11
|
+
path: 'container.image', // required: defines the path of the value to be tested against it's rules. Looks for the relevant path in `this.value` unless an is passed in via rootObject
|
|
12
|
+
rootObject: { container: { image: 'name' } } // optional: redirects the path to the object passed here,
|
|
13
|
+
rules: ['noSpaces', 'noPeriods'], // required: array of strings that match which validator functions to run against the value of the field defined by the path (and optionally the rulesets rootObject),
|
|
14
|
+
translationKey: 'Image Name', // optional: defines the displaykey, overrides displaykeys that may otherwise be passed into the translation
|
|
15
|
+
}
|
|
16
|
+
*/
|
|
17
|
+
],
|
|
18
|
+
fvReportedValidationPaths: [
|
|
19
|
+
// an array of strings that track which ruleset paths have been bound to a field for error reporting
|
|
20
|
+
// tracked in a seperate array from the actual rulesets since we want the option of keeping track of modelValidationRules without mutating the model itself
|
|
21
|
+
// you may place a path in here manually as part of your form's data props...
|
|
22
|
+
// ... or you may place a path in here programitcally by using the "fvGetAndReportPathRules" method
|
|
23
|
+
]
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
methods: {
|
|
28
|
+
// returns an array of validator functions based off path property of the ruleset, use this if you want the array but you don't want the form to track that the rules have been bound to a field
|
|
29
|
+
fvGetPathRules(path) {
|
|
30
|
+
return this.fvRulesets.find(ruleset => ruleset.path === path)?.rules || [];
|
|
31
|
+
},
|
|
32
|
+
// returns an array of validator functions and pushes the path of the relevant ruleset into fvReportedValidationPaths so that we know any error messages are handled by the field using it
|
|
33
|
+
fvGetAndReportPathRules(path) {
|
|
34
|
+
const rules = this.fvGetPathRules(path);
|
|
35
|
+
|
|
36
|
+
if (rules.length > 0 && !this.fvReportedValidationPaths.includes(path)) {
|
|
37
|
+
this.fvReportedValidationPaths = [...this.fvReportedValidationPaths, path];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return rules;
|
|
41
|
+
},
|
|
42
|
+
fvGetPathValues(path) { // validates that the path is one that belongs to a ruleset (either a formRuleset or from the modelValidationRules) and returns its value(s) in an array
|
|
43
|
+
// returns even single values as an array to simplify validation logic since some fields may have multiple values
|
|
44
|
+
const relevantRuleset = this.fvRulesets.find(ruleset => ruleset.path === path);
|
|
45
|
+
|
|
46
|
+
if (!relevantRuleset) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return getAllValues(relevantRuleset?.rootObject || this.value, relevantRuleset?.path);
|
|
51
|
+
},
|
|
52
|
+
fvGetPathErrors(paths = []) { // gets errors from multiple paths, usually used externally to check a single path but used within the mixin to check all paths for errors
|
|
53
|
+
const messages = paths.reduce((acc, path) => {
|
|
54
|
+
const pathErrors = [];
|
|
55
|
+
const relevantRules = this.fvGetPathRules(path);
|
|
56
|
+
const relevantValues = this.fvGetPathValues(path).map((val, idx, arr) => (arr.length > 1 && typeof val === 'object' && !Array.isArray(val) && val !== null ? { ...val, idx } : val));
|
|
57
|
+
|
|
58
|
+
relevantRules.forEach((rule) => {
|
|
59
|
+
relevantValues.forEach((value) => {
|
|
60
|
+
pathErrors.push(rule(value));
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return [...acc, ...pathErrors].filter(error => !!error);
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
67
|
+
return messages;
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
computed: {
|
|
71
|
+
// fvExtraRules allows you to create rules that might be specific to a form inside of that form component and pass them into the mixin's logic. fvExtraRules needs to return an object with a validation rule function in each key.
|
|
72
|
+
// This is a computed property as returning functions in the data props is not considered a best practice
|
|
73
|
+
fvExtraRules() {
|
|
74
|
+
return {};
|
|
75
|
+
},
|
|
76
|
+
// rulesets is a combination of the rules defined in the fvFormRuleSets array and the modelValidationRules in the model. Theoretically, a form could just use the rulesets defined in the model however in practice this can be limiting
|
|
77
|
+
fvRulesets() {
|
|
78
|
+
const nullValidator = () => undefined;
|
|
79
|
+
|
|
80
|
+
return [
|
|
81
|
+
...this.fvFormRuleSets.map((ruleset) => {
|
|
82
|
+
const formRules = {
|
|
83
|
+
...formRulesGenerator(this.$store.getters['i18n/t'], { displayKey: ruleset?.translationKey ? this.$store.getters['i18n/t'](ruleset.translationKey) : 'Value' }),
|
|
84
|
+
...this.fvExtraRules
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
...ruleset,
|
|
89
|
+
rules: ruleset.rules.map(rule => formRules[rule] || nullValidator),
|
|
90
|
+
formValidationRule: true
|
|
91
|
+
};
|
|
92
|
+
}),
|
|
93
|
+
...(this?.value?.modelValidationRules || []).map(rule => ({
|
|
94
|
+
...rule,
|
|
95
|
+
formValidationRule: false
|
|
96
|
+
}))
|
|
97
|
+
];
|
|
98
|
+
},
|
|
99
|
+
fvUnreportedValidationErrors() { // if either the fvFormRuleSets or the modelValidationRules throw an error and the associated path isn't in the reportValidationPaths then it'll show up here.
|
|
100
|
+
// useful for throwing unreported errors into a generic banner
|
|
101
|
+
const paths = this.fvRulesets
|
|
102
|
+
.filter(ruleset => !!ruleset.formValidationRule && !this.fvReportedValidationPaths.includes(ruleset.path))
|
|
103
|
+
.map(ruleset => ruleset.path);
|
|
104
|
+
|
|
105
|
+
const formErrors = this.fvGetPathErrors(paths);
|
|
106
|
+
|
|
107
|
+
const modelErrors = this.value.customValidationErrors(this.value, this.fvReportedValidationPaths); // the model already has a means of producing errors, not reinventing the wheel... yet...
|
|
108
|
+
|
|
109
|
+
return [...formErrors, ...modelErrors, ...(this.errors || [])];
|
|
110
|
+
},
|
|
111
|
+
fvValidationErrors() { // checks for any and all errors, regardless of being bound, from the model, or from the form
|
|
112
|
+
const paths = this.fvRulesets.filter(ruleset => !!ruleset.formValidationRule).map(ruleset => ruleset.path);
|
|
113
|
+
const formErrors = this.fvGetPathErrors(paths);
|
|
114
|
+
const modelErrors = this.value.customValidationErrors(this.value); // the model already has a means of producing errors, not reinventing the wheel... yet...
|
|
115
|
+
|
|
116
|
+
return [...formErrors, ...modelErrors];
|
|
117
|
+
},
|
|
118
|
+
fvFormIsValid() {
|
|
119
|
+
return this.fvValidationErrors.length === 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import YAML from 'yaml';
|
|
1
2
|
import jsyaml from 'js-yaml';
|
|
2
3
|
import isEqual from 'lodash/isEqual';
|
|
3
4
|
import isEmpty from 'lodash/isEmpty';
|
|
4
5
|
import difference from 'lodash/difference';
|
|
5
6
|
|
|
6
7
|
import { sortBy } from '@shell/utils/sort';
|
|
7
|
-
import {
|
|
8
|
+
import { set } from '@shell/utils/object';
|
|
9
|
+
|
|
8
10
|
import { allHash } from '@shell/utils/promise';
|
|
9
11
|
import { randomStr } from '@shell/utils/string';
|
|
10
12
|
import { base64Decode } from '@shell/utils/crypto';
|
|
@@ -131,7 +133,7 @@ export default {
|
|
|
131
133
|
accessCredentials: [],
|
|
132
134
|
efiEnabled: false,
|
|
133
135
|
secureBoot: false,
|
|
134
|
-
userDataTemplateId: ''
|
|
136
|
+
userDataTemplateId: '',
|
|
135
137
|
};
|
|
136
138
|
},
|
|
137
139
|
|
|
@@ -515,7 +517,7 @@ export default {
|
|
|
515
517
|
}
|
|
516
518
|
|
|
517
519
|
if (!disks.find( D => D.name === 'cloudinitdisk')) {
|
|
518
|
-
if (this.
|
|
520
|
+
if (!this.isWindows) {
|
|
519
521
|
disks.push({
|
|
520
522
|
name: 'cloudinitdisk',
|
|
521
523
|
disk: { bus: 'virtio' }
|
|
@@ -697,44 +699,43 @@ export default {
|
|
|
697
699
|
|
|
698
700
|
getInitUserData(config) {
|
|
699
701
|
const _QGA_JSON = this.getMatchQGA(config.osType);
|
|
702
|
+
|
|
700
703
|
const out = jsyaml.dump(_QGA_JSON);
|
|
701
704
|
|
|
702
|
-
return
|
|
705
|
+
return `#cloud-config\n${ out }`;
|
|
703
706
|
},
|
|
704
707
|
|
|
708
|
+
/**
|
|
709
|
+
* Generate user data yaml which is decide by the "Install guest agent",
|
|
710
|
+
* "OS type", "SSH Keys" and user input.
|
|
711
|
+
* @param config
|
|
712
|
+
*/
|
|
705
713
|
getUserData(config) {
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
const sshAuthorizedKeys = userDataJson?.ssh_authorized_keys || [];
|
|
711
|
-
|
|
712
|
-
if (userDataJson && sshAuthorizedKeys) {
|
|
713
|
-
const sshList = new Set([...this.getSSHListValue(this.sshKey), ...sshAuthorizedKeys]);
|
|
714
|
-
|
|
715
|
-
userDataJson.ssh_authorized_keys = [...sshList];
|
|
716
|
-
} else {
|
|
717
|
-
userDataJson.ssh_authorized_keys = this.getSSHListValue(this.sshKey);
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
if (userDataJson.ssh_authorized_keys && userDataJson.ssh_authorized_keys.length === 0) {
|
|
721
|
-
delete userDataJson.ssh_authorized_keys;
|
|
722
|
-
}
|
|
714
|
+
try {
|
|
715
|
+
// https://github.com/eemeli/yaml/issues/136
|
|
716
|
+
let userDataDoc = this.userScript ? YAML.parseDocument(this.userScript) : YAML.parseDocument({});
|
|
723
717
|
|
|
724
|
-
|
|
718
|
+
const allSSHAuthorizedKeys = this.mergeSSHAuthorizedKeys(this.userScript);
|
|
725
719
|
|
|
726
|
-
|
|
727
|
-
|
|
720
|
+
if (allSSHAuthorizedKeys.length > 0) {
|
|
721
|
+
userDataDoc.setIn(['ssh_authorized_keys'], allSSHAuthorizedKeys);
|
|
722
|
+
} else if (YAML.isCollection(userDataDoc.getIn('ssh_authorized_keys'))) {
|
|
723
|
+
userDataDoc.deleteIn(['ssh_authorized_keys']);
|
|
724
|
+
}
|
|
728
725
|
|
|
729
|
-
|
|
726
|
+
userDataDoc = config.installAgent ? this.mergeQGA({ userDataDoc, ...config }) : this.deleteQGA({ userDataDoc, ...config });
|
|
727
|
+
const userDataYaml = userDataDoc.toString();
|
|
730
728
|
|
|
731
|
-
if (
|
|
729
|
+
if (userDataYaml === '{}\n') {
|
|
730
|
+
// When the YAML parsed value is '{}\n', it means that the userData is empty, then undefined is returned.
|
|
732
731
|
return undefined;
|
|
733
732
|
}
|
|
734
733
|
|
|
735
|
-
return
|
|
736
|
-
}
|
|
737
|
-
|
|
734
|
+
return userDataYaml;
|
|
735
|
+
} catch (e) {
|
|
736
|
+
console.error('Error: Unable to parse yaml document', e); // eslint-disable-line no-console
|
|
737
|
+
|
|
738
|
+
return this.userScript;
|
|
738
739
|
}
|
|
739
740
|
},
|
|
740
741
|
|
|
@@ -800,6 +801,8 @@ export default {
|
|
|
800
801
|
if (image) {
|
|
801
802
|
out.spec.storageClassName = `longhorn-${ image.metadata.name }`;
|
|
802
803
|
out.metadata.annotations = { [HCI_ANNOTATIONS.IMAGE_ID]: image.id };
|
|
804
|
+
} else if (this.resource === HCI.VM_VERSION) {
|
|
805
|
+
out.metadata.annotations = { [HCI_ANNOTATIONS.IMAGE_ID]: '' };
|
|
803
806
|
}
|
|
804
807
|
|
|
805
808
|
break;
|
|
@@ -823,20 +826,6 @@ export default {
|
|
|
823
826
|
_interface.macAddress = R.macAddress;
|
|
824
827
|
}
|
|
825
828
|
|
|
826
|
-
// TODO: delete
|
|
827
|
-
if (R.ports && R.type === 'masquerade') {
|
|
828
|
-
const ports = [];
|
|
829
|
-
|
|
830
|
-
for (const item of R.ports) {
|
|
831
|
-
ports.push({
|
|
832
|
-
...item,
|
|
833
|
-
port: parseInt(item.port)
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
_interface.ports = ports;
|
|
838
|
-
}
|
|
839
|
-
|
|
840
829
|
_interface.model = R.model;
|
|
841
830
|
_interface.name = R.name;
|
|
842
831
|
|
|
@@ -863,24 +852,62 @@ export default {
|
|
|
863
852
|
this.networkScript = value;
|
|
864
853
|
},
|
|
865
854
|
|
|
855
|
+
mergeSSHAuthorizedKeys(yaml) {
|
|
856
|
+
try {
|
|
857
|
+
const sshAuthorizedKeys = YAML.parseDocument(yaml)
|
|
858
|
+
.get('ssh_authorized_keys')
|
|
859
|
+
?.toJSON() || [];
|
|
860
|
+
|
|
861
|
+
const sshList = this.getSSHListValue(this.sshKey);
|
|
862
|
+
|
|
863
|
+
return sshAuthorizedKeys.length ? [...new Set([...sshList, ...sshAuthorizedKeys])] : sshList;
|
|
864
|
+
} catch (e) {
|
|
865
|
+
return [];
|
|
866
|
+
}
|
|
867
|
+
},
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* @param paths A Object path, e.g. 'a.b.c' => ['a', 'b', 'c']. Refer to https://eemeli.org/yaml/#scalar-values
|
|
871
|
+
* @returns
|
|
872
|
+
*/
|
|
873
|
+
deleteYamlDocProp(doc, paths) {
|
|
874
|
+
try {
|
|
875
|
+
const item = doc.getIn([])?.items[0];
|
|
876
|
+
const key = item?.key;
|
|
877
|
+
const hasCloudConfigComment = !!key?.commentBefore?.includes('cloud-config');
|
|
878
|
+
const isMatchProp = key.source === paths[paths.length - 1];
|
|
879
|
+
|
|
880
|
+
if (key && hasCloudConfigComment && isMatchProp) {
|
|
881
|
+
// Comments are mounted on the next node and we should not delete the node containing cloud-config
|
|
882
|
+
} else {
|
|
883
|
+
doc.deleteIn(paths);
|
|
884
|
+
}
|
|
885
|
+
} catch (e) {}
|
|
886
|
+
},
|
|
887
|
+
|
|
866
888
|
mergeQGA(config) {
|
|
867
|
-
const {
|
|
889
|
+
const { osType, userDataDoc } = config;
|
|
868
890
|
const _QGA_JSON = this.getMatchQGA(osType);
|
|
891
|
+
const userDataYAML = userDataDoc.toString();
|
|
892
|
+
const userDataJSON = YAML.parse(userDataYAML);
|
|
893
|
+
let packages = userDataJSON?.packages || [];
|
|
894
|
+
let runcmd = userDataJSON?.runcmd || [];
|
|
895
|
+
|
|
896
|
+
userDataDoc.setIn(['package_update'], true);
|
|
869
897
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
userDataJson.packages.push('qemu-guest-agent');
|
|
898
|
+
if (Array.isArray(packages)) {
|
|
899
|
+
if (!packages.includes('qemu-guest-agent')) {
|
|
900
|
+
packages.push('qemu-guest-agent');
|
|
874
901
|
}
|
|
875
902
|
} else {
|
|
876
|
-
|
|
903
|
+
packages = QGA_JSON.packages;
|
|
877
904
|
}
|
|
878
905
|
|
|
879
|
-
if (Array.isArray(
|
|
906
|
+
if (Array.isArray(runcmd)) {
|
|
880
907
|
let findIndex = -1;
|
|
881
|
-
const hasSameRuncmd =
|
|
908
|
+
const hasSameRuncmd = runcmd.find( S => Array.isArray(S) && S.join('-') === _QGA_JSON.runcmd[0].join('-'));
|
|
882
909
|
|
|
883
|
-
const hasSimilarRuncmd =
|
|
910
|
+
const hasSimilarRuncmd = runcmd.find( (S, index) => {
|
|
884
911
|
if (Array.isArray(S) && S.join('-') === this.getSimilarRuncmd(osType).join('-')) {
|
|
885
912
|
findIndex = index;
|
|
886
913
|
|
|
@@ -891,61 +918,78 @@ export default {
|
|
|
891
918
|
});
|
|
892
919
|
|
|
893
920
|
if (hasSimilarRuncmd) {
|
|
894
|
-
|
|
921
|
+
runcmd[findIndex] = _QGA_JSON.runcmd[0];
|
|
895
922
|
} else if (!hasSameRuncmd) {
|
|
896
|
-
|
|
923
|
+
runcmd.push(_QGA_JSON.runcmd[0]);
|
|
897
924
|
}
|
|
898
925
|
} else {
|
|
899
|
-
|
|
926
|
+
runcmd = _QGA_JSON.runcmd;
|
|
900
927
|
}
|
|
901
928
|
|
|
902
|
-
|
|
929
|
+
if (packages.length > 0) {
|
|
930
|
+
userDataDoc.setIn(['packages'], packages);
|
|
931
|
+
} else {
|
|
932
|
+
userDataDoc.setIn(['packages'], []); // It needs to be set empty first, as it is possible that cloud-init comments are mounted on this node
|
|
933
|
+
this.deleteYamlDocProp(userDataDoc, ['packages']);
|
|
934
|
+
this.deleteYamlDocProp(userDataDoc, ['package_update']);
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
if (runcmd.length > 0) {
|
|
938
|
+
userDataDoc.setIn(['runcmd'], runcmd);
|
|
939
|
+
} else {
|
|
940
|
+
this.deleteYamlDocProp(userDataDoc, ['runcmd']);
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
return userDataDoc;
|
|
903
944
|
},
|
|
904
945
|
|
|
905
946
|
deleteQGA(config) {
|
|
906
|
-
const {
|
|
947
|
+
const { osType, userDataDoc, deletePackage = false } = config;
|
|
907
948
|
|
|
908
949
|
const userDataTemplateValue = this.$store.getters['harvester/byId'](CONFIG_MAP, this.userDataTemplateId)?.data?.cloudInit || '';
|
|
909
950
|
|
|
910
|
-
|
|
951
|
+
const userDataYAML = userDataDoc.toString();
|
|
952
|
+
const userDataJSON = YAML.parse(userDataYAML);
|
|
953
|
+
const packages = userDataJSON?.packages || [];
|
|
954
|
+
const runcmd = userDataJSON?.runcmd || [];
|
|
955
|
+
|
|
956
|
+
if (Array.isArray(packages) && deletePackage) {
|
|
911
957
|
const templateHasQGAPackage = this.convertToJson(userDataTemplateValue);
|
|
912
958
|
|
|
913
|
-
for (let i = 0; i <
|
|
914
|
-
if (
|
|
959
|
+
for (let i = 0; i < packages.length; i++) {
|
|
960
|
+
if (packages[i] === 'qemu-guest-agent') {
|
|
915
961
|
if (!(Array.isArray(templateHasQGAPackage?.packages) && templateHasQGAPackage.packages.includes('qemu-guest-agent'))) {
|
|
916
|
-
|
|
962
|
+
packages.splice(i, 1);
|
|
917
963
|
}
|
|
918
964
|
}
|
|
919
965
|
}
|
|
920
|
-
|
|
921
|
-
if (userDataJson.packages?.length === 0) {
|
|
922
|
-
delete userDataJson.packages;
|
|
923
|
-
}
|
|
924
966
|
}
|
|
925
967
|
|
|
926
|
-
if (Array.isArray(
|
|
968
|
+
if (Array.isArray(runcmd)) {
|
|
927
969
|
const _QGA_JSON = this.getMatchQGA(osType);
|
|
928
970
|
|
|
929
|
-
for (let i = 0; i <
|
|
930
|
-
if (Array.isArray(
|
|
931
|
-
|
|
971
|
+
for (let i = 0; i < runcmd.length; i++) {
|
|
972
|
+
if (Array.isArray(runcmd[i]) && runcmd[i].join('-') === _QGA_JSON.runcmd[0].join('-')) {
|
|
973
|
+
runcmd.splice(i, 1);
|
|
932
974
|
}
|
|
933
975
|
}
|
|
934
|
-
|
|
935
|
-
if (userDataJson.runcmd.length === 0) {
|
|
936
|
-
delete userDataJson.runcmd;
|
|
937
|
-
}
|
|
938
976
|
}
|
|
939
977
|
|
|
940
|
-
if (
|
|
941
|
-
|
|
978
|
+
if (packages.length > 0) {
|
|
979
|
+
userDataDoc.setIn(['packages'], packages);
|
|
980
|
+
} else {
|
|
981
|
+
userDataDoc.setIn(['packages'], []);
|
|
982
|
+
this.deleteYamlDocProp(userDataDoc, ['packages']);
|
|
983
|
+
this.deleteYamlDocProp(userDataDoc, ['package_update']);
|
|
942
984
|
}
|
|
943
985
|
|
|
944
|
-
if (
|
|
945
|
-
|
|
986
|
+
if (runcmd.length > 0) {
|
|
987
|
+
userDataDoc.setIn(['runcmd'], runcmd);
|
|
988
|
+
} else {
|
|
989
|
+
this.deleteYamlDocProp(userDataDoc, ['runcmd']);
|
|
946
990
|
}
|
|
947
991
|
|
|
948
|
-
return
|
|
992
|
+
return userDataDoc;
|
|
949
993
|
},
|
|
950
994
|
|
|
951
995
|
generateSecretName(name) {
|
|
@@ -967,7 +1011,7 @@ export default {
|
|
|
967
1011
|
},
|
|
968
1012
|
|
|
969
1013
|
async saveSecret(vm) {
|
|
970
|
-
if (!vm?.spec || !this.secretName) {
|
|
1014
|
+
if (!vm?.spec || !this.secretName || this.isWindows) {
|
|
971
1015
|
return true;
|
|
972
1016
|
}
|
|
973
1017
|
|
|
@@ -989,13 +1033,8 @@ export default {
|
|
|
989
1033
|
|
|
990
1034
|
try {
|
|
991
1035
|
if (secret) {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
if (this.networkScript) {
|
|
997
|
-
secret.setData('networkdata', this.networkScript);
|
|
998
|
-
}
|
|
1036
|
+
secret.setData('userdata', userData);
|
|
1037
|
+
secret.setData('networkdata', this.networkScript);
|
|
999
1038
|
|
|
1000
1039
|
await secret.save();
|
|
1001
1040
|
}
|
|
@@ -1211,7 +1250,13 @@ export default {
|
|
|
1211
1250
|
}
|
|
1212
1251
|
});
|
|
1213
1252
|
}
|
|
1214
|
-
}
|
|
1253
|
+
},
|
|
1254
|
+
|
|
1255
|
+
updateReserved(value = {}) {
|
|
1256
|
+
const { memory } = value;
|
|
1257
|
+
|
|
1258
|
+
this.$set(this, 'reservedMemory', memory);
|
|
1259
|
+
},
|
|
1215
1260
|
},
|
|
1216
1261
|
|
|
1217
1262
|
watch: {
|
|
@@ -1224,7 +1269,7 @@ export default {
|
|
|
1224
1269
|
|
|
1225
1270
|
const oldImageId = old[0]?.image;
|
|
1226
1271
|
|
|
1227
|
-
if (this.isCreate && oldImageId === imageId) {
|
|
1272
|
+
if (this.isCreate && oldImageId === imageId && imageId) {
|
|
1228
1273
|
this.osType = osType;
|
|
1229
1274
|
}
|
|
1230
1275
|
}
|
|
@@ -1282,8 +1327,7 @@ export default {
|
|
|
1282
1327
|
}
|
|
1283
1328
|
this.deleteAgent = true;
|
|
1284
1329
|
this.deletePackage = false;
|
|
1285
|
-
}
|
|
1286
|
-
immediate: true
|
|
1330
|
+
}
|
|
1287
1331
|
},
|
|
1288
1332
|
|
|
1289
1333
|
osType(neu) {
|