From c302c5cb4764b7107d15137c98cbb00e9b1dd460 Mon Sep 17 00:00:00 2001 From: Isteb4k Date: Wed, 19 Jun 2024 12:50:12 +0200 Subject: [PATCH] fix(vmbda): fix hotplug api call Signed-off-by: Isteb4k --- ...rrord.json => mirrord_virtualization.json} | 0 .mirrord/mirrord_virtualization_api.json | 25 +++++ .../generated/openapi/zz_generated.openapi.go | 54 +++++++++++ api/subresources/register.go | 2 + api/subresources/types.go | 16 ++++ api/subresources/v1alpha2/register.go | 2 + api/subresources/v1alpha2/types.go | 18 ++++ .../v1alpha2/zz_generated.conversion.go | 88 ++++++++++++++++++ .../v1alpha2/zz_generated.deepcopy.go | 50 ++++++++++ api/subresources/zz_generated.deepcopy.go | 50 ++++++++++ .../patches/017-fix-vmi-subresource-url.patch | 57 ++++++++++++ .../pkg/apiserver/api/install.go | 10 +- .../apiserver/registry/vm/rest/add_volume.go | 91 +++++++++++++++++++ .../pkg/apiserver/registry/vm/rest/console.go | 2 +- .../apiserver/registry/vm/rest/portforward.go | 2 +- .../registry/vm/rest/remove_volume.go | 91 +++++++++++++++++++ .../pkg/apiserver/registry/vm/rest/stream.go | 8 +- .../pkg/apiserver/registry/vm/rest/vnc.go | 2 +- .../apiserver/registry/vm/storage/storage.go | 12 +++ .../pkg/apiserver/server/config.go | 7 +- .../pkg/controller/importer/importer_pod.go | 6 -- .../kubevirt/virt-operator/rbac-for-us.yaml | 7 ++ templates/user-authz-cluster-roles.yaml | 2 + 23 files changed, 583 insertions(+), 19 deletions(-) rename .mirrord/{mirrord.json => mirrord_virtualization.json} (100%) create mode 100644 .mirrord/mirrord_virtualization_api.json create mode 100644 images/virt-artifact/patches/017-fix-vmi-subresource-url.patch create mode 100644 images/virtualization-artifact/pkg/apiserver/registry/vm/rest/add_volume.go create mode 100644 images/virtualization-artifact/pkg/apiserver/registry/vm/rest/remove_volume.go diff --git a/.mirrord/mirrord.json b/.mirrord/mirrord_virtualization.json similarity index 100% rename from .mirrord/mirrord.json rename to .mirrord/mirrord_virtualization.json diff --git a/.mirrord/mirrord_virtualization_api.json b/.mirrord/mirrord_virtualization_api.json new file mode 100644 index 000000000..833065559 --- /dev/null +++ b/.mirrord/mirrord_virtualization_api.json @@ -0,0 +1,25 @@ +{ + "feature": { + "network": { + "incoming": "steal", + "outgoing": true + }, + "fs": { + "mode": "read", + "read_only": [ "^/var/", "^/etc/" ] + }, + "env": true + }, + "agent": { + "communication_timeout": 6000, + "startup_timeout": 56000 + }, + "internal_proxy": { + "start_idle_timeout": 13000, + "idle_timeout": 1500 + }, + "target": { + "namespace": "d8-virtualization", + "path": "deployment/virtualization-api/container/virtualization-api" + } +} diff --git a/api/pkg/apiserver/api/generated/openapi/zz_generated.openapi.go b/api/pkg/apiserver/api/generated/openapi/zz_generated.openapi.go index bb65cd646..8c887553c 100644 --- a/api/pkg/apiserver/api/generated/openapi/zz_generated.openapi.go +++ b/api/pkg/apiserver/api/generated/openapi/zz_generated.openapi.go @@ -109,8 +109,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/deckhouse/virtualization/api/core/v1alpha2.VirtualMachineStats": schema_virtualization_api_core_v1alpha2_VirtualMachineStats(ref), "github.com/deckhouse/virtualization/api/core/v1alpha2.VirtualMachineStatus": schema_virtualization_api_core_v1alpha2_VirtualMachineStatus(ref), "github.com/deckhouse/virtualization/api/core/v1alpha2.WeightedVirtualMachineAndPodAffinityTerm": schema_virtualization_api_core_v1alpha2_WeightedVirtualMachineAndPodAffinityTerm(ref), + "github.com/deckhouse/virtualization/api/subresources/v1alpha2.VirtualMachineAddVolume": schema_virtualization_api_subresources_v1alpha2_VirtualMachineAddVolume(ref), "github.com/deckhouse/virtualization/api/subresources/v1alpha2.VirtualMachineConsole": schema_virtualization_api_subresources_v1alpha2_VirtualMachineConsole(ref), "github.com/deckhouse/virtualization/api/subresources/v1alpha2.VirtualMachinePortForward": schema_virtualization_api_subresources_v1alpha2_VirtualMachinePortForward(ref), + "github.com/deckhouse/virtualization/api/subresources/v1alpha2.VirtualMachineRemoveVolume": schema_virtualization_api_subresources_v1alpha2_VirtualMachineRemoveVolume(ref), "github.com/deckhouse/virtualization/api/subresources/v1alpha2.VirtualMachineVNC": schema_virtualization_api_subresources_v1alpha2_VirtualMachineVNC(ref), "k8s.io/api/core/v1.AWSElasticBlockStoreVolumeSource": schema_k8sio_api_core_v1_AWSElasticBlockStoreVolumeSource(ref), "k8s.io/api/core/v1.Affinity": schema_k8sio_api_core_v1_Affinity(ref), @@ -3778,6 +3780,32 @@ func schema_virtualization_api_core_v1alpha2_WeightedVirtualMachineAndPodAffinit } } +func schema_virtualization_api_subresources_v1alpha2_VirtualMachineAddVolume(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_virtualization_api_subresources_v1alpha2_VirtualMachineConsole(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3845,6 +3873,32 @@ func schema_virtualization_api_subresources_v1alpha2_VirtualMachinePortForward(r } } +func schema_virtualization_api_subresources_v1alpha2_VirtualMachineRemoveVolume(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_virtualization_api_subresources_v1alpha2_VirtualMachineVNC(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/api/subresources/register.go b/api/subresources/register.go index 864ed9f7d..4b81d7f3a 100644 --- a/api/subresources/register.go +++ b/api/subresources/register.go @@ -54,6 +54,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &VirtualMachineConsole{}, &VirtualMachineVNC{}, &VirtualMachinePortForward{}, + &VirtualMachineAddVolume{}, + &VirtualMachineRemoveVolume{}, &virtv2.VirtualMachine{}, &virtv2.VirtualMachineList{}, ) diff --git a/api/subresources/types.go b/api/subresources/types.go index 9e270201b..9b800f223 100644 --- a/api/subresources/types.go +++ b/api/subresources/types.go @@ -44,3 +44,19 @@ type VirtualMachinePortForward struct { Protocol string Port int } + +// +genclient +// +genclient:readonly +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type VirtualMachineAddVolume struct { + metav1.TypeMeta +} + +// +genclient +// +genclient:readonly +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +type VirtualMachineRemoveVolume struct { + metav1.TypeMeta +} diff --git a/api/subresources/v1alpha2/register.go b/api/subresources/v1alpha2/register.go index 4c659e98d..8d5e381a7 100644 --- a/api/subresources/v1alpha2/register.go +++ b/api/subresources/v1alpha2/register.go @@ -54,6 +54,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &VirtualMachineConsole{}, &VirtualMachineVNC{}, &VirtualMachinePortForward{}, + &VirtualMachineAddVolume{}, + &VirtualMachineRemoveVolume{}, &virtv2.VirtualMachine{}, &virtv2.VirtualMachineList{}, ) diff --git a/api/subresources/v1alpha2/types.go b/api/subresources/v1alpha2/types.go index e10da51da..ccefa45d8 100644 --- a/api/subresources/v1alpha2/types.go +++ b/api/subresources/v1alpha2/types.go @@ -47,3 +47,21 @@ type VirtualMachinePortForward struct { Protocol string `json:"protocol"` Port int `json:"port"` } + +// +genclient +// +genclient:readonly +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:conversion-gen:explicit-from=net/url.Values + +type VirtualMachineAddVolume struct { + metav1.TypeMeta `json:",inline"` +} + +// +genclient +// +genclient:readonly +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +k8s:conversion-gen:explicit-from=net/url.Values + +type VirtualMachineRemoveVolume struct { + metav1.TypeMeta `json:",inline"` +} diff --git a/api/subresources/v1alpha2/zz_generated.conversion.go b/api/subresources/v1alpha2/zz_generated.conversion.go index 4f7d0426d..e62c6817f 100644 --- a/api/subresources/v1alpha2/zz_generated.conversion.go +++ b/api/subresources/v1alpha2/zz_generated.conversion.go @@ -35,6 +35,16 @@ func init() { // RegisterConversions adds conversion functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*VirtualMachineAddVolume)(nil), (*subresources.VirtualMachineAddVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_VirtualMachineAddVolume_To_subresources_VirtualMachineAddVolume(a.(*VirtualMachineAddVolume), b.(*subresources.VirtualMachineAddVolume), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*subresources.VirtualMachineAddVolume)(nil), (*VirtualMachineAddVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_subresources_VirtualMachineAddVolume_To_v1alpha2_VirtualMachineAddVolume(a.(*subresources.VirtualMachineAddVolume), b.(*VirtualMachineAddVolume), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*VirtualMachineConsole)(nil), (*subresources.VirtualMachineConsole)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_VirtualMachineConsole_To_subresources_VirtualMachineConsole(a.(*VirtualMachineConsole), b.(*subresources.VirtualMachineConsole), scope) }); err != nil { @@ -55,6 +65,16 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*VirtualMachineRemoveVolume)(nil), (*subresources.VirtualMachineRemoveVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_VirtualMachineRemoveVolume_To_subresources_VirtualMachineRemoveVolume(a.(*VirtualMachineRemoveVolume), b.(*subresources.VirtualMachineRemoveVolume), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*subresources.VirtualMachineRemoveVolume)(nil), (*VirtualMachineRemoveVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_subresources_VirtualMachineRemoveVolume_To_v1alpha2_VirtualMachineRemoveVolume(a.(*subresources.VirtualMachineRemoveVolume), b.(*VirtualMachineRemoveVolume), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*VirtualMachineVNC)(nil), (*subresources.VirtualMachineVNC)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1alpha2_VirtualMachineVNC_To_subresources_VirtualMachineVNC(a.(*VirtualMachineVNC), b.(*subresources.VirtualMachineVNC), scope) }); err != nil { @@ -65,6 +85,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VirtualMachineAddVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_url_Values_To_v1alpha2_VirtualMachineAddVolume(a.(*url.Values), b.(*VirtualMachineAddVolume), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VirtualMachineConsole)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_url_Values_To_v1alpha2_VirtualMachineConsole(a.(*url.Values), b.(*VirtualMachineConsole), scope) }); err != nil { @@ -75,6 +100,11 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VirtualMachineRemoveVolume)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_url_Values_To_v1alpha2_VirtualMachineRemoveVolume(a.(*url.Values), b.(*VirtualMachineRemoveVolume), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*url.Values)(nil), (*VirtualMachineVNC)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_url_Values_To_v1alpha2_VirtualMachineVNC(a.(*url.Values), b.(*VirtualMachineVNC), scope) }); err != nil { @@ -83,6 +113,35 @@ func RegisterConversions(s *runtime.Scheme) error { return nil } +func autoConvert_v1alpha2_VirtualMachineAddVolume_To_subresources_VirtualMachineAddVolume(in *VirtualMachineAddVolume, out *subresources.VirtualMachineAddVolume, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha2_VirtualMachineAddVolume_To_subresources_VirtualMachineAddVolume is an autogenerated conversion function. +func Convert_v1alpha2_VirtualMachineAddVolume_To_subresources_VirtualMachineAddVolume(in *VirtualMachineAddVolume, out *subresources.VirtualMachineAddVolume, s conversion.Scope) error { + return autoConvert_v1alpha2_VirtualMachineAddVolume_To_subresources_VirtualMachineAddVolume(in, out, s) +} + +func autoConvert_subresources_VirtualMachineAddVolume_To_v1alpha2_VirtualMachineAddVolume(in *subresources.VirtualMachineAddVolume, out *VirtualMachineAddVolume, s conversion.Scope) error { + return nil +} + +// Convert_subresources_VirtualMachineAddVolume_To_v1alpha2_VirtualMachineAddVolume is an autogenerated conversion function. +func Convert_subresources_VirtualMachineAddVolume_To_v1alpha2_VirtualMachineAddVolume(in *subresources.VirtualMachineAddVolume, out *VirtualMachineAddVolume, s conversion.Scope) error { + return autoConvert_subresources_VirtualMachineAddVolume_To_v1alpha2_VirtualMachineAddVolume(in, out, s) +} + +func autoConvert_url_Values_To_v1alpha2_VirtualMachineAddVolume(in *url.Values, out *VirtualMachineAddVolume, s conversion.Scope) error { + // WARNING: Field TypeMeta does not have json tag, skipping. + + return nil +} + +// Convert_url_Values_To_v1alpha2_VirtualMachineAddVolume is an autogenerated conversion function. +func Convert_url_Values_To_v1alpha2_VirtualMachineAddVolume(in *url.Values, out *VirtualMachineAddVolume, s conversion.Scope) error { + return autoConvert_url_Values_To_v1alpha2_VirtualMachineAddVolume(in, out, s) +} + func autoConvert_v1alpha2_VirtualMachineConsole_To_subresources_VirtualMachineConsole(in *VirtualMachineConsole, out *subresources.VirtualMachineConsole, s conversion.Scope) error { return nil } @@ -159,6 +218,35 @@ func Convert_url_Values_To_v1alpha2_VirtualMachinePortForward(in *url.Values, ou return autoConvert_url_Values_To_v1alpha2_VirtualMachinePortForward(in, out, s) } +func autoConvert_v1alpha2_VirtualMachineRemoveVolume_To_subresources_VirtualMachineRemoveVolume(in *VirtualMachineRemoveVolume, out *subresources.VirtualMachineRemoveVolume, s conversion.Scope) error { + return nil +} + +// Convert_v1alpha2_VirtualMachineRemoveVolume_To_subresources_VirtualMachineRemoveVolume is an autogenerated conversion function. +func Convert_v1alpha2_VirtualMachineRemoveVolume_To_subresources_VirtualMachineRemoveVolume(in *VirtualMachineRemoveVolume, out *subresources.VirtualMachineRemoveVolume, s conversion.Scope) error { + return autoConvert_v1alpha2_VirtualMachineRemoveVolume_To_subresources_VirtualMachineRemoveVolume(in, out, s) +} + +func autoConvert_subresources_VirtualMachineRemoveVolume_To_v1alpha2_VirtualMachineRemoveVolume(in *subresources.VirtualMachineRemoveVolume, out *VirtualMachineRemoveVolume, s conversion.Scope) error { + return nil +} + +// Convert_subresources_VirtualMachineRemoveVolume_To_v1alpha2_VirtualMachineRemoveVolume is an autogenerated conversion function. +func Convert_subresources_VirtualMachineRemoveVolume_To_v1alpha2_VirtualMachineRemoveVolume(in *subresources.VirtualMachineRemoveVolume, out *VirtualMachineRemoveVolume, s conversion.Scope) error { + return autoConvert_subresources_VirtualMachineRemoveVolume_To_v1alpha2_VirtualMachineRemoveVolume(in, out, s) +} + +func autoConvert_url_Values_To_v1alpha2_VirtualMachineRemoveVolume(in *url.Values, out *VirtualMachineRemoveVolume, s conversion.Scope) error { + // WARNING: Field TypeMeta does not have json tag, skipping. + + return nil +} + +// Convert_url_Values_To_v1alpha2_VirtualMachineRemoveVolume is an autogenerated conversion function. +func Convert_url_Values_To_v1alpha2_VirtualMachineRemoveVolume(in *url.Values, out *VirtualMachineRemoveVolume, s conversion.Scope) error { + return autoConvert_url_Values_To_v1alpha2_VirtualMachineRemoveVolume(in, out, s) +} + func autoConvert_v1alpha2_VirtualMachineVNC_To_subresources_VirtualMachineVNC(in *VirtualMachineVNC, out *subresources.VirtualMachineVNC, s conversion.Scope) error { return nil } diff --git a/api/subresources/v1alpha2/zz_generated.deepcopy.go b/api/subresources/v1alpha2/zz_generated.deepcopy.go index bc63c10df..89ba8a7b6 100644 --- a/api/subresources/v1alpha2/zz_generated.deepcopy.go +++ b/api/subresources/v1alpha2/zz_generated.deepcopy.go @@ -24,6 +24,31 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VirtualMachineAddVolume) DeepCopyInto(out *VirtualMachineAddVolume) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualMachineAddVolume. +func (in *VirtualMachineAddVolume) DeepCopy() *VirtualMachineAddVolume { + if in == nil { + return nil + } + out := new(VirtualMachineAddVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VirtualMachineAddVolume) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VirtualMachineConsole) DeepCopyInto(out *VirtualMachineConsole) { *out = *in @@ -74,6 +99,31 @@ func (in *VirtualMachinePortForward) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VirtualMachineRemoveVolume) DeepCopyInto(out *VirtualMachineRemoveVolume) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualMachineRemoveVolume. +func (in *VirtualMachineRemoveVolume) DeepCopy() *VirtualMachineRemoveVolume { + if in == nil { + return nil + } + out := new(VirtualMachineRemoveVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VirtualMachineRemoveVolume) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VirtualMachineVNC) DeepCopyInto(out *VirtualMachineVNC) { *out = *in diff --git a/api/subresources/zz_generated.deepcopy.go b/api/subresources/zz_generated.deepcopy.go index e2c01e28a..02ab1e07f 100644 --- a/api/subresources/zz_generated.deepcopy.go +++ b/api/subresources/zz_generated.deepcopy.go @@ -24,6 +24,31 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VirtualMachineAddVolume) DeepCopyInto(out *VirtualMachineAddVolume) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualMachineAddVolume. +func (in *VirtualMachineAddVolume) DeepCopy() *VirtualMachineAddVolume { + if in == nil { + return nil + } + out := new(VirtualMachineAddVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VirtualMachineAddVolume) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VirtualMachineConsole) DeepCopyInto(out *VirtualMachineConsole) { *out = *in @@ -74,6 +99,31 @@ func (in *VirtualMachinePortForward) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VirtualMachineRemoveVolume) DeepCopyInto(out *VirtualMachineRemoveVolume) { + *out = *in + out.TypeMeta = in.TypeMeta + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualMachineRemoveVolume. +func (in *VirtualMachineRemoveVolume) DeepCopy() *VirtualMachineRemoveVolume { + if in == nil { + return nil + } + out := new(VirtualMachineRemoveVolume) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VirtualMachineRemoveVolume) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VirtualMachineVNC) DeepCopyInto(out *VirtualMachineVNC) { *out = *in diff --git a/images/virt-artifact/patches/017-fix-vmi-subresource-url.patch b/images/virt-artifact/patches/017-fix-vmi-subresource-url.patch new file mode 100644 index 000000000..8bed9c233 --- /dev/null +++ b/images/virt-artifact/patches/017-fix-vmi-subresource-url.patch @@ -0,0 +1,57 @@ +diff --git a/pkg/virt-operator/resource/generate/rbac/controller.go b/pkg/virt-operator/resource/generate/rbac/controller.go +index 8b8313112..2b9061aef 100644 +--- a/pkg/virt-operator/resource/generate/rbac/controller.go ++++ b/pkg/virt-operator/resource/generate/rbac/controller.go +@@ -363,6 +363,18 @@ func newControllerClusterRole() *rbacv1.ClusterRole { + "*", + }, + }, ++ { ++ APIGroups: []string{ ++ "subresources.virtualization.deckhouse.io", ++ }, ++ Resources: []string{ ++ "virtualmachines/addvolume", ++ "virtualmachines/removevolume", ++ }, ++ Verbs: []string{ ++ "update", ++ }, ++ }, + { + APIGroups: []string{ + "subresources.kubevirt.io", +diff --git a/staging/src/kubevirt.io/client-go/kubecli/vmi.go b/staging/src/kubevirt.io/client-go/kubecli/vmi.go +index a9e071350..59c17b0f8 100644 +--- a/staging/src/kubevirt.io/client-go/kubecli/vmi.go ++++ b/staging/src/kubevirt.io/client-go/kubecli/vmi.go +@@ -47,7 +47,10 @@ import ( + "kubevirt.io/client-go/subresources" + ) + +-const vmiSubresourceURL = "/apis/subresources.kubevirt.io/%s/namespaces/%s/virtualmachineinstances/%s/%s" ++const ( ++ vmiSubresourceURL = "/apis/subresources.kubevirt.io/%s/namespaces/%s/virtualmachineinstances/%s/%s" ++ vmiSubresourceVirtualizationURL = "/apis/subresources.virtualization.deckhouse.io/v1alpha2/namespaces/%s/virtualmachines/%s/%s" ++) + + func (k *kubevirt) VirtualMachineInstance(namespace string) VirtualMachineInstanceInterface { + return &vmis{ +@@ -470,7 +473,7 @@ func (v *vmis) Screenshot(ctx context.Context, name string, screenshotOptions *v + } + + func (v *vmis) AddVolume(ctx context.Context, name string, addVolumeOptions *v1.AddVolumeOptions) error { +- uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "addvolume") ++ uri := fmt.Sprintf(vmiSubresourceVirtualizationURL, v.namespace, name, "addvolume") + + JSON, err := json.Marshal(addVolumeOptions) + +@@ -482,7 +485,7 @@ func (v *vmis) AddVolume(ctx context.Context, name string, addVolumeOptions *v1. + } + + func (v *vmis) RemoveVolume(ctx context.Context, name string, removeVolumeOptions *v1.RemoveVolumeOptions) error { +- uri := fmt.Sprintf(vmiSubresourceURL, v1.ApiStorageVersion, v.namespace, name, "removevolume") ++ uri := fmt.Sprintf(vmiSubresourceVirtualizationURL, v.namespace, name, "removevolume") + + JSON, err := json.Marshal(removeVolumeOptions) + diff --git a/images/virtualization-artifact/pkg/apiserver/api/install.go b/images/virtualization-artifact/pkg/apiserver/api/install.go index 3454241d4..5cf813bb2 100644 --- a/images/virtualization-artifact/pkg/apiserver/api/install.go +++ b/images/virtualization-artifact/pkg/apiserver/api/install.go @@ -57,10 +57,12 @@ func init() { func Build(store *storage.VirtualMachineStorage) genericapiserver.APIGroupInfo { apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(subresources.GroupName, Scheme, ParameterCodec, Codecs) resources := map[string]rest.Storage{ - "virtualmachines": store, - "virtualmachines/console": store.ConsoleREST(), - "virtualmachines/vnc": store.VncREST(), - "virtualmachines/portforward": store.PortForwardREST(), + "virtualmachines": store, + "virtualmachines/console": store.ConsoleREST(), + "virtualmachines/vnc": store.VncREST(), + "virtualmachines/portforward": store.PortForwardREST(), + "virtualmachines/addvolume": store.AddVolumeREST(), + "virtualmachines/removevolume": store.RemoveVolumeREST(), } apiGroupInfo.VersionedResourcesStorageMap[v1alpha2.SchemeGroupVersion.Version] = resources return apiGroupInfo diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/add_volume.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/add_volume.go new file mode 100644 index 000000000..df9bb697e --- /dev/null +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/add_volume.go @@ -0,0 +1,91 @@ +/* +Copyright 2024 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 rest + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/client-go/tools/cache" + + "github.com/deckhouse/virtualization-controller/pkg/tls/certmanager" + "github.com/deckhouse/virtualization/api/subresources" +) + +type AddVolumeREST struct { + vmLister cache.GenericLister + proxyCertManager certmanager.CertificateManager + kubevirt KubevirtApiServerConfig +} + +var ( + _ rest.Storage = &AddVolumeREST{} + _ rest.Connecter = &AddVolumeREST{} +) + +func NewAddVolumeREST(vmLister cache.GenericLister, kubevirt KubevirtApiServerConfig, proxyCertManager certmanager.CertificateManager) *AddVolumeREST { + return &AddVolumeREST{ + vmLister: vmLister, + kubevirt: kubevirt, + proxyCertManager: proxyCertManager, + } +} + +func (r AddVolumeREST) New() runtime.Object { + return &subresources.VirtualMachineAddVolume{} +} + +func (r AddVolumeREST) Destroy() { +} + +func (r AddVolumeREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { + addVolumeOpts, ok := opts.(*subresources.VirtualMachineAddVolume) + if !ok { + return nil, fmt.Errorf("invalid options object: %#v", opts) + } + location, transport, err := AddVolumeLocation(ctx, r.vmLister, name, addVolumeOpts, r.kubevirt, r.proxyCertManager) + if err != nil { + return nil, err + } + handler := newThrottledUpgradeAwareProxyHandler(location, transport, false, responder, r.kubevirt.ServiceAccount) + return handler, nil +} + +// NewConnectOptions implements rest.Connecter interface +func (r AddVolumeREST) NewConnectOptions() (runtime.Object, bool, string) { + return &subresources.VirtualMachineAddVolume{}, false, "" +} + +// ConnectMethods implements rest.Connecter interface +func (r AddVolumeREST) ConnectMethods() []string { + return []string{http.MethodPut} +} + +func AddVolumeLocation( + ctx context.Context, + getter cache.GenericLister, + name string, + opts *subresources.VirtualMachineAddVolume, + kubevirt KubevirtApiServerConfig, + proxyCertManager certmanager.CertificateManager, +) (*url.URL, *http.Transport, error) { + return streamLocation(ctx, getter, name, opts, "addvolume", kubevirt, proxyCertManager) +} diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/console.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/console.go index 672bf7233..552b73ed9 100644 --- a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/console.go +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/console.go @@ -74,7 +74,7 @@ func (r ConsoleREST) Connect(ctx context.Context, name string, opts runtime.Obje if err != nil { return nil, err } - handler := newThrottledUpgradeAwareProxyHandler(location, transport, false, true, responder, r.kubevirt.ServiceAccount) + handler := newThrottledUpgradeAwareProxyHandler(location, transport, true, responder, r.kubevirt.ServiceAccount) return handler, nil } diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/portforward.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/portforward.go index bdbb90cd6..319e9193f 100644 --- a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/portforward.go +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/portforward.go @@ -69,7 +69,7 @@ func (r PortForwardREST) Connect(ctx context.Context, name string, opts runtime. if err != nil { return nil, err } - handler := newThrottledUpgradeAwareProxyHandler(location, transport, false, true, responder, r.kubevirt.ServiceAccount) + handler := newThrottledUpgradeAwareProxyHandler(location, transport, true, responder, r.kubevirt.ServiceAccount) return handler, nil } diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/remove_volume.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/remove_volume.go new file mode 100644 index 000000000..f805028f5 --- /dev/null +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/remove_volume.go @@ -0,0 +1,91 @@ +/* +Copyright 2024 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 rest + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/rest" + "k8s.io/client-go/tools/cache" + + "github.com/deckhouse/virtualization-controller/pkg/tls/certmanager" + "github.com/deckhouse/virtualization/api/subresources" +) + +type RemoveVolumeREST struct { + vmLister cache.GenericLister + proxyCertManager certmanager.CertificateManager + kubevirt KubevirtApiServerConfig +} + +var ( + _ rest.Storage = &RemoveVolumeREST{} + _ rest.Connecter = &RemoveVolumeREST{} +) + +func NewRemoveVolumeREST(vmLister cache.GenericLister, kubevirt KubevirtApiServerConfig, proxyCertManager certmanager.CertificateManager) *RemoveVolumeREST { + return &RemoveVolumeREST{ + vmLister: vmLister, + kubevirt: kubevirt, + proxyCertManager: proxyCertManager, + } +} + +func (r RemoveVolumeREST) New() runtime.Object { + return &subresources.VirtualMachineRemoveVolume{} +} + +func (r RemoveVolumeREST) Destroy() { +} + +func (r RemoveVolumeREST) Connect(ctx context.Context, name string, opts runtime.Object, responder rest.Responder) (http.Handler, error) { + removeVolumeOpts, ok := opts.(*subresources.VirtualMachineRemoveVolume) + if !ok { + return nil, fmt.Errorf("invalid options object: %#v", opts) + } + location, transport, err := RemoveVolumeRESTLocation(ctx, r.vmLister, name, removeVolumeOpts, r.kubevirt, r.proxyCertManager) + if err != nil { + return nil, err + } + handler := newThrottledUpgradeAwareProxyHandler(location, transport, false, responder, r.kubevirt.ServiceAccount) + return handler, nil +} + +// NewConnectOptions implements rest.Connecter interface +func (r RemoveVolumeREST) NewConnectOptions() (runtime.Object, bool, string) { + return &subresources.VirtualMachineRemoveVolume{}, false, "" +} + +// ConnectMethods implements rest.Connecter interface +func (r RemoveVolumeREST) ConnectMethods() []string { + return []string{http.MethodPut} +} + +func RemoveVolumeRESTLocation( + ctx context.Context, + getter cache.GenericLister, + name string, + opts *subresources.VirtualMachineRemoveVolume, + kubevirt KubevirtApiServerConfig, + proxyCertManager certmanager.CertificateManager, +) (*url.URL, *http.Transport, error) { + return streamLocation(ctx, getter, name, opts, "removevolume", kubevirt, proxyCertManager) +} diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/stream.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/stream.go index 4f0ec8d7e..6b1308e2a 100644 --- a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/stream.go +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/stream.go @@ -116,6 +116,10 @@ func streamParams(_ url.Values, opts runtime.Object) error { return nil case *subresources.VirtualMachinePortForward: return nil + case *subresources.VirtualMachineAddVolume: + return nil + case *subresources.VirtualMachineRemoveVolume: + return nil default: return fmt.Errorf("unknown object for streaming: %v", opts) } @@ -124,14 +128,14 @@ func streamParams(_ url.Values, opts runtime.Object) error { func newThrottledUpgradeAwareProxyHandler( location *url.URL, transport *http.Transport, - wrapTransport, upgradeRequired bool, + upgradeRequired bool, responder rest.Responder, sa types.NamespacedName, ) http.Handler { var handler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) { r.Header.Add(userHeader, fmt.Sprintf("system:serviceaccount:%s:%s", sa.Namespace, sa.Name)) r.Header.Add(groupHeader, "system:serviceaccounts") - proxyHandler := proxy.NewUpgradeAwareHandler(location, transport, wrapTransport, upgradeRequired, proxy.NewErrorResponder(responder)) + proxyHandler := proxy.NewUpgradeAwareHandler(location, transport, false, upgradeRequired, proxy.NewErrorResponder(responder)) proxyHandler.ServeHTTP(w, r) } return handler diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/vnc.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/vnc.go index 9c41e60b4..cf774fe5b 100644 --- a/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/vnc.go +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/rest/vnc.go @@ -67,7 +67,7 @@ func (r VNCREST) Connect(ctx context.Context, name string, opts runtime.Object, if err != nil { return nil, err } - handler := newThrottledUpgradeAwareProxyHandler(location, transport, false, true, responder, r.kubevirt.ServiceAccount) + handler := newThrottledUpgradeAwareProxyHandler(location, transport, true, responder, r.kubevirt.ServiceAccount) return handler, nil } diff --git a/images/virtualization-artifact/pkg/apiserver/registry/vm/storage/storage.go b/images/virtualization-artifact/pkg/apiserver/registry/vm/storage/storage.go index 62c0818e1..233031d4f 100644 --- a/images/virtualization-artifact/pkg/apiserver/registry/vm/storage/storage.go +++ b/images/virtualization-artifact/pkg/apiserver/registry/vm/storage/storage.go @@ -44,6 +44,8 @@ type VirtualMachineStorage struct { console *vmrest.ConsoleREST vnc *vmrest.VNCREST portforward *vmrest.PortForwardREST + addVolume *vmrest.AddVolumeREST + removeVolume *vmrest.RemoveVolumeREST convertor rest.TableConvertor } @@ -85,6 +87,8 @@ func NewStorage( console: vmrest.NewConsoleREST(vmLister, kubevirt, proxyCertManager), vnc: vmrest.NewVNCREST(vmLister, kubevirt, proxyCertManager), portforward: vmrest.NewPortForwardREST(vmLister, kubevirt, proxyCertManager), + addVolume: vmrest.NewAddVolumeREST(vmLister, kubevirt, proxyCertManager), + removeVolume: vmrest.NewRemoveVolumeREST(vmLister, kubevirt, proxyCertManager), convertor: convertor, } } @@ -101,6 +105,14 @@ func (store VirtualMachineStorage) PortForwardREST() *vmrest.PortForwardREST { return store.portforward } +func (store VirtualMachineStorage) AddVolumeREST() *vmrest.AddVolumeREST { + return store.addVolume +} + +func (store VirtualMachineStorage) RemoveVolumeREST() *vmrest.RemoveVolumeREST { + return store.removeVolume +} + // New implements rest.Storage interface func (store VirtualMachineStorage) New() runtime.Object { return &virtv2.VirtualMachine{} diff --git a/images/virtualization-artifact/pkg/apiserver/server/config.go b/images/virtualization-artifact/pkg/apiserver/server/config.go index b9e76bf02..51b3292ce 100644 --- a/images/virtualization-artifact/pkg/apiserver/server/config.go +++ b/images/virtualization-artifact/pkg/apiserver/server/config.go @@ -93,14 +93,13 @@ func (c Config) Complete() (*Server, error) { if err != nil { return nil, err } - if err := api.Install(vmInformer.Lister(), genericServer, c.Kubevirt, proxyCertManager, crd); err != nil { + if err = api.Install(vmInformer.Lister(), genericServer, c.Kubevirt, proxyCertManager, crd); err != nil { return nil, err } - s := NewServer( + return NewServer( vmInformer.Informer(), genericServer, proxyCertManager, - ) - return s, nil + ), nil } diff --git a/images/virtualization-artifact/pkg/controller/importer/importer_pod.go b/images/virtualization-artifact/pkg/controller/importer/importer_pod.go index efe25d3d8..20ed812a5 100644 --- a/images/virtualization-artifact/pkg/controller/importer/importer_pod.go +++ b/images/virtualization-artifact/pkg/controller/importer/importer_pod.go @@ -25,7 +25,6 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/client" common "github.com/deckhouse/virtualization-controller/pkg/common" @@ -389,8 +388,3 @@ type PodNamer interface { func FindPod(ctx context.Context, client client.Client, name PodNamer) (*corev1.Pod, error) { return helper.FetchObject(ctx, name.ImporterPod(), client, &corev1.Pod{}) } - -func DeletePod(ctx context.Context, clientset kubernetes.Interface, name PodNamer) error { - key := name.ImporterPod() - return clientset.CoreV1().Pods(key.Namespace).Delete(ctx, key.Name, metav1.DeleteOptions{}) -} diff --git a/templates/kubevirt/virt-operator/rbac-for-us.yaml b/templates/kubevirt/virt-operator/rbac-for-us.yaml index c5ba59497..bf587b0e3 100644 --- a/templates/kubevirt/virt-operator/rbac-for-us.yaml +++ b/templates/kubevirt/virt-operator/rbac-for-us.yaml @@ -582,6 +582,13 @@ rules: - '*' verbs: - '*' +- apiGroups: + - subresources.virtualization.deckhouse.io + resources: + - virtualmachines/addvolume + - virtualmachines/removevolume + verbs: + - update - apiGroups: - subresources.kubevirt.io resources: diff --git a/templates/user-authz-cluster-roles.yaml b/templates/user-authz-cluster-roles.yaml index 4c06d98e4..96f4fcc4c 100644 --- a/templates/user-authz-cluster-roles.yaml +++ b/templates/user-authz-cluster-roles.yaml @@ -51,6 +51,8 @@ rules: - virtualmachines/console - virtualmachines/vnc - virtualmachines/portforward + - virtualmachines/addvolume + - virtualmachines/removevolume verbs: - get - create