From 8402649b3d53b0d2ae6997ba146598ca059fd41b Mon Sep 17 00:00:00 2001 From: Johannes Frey Date: Thu, 8 Aug 2024 10:22:55 +0200 Subject: [PATCH] chore: bump to vcluster v0.20.0-beta.15 and remove eks --- .github/workflows/e2e.yaml | 23 +--- go.mod | 2 +- go.sum | 4 +- templates/cluster-template.yaml | 2 +- .../controllerstest/controllers_suite_test.go | 109 +++--------------- test/e2e/eks-values.yaml | 22 ---- .../vcluster/cmd/vclusterctl/cmd/connect.go | 14 +++ .../cmd/vclusterctl/cmd/convert/config.go | 7 +- .../vcluster/cmd/vclusterctl/cmd/list.go | 2 +- .../vclusterctl/cmd/platform/add/cluster.go | 2 +- .../cmd/vclusterctl/cmd/platform/list/list.go | 7 +- .../vclusterctl/cmd/platform/list/projects.go | 75 ++++++++++++ .../cmd/platform/list/vclusters.go | 10 +- .../cmd/vclusterctl/cmd/platform/platform.go | 2 +- .../vcluster/cmd/vclusterctl/cmd/resume.go | 12 +- .../loft-sh/vcluster/config/config.go | 66 +++++++++-- .../vcluster/config/default_extra_values.go | 66 ----------- .../loft-sh/vcluster/config/diff.go | 6 + .../vcluster/config/legacyconfig/migrate.go | 59 ++++++---- .../loft-sh/vcluster/config/values.yaml | 43 +------ .../vcluster/pkg/cli/add_vcluster_helm.go | 50 +++++++- .../loft-sh/vcluster/pkg/cli/create_helm.go | 44 ++++--- .../vcluster/pkg/cli/create_platform.go | 2 +- .../loft-sh/vcluster/pkg/cli/find/find.go | 38 ++++-- .../loft-sh/vcluster/pkg/cli/list_platform.go | 4 +- .../loft-sh/vcluster/pkg/cli/pause_helm.go | 5 + .../vcluster/pkg/cli/pause_platform.go | 8 +- .../loft-sh/vcluster/pkg/cli/resume_helm.go | 7 ++ .../vcluster/pkg/cli/resume_platform.go | 10 +- .../loft-sh/vcluster/pkg/config/config.go | 6 +- .../vcluster/pkg/config/controller_context.go | 3 - .../loft-sh/vcluster/pkg/config/validation.go | 3 - .../loft-sh/vcluster/pkg/kube/meta.go | 30 ++++- .../vcluster/pkg/lifecycle/lifecycle.go | 13 ++- .../loft-sh/vcluster/pkg/platform/helper.go | 26 ++++- .../pkg/platform/sleepmode/sleepmode.go | 16 +++ .../vcluster/pkg/util/clihelper/clihelper.go | 1 + vendor/modules.txt | 3 +- 38 files changed, 464 insertions(+), 338 deletions(-) delete mode 100644 test/e2e/eks-values.yaml create mode 100644 vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/projects.go create mode 100644 vendor/github.com/loft-sh/vcluster/pkg/platform/sleepmode/sleepmode.go diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index bbc82f1d6..b245feed0 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -113,7 +113,7 @@ jobs: run: | export CLUSTER_NAME=vcluster-k3s export CLUSTER_NAMESPACE=vcluster-k3s - export CHART_VERSION=0.20.0-beta.12 + export CHART_VERSION=0.20.0-beta.15 export VCLUSTER_YAML=$(cat ./test/e2e/k3s-values.yaml | sed -z 's/\n/\\n/g') kubectl create namespace ${CLUSTER_NAMESPACE} cat templates/cluster-template.yaml | ./bin/envsubst | kubectl apply -n ${CLUSTER_NAMESPACE} -f - @@ -129,7 +129,7 @@ jobs: run: | export CLUSTER_NAME=vcluster-k0s export CLUSTER_NAMESPACE=vcluster-k0s - export CHART_VERSION=0.20.0-beta.12 + export CHART_VERSION=0.20.0-beta.15 export CHART_NAME=vcluster export VCLUSTER_YAML=$(cat ./test/e2e/k0s-values.yaml | sed -z 's/\n/\\n/g') kubectl create namespace ${CLUSTER_NAMESPACE} @@ -146,7 +146,7 @@ jobs: run: | export CLUSTER_NAME=vcluster-k8s export CLUSTER_NAMESPACE=vcluster-k8s - export CHART_VERSION=0.20.0-beta.12 + export CHART_VERSION=0.20.0-beta.15 export CHART_NAME=vcluster export VCLUSTER_YAML=$(cat ./test/e2e/k8s-values.yaml | sed -z 's/\n/\\n/g') kubectl create namespace ${CLUSTER_NAMESPACE} @@ -158,20 +158,3 @@ jobs: - name: Run E2E Tests K8S run: CLUSTER_NAME=vcluster-k8s NAMESPACE=vcluster-k8s LOCAL_PORT=14552 go test -mod=vendor ./test/e2e -v - - - name: Create Vcluster Custom Resource EKS - run: | - export CLUSTER_NAME=vcluster-eks - export CLUSTER_NAMESPACE=vcluster-eks - export CHART_VERSION=0.20.0-beta.12 - export CHART_NAME=vcluster - export VCLUSTER_YAML=$(cat ./test/e2e/eks-values.yaml | sed -z 's/\n/\\n/g') - kubectl create namespace ${CLUSTER_NAMESPACE} - cat templates/cluster-template.yaml | ./bin/envsubst | kubectl apply -n ${CLUSTER_NAMESPACE} -f - - - - name: Validate Resource Ready EKS - run: | - kubectl wait --for=condition=ready vcluster -n vcluster-eks vcluster-eks --timeout=100s - - - name: Run E2E Tests EKS - run: CLUSTER_NAME=vcluster-eks NAMESPACE=vcluster-eks LOCAL_PORT=14553 go test -mod=vendor ./test/e2e -v diff --git a/go.mod b/go.mod index e9ee4f08c..0aa74a6fe 100644 --- a/go.mod +++ b/go.mod @@ -307,7 +307,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/loft-sh/vcluster v0.20.0-beta.12 + github.com/loft-sh/vcluster v0.20.0-beta.15 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 74bfd4873..6fca3c0a3 100644 --- a/go.sum +++ b/go.sum @@ -504,8 +504,8 @@ github.com/loft-sh/log v0.0.0-20240219160058-26d83ffb46ac h1:Gz/7Lb7WgdgIv+KJz87 github.com/loft-sh/log v0.0.0-20240219160058-26d83ffb46ac/go.mod h1:YImeRjXH34Yf5E79T7UHBQpDZl9fIaaFRgyZ/bkY+UQ= github.com/loft-sh/utils v0.0.29 h1:P/MObccXToAZy2QoJSQDJ+OJx1qHitpFHEVj3QBSNJs= github.com/loft-sh/utils v0.0.29/go.mod h1:9hlX9cGpWHg3mNi/oBlv3X4ePGDMK66k8MbOZGFMDTI= -github.com/loft-sh/vcluster v0.20.0-beta.12 h1:xqHLLYbcWEiKyA998CEKaI0AyQ0rf4isPk7DvUri94k= -github.com/loft-sh/vcluster v0.20.0-beta.12/go.mod h1:Xm+Y8EADJCix31Lvb9kIPO3CIoRRV6RJrL48/skB5qw= +github.com/loft-sh/vcluster v0.20.0-beta.15 h1:/E3CBS0a3sGeakKtYxwJCo9aSsQZ5oFWiGbZESytF/A= +github.com/loft-sh/vcluster v0.20.0-beta.15/go.mod h1:Xm+Y8EADJCix31Lvb9kIPO3CIoRRV6RJrL48/skB5qw= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= diff --git a/templates/cluster-template.yaml b/templates/cluster-template.yaml index 868cb0474..6fbd1c590 100644 --- a/templates/cluster-template.yaml +++ b/templates/cluster-template.yaml @@ -22,7 +22,7 @@ spec: chart: name: ${CHART_NAME:=vcluster} repo: ${CHART_REPO:=https://charts.loft.sh} - version: ${CHART_VERSION:=0.20.0-beta.12} + version: ${CHART_VERSION:=0.20.0-beta.15} controlPlaneEndpoint: host: ${VCLUSTER_HOST:=""} port: ${VCLUSTER_PORT:=0} diff --git a/test/controllerstest/controllers_suite_test.go b/test/controllerstest/controllers_suite_test.go index 84db70396..bf78d75a4 100644 --- a/test/controllerstest/controllers_suite_test.go +++ b/test/controllerstest/controllers_suite_test.go @@ -75,14 +75,7 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { } }) - ginkgo.It("reconcile successfully on k3s", func() { - values := map[string]any{ - "vcluster": map[string]string{ - "image": "rancher/k3s:v1.28.2-k3s1", - }, - } - yamlBytes, yamlErr := yaml.Marshal(&values) - gomega.Expect(yamlErr).NotTo(gomega.HaveOccurred()) + ginkgo.It("reconcile successfully on k8s", func() { vCluster := &v1alpha1.VCluster{ ObjectMeta: metav1.ObjectMeta{ Name: "test-vcluster", @@ -91,9 +84,8 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { Spec: v1alpha1.VClusterSpec{ HelmRelease: &v1alpha1.VirtualClusterHelmRelease{ Chart: v1alpha1.VirtualClusterHelmChart{ - Version: "0.19", + Version: "0.20.0-beta.15", }, - Values: string(yamlBytes), }, }, } @@ -128,75 +120,16 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { gomega.Expect(result.RequeueAfter).Should(gomega.Equal(time.Minute)) }) - ginkgo.It("reconcile successfully on k0s", func() { + ginkgo.It("reconcile successfully on k3s", func() { values := map[string]any{ - "vcluster": map[string]string{ - "image": "rancher/k3s:v1.28.2-k3s1", - }, - } - yamlBytes, yamlErr := yaml.Marshal(&values) - gomega.Expect(yamlErr).NotTo(gomega.HaveOccurred()) - vCluster := &v1alpha1.VCluster{ - ObjectMeta: metav1.ObjectMeta{ - Name: "test-vcluster", - Namespace: "default", - }, - Spec: v1alpha1.VClusterSpec{ - HelmRelease: &v1alpha1.VirtualClusterHelmRelease{ - Chart: v1alpha1.VirtualClusterHelmChart{ - Name: "vcluster-k0s", - Version: "0.19", + "controlPlane": map[string]any{ + "distro": map[string]any{ + "k3s": map[string]bool{ + "enabled": true, }, - Values: string(yamlBytes), }, }, } - hemlClient.On("Upgrade").Return(nil) - f := fakeclientset.NewSimpleClientset() - - _, err := f.CoreV1().ServiceAccounts("default").Create(context.Background(), &corev1.ServiceAccount{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: "default", - }, - }, metav1.CreateOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - reconciler = &controllers.VClusterReconciler{ - Client: fakeclient.NewClientBuilder().WithScheme(scheme).WithObjects(vCluster, secret).WithStatusSubresource(vCluster).Build(), - HelmClient: hemlClient, - Scheme: scheme, - ClientConfigGetter: &fakeConfigGetter{ - fake: f, - }, - HTTPClientGetter: &fakeHTTPClientGetter{}, - } - req := ctrl.Request{ - NamespacedName: types.NamespacedName{ - Name: vCluster.Name, - Namespace: vCluster.Namespace, - }, - } - result, err := reconciler.Reconcile(ctx, req) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - gomega.Expect(result.RequeueAfter).Should(gomega.Equal(time.Minute)) - }) - - ginkgo.It("reconcile successfully on k8s", func() { - values := map[string]any{ - "api": map[string]string{ - "image": "registry.k8s.io/kube-apiserver:v1.28.2", - }, - "scheduler": map[string]string{ - "image": "registry.k8s.io/kube-scheduler:v1.28.2", - }, - "controller": map[string]string{ - "image": "registry.k8s.io/kube-controller-manager:v1.28.2", - }, - "etcd": map[string]string{ - "image": "registry.k8s.io/etcd:3.5.9-0", - }, - } yamlBytes, yamlErr := yaml.Marshal(&values) gomega.Expect(yamlErr).NotTo(gomega.HaveOccurred()) vCluster := &v1alpha1.VCluster{ @@ -207,8 +140,8 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { Spec: v1alpha1.VClusterSpec{ HelmRelease: &v1alpha1.VirtualClusterHelmRelease{ Chart: v1alpha1.VirtualClusterHelmChart{ - Name: "vcluster-k8s", - Version: "0.19", + Name: "vcluster", + Version: "0.20.0-beta.15", }, Values: string(yamlBytes), }, @@ -245,19 +178,14 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { gomega.Expect(result.RequeueAfter).Should(gomega.Equal(time.Minute)) }) - ginkgo.It("reconcile successfully on eks", func() { + ginkgo.It("reconcile successfully on k0s", func() { values := map[string]any{ - "api": map[string]string{ - "image": "test", - }, - "coredns": map[string]string{ - "image": "test", - }, - "controller": map[string]string{ - "image": "test", - }, - "etcd": map[string]string{ - "image": "test", + "controlPlane": map[string]any{ + "distro": map[string]any{ + "k0s": map[string]bool{ + "enabled": true, + }, + }, }, } yamlBytes, yamlErr := yaml.Marshal(&values) @@ -270,8 +198,8 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { Spec: v1alpha1.VClusterSpec{ HelmRelease: &v1alpha1.VirtualClusterHelmRelease{ Chart: v1alpha1.VirtualClusterHelmChart{ - Name: "vcluster-eks", - Version: "0.19", + Name: "vcluster", + Version: "0.20.0-beta.15", }, Values: string(yamlBytes), }, @@ -307,6 +235,7 @@ var _ = ginkgo.Describe("Vcluster Controller test", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) gomega.Expect(result.RequeueAfter).Should(gomega.Equal(time.Minute)) }) + }) }) diff --git a/test/e2e/eks-values.yaml b/test/e2e/eks-values.yaml deleted file mode 100644 index 00a990bc4..000000000 --- a/test/e2e/eks-values.yaml +++ /dev/null @@ -1,22 +0,0 @@ -controlPlane: - backingStore: - etcd: - deploy: - enabled: true - statefulSet: - image: - registry: public.ecr.aws - repository: eks-distro/etcd-io/etcd - tag: v3.5.9-eks-1-28-6 - coredns: - deployment: - image: public.ecr.aws/eks-distro/coredns/coredns:v1.10.1-eks-1-28-6 - distro: - eks: - enabled: true - service: - spec: - type: NodePort - statefulSet: - scheduling: - podManagementPolicy: OrderedReady diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/connect.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/connect.go index 2dd7873ee..f89412136 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/connect.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/connect.go @@ -4,6 +4,10 @@ import ( "cmp" "context" "fmt" + "io" + "os" + + "github.com/sirupsen/logrus" "github.com/loft-sh/log" "github.com/loft-sh/vcluster/pkg/cli" @@ -77,6 +81,7 @@ func (cmd *ConnectCmd) Run(ctx context.Context, args []string) error { if err != nil { return err } + cmd.overrideLogStdoutIfNeeded() cfg := cmd.LoadedConfig(cmd.Log) @@ -100,3 +105,12 @@ func (cmd *ConnectCmd) validateFlags() error { return nil } + +// overrideLogStdoutIfNeeded +// If user specifies --print flag, we have to discard all the logs, otherwise +// we will get invalid kubeconfig. +func (cmd *ConnectCmd) overrideLogStdoutIfNeeded() { + if cmd.Print { + cmd.Log = log.NewStdoutLogger(os.Stdin, io.Discard, os.Stderr, logrus.InfoLevel) + } +} diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/convert/config.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/convert/config.go index 0b16408ad..cf6a3e955 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/convert/config.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/convert/config.go @@ -34,7 +34,8 @@ func convertValues(globalFlags *flags.GlobalFlags) *cobra.Command { Long: `############################################################## ################## vcluster convert config ################### ############################################################## -Converts virtual cluster config config to the v0.20 format +Converts the given virtual cluster config to the v0.20 format. +Reads from stdin if no file is given via "-f". Examples: vcluster convert config --distro k8s -f /my/k8s/values.yaml @@ -47,7 +48,7 @@ cat /my/k0s/values.yaml | vcluster convert config --distro k0s }} cobraCmd.Flags().StringVarP(&c.filePath, "file", "f", "", "Path to the input file") - cobraCmd.Flags().StringVar(&c.distro, "distro", "", fmt.Sprintf("Kubernetes distro of the config. Allowed distros: %s", strings.Join([]string{"k8s", "k3s", "k0s", "eks"}, ", "))) + cobraCmd.Flags().StringVar(&c.distro, "distro", "", fmt.Sprintf("Kubernetes distro of the config. Allowed distros: %s", strings.Join([]string{"k8s", "k3s", "k0s"}, ", "))) cobraCmd.Flags().StringVarP(&c.format, "output", "o", "yaml", "Prints the output in the specified format. Allowed values: yaml, json") return cobraCmd @@ -60,7 +61,7 @@ func (cmd *configCmd) Run() error { ) if cmd.distro == "" { - return fmt.Errorf("no distro given: please set \"--distro\" (IMPORTANT: distro must match the given config values)") + return fmt.Errorf("no distro given: please set \"--distro\" (IMPORTANT: distro must match the given config values, or be \"k8s\" if you are migrating from eks distro)") } if cmd.filePath != "" { diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/list.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/list.go index 18ebca3de..41c998347 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/list.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/list.go @@ -63,7 +63,7 @@ func (cmd *ListCmd) Run(cobraCmd *cobra.Command) error { return fmt.Errorf("parse driver type: %w", err) } if driverType == config.PlatformDriver { - return cli.ListPlatform(cobraCmd.Context(), &cmd.ListOptions, cmd.GlobalFlags, cmd.log) + return cli.ListPlatform(cobraCmd.Context(), &cmd.ListOptions, cmd.GlobalFlags, cmd.log, "") } return cli.ListHelm(cobraCmd.Context(), &cmd.ListOptions, cmd.GlobalFlags, cmd.log) diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/add/cluster.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/add/cluster.go index 81a5e008f..a5c763697 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/add/cluster.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/add/cluster.go @@ -143,7 +143,7 @@ func (cmd *ClusterCmd) Run(ctx context.Context, args []string) error { if os.Getenv("DEVELOPMENT") == "true" { helmArgs = []string{ - "upgrade", "--install", "loft", "./chart", + "upgrade", "--install", "loft", cmp.Or(os.Getenv("DEVELOPMENT_CHART_DIR"), "./chart"), "--create-namespace", "--namespace", namespace, "--set", "agentOnly=true", diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/list.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/list.go index a544b1639..f896e0292 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/list.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/list.go @@ -2,13 +2,13 @@ package list import ( "github.com/loft-sh/api/v4/pkg/product" - "github.com/loft-sh/vcluster/pkg/cli/flags" + pdefaults "github.com/loft-sh/vcluster/pkg/platform/defaults" "github.com/spf13/cobra" ) // NewListCmd creates a new cobra command -func NewListCmd(globalFlags *flags.GlobalFlags) *cobra.Command { +func NewListCmd(globalFlags *flags.GlobalFlags, defaults *pdefaults.Defaults) *cobra.Command { description := product.ReplaceWithHeader("list", "") listCmd := &cobra.Command{ Use: "list", @@ -18,9 +18,10 @@ func NewListCmd(globalFlags *flags.GlobalFlags) *cobra.Command { } listCmd.AddCommand(newClustersCmd(globalFlags)) + listCmd.AddCommand(newProjectsCmd(globalFlags)) listCmd.AddCommand(newSharedSecretsCmd(globalFlags)) listCmd.AddCommand(newTeamsCmd(globalFlags)) - listCmd.AddCommand(newVClustersCmd(globalFlags)) + listCmd.AddCommand(newVClustersCmd(globalFlags, defaults)) listCmd.AddCommand(newNamespacesCmd(globalFlags)) return listCmd } diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/projects.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/projects.go new file mode 100644 index 000000000..cdfe3cd22 --- /dev/null +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/projects.go @@ -0,0 +1,75 @@ +package list + +import ( + "context" + + "github.com/loft-sh/api/v4/pkg/product" + "github.com/loft-sh/log" + "github.com/loft-sh/log/table" + "github.com/loft-sh/vcluster/pkg/cli/flags" + "github.com/loft-sh/vcluster/pkg/platform" + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ProjectsCmd holds the login cmd flags +type ProjectsCmd struct { + *flags.GlobalFlags + + log log.Logger +} + +// newProjectsCmd creates a new spaces command +func newProjectsCmd(globalFlags *flags.GlobalFlags) *cobra.Command { + cmd := &ProjectsCmd{ + GlobalFlags: globalFlags, + log: log.GetInstance(), + } + description := product.ReplaceWithHeader("list projects", ` +List the vcluster platform projects you have access to + +Example: +vcluster platform list projects +######################################################## + `) + projectsCmd := &cobra.Command{ + Use: "projects", + Short: product.Replace("Lists the loft projects you have access to"), + Long: description, + Args: cobra.NoArgs, + RunE: func(cobraCmd *cobra.Command, _ []string) error { + return cmd.RunProjects(cobraCmd.Context()) + }, + } + + return projectsCmd +} + +// RunProjects executes the functionality +func (cmd *ProjectsCmd) RunProjects(ctx context.Context) error { + platformClient, err := platform.InitClientFromConfig(ctx, cmd.LoadedConfig(cmd.log)) + if err != nil { + return err + } + + managementClient, err := platformClient.Management() + if err != nil { + return err + } + + projectList, err := managementClient.Loft().ManagementV1().Projects().List(ctx, metav1.ListOptions{}) + if err != nil { + return err + } + + header := []string{ + "Project", + } + projects := make([][]string, len(projectList.Items)) + for i, project := range projectList.Items { + projects[i] = []string{project.Name} + } + + table.PrintTable(cmd.log, header, projects) + return nil +} diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/vclusters.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/vclusters.go index a12b4aa79..c7c41cca9 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/vclusters.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/list/vclusters.go @@ -6,6 +6,7 @@ import ( "github.com/loft-sh/log" "github.com/loft-sh/vcluster/pkg/cli" "github.com/loft-sh/vcluster/pkg/cli/flags" + pdefaults "github.com/loft-sh/vcluster/pkg/platform/defaults" "github.com/spf13/cobra" ) @@ -14,11 +15,12 @@ type VClustersCmd struct { *flags.GlobalFlags cli.ListOptions - log log.Logger + log log.Logger + Project string } // newVClustersCmd creates a new command -func newVClustersCmd(globalFlags *flags.GlobalFlags) *cobra.Command { +func newVClustersCmd(globalFlags *flags.GlobalFlags, defaults *pdefaults.Defaults) *cobra.Command { cmd := &VClustersCmd{ GlobalFlags: globalFlags, log: log.GetInstance(), @@ -42,11 +44,13 @@ vcluster platform list vclusters }, } + p, _ := defaults.Get(pdefaults.KeyProject, "") + cobraCmd.Flags().StringVarP(&cmd.Project, "project", "p", p, "The project to use") cobraCmd.Flags().StringVar(&cmd.Output, "output", "table", "Choose the format of the output. [table|json]") return cobraCmd } func (cmd *VClustersCmd) Run(ctx context.Context) error { - return cli.ListPlatform(ctx, &cmd.ListOptions, cmd.GlobalFlags, cmd.log) + return cli.ListPlatform(ctx, &cmd.ListOptions, cmd.GlobalFlags, cmd.log, cmd.Project) } diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/platform.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/platform.go index 36ee5251a..2eaa663cb 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/platform.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/platform/platform.go @@ -55,7 +55,7 @@ func NewPlatformCmd(globalFlags *flags.GlobalFlags) (*cobra.Command, error) { platformCmd.AddCommand(NewAccessKeyCmd(globalFlags)) platformCmd.AddCommand(get.NewGetCmd(globalFlags, defaults)) platformCmd.AddCommand(connect.NewConnectCmd(globalFlags, defaults)) - platformCmd.AddCommand(list.NewListCmd(globalFlags)) + platformCmd.AddCommand(list.NewListCmd(globalFlags, defaults)) platformCmd.AddCommand(set.NewSetCmd(globalFlags, defaults)) platformCmd.AddCommand(backup.NewBackupCmd(globalFlags)) platformCmd.AddCommand(wakeup.NewWakeupCmd(globalFlags, defaults)) diff --git a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/resume.go b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/resume.go index a6428170b..07508da13 100644 --- a/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/resume.go +++ b/vendor/github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/resume.go @@ -3,6 +3,7 @@ package cmd import ( "cmp" "context" + "errors" "fmt" "github.com/loft-sh/log" @@ -73,5 +74,14 @@ func (cmd *ResumeCmd) Run(ctx context.Context, args []string) error { return cli.ResumePlatform(ctx, &cmd.ResumeOptions, cfg, args[0], cmd.Log) } - return cli.ResumeHelm(ctx, cmd.GlobalFlags, args[0], cmd.Log) + if err := cli.ResumeHelm(ctx, cmd.GlobalFlags, args[0], cmd.Log); err != nil { + // If they specified a driver, don't fall back to the platform automatically. + if cmd.Driver == "" && errors.Is(err, cli.ErrPlatformDriverRequired) { + return cli.ResumePlatform(ctx, &cmd.ResumeOptions, cfg, args[0], cmd.Log) + } + + return err + } + + return nil } diff --git a/vendor/github.com/loft-sh/vcluster/config/config.go b/vendor/github.com/loft-sh/vcluster/config/config.go index 41eb1ef80..a0a446bc4 100644 --- a/vendor/github.com/loft-sh/vcluster/config/config.go +++ b/vendor/github.com/loft-sh/vcluster/config/config.go @@ -87,6 +87,9 @@ type MetricsServer struct { // Enabled signals the metrics server integration should be enabled. Enabled bool `json:"enabled,omitempty"` + // APIService holds information about where to find the metrics-server service. Defaults to metrics-server/kube-system. + APIService APIService `json:"apiService,omitempty"` + // Nodes defines if metrics-server nodes api should get proxied from host to virtual cluster. Nodes bool `json:"nodes,omitempty"` @@ -94,6 +97,24 @@ type MetricsServer struct { Pods bool `json:"pods,omitempty"` } +// APIService holds configuration related to the api server +type APIService struct { + // Service is a reference to the service for the API server. + Service APIServiceService `json:"service,omitempty"` +} + +// APIServiceService holds the service name and namespace of the host apiservice. +type APIServiceService struct { + // Name is the name of the host service of the apiservice. + Name string `json:"name,omitempty"` + + // Namespace is the name of the host service of the apiservice. + Namespace string `json:"namespace,omitempty"` + + // Port is the target port on the host service to connect to. + Port int `json:"port,omitempty"` +} + // ExternalConfig holds external tool configuration type ExternalConfig map[string]interface{} @@ -157,6 +178,10 @@ func (c *Config) BackingStoreType() StoreType { } } +func (c *Config) EmbeddedDatabase() bool { + return !c.ControlPlane.BackingStore.Database.External.Enabled && !c.ControlPlane.BackingStore.Etcd.Embedded.Enabled && !c.ControlPlane.BackingStore.Etcd.Deploy.Enabled +} + func (c *Config) Distro() string { if c.ControlPlane.Distro.K3S.Enabled { return K3SDistro @@ -164,13 +189,19 @@ func (c *Config) Distro() string { return K0SDistro } else if c.ControlPlane.Distro.K8S.Enabled { return K8SDistro - } else if c.ControlPlane.Distro.EKS.Enabled { - return EKSDistro } return K8SDistro } +func (c *Config) IsConfiguredForSleepMode() bool { + if c != nil && c.External != nil && c.External["platform"] == nil { + return false + } + + return c.External["platform"]["autoSleep"] != nil || c.External["platform"]["autoDelete"] != nil +} + // ValidateChanges checks for disallowed config changes. // Currently only certain backingstore changes are allowed but no distro change. func ValidateChanges(oldCfg, newCfg *Config) error { @@ -182,7 +213,7 @@ func ValidateChanges(oldCfg, newCfg *Config) error { // ValidateStoreAndDistroChanges checks whether migrating from one store to the other is allowed. func ValidateStoreAndDistroChanges(currentStoreType, previousStoreType StoreType, currentDistro, previousDistro string) error { - if currentDistro != previousDistro { + if currentDistro != previousDistro && !(previousDistro == "eks" && currentDistro == K8SDistro) { return fmt.Errorf("seems like you were using %s as a distro before and now have switched to %s, please make sure to not switch between vCluster distros", previousDistro, currentDistro) } @@ -207,7 +238,7 @@ func (c *Config) IsProFeatureEnabled() bool { return true } - if c.Distro() == K8SDistro || c.Distro() == EKSDistro { + if c.Distro() == K8SDistro { if c.ControlPlane.BackingStore.Database.External.Enabled { return true } @@ -702,9 +733,6 @@ type Distro struct { // K0S holds k0s relevant configuration. K0S DistroK0s `json:"k0s,omitempty"` - - // EKS holds eks relevant configuration. - EKS DistroK8s `json:"eks,omitempty"` } type DistroK3s struct { @@ -722,6 +750,18 @@ type DistroK8s struct { // Enabled specifies if the K8s distro should be enabled. Only one distro can be enabled at the same time. Enabled bool `json:"enabled,omitempty"` + // Version specifies k8s components (scheduler, kube-controller-manager & apiserver) version. + // It is a shortcut for controlPlane.distro.k8s.apiServer.image.tag, + // controlPlane.distro.k8s.controllerManager.image.tag and + // controlPlane.distro.k8s.scheduler.image.tag + // If e.g. controlPlane.distro.k8s.version is set to v1.30.1 and + // controlPlane.distro.k8s.scheduler.image.tag + //(or controlPlane.distro.k8s.controllerManager.image.tag or controlPlane.distro.k8s.apiServer.image.tag) + // is set to v1.31.0, + // value from controlPlane.distro.k8s..image.tag will be used + // (where 0 case int: retMap[k] = 0 + // if its an int, its 3 -> 0 + case int64: + retMap[k] = int64(0) + // if its an int, its 3 -> 0 + case float64: + retMap[k] = float64(0) } } else if !reflect.DeepEqual(fromValue, toValue) { switch fromValue.(type) { diff --git a/vendor/github.com/loft-sh/vcluster/config/legacyconfig/migrate.go b/vendor/github.com/loft-sh/vcluster/config/legacyconfig/migrate.go index 9a22f9479..ead44a184 100644 --- a/vendor/github.com/loft-sh/vcluster/config/legacyconfig/migrate.go +++ b/vendor/github.com/loft-sh/vcluster/config/legacyconfig/migrate.go @@ -26,8 +26,8 @@ func MigrateLegacyConfig(distro, oldValues string) (string, error) { if err != nil { return "", fmt.Errorf("migrate legacy %s values: %w", distro, err) } - case config.K8SDistro, config.EKSDistro: - err = migrateK8sAndEKS(distro, oldValues, toConfig) + case config.K8SDistro, "eks": + err = migrateK8sAndEKS(oldValues, toConfig) if err != nil { return "", fmt.Errorf("migrate legacy %s values: %w", distro, err) } @@ -38,7 +38,7 @@ func MigrateLegacyConfig(distro, oldValues string) (string, error) { return config.Diff(fromConfig, toConfig) } -func migrateK8sAndEKS(distro, oldValues string, newConfig *config.Config) error { +func migrateK8sAndEKS(oldValues string, newConfig *config.Config) error { // unmarshal legacy config oldConfig := &LegacyK8s{} err := oldConfig.UnmarshalYAMLStrict([]byte(oldValues)) @@ -46,18 +46,10 @@ func migrateK8sAndEKS(distro, oldValues string, newConfig *config.Config) error return fmt.Errorf("unmarshal legacy config: %w", err) } - // k8s specific - if distro == config.K8SDistro { - newConfig.ControlPlane.Distro.K8S.Enabled = true - convertAPIValues(oldConfig.API, &newConfig.ControlPlane.Distro.K8S.APIServer) - convertControllerValues(oldConfig.Controller, &newConfig.ControlPlane.Distro.K8S.ControllerManager) - convertSchedulerValues(oldConfig.Scheduler, &newConfig.ControlPlane.Distro.K8S.Scheduler) - } else if distro == config.EKSDistro { - newConfig.ControlPlane.Distro.EKS.Enabled = true - convertAPIValues(oldConfig.API, &newConfig.ControlPlane.Distro.EKS.APIServer) - convertControllerValues(oldConfig.Controller, &newConfig.ControlPlane.Distro.EKS.ControllerManager) - convertSchedulerValues(oldConfig.Scheduler, &newConfig.ControlPlane.Distro.EKS.Scheduler) - } + newConfig.ControlPlane.Distro.K8S.Enabled = true + convertAPIValues(oldConfig.API, &newConfig.ControlPlane.Distro.K8S.APIServer) + convertControllerValues(oldConfig.Controller, &newConfig.ControlPlane.Distro.K8S.ControllerManager) + convertSchedulerValues(oldConfig.Scheduler, &newConfig.ControlPlane.Distro.K8S.Scheduler) // convert etcd err = convertEtcd(oldConfig.Etcd, newConfig) @@ -158,7 +150,7 @@ func convertEtcd(oldConfig EtcdValues, newConfig *config.Config) error { } newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.ExtraArgs = oldConfig.ExtraArgs if oldConfig.Resources != nil { - newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.Resources = *oldConfig.Resources + newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.Resources = mergeResources(newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.Resources, *oldConfig.Resources) } newConfig.ControlPlane.BackingStore.Etcd.Deploy.StatefulSet.Persistence.AddVolumes = oldConfig.Volumes if oldConfig.PriorityClassName != "" { @@ -416,19 +408,19 @@ func convertBaseValues(oldConfig BaseHelm, newConfig *config.Config) error { } if len(oldConfig.Isolation.LimitRange.Default) > 0 { - newConfig.Policies.LimitRange.Default = oldConfig.Isolation.LimitRange.Default + newConfig.Policies.LimitRange.Default = mergeMaps(newConfig.Policies.LimitRange.Default, oldConfig.Isolation.LimitRange.Default) } if len(oldConfig.Isolation.LimitRange.DefaultRequest) > 0 { - newConfig.Policies.LimitRange.DefaultRequest = oldConfig.Isolation.LimitRange.DefaultRequest + newConfig.Policies.LimitRange.DefaultRequest = mergeMaps(newConfig.Policies.LimitRange.DefaultRequest, oldConfig.Isolation.LimitRange.DefaultRequest) } if len(oldConfig.Isolation.ResourceQuota.Quota) > 0 { - newConfig.Policies.ResourceQuota.Quota = oldConfig.Isolation.ResourceQuota.Quota + newConfig.Policies.ResourceQuota.Quota = mergeMaps(newConfig.Policies.ResourceQuota.Quota, oldConfig.Isolation.ResourceQuota.Quota) } if len(oldConfig.Isolation.ResourceQuota.Scopes) > 0 { newConfig.Policies.ResourceQuota.Scopes = oldConfig.Isolation.ResourceQuota.Scopes } if len(oldConfig.Isolation.ResourceQuota.ScopeSelector) > 0 { - newConfig.Policies.ResourceQuota.ScopeSelector = oldConfig.Isolation.ResourceQuota.ScopeSelector + newConfig.Policies.ResourceQuota.ScopeSelector = mergeMaps(newConfig.Policies.ResourceQuota.ScopeSelector, oldConfig.Isolation.ResourceQuota.ScopeSelector) } if oldConfig.Isolation.Namespace != nil { @@ -463,7 +455,7 @@ func convertBaseValues(oldConfig BaseHelm, newConfig *config.Config) error { newConfig.ControlPlane.CoreDNS.Deployment.Pods.Labels = oldConfig.Coredns.PodLabels newConfig.ControlPlane.CoreDNS.Deployment.Pods.Annotations = oldConfig.Coredns.PodAnnotations if oldConfig.Coredns.Resources != nil { - newConfig.ControlPlane.CoreDNS.Deployment.Resources = *oldConfig.Coredns.Resources + newConfig.ControlPlane.CoreDNS.Deployment.Resources = mergeResources(newConfig.ControlPlane.CoreDNS.Deployment.Resources, *oldConfig.Coredns.Resources) } if oldConfig.Coredns.Plugin.Enabled { if len(oldConfig.Coredns.Plugin.Config) > 0 { @@ -711,7 +703,7 @@ func convertSyncerConfig(oldConfig SyncerValues, newConfig *config.Config) error return fmt.Errorf("syncer.volumeMounts is not allowed anymore, please remove this field or use syncer.extraVolumeMounts") } if len(oldConfig.Resources.Limits) > 0 || len(oldConfig.Resources.Requests) > 0 { - newConfig.ControlPlane.StatefulSet.Resources = oldConfig.Resources + newConfig.ControlPlane.StatefulSet.Resources = mergeResources(newConfig.ControlPlane.StatefulSet.Resources, oldConfig.Resources) } newConfig.ControlPlane.Service.Annotations = oldConfig.ServiceAnnotations @@ -1066,7 +1058,7 @@ func convertVClusterConfig(oldConfig VClusterValues, retDistroCommon *config.Dis retDistroCommon.Env = oldConfig.Env convertImage(oldConfig.Image, &retDistroContainer.Image) if len(oldConfig.Resources) > 0 { - retDistroCommon.Resources = oldConfig.Resources + retDistroCommon.Resources = mergeMaps(retDistroCommon.Resources, oldConfig.Resources) } retDistroContainer.ExtraArgs = append(retDistroContainer.ExtraArgs, oldConfig.ExtraArgs...) if oldConfig.ImagePullPolicy != "" { @@ -1152,3 +1144,24 @@ func convertObject(from, to interface{}) error { return json.Unmarshal(out, to) } + +func mergeResources(from, to config.Resources) config.Resources { + return config.Resources{ + Limits: mergeMaps(from.Limits, to.Limits), + Requests: mergeMaps(from.Requests, to.Requests), + } +} + +func mergeMaps(from, to map[string]interface{}) map[string]interface{} { + if from == nil && to == nil { + return nil + } + retMap := map[string]interface{}{} + for k, v := range from { + retMap[k] = v + } + for k, v := range to { + retMap[k] = v + } + return retMap +} diff --git a/vendor/github.com/loft-sh/vcluster/config/values.yaml b/vendor/github.com/loft-sh/vcluster/config/values.yaml index 29986edd3..2553bcbb1 100644 --- a/vendor/github.com/loft-sh/vcluster/config/values.yaml +++ b/vendor/github.com/loft-sh/vcluster/config/values.yaml @@ -79,6 +79,7 @@ controlPlane: distro: k8s: enabled: false + version: "" apiServer: enabled: true command: [] @@ -104,7 +105,7 @@ controlPlane: image: registry: registry.k8s.io repository: "kube-scheduler" - tag: "v1.29.0" + tag: "v1.30.2" env: [] securityContext: {} resources: @@ -152,44 +153,6 @@ controlPlane: cpu: 40m memory: 64Mi - eks: - enabled: false - apiServer: - enabled: true - command: [] - extraArgs: [] - imagePullPolicy: "" - image: - registry: "public.ecr.aws" - repository: "eks-distro/kubernetes/kube-apiserver" - tag: "v1.28.2-eks-1-28-6" - controllerManager: - enabled: true - command: [] - extraArgs: [] - imagePullPolicy: "" - image: - registry: "public.ecr.aws" - repository: "eks-distro/kubernetes/kube-controller-manager" - tag: "v1.28.2-eks-1-28-6" - scheduler: - command: [] - extraArgs: [] - imagePullPolicy: "" - image: - registry: "public.ecr.aws" - repository: "eks-distro/kubernetes/kube-scheduler" - tag: "v1.28.2-eks-1-28-6" - env: [] - securityContext: {} - resources: - limits: - cpu: 100m - memory: 256Mi - requests: - cpu: 40m - memory: 64Mi - backingStore: database: embedded: @@ -365,6 +328,7 @@ controlPlane: volumeClaimTemplates: [] addVolumeMounts: [] addVolumes: [] + dataVolume: [] binariesVolume: - name: binaries emptyDir: {} @@ -485,6 +449,7 @@ policies: annotations: {} fallbackDns: 8.8.8.8 outgoingConnections: + platform: true ipBlock: cidr: 0.0.0.0/0 except: diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/add_vcluster_helm.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/add_vcluster_helm.go index 5d38bed26..d702d8f3c 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/add_vcluster_helm.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/add_vcluster_helm.go @@ -3,12 +3,16 @@ package cli import ( "context" "fmt" + "time" "github.com/loft-sh/log" + "github.com/loft-sh/log/survey" "github.com/loft-sh/vcluster/pkg/cli/find" "github.com/loft-sh/vcluster/pkg/cli/flags" "github.com/loft-sh/vcluster/pkg/lifecycle" "github.com/loft-sh/vcluster/pkg/platform" + "github.com/loft-sh/vcluster/pkg/platform/clihelper" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" ) @@ -44,6 +48,45 @@ func AddVClusterHelm( return err } + snoozed := false + // If the vCluster was paused with the helm driver, adding it to the platform will only create the secret for registration + // which leads to confusing behavior for the user since they won't see the cluster in the platform UI until it is resumed. + if lifecycle.IsPaused(vCluster) { + log.Infof("vCluster %s is currently sleeping. It will not be added to the platform until it wakes again.", vCluster.Name) + + snoozeConfirmation := "No. Leave it sleeping. (It will be added automatically on next wakeup)" + answer, err := log.Question(&survey.QuestionOptions{ + Question: fmt.Sprintf("Would you like to wake vCluster %s now to add immediately?", vCluster.Name), + DefaultValue: snoozeConfirmation, + Options: []string{ + snoozeConfirmation, + "Yes. Wake and add now.", + }, + }) + if err != nil { + return fmt.Errorf("failed to capture your response %w", err) + } + + if snoozed = answer == snoozeConfirmation; !snoozed { + if err = ResumeHelm(ctx, globalFlags, vClusterName, log); err != nil { + return fmt.Errorf("failed to wake up vCluster %s: %w", vClusterName, err) + } + + err = wait.PollUntilContextTimeout(ctx, time.Second, clihelper.Timeout(), false, func(ctx context.Context) (done bool, err error) { + vCluster, err = find.GetVCluster(ctx, globalFlags.Context, vClusterName, globalFlags.Namespace, log) + if err != nil { + return false, err + } + + return !lifecycle.IsPaused(vCluster), nil + }) + + if err != nil { + return fmt.Errorf("error waiting for vCluster to wake up %w", err) + } + } + } + // apply platform secret err = platform.ApplyPlatformSecret( ctx, @@ -68,6 +111,11 @@ func AddVClusterHelm( } } - log.Donef("Successfully added vCluster %s/%s", vCluster.Namespace, vCluster.Name) + if snoozed { + log.Infof("vCluster %s/%s will be added the next time it awakes", vCluster.Namespace, vCluster.Name) + log.Donef("Run 'vcluster wakeup --help' to learn how to wake up vCluster %s/%s to complete the add operation.", vCluster.Namespace, vCluster.Name) + } else { + log.Donef("Successfully added vCluster %s/%s", vCluster.Namespace, vCluster.Name) + } return nil } diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/create_helm.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/create_helm.go index b4e074593..6b9127037 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/create_helm.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/create_helm.go @@ -89,7 +89,7 @@ type CreateOptions struct { var CreatedByVClusterAnnotation = "vcluster.loft.sh/created" -var AllowedDistros = []string{config.K8SDistro, config.K3SDistro, config.K0SDistro, config.EKSDistro} +var AllowedDistros = []string{config.K8SDistro, config.K3SDistro, config.K0SDistro} type createHelm struct { *flags.GlobalFlags @@ -268,7 +268,7 @@ func CreateHelm(ctx context.Context, options *CreateOptions, globalFlags *flags. cmd.Connect = false } - if isSleepModeConfigured(vClusterConfig) { + if vClusterConfig.IsConfiguredForSleepMode() { if agentDeployed, err := cmd.isLoftAgentDeployed(ctx); err != nil { return fmt.Errorf("is agent deployed: %w", err) } else if !agentDeployed { @@ -276,7 +276,13 @@ func CreateHelm(ctx context.Context, options *CreateOptions, globalFlags *flags. } } + err = validateHABackingStoreCompatibility(vClusterConfig) + if err != nil { + return err + } + verb := "created" if isVClusterDeployed(release) { + verb = "upgraded" // While certain backing store changes are allowed we prohibit changes to another distro. if err := config.ValidateChanges(currentVClusterConfig, vClusterConfig); err != nil { return err @@ -299,7 +305,7 @@ func CreateHelm(ctx context.Context, options *CreateOptions, globalFlags *flags. // check if we should connect to the vcluster or print the kubeconfig if cmd.Connect || cmd.Print { - cmd.log.Donef("Successfully created virtual cluster %s in namespace %s", vClusterName, cmd.Namespace) + cmd.log.Donef("Successfully %s virtual cluster %s in namespace %s", verb, vClusterName, cmd.Namespace) return ConnectHelm(ctx, &ConnectOptions{ BackgroundProxy: cmd.BackgroundProxy, UpdateCurrent: cmd.UpdateCurrent, @@ -310,9 +316,18 @@ func CreateHelm(ctx context.Context, options *CreateOptions, globalFlags *flags. } if cmd.localCluster { - cmd.log.Donef("Successfully created virtual cluster %s in namespace %s. \n- Use 'vcluster connect %s --namespace %s' to access the virtual cluster", vClusterName, cmd.Namespace, vClusterName, cmd.Namespace) + cmd.log.Donef( + "Successfully %s virtual cluster %s in namespace %s. \n"+ + "- Use 'vcluster connect %s --namespace %s' to access the virtual cluster", + verb, vClusterName, cmd.Namespace, vClusterName, cmd.Namespace, + ) } else { - cmd.log.Donef("Successfully created virtual cluster %s in namespace %s. \n- Use 'vcluster connect %s --namespace %s' to access the virtual cluster\n- Use `vcluster connect %s --namespace %s -- kubectl get ns` to run a command directly within the vcluster", vClusterName, cmd.Namespace, vClusterName, cmd.Namespace, vClusterName, cmd.Namespace) + cmd.log.Donef( + "Successfully %s virtual cluster %s in namespace %s. \n"+ + "- Use 'vcluster connect %s --namespace %s' to access the virtual cluster\n"+ + "- Use `vcluster connect %s --namespace %s -- kubectl get ns` to run a command directly within the vcluster", + verb, vClusterName, cmd.Namespace, vClusterName, cmd.Namespace, vClusterName, cmd.Namespace, + ) } return nil @@ -337,7 +352,7 @@ func (cmd *createHelm) parseVClusterYAML(chartValues string) (*config.Config, er // We cannot discriminate between k0s/k3s and eks/k8s. So we cannot prompt the actual values to convert, as this would cause false positives, // because users are free to e.g. pass a k0s values file to a currently running k3s virtual cluster. if isLegacyConfig([]byte(oldValues)) { - return nil, fmt.Errorf("it appears you are using a vCluster configuration using pre-v0.20 formatting. Please run %q to convert the values to the latest format", "vcluster convert config") + return nil, fmt.Errorf("it appears you are using a vCluster configuration using pre-v0.20 formatting. Please run %q to convert the values to the latest format", "vcluster convert config --distro -f /path/to/vcluster.yaml") } // TODO end @@ -384,13 +399,6 @@ func (cmd *createHelm) isLoftAgentDeployed(ctx context.Context) (bool, error) { return len(podList.Items) > 0, nil } -func isSleepModeConfigured(vClusterConfig *config.Config) bool { - if vClusterConfig == nil || vClusterConfig.External == nil || vClusterConfig.External["platform"] == nil { - return false - } - return vClusterConfig.External["platform"]["autoSleep"] != nil || vClusterConfig.External["platform"]["autoDelete"] != nil -} - func isVClusterDeployed(release *helm.Release) bool { return release != nil && release.Chart != nil && @@ -410,6 +418,16 @@ func isLegacyVCluster(version string) bool { return semver.Compare("v"+version, "v0.20.0-alpha.0") == -1 } +func validateHABackingStoreCompatibility(config *config.Config) error { + if !config.EmbeddedDatabase() { + return nil + } + if !(config.ControlPlane.StatefulSet.HighAvailability.Replicas > 1) { + return nil + } + return fmt.Errorf("cannot use default embedded database (sqlite) in high availability mode. Try embedded etcd backing store instead") +} + func isLegacyConfig(values []byte) bool { cfg := legacyconfig.LegacyK0sAndK3s{} if err := cfg.UnmarshalYAMLStrict(values); err != nil { diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/create_platform.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/create_platform.go index 3a9f08a3c..821d2898d 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/create_platform.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/create_platform.go @@ -590,7 +590,7 @@ func validateTemplateOptions(options *CreateOptions) error { if options.KubernetesVersion != "" { return fmt.Errorf("cannot use --kubernetes-version because the vcluster is using a template") } - if options.Distro != "" && options.Distro != "k3s" { + if options.Distro != "" && options.Distro != "k8s" { return fmt.Errorf("cannot use --distro because the vcluster is using a template") } if options.ChartName != "vcluster" { diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/find/find.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/find/find.go index 357e9fd65..386b39263 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/find/find.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/find/find.go @@ -11,6 +11,7 @@ import ( "github.com/loft-sh/log/survey" "github.com/loft-sh/log/terminal" "github.com/loft-sh/vcluster/pkg/platform" + "github.com/loft-sh/vcluster/pkg/platform/sleepmode" "sigs.k8s.io/controller-runtime/pkg/client" "github.com/loft-sh/vcluster/pkg/constants" @@ -27,9 +28,10 @@ import ( const VirtualClusterSelector = "app=vcluster" type VCluster struct { - Name string - Namespace string - + Name string + Namespace string + Annotations map[string]string + Labels map[string]string Status Status Created metav1.Time Context string @@ -158,6 +160,20 @@ func GetVCluster(ctx context.Context, context, name, namespace string, log log.L return nil, fmt.Errorf("unexpected error searching for selected virtual cluster") } +func (v *VCluster) IsSleeping() bool { + return sleepmode.IsSleeping(v) +} + +// GetAnnotations implements Annotated +func (v *VCluster) GetAnnotations() map[string]string { + return v.Annotations +} + +// GetLabels implements Labeled +func (v *VCluster) GetLabels() map[string]string { + return v.Labels +} + func FormatOptions(format string, options [][]string) []string { if len(options) == 0 { return []string{} @@ -309,12 +325,7 @@ func findInContext(ctx context.Context, context, name, namespace string, timeout continue } - var paused string - - if p.Annotations != nil { - paused = p.Annotations[constants.PausedAnnotation] - } - if p.Spec.Replicas != nil && *p.Spec.Replicas == 0 && paused != "true" { + if p.Spec.Replicas != nil && *p.Spec.Replicas == 0 && !isPaused(&p) { // if the stateful set has been scaled down we'll ignore it -- this happens when // using devspace to do vcluster plugin dev for example, devspace scales down the // vcluster stateful set and re-creates a deployment for "dev mode" so we end up @@ -410,6 +421,8 @@ func getVCluster(ctx context.Context, object client.Object, context, release str return VCluster{ Name: release, Namespace: namespace, + Annotations: object.GetAnnotations(), + Labels: object.GetLabels(), Status: Status(status), Created: created, Context: context, @@ -558,3 +571,10 @@ func GetPodStatus(pod *corev1.Pod) string { } return reason } + +func isPaused(v client.Object) bool { + annotations := v.GetAnnotations() + labels := v.GetLabels() + + return annotations[constants.PausedAnnotation] == "true" || labels[sleepmode.Label] == "true" +} diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/list_platform.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/list_platform.go index 9deb3aeaa..9a9e7d070 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/list_platform.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/list_platform.go @@ -11,7 +11,7 @@ import ( "k8s.io/client-go/tools/clientcmd" ) -func ListPlatform(ctx context.Context, options *ListOptions, globalFlags *flags.GlobalFlags, logger log.Logger) error { +func ListPlatform(ctx context.Context, options *ListOptions, globalFlags *flags.GlobalFlags, logger log.Logger, projectName string) error { rawConfig, err := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(clientcmd.NewDefaultClientConfigLoadingRules(), &clientcmd.ConfigOverrides{}).RawConfig() if err != nil { return err @@ -27,7 +27,7 @@ func ListPlatform(ctx context.Context, options *ListOptions, globalFlags *flags. return err } - proVClusters, err := platform.ListVClusters(ctx, platformClient, "", "") + proVClusters, err := platform.ListVClusters(ctx, platformClient, "", projectName) if err != nil { return err } diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_helm.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_helm.go index 0826c6812..33f9db5c9 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_helm.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_helm.go @@ -30,6 +30,11 @@ func PauseHelm(ctx context.Context, globalFlags *flags.GlobalFlags, vClusterName return err } + if vCluster.IsSleeping() { + log.Infof("vcluster %s/%s is already sleeping", globalFlags.Namespace, vClusterName) + return nil + } + err = lifecycle.PauseVCluster(ctx, kubeClient, vClusterName, globalFlags.Namespace, log) if err != nil { return err diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_platform.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_platform.go index e5bf54856..26869e9b0 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_platform.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/pause_platform.go @@ -22,11 +22,15 @@ func PausePlatform(ctx context.Context, options *PauseOptions, cfg *cliconfig.CL if err != nil { return err } + vCluster, err := find.GetPlatformVCluster(ctx, platformClient, vClusterName, options.Project, log) if err != nil { return err - } else if vCluster.VirtualCluster != nil && vCluster.VirtualCluster.Spec.External { - return fmt.Errorf("cannot pause a virtual cluster that was created via helm, please run 'vcluster use driver helm' or use the '--driver helm' flag") + } + + if vCluster.IsInstanceSleeping() { + log.Infof("vcluster %s/%s is already paused", vCluster.VirtualCluster.Namespace, vClusterName) + return nil } managementClient, err := platformClient.Management() diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_helm.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_helm.go index 64a6a6ab7..6d986da8d 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_helm.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_helm.go @@ -2,6 +2,7 @@ package cli import ( "context" + "errors" "fmt" "github.com/loft-sh/log" @@ -17,12 +18,18 @@ type ResumeOptions struct { Project string } +var ErrPlatformDriverRequired = errors.New("cannot resume a virtual cluster that is paused by the platform, please run 'vcluster use driver platform' or use the '--driver platform' flag") + func ResumeHelm(ctx context.Context, globalFlags *flags.GlobalFlags, vClusterName string, log log.Logger) error { vCluster, err := find.GetVCluster(ctx, globalFlags.Context, vClusterName, globalFlags.Namespace, log) if err != nil { return err } + if vCluster.IsSleeping() { + return ErrPlatformDriverRequired + } + kubeClient, err := prepareResume(vCluster, globalFlags) if err != nil { return err diff --git a/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_platform.go b/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_platform.go index 0dc1c493a..e8683fc99 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_platform.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/cli/resume_platform.go @@ -18,8 +18,14 @@ func ResumePlatform(ctx context.Context, options *ResumeOptions, config *config. vCluster, err := find.GetPlatformVCluster(ctx, platformClient, vClusterName, options.Project, log) if err != nil { return err - } else if vCluster.VirtualCluster != nil && vCluster.VirtualCluster.Spec.External { - return fmt.Errorf("cannot resume a virtual cluster that was created via helm, please run 'vcluster use driver helm' or use the '--driver helm' flag") + } + + if !vCluster.IsInstanceSleeping() { + return fmt.Errorf( + "couldn't find a paused vcluster %s in namespace %s. Make sure the vcluster exists and was paused previously", + vCluster.VirtualCluster.Spec.ClusterRef.VirtualCluster, + vCluster.VirtualCluster.Spec.ClusterRef.Namespace, + ) } managementClient, err := platformClient.Management() diff --git a/vendor/github.com/loft-sh/vcluster/pkg/config/config.go b/vendor/github.com/loft-sh/vcluster/pkg/config/config.go index c103e2785..4d1961f94 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/config/config.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/config/config.go @@ -53,10 +53,6 @@ type VirtualClusterConfig struct { ControlPlaneNamespace string `json:"controlPlaneNamespace,omitempty"` } -func (v VirtualClusterConfig) EmbeddedDatabase() bool { - return !v.ControlPlane.BackingStore.Database.External.Enabled && !v.ControlPlane.BackingStore.Etcd.Embedded.Enabled && !v.ControlPlane.BackingStore.Etcd.Deploy.Enabled -} - func (v VirtualClusterConfig) VirtualClusterKubeConfig() config.VirtualClusterKubeConfig { distroConfig := config.VirtualClusterKubeConfig{} switch v.Distro() { @@ -76,7 +72,7 @@ func (v VirtualClusterConfig) VirtualClusterKubeConfig() config.VirtualClusterKu ClientCACert: "/data/k0s/pki/ca.crt", RequestHeaderCACert: "/data/k0s/pki/front-proxy-ca.crt", } - case config.EKSDistro, config.K8SDistro: + case config.K8SDistro: distroConfig = config.VirtualClusterKubeConfig{ KubeConfig: "/data/pki/admin.conf", ServerCAKey: "/data/pki/ca.key", diff --git a/vendor/github.com/loft-sh/vcluster/pkg/config/controller_context.go b/vendor/github.com/loft-sh/vcluster/pkg/config/controller_context.go index 3c73d4cd2..2de2ccf01 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/config/controller_context.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/config/controller_context.go @@ -32,9 +32,6 @@ type ControllerContext struct { // AcquiredLeaderHooks are hooks to start after vCluster acquired leader AcquiredLeaderHooks []Hook - - // StartAPIServiceProxy will start the api service proxy if needed - StartAPIServiceProxy bool } type Filter func(http.Handler, Clients) http.Handler diff --git a/vendor/github.com/loft-sh/vcluster/pkg/config/validation.go b/vendor/github.com/loft-sh/vcluster/pkg/config/validation.go index ded03a8d9..9185654ca 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/config/validation.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/config/validation.go @@ -125,9 +125,6 @@ func validateDistro(config *VirtualClusterConfig) error { if config.Config.ControlPlane.Distro.K8S.Enabled { enabledDistros++ } - if config.Config.ControlPlane.Distro.EKS.Enabled { - enabledDistros++ - } if enabledDistros > 1 { return fmt.Errorf("only one distribution can be enabled") diff --git a/vendor/github.com/loft-sh/vcluster/pkg/kube/meta.go b/vendor/github.com/loft-sh/vcluster/pkg/kube/meta.go index 302482913..8b7bd4549 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/kube/meta.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/kube/meta.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/loft-sh/log" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -17,7 +16,30 @@ const ( LoftCustomLinksDelimiter = "\n" ) -func UpdateLabels(obj metav1.Object, labelList []string) (bool, error) { +type ( + // Annotated is an interface for objects that have annotations + Annotated interface { + GetAnnotations() map[string]string + } + // Annotatable is an interface for objects that have annotations and ` + Annotatable interface { + Annotated + SetAnnotations(map[string]string) + } + + // Labeled is an interface for objects that have labels + Labeled interface { + GetLabels() map[string]string + } + + // Labelable is an interface for objects that have labels and can set them + Labelable interface { + Labeled + SetLabels(map[string]string) + } +) + +func UpdateLabels(obj Labelable, labelList []string) (bool, error) { // parse strings to map labels, err := parseStringMap(labelList) if err != nil { @@ -44,7 +66,7 @@ func UpdateLabels(obj metav1.Object, labelList []string) (bool, error) { return changed, nil } -func UpdateAnnotations(obj metav1.Object, annotationList []string) (bool, error) { +func UpdateAnnotations(obj Annotatable, annotationList []string) (bool, error) { // parse strings to map annotations, err := parseStringMap(annotationList) if err != nil { @@ -72,7 +94,7 @@ func UpdateAnnotations(obj metav1.Object, annotationList []string) (bool, error) // SetCustomLinksAnnotation sets the list of links for the UI to display next to the project member({space/virtualcluster}instance) // it handles unspecified links (empty) during create and update -func SetCustomLinksAnnotation(obj metav1.Object, links []string) bool { +func SetCustomLinksAnnotation(obj Annotatable, links []string) bool { var changed bool if obj == nil { log.GetInstance().Error("SetCustomLinksAnnotation called on nil object") diff --git a/vendor/github.com/loft-sh/vcluster/pkg/lifecycle/lifecycle.go b/vendor/github.com/loft-sh/vcluster/pkg/lifecycle/lifecycle.go index bb9cc90ef..140e80897 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/lifecycle/lifecycle.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/lifecycle/lifecycle.go @@ -7,6 +7,7 @@ import ( "github.com/loft-sh/log" "github.com/loft-sh/vcluster/pkg/constants" + "github.com/loft-sh/vcluster/pkg/kube" "github.com/loft-sh/vcluster/pkg/util/translate" "github.com/pkg/errors" kerrors "k8s.io/apimachinery/pkg/api/errors" @@ -117,7 +118,7 @@ func scaleDownDeployment(ctx context.Context, kubeClient kubernetes.Interface, l zero := int32(0) for _, item := range list.Items { - if item.Annotations != nil && item.Annotations[constants.PausedAnnotation] == "true" { + if IsPaused(&item) { log.Infof("vcluster %s/%s is already paused", namespace, item.Name) return true, nil } else if item.Spec.Replicas != nil && *item.Spec.Replicas == 0 { @@ -179,7 +180,7 @@ func scaleDownStatefulSet(ctx context.Context, kubeClient kubernetes.Interface, zero := int32(0) for _, item := range list.Items { - if item.Annotations != nil && item.Annotations[constants.PausedAnnotation] == "true" { + if IsPaused(&item) { log.Infof("vcluster %s/%s is already paused", namespace, item.Name) return true, nil } else if item.Spec.Replicas != nil && *item.Spec.Replicas == 0 { @@ -277,7 +278,7 @@ func scaleUpDeployment(ctx context.Context, kubeClient kubernetes.Interface, lab } for _, item := range list.Items { - if item.Annotations == nil || item.Annotations[constants.PausedAnnotation] != "true" { + if !IsPaused(&item) { return false, nil } @@ -323,7 +324,7 @@ func scaleUpStatefulSet(ctx context.Context, kubeClient kubernetes.Interface, la } for _, item := range list.Items { - if item.Annotations == nil || item.Annotations[constants.PausedAnnotation] != "true" { + if !IsPaused(&item) { return false, nil } @@ -359,3 +360,7 @@ func scaleUpStatefulSet(ctx context.Context, kubeClient kubernetes.Interface, la return true, nil } + +func IsPaused(annotated kube.Annotated) bool { + return annotated != nil && annotated.GetAnnotations()[constants.PausedAnnotation] == "true" +} diff --git a/vendor/github.com/loft-sh/vcluster/pkg/platform/helper.go b/vendor/github.com/loft-sh/vcluster/pkg/platform/helper.go index 260ecb636..f4da8b491 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/platform/helper.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/platform/helper.go @@ -21,6 +21,7 @@ import ( "github.com/loft-sh/vcluster/pkg/platform/clihelper" "github.com/loft-sh/vcluster/pkg/platform/kube" "github.com/loft-sh/vcluster/pkg/platform/kubeconfig" + "github.com/loft-sh/vcluster/pkg/platform/sleepmode" "github.com/loft-sh/vcluster/pkg/projectutil" "github.com/loft-sh/vcluster/pkg/util" perrors "github.com/pkg/errors" @@ -545,6 +546,10 @@ type ProjectProjectSecret struct { Project string } +func (vci *VirtualClusterInstanceProject) IsInstanceSleeping() bool { + return vci != nil && vci.VirtualCluster != nil && sleepmode.IsInstanceSleeping(vci.VirtualCluster) +} + func GetProjectSecrets(ctx context.Context, managementClient kube.Interface, projectNames ...string) ([]*ProjectProjectSecret, error) { var projects []*managementv1.Project if len(projectNames) == 0 { @@ -675,7 +680,22 @@ func CreateVirtualClusterInstanceOptions(ctx context.Context, client Client, con // get server for _, val := range kubeConfig.Clusters { - contextOptions.Server = val.Server + if val != nil { + contextOptions.Server = val.Server + } + } + + if len(kubeConfig.AuthInfos) == 0 { + return kubeconfig.ContextOptions{}, errors.New("ingress access is configured but no credentials were present in the kubeconfig") + } + // find the first user and fill cert data with it + for _, v := range kubeConfig.AuthInfos { + contextOptions.ClientCertificateData = v.ClientCertificateData + contextOptions.ClientKeyData = v.ClientKeyData + break + } + if contextOptions.Server == "" { + return kubeconfig.ContextOptions{}, errors.New("could not determine server url") } contextOptions.InsecureSkipTLSVerify = true @@ -1088,8 +1108,8 @@ func WaitForVirtualClusterInstance(ctx context.Context, managementClient kube.In } if virtualClusterInstance.Status.Phase == storagev1.InstanceSleeping { - log.Info("Wait until vcluster wakes up") - defer log.Donef("Successfully woken up vcluster %s", name) + log.Info("Wait until vcluster instance wakes up") + defer log.Donef("virtual cluster %s wakeup successful", name) err := wakeupVCluster(ctx, managementClient, virtualClusterInstance) if err != nil { return nil, fmt.Errorf("error waking up vcluster %s: %s", name, util.GetCause(err)) diff --git a/vendor/github.com/loft-sh/vcluster/pkg/platform/sleepmode/sleepmode.go b/vendor/github.com/loft-sh/vcluster/pkg/platform/sleepmode/sleepmode.go new file mode 100644 index 000000000..3a6381cc7 --- /dev/null +++ b/vendor/github.com/loft-sh/vcluster/pkg/platform/sleepmode/sleepmode.go @@ -0,0 +1,16 @@ +package sleepmode + +import "github.com/loft-sh/vcluster/pkg/kube" + +const ( + Label = "loft.sh/sleep-mode" + SleepingSinceAnnotation = "sleepmode.loft.sh/sleeping-since" +) + +func IsSleeping(labeled kube.Labeled) bool { + return labeled.GetLabels()[Label] == "true" +} + +func IsInstanceSleeping(annotated kube.Annotated) bool { + return annotated != nil && annotated.GetAnnotations()[SleepingSinceAnnotation] != "" +} diff --git a/vendor/github.com/loft-sh/vcluster/pkg/util/clihelper/clihelper.go b/vendor/github.com/loft-sh/vcluster/pkg/util/clihelper/clihelper.go index 025747e9f..67261abb6 100644 --- a/vendor/github.com/loft-sh/vcluster/pkg/util/clihelper/clihelper.go +++ b/vendor/github.com/loft-sh/vcluster/pkg/util/clihelper/clihelper.go @@ -88,6 +88,7 @@ func GetKubeConfig(ctx context.Context, kubeClient *kubernetes.Clientset, vclust if err != nil { return false, nil } + log.Done("vCluster is up and running") return true, nil }) if err != nil { diff --git a/vendor/modules.txt b/vendor/modules.txt index 6e04474ff..99086c682 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -679,7 +679,7 @@ github.com/loft-sh/utils/pkg/command github.com/loft-sh/utils/pkg/downloader github.com/loft-sh/utils/pkg/downloader/commands github.com/loft-sh/utils/pkg/extract -# github.com/loft-sh/vcluster v0.20.0-beta.12 +# github.com/loft-sh/vcluster v0.20.0-beta.15 ## explicit; go 1.22.4 github.com/loft-sh/vcluster/cmd/vclusterctl/cmd github.com/loft-sh/vcluster/cmd/vclusterctl/cmd/convert @@ -728,6 +728,7 @@ github.com/loft-sh/vcluster/pkg/platform/defaults github.com/loft-sh/vcluster/pkg/platform/kube github.com/loft-sh/vcluster/pkg/platform/kubeconfig github.com/loft-sh/vcluster/pkg/platform/random +github.com/loft-sh/vcluster/pkg/platform/sleepmode github.com/loft-sh/vcluster/pkg/projectutil github.com/loft-sh/vcluster/pkg/strvals github.com/loft-sh/vcluster/pkg/telemetry