Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions api/client/examples/resourceclaim/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module github.com/deckhouse/virtualization/api/client/examples/resourceclaim

go 1.24.7

require (
github.com/deckhouse/virtualization/api v1.0.0
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openshift/custom-resource-status v1.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.3 // indirect
golang.org/x/net v0.39.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.9.0 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.33.3 // indirect
k8s.io/apiextensions-apiserver v0.33.3 // indirect
k8s.io/apimachinery v0.33.3 // indirect
k8s.io/client-go v0.33.3 // indirect
k8s.io/klog/v2 v2.130.1 // indirect
k8s.io/kube-openapi v0.0.0-20250701173324-9bd5c66d9911 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
kubevirt.io/api v1.6.2 // indirect
kubevirt.io/containerized-data-importer-api v1.60.3-0.20241105012228-50fbed985de9 // indirect
kubevirt.io/controller-lifecycle-operator-sdk/api v0.0.0-20220329064328-f3cc58c6ed90 // indirect
sigs.k8s.io/controller-runtime v0.21.0 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

replace github.com/deckhouse/virtualization/api => ./../../../../api
392 changes: 392 additions & 0 deletions api/client/examples/resourceclaim/go.sum

Large diffs are not rendered by default.

211 changes: 211 additions & 0 deletions api/client/examples/resourceclaim/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/*
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 main

import (
"context"
"fmt"
"os"
"os/signal"
"syscall"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/deckhouse/virtualization/api/client/kubeclient"
subv1alpha2 "github.com/deckhouse/virtualization/api/subresources/v1alpha2"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
)

func main() {
ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGTERM, os.Interrupt)
if err := NewResourceClaimCommand().ExecuteContext(ctx); err != nil {
_, _ = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}

func NewResourceClaimCommand() *cobra.Command {
cmd := cobra.Command{
Use: "resourceclaim (VirtualMachine)",
Short: "add/remove resource claim to/from a VirtualMachine.",
SilenceErrors: true,
SilenceUsage: true,
}

cmd.AddCommand(
NewAddResourceClaimCommand(),
NewRemoveResourceClaimCommand(),
)

return &cmd
}

func NewAddResourceClaimCommand() *cobra.Command {
opts := &addResourceClaimOptions{}

cmd := cobra.Command{
Use: "add (VirtualMachine)",
Short: "add resource claim to a VirtualMachine.",
Args: cobra.ExactArgs(1),
SilenceErrors: true,
SilenceUsage: true,
RunE: opts.Run,
}

opts.AddFlags(cmd.Flags())

return &cmd
}

type addResourceClaimOptions struct {
Namespace string
HotplugName string
RequestName string
ResourceClaimTemplateName string
DryRun bool
}

func (o *addResourceClaimOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVarP(&o.Namespace, "namespace", "n", "", "namespace of virtual machine")
fs.StringVar(&o.HotplugName, "hotplug-name", "", "name of the hotplug device")
fs.StringVarP(&o.RequestName, "request-name", "r", "", "name of the resource claim request")
fs.StringVarP(&o.ResourceClaimTemplateName, "resource-claim-template-name", "t", "", "name of the resource claim template")
fs.BoolVarP(&o.DryRun, "dry-run", "d", false, "dry run")
}

func (o *addResourceClaimOptions) Validate() error {
if o.HotplugName == "" {
return fmt.Errorf("hotplug-name is required")
}
if o.RequestName == "" {
return fmt.Errorf("request-name is required")
}
if o.ResourceClaimTemplateName == "" {
return fmt.Errorf("resource-claim-template-name is required")
}
return nil
}

func (o *addResourceClaimOptions) Run(cmd *cobra.Command, args []string) error {
err := o.Validate()
if err != nil {
return err
}

client, namespace, err := getClientAndNamespace(o.Namespace)
if err != nil {
return err
}

name := args[0]
options := subv1alpha2.VirtualMachineAddResourceClaim{
Name: o.HotplugName,
ResourceClaimTemplateName: o.ResourceClaimTemplateName,
RequestName: o.RequestName,
DryRun: dryRun(o.DryRun),
}

cmd.Println("Options:", options)

return client.VirtualMachines(namespace).AddResourceClaim(cmd.Context(), name, options)
}

func NewRemoveResourceClaimCommand() *cobra.Command {
opts := removeResourceClaimOptions{}

cmd := cobra.Command{
Use: "remove (VirtualMachine)",
Short: "remove resource claim from a VirtualMachine.",
Args: cobra.ExactArgs(1),
SilenceErrors: true,
SilenceUsage: true,
RunE: opts.Run,
}

opts.AddFlags(&cmd)

return &cmd
}

type removeResourceClaimOptions struct {
Namespace string
HotplugName string
DryRun bool
}

func (o *removeResourceClaimOptions) AddFlags(cmd *cobra.Command) {
fs := cmd.Flags()
fs.StringVarP(&o.Namespace, "namespace", "n", "", "namespace of virtual machine")
fs.StringVar(&o.HotplugName, "hotplug-name", "", "name of the hotplug device")
fs.BoolVarP(&o.DryRun, "dry-run", "d", false, "dry run")
}

func (o *removeResourceClaimOptions) Validate() error {
if o.HotplugName == "" {
return fmt.Errorf("hotplug-name is required")
}
return nil
}

func (o *removeResourceClaimOptions) Run(cmd *cobra.Command, args []string) error {
err := o.Validate()
if err != nil {
return err
}

client, namespace, err := getClientAndNamespace(o.Namespace)
if err != nil {
return err
}

name := args[0]
options := subv1alpha2.VirtualMachineRemoveResourceClaim{
Name: o.HotplugName,
DryRun: dryRun(o.DryRun),
}

return client.VirtualMachines(namespace).RemoveResourceClaim(cmd.Context(), name, options)
}

func getClientAndNamespace(defaultNamespace string) (kubeclient.Client, string, error) {
namespace := defaultNamespace
clientConfig := kubeclient.DefaultClientConfig(&pflag.FlagSet{})

if namespace == "" {
ns, _, err := clientConfig.Namespace()
if err != nil {
return nil, "", err
}
namespace = ns
}

client, err := kubeclient.GetClientFromClientConfig(clientConfig)
if err != nil {
return nil, "", err
}

return client, namespace, nil
}

func dryRun(should bool) []string {
if should {
return []string{metav1.DryRunAll}
}
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,11 @@ func (c *fakeVirtualMachines) RemoveVolume(ctx context.Context, name string, opt
func (c *fakeVirtualMachines) CancelEvacuation(ctx context.Context, name string, dryRun []string) error {
return nil
}

func (c *fakeVirtualMachines) AddResourceClaim(ctx context.Context, name string, opts v1alpha2.VirtualMachineAddResourceClaim) error {
return nil
}

func (c *fakeVirtualMachines) RemoveResourceClaim(ctx context.Context, name string, opts v1alpha2.VirtualMachineRemoveResourceClaim) error {
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type VirtualMachineExpansion interface {
AddVolume(ctx context.Context, name string, opts v1alpha2.VirtualMachineAddVolume) error
RemoveVolume(ctx context.Context, name string, opts v1alpha2.VirtualMachineRemoveVolume) error
CancelEvacuation(ctx context.Context, name string, dryRun []string) error
AddResourceClaim(ctx context.Context, name string, opts v1alpha2.VirtualMachineAddResourceClaim) error
RemoveResourceClaim(ctx context.Context, name string, opts v1alpha2.VirtualMachineRemoveResourceClaim) error
}

type SerialConsoleOptions struct {
Expand Down Expand Up @@ -81,3 +83,11 @@ func (c *virtualMachines) RemoveVolume(ctx context.Context, name string, opts v1
func (c *virtualMachines) CancelEvacuation(ctx context.Context, name string, dryRun []string) error {
return fmt.Errorf("not implemented")
}

func (c *virtualMachines) AddResourceClaim(ctx context.Context, name string, opts v1alpha2.VirtualMachineAddResourceClaim) error {
return fmt.Errorf("not implemented")
}

func (c *virtualMachines) RemoveResourceClaim(ctx context.Context, name string, opts v1alpha2.VirtualMachineRemoveResourceClaim) error {
return fmt.Errorf("not implemented")
}
27 changes: 27 additions & 0 deletions api/client/kubeclient/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,30 @@ func (v vm) CancelEvacuation(ctx context.Context, name string, dryRun []string)
}
return c.Do(ctx).Error()
}

func (v vm) AddResourceClaim(ctx context.Context, name string, opts subv1alpha2.VirtualMachineAddResourceClaim) error {
path := fmt.Sprintf(subresourceURLTpl, v.namespace, v.resource, name, "addresourceclaim")
c := v.restClient.
Put().
AbsPath(path).
Param("name", opts.Name).
Param("resourceClaimTemplateName", opts.ResourceClaimTemplateName).
Param("requestName", opts.RequestName)

for _, value := range opts.DryRun {
c.Param("dryRun", value)
}
return c.Do(ctx).Error()
}

func (v vm) RemoveResourceClaim(ctx context.Context, name string, opts subv1alpha2.VirtualMachineRemoveResourceClaim) error {
path := fmt.Sprintf(subresourceURLTpl, v.namespace, v.resource, name, "removeresourceclaim")
c := v.restClient.
Put().
AbsPath(path).
Param("name", opts.Name)
for _, value := range opts.DryRun {
c.Param("dryRun", value)
}
return c.Do(ctx).Error()
}
2 changes: 2 additions & 0 deletions api/subresources/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&VirtualMachineFreeze{},
&VirtualMachineUnfreeze{},
&VirtualMachineCancelEvacuation{},
&VirtualMachineAddResourceClaim{},
&VirtualMachineRemoveResourceClaim{},
)
return nil
}
21 changes: 21 additions & 0 deletions api/subresources/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,24 @@ type VirtualMachineCancelEvacuation struct {

DryRun []string
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type VirtualMachineAddResourceClaim struct {
metav1.TypeMeta

Name string
ResourceClaimTemplateName string
RequestName string

DryRun []string
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

type VirtualMachineRemoveResourceClaim struct {
metav1.TypeMeta

Name string
DryRun []string
}
2 changes: 2 additions & 0 deletions api/subresources/v1alpha2/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&VirtualMachineFreeze{},
&VirtualMachineUnfreeze{},
&VirtualMachineCancelEvacuation{},
&VirtualMachineAddResourceClaim{},
&VirtualMachineRemoveResourceClaim{},
)
return nil
}
Loading
Loading