containerized-data-importer/pkg/apiserver/webhooks/transfer-validate.go
akalenyu 0428dc5465
Stop using deprecated admissionregistration, apiregistration v1beta1 (#1804)
Switch admissionregistration.k8s.io/v1beta, apiregistration.k8s.io/v1beta1 to v1
as they are deprecated and will be removed from k8s-1.22.

apiextensions.k8s.io/v1beta1 was updated to v1 by https://github.com/kubevirt/containerized-data-importer/pull/1307.

Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com>
2021-05-26 22:52:47 +02:00

112 lines
3.4 KiB
Go

/*
* This file is part of the CDI project
*
* 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.
*
* Copyright 2020 Red Hat, Inc.
*
*/
package webhooks
import (
"context"
"encoding/json"
"fmt"
admissionv1 "k8s.io/api/admission/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
cdiv1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1beta1"
cdiclient "kubevirt.io/containerized-data-importer/pkg/client/clientset/versioned"
)
type objectTransferValidatingWebhook struct {
k8sClient kubernetes.Interface
cdiClient cdiclient.Interface
}
func (wh *objectTransferValidatingWebhook) Admit(ar admissionv1.AdmissionReview) *admissionv1.AdmissionResponse {
klog.V(3).Infof("Got AdmissionReview %+v", ar)
if ar.Request.Resource.Group != cdiv1.CDIGroupVersionKind.Group || ar.Request.Resource.Resource != "objecttransfers" {
klog.V(3).Infof("Got unexpected resource type %s", ar.Request.Resource.Resource)
return toAdmissionResponseError(fmt.Errorf("unexpected resource: %s", ar.Request.Resource.Resource))
}
switch ar.Request.Operation {
case admissionv1.Create:
case admissionv1.Update:
default:
klog.V(3).Infof("Got unexpected operation type %s", ar.Request.Operation)
return allowedAdmissionResponse()
}
obj := &cdiv1.ObjectTransfer{}
if err := json.Unmarshal(ar.Request.Object.Raw, obj); err != nil {
return toAdmissionResponseError(err)
}
if ar.Request.Operation == admissionv1.Update {
oldObj := &cdiv1.ObjectTransfer{}
if err := json.Unmarshal(ar.Request.OldObject.Raw, oldObj); err != nil {
return toAdmissionResponseError(err)
}
if !apiequality.Semantic.DeepEqual(obj.Spec, oldObj.Spec) {
return toAdmissionResponseError(fmt.Errorf("ObjectTransfer spec is immutable"))
}
return allowedAdmissionResponse()
}
if obj.Spec.Target.Namespace == nil && obj.Spec.Target.Name == nil {
return toAdmissionResponseError(fmt.Errorf("Target namespace and/or target name must be supplied"))
}
var err error
ns := obj.Spec.Source.Namespace
name := obj.Spec.Source.Name
if obj.Spec.Target.Namespace != nil {
ns = *obj.Spec.Target.Namespace
}
if obj.Spec.Target.Name != nil {
name = *obj.Spec.Target.Name
}
switch obj.Spec.Source.Kind {
case "DataVolume":
_, err = wh.cdiClient.CdiV1beta1().DataVolumes(ns).Get(context.TODO(), name, metav1.GetOptions{})
case "PersistentVolumeClaim":
_, err = wh.k8sClient.CoreV1().PersistentVolumeClaims(ns).Get(context.TODO(), name, metav1.GetOptions{})
default:
return toAdmissionResponseError(fmt.Errorf("Unsupported kind %q", obj.Spec.Source.Kind))
}
if err == nil {
return toAdmissionResponseError(fmt.Errorf("ObjectTransfer target \"%s/%s\" already exists", ns, name))
}
if !errors.IsNotFound(err) {
return toAdmissionResponseError(err)
}
return allowedAdmissionResponse()
}