Как идиоматически заполнять пустые поля значениями по умолчанию для объектов API Kubernetes? - PullRequest
1 голос
/ 13 мая 2019

Я хочу сравнить два объекта API Kubernetes (например, v1.PodSpec s): один из них был создан вручную (ожидаемое состояние), другой был получен от API / клиента Kubernetes (фактическое состояние). Проблема заключается в том, что даже если два объекта семантически равны, созданная вручную структура имеет нулевые значения для неопределенных полей, где другая структура имеет значения по умолчанию, и поэтому эти два не совпадают. Это означает, что простого вызова reflect.DeepEqual() недостаточно для сравнения.

например. после этого:

expected := &v1.Container{
    Name:  "busybox",
    Image: "busybox",
}

actual := getContainerSpecFromApi(...)

expected.ImagePullPolicy будет "", а actual.ImagePullPolicy будет "IfNotPresent" (значение по умолчанию), поэтому сравнение не удастся.

Существует ли идиоматический способ замены нулевых значений значениями по умолчанию в структурах API Kubernetes? Или, альтернативно, есть функция конструктора, которая инициализирует структуру со значениями по умолчанию, доступными для них где-то?

EDIT: В настоящее время я использую рукописные тесты на равенство для каждого типа объектов API K8s, но мне это не представляется возможным. Я ищу простую (набор) функцию (и), которая «знает» значения по умолчанию для всех встроенных полей объекта API Kubernetes (возможно, где-то под k8s.io/api*?). Примерно так:

expected = api.ApplyContainerDefaults(expected)
if !reflect.DeepEqual(expected, actual) {
    reconcile(expected, actual)
}

1 Ответ

2 голосов
/ 17 мая 2019

Есть помощники для заполнения значений по умолчанию вместо пустых / нулевых.

Посмотрите, например, на SetObjectDefaults_Deployment для развертывания.

Похоже на правильныеспособ позвонить через (*runtime.Scheme).Default.Ниже приведен фрагмент, демонстрирующий общую идею:

import (
    "reflect"

    appsv1 "k8s.io/api/apps/v1"
    "k8s.io/client-go/kubernetes/scheme"
)

func compare() {
    scheme := scheme.Scheme

    // fetch the existing &appsv1.Deployment via API
    actual := ...
    expected := &appsv1.Deployment{}

    // fill in the fields to generate your expected state
    // ...

    scheme.Default(expected)
    // now you should have your empty values filled in
    if !reflect.DeepEqual(expected.Spec, actual.Spec) {
        reconcile(expected, actual)
    }
}

Если вам нужно менее строгое сравнение, например, если вам нужно допустить некоторые инъецированные контейнеры, то следует использовать что-то более расслабленное, например this .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...