无论类型如何反序列化 ObjectMeta

如何在事先metav1.ObjectMeta不知道对象的情况下灵活地解码 k8s API 对象并检查其顶级结构?Kind


我正在编写一个准入控制器端点,它将metav1.AdmissionReview对象的Request.Object.Raw字段解组为基于该Request.Kind字段的具体对象 - 例如


if kind == "Pod" {

    var pod core.Pod

    // ...

    if _, _, err := deserializer.Decode(admissionReview.Request.Object.Raw, nil, &pod); err != nil {

        return nil, err

    }


    annotations := pod.ObjectMeta.Annotations

    // inspect/validate the annotations...

这需要预先了解所有可能的类型,或者可能要求用户提供map[kind]corev1.Object我们可以使用的更灵活的类型。


我想要实现的目标是更接近:


var objMeta core.ObjectMeta

if _, _, err := deserializer.Decode(admissionReview.Request.Object.Raw, nil, &objMeta); err != nil {

        return nil, err

}


// if objMeta is populated, validate the fields, else

// assume it is an object that does not define an ObjectMeta

// as part of its schema.

这可能吗?k8s API 表面相当广泛,我已经浏览了metav1 godoc、 corev1 godoc 和https://cs.k8s.io的现有技术,但没有一个像样的例子。

我发现的最接近的可能是ObjectMetaAccessor接口,但我需要从AdmissionReview.Request.Object(type runtime.RawExtension) 到第runtime.Object一个。


波斯汪
浏览 156回答 2
2回答

守候你守候我

我最近发现了一种方法可以做到这一点,让我在这里描述一下:快速免责声明:我使用了admission/v1,但从未使用admission/v1beta1 进行过测试,它的工作原理应该是相同的。的数据类型admissionReview.Request.Object为runtime.RawExtension,并且提供了将 转换为 a 的k8s.io/apimachinery/pkg/runtime方法。该方法称为. 从那里,您可以轻松地转换为数据类型,该数据类型具有可以通过简单的 getter 方法访问的对象的所有字段。runtime.RawExtensionruntime.Objectruntime.Convert_runtime_RawExtension_To_runtime_Object(...)unstructured.UnstructuredMetaV1这是一个可以让您完成此任务的代码片段:import (    // ...    "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"    "k8s.io/apimachinery/pkg/runtime"    // ...)// ...func dummyFunc(ar *v1.AdmissionReview) {    // ...    var obj runtime.Object    var scope conversion.Scope // While not actually used within the function, need to pass in    err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&ar.Request.Object, &obj, scope)    if err != nil {        // ...    }    innerObj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj)    if err != nil {        // ...    }    u := unstructured.Unstructured{Object: innerObj}    // Now the `u` variable has all the meta info available with simple getters.    // Sample:    labels := u.GetLabels()    kind := u.GetKind()    // etc.    // ...}

一只名叫tom的猫

我相信你找不到你要找的东西,因为在解码对象时,Kubernetes 使用GetObjectKind并将结果与方案进行比较,以将对象转换为具体类型,而不是使用一些通用的方法并与字段交互对象的具体类型而不知道它的具体类型。所以你可以使用反射来代替,比如:k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()k8sObjObjectMeta := k8sObjValue.FieldByName("ObjectMeta")annotations, ok := k8sObjObjectMeta.FieldByName("Annotations").Interface().(map[string]string)if !ok {    panic("failed to retrieve annotations")}编辑:或者更接近您的要求,转换为 ObjectMeta 对象k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()objMeta, ok := k8sObjValue.FieldByName("ObjectMeta").Interface().(core.ObjectMeta)if !ok {    panic("failed to retrieve object metadata")}

摇曳的蔷薇

看来有两种可能:要么该字段Object应该已经包含正确的对象实例尝试使用此处的转换器
打开App,查看更多内容
随时随地看视频慕课网APP