Десериализация ObjectMeta независимо от вида - PullRequest
8 голосов
/ 26 июня 2019

TL; DR: Как можно гибко декодировать объект API k8s и проверять его структуру metav1.ObjectMeta верхнего уровня, не зная заранее 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.

Isэто возможно?Поверхность API k8s довольно обширна, и я просканировал metav1 godoc , corev1 godoc & https://cs.k8s.io для предшествующего уровня техники без приличного примера.

Ближайший IВозможно, обнаружен интерфейс ObjectMetaAccessor, но мне нужно было бы перейти от AdmissionReview.Request.Object (тип runtime.RawExtension) к runtime.Object сначала.

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Полагаю, вы не можете найти то, что ищете, потому что при декодировании объекта Kubernetes использует GetObjectKind и сравнивает результат с Схемой для преобразования объекта вконкретный тип, вместо того, чтобы использовать какой-то общий подобный подход и взаимодействовать с полями объекта, не зная, что это конкретный тип.

Таким образом, вы можете использовать отражение вместо чего-то вроде:

k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()
k8sObjObjectMeta := k8sObjValue.FieldByName("ObjectMeta")
annotations, ok := k8sObjObjectMeta.FieldByName("Annotations").(map[string]string)
if !ok {
    panic("failed to retrieve annotations")
}

РЕДАКТИРОВАТЬ:

Или ближе к вашим требованиям, преобразовать в объект ObjectMeta

k8sObjValue := reflect.ValueOf(admissionReview.Request.Object.Raw).Elem()
objMeta, ok := k8sObjValue.FieldByName("ObjectMeta").(core.ObjectMeta)
if !ok {
    panic("failed to retrieve object metadata")
}
0 голосов
/ 27 июня 2019

Кажется, есть две возможности:

  1. Либо поле Object должно уже содержать правильный экземпляр объекта, при использовании клиента Go, проверьте код здесь .
  2. Попробуйте использовать конвертеры здесь
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...