diff --git a/api/client/kubeclient/client.go b/api/client/kubeclient/client.go index 42c0655194..bb233e5eac 100644 --- a/api/client/kubeclient/client.go +++ b/api/client/kubeclient/client.go @@ -21,6 +21,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "github.com/deckhouse/virtualization/api/client/generated/clientset/versioned" @@ -50,6 +51,7 @@ func init() { } type Client interface { + kubernetes.Interface ClusterVirtualImages() virtualizationv1alpha2.ClusterVirtualImageInterface VirtualMachines(namespace string) virtualizationv1alpha2.VirtualMachineInterface VirtualImages(namespace string) virtualizationv1alpha2.VirtualImageInterface @@ -63,6 +65,7 @@ type Client interface { VirtualMachineMACAddressLeases() virtualizationv1alpha2.VirtualMachineMACAddressLeaseInterface } type client struct { + kubernetes.Interface config *rest.Config shallowCopy *rest.Config restClient *rest.RESTClient diff --git a/api/client/kubeclient/config.go b/api/client/kubeclient/config.go index dd61399421..c50413f28d 100644 --- a/api/client/kubeclient/config.go +++ b/api/client/kubeclient/config.go @@ -25,6 +25,7 @@ import ( "github.com/spf13/pflag" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -67,11 +68,18 @@ func GetClientFromRESTConfig(config *rest.Config) (Client, error) { if err != nil { return nil, err } + + clientset, err := kubernetes.NewForConfig(&shallowCopy) + if err != nil { + return nil, err + } + virtClient, err := versioned.NewForConfig(&shallowCopy) if err != nil { return nil, err } return &client{ + Interface: clientset, config: config, shallowCopy: &shallowCopy, restClient: restClient, diff --git a/src/cli/internal/comp/namespace.go b/src/cli/internal/comp/namespace.go new file mode 100644 index 0000000000..8c453fdb6d --- /dev/null +++ b/src/cli/internal/comp/namespace.go @@ -0,0 +1,49 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package comp + +import ( + "strings" + + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/deckhouse/virtualization/src/cli/internal/clientconfig" +) + +func NamespaceFlagCompletionFunc(cmd *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) { + directive := cobra.ShellCompDirectiveNoFileComp + + client, _, _, err := clientconfig.ClientAndNamespaceFromContext(cmd.Context()) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + namespaces, err := client.CoreV1().Namespaces().List(cmd.Context(), metav1.ListOptions{}) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var comps []string + for _, namespace := range namespaces.Items { + if strings.HasPrefix(namespace.Name, toComplete) { + comps = append(comps, namespace.Name) + } + } + + return comps, directive +} diff --git a/src/cli/internal/comp/virtualmachine.go b/src/cli/internal/comp/virtualmachine.go new file mode 100644 index 0000000000..9e5a1b812b --- /dev/null +++ b/src/cli/internal/comp/virtualmachine.go @@ -0,0 +1,53 @@ +/* +Copyright 2025 Flant JSC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package comp + +import ( + "strings" + + "github.com/spf13/cobra" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/deckhouse/virtualization/src/cli/internal/clientconfig" +) + +func VirtualMachineNameCompletionFunc(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + directive := cobra.ShellCompDirectiveNoFileComp + + if len(args) > 0 { + return nil, directive + } + + client, namespace, _, err := clientconfig.ClientAndNamespaceFromContext(cmd.Context()) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + vms, err := client.VirtualMachines(namespace).List(cmd.Context(), metav1.ListOptions{}) + if err != nil { + return nil, cobra.ShellCompDirectiveError + } + + var comps []string + for _, vm := range vms.Items { + if strings.HasPrefix(vm.Name, toComplete) { + comps = append(comps, vm.Name) + } + } + + return comps, directive +} diff --git a/src/cli/pkg/command/virtualization.go b/src/cli/pkg/command/virtualization.go index 715e645ee4..403c0047c2 100644 --- a/src/cli/pkg/command/virtualization.go +++ b/src/cli/pkg/command/virtualization.go @@ -37,6 +37,7 @@ import ( "github.com/deckhouse/virtualization/src/cli/internal/cmd/scp" "github.com/deckhouse/virtualization/src/cli/internal/cmd/ssh" "github.com/deckhouse/virtualization/src/cli/internal/cmd/vnc" + "github.com/deckhouse/virtualization/src/cli/internal/comp" "github.com/deckhouse/virtualization/src/cli/internal/templates" ) @@ -98,8 +99,11 @@ func NewCommand(programName string) *cobra.Command { ctxWithClient := clientconfig.NewContext(ctx, kubeclient.DefaultClientConfig(virtCmd.PersistentFlags())) virtCmd.SetContext(ctxWithClient) + _ = virtCmd.RegisterFlagCompletionFunc("namespace", comp.NamespaceFlagCompletionFunc) + for _, cmd := range virtCmd.Commands() { cmd.SetContext(ctxWithClient) + cmd.ValidArgsFunction = comp.VirtualMachineNameCompletionFunc } return virtCmd