# Декларативна перевірка API

LLMS index: [llms.txt](/llms.txt)

---

<div class="feature-state-notice feature-beta">
      <span class="feature-state-name">СТАН ФУНКЦІОНАЛУ:</span>
      <code>Kubernetes v1.33 [beta]</code>
    </div>
  



Kubernetes 1.36 включає необовʼязкову *декларативну перевірку* для API. Якщо її увімкнено, сервер API Kubernetes може використовувати цей механізм, а не застарілий підхід, який покладається на рукописний код Go (файли `validation.go`), щоб гарантувати, що запити до API є дійсними. Розробники Kubernetes та люди, які [розширюють Kubernetes API](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/), можуть визначати правила валідації безпосередньо поряд з визначеннями типів API (файли `types.go`). Автори коду визначають спеціальні теґи коментарів (наприклад, `+k8s:minimum=0`). Генератор коду (`validation-gen`) потім використовує ці теґи для створення оптимізованого коду Go для перевірки API.

Хоча ця функція в першу чергу впливає на учасників Kubernetes і потенційних розробників [серверів API розширень](/docs/concepts/extend-kubernetes/api-extension/apiserver-aggregation/), адміністратори кластерів повинні розуміти її поведінку, особливо на етапах її розгортання.

Теги декларативної перевірки можуть застосовуватися безпосередньо до нових полів API без необхідності будь-якого механізму життєвого циклу (наприклад, можливо використовувати `+k8s:minimum=1`). Для міграції наявних рукописних перевірок, де декларативна перевірка заміщає поточну логіку рукописної перевірки, впровадження контролюється тегами життєвого циклу перевірки (`+k8s:alpha` та `+k8s:beta`) разом із функціональним прапорцем `DeclarativeValidationBeta`:

* `DeclarativeValidation`: (GA у v1.36, Стандартно: `true`, LockToDefault: `true`) Сервер API виконує *обидві* системи перевірки — нову декларативну та стару рукописну для перенесених типів/полів у режимі "тіньової перевірки" (Alpha). Результати порівнюються внутрішньо.
* `DeclarativeValidationBeta`: (Beta, Стандартно: `true`) Введено у v1.36. Цей прапорець контролює застосування правил перевірки на етапі бета-версії. Якщо увімкнено, правила, позначені як `+k8s:beta`, є авторитетними; якщо вимкнено, вони повертаються до режиму тіньової перевірки.
* `DeclarativeValidationTakeover`: (Визнано застарілим у v1.36). Раніше використовувався для визначення, чи є результати декларативної перевірки авторитетними. Тепер не враховується, але його можна встановити, щоб уникнути помилок "gate not recognized".

**Типова поведінка (Kubernetes 1.36):**

* Зі значеннями `DeclarativeValidationBeta=true` (стандартно) працюють обидві системи валідації для Alpha та тіньових правил. Діють правила бета-версії.
* **Використовуються результати *рукописної* валідації для Alpha правил.** Декларативна валідація запускається у режимі розбіжностей для порівняння.
* Невідповідності між двома системами валідації реєструються сервером API і збільшують метрику `declarative_validation_mismatch_total`. Ці дані дозволяють розробникам виявляти та виправляти розбіжності на етапі тіньової перевірки.

Адміністратори можуть явно вимкнути функціональну можливість `DeclarativeValidationBeta`, щоб повернути правила перевірки `+k8s:beta` у режим тіньової перевірки, якщо спостерігається неочікувана поведінка перевірки або регресії.

## Вимкнення DeclarativeValidationBeta {#opt-out}

Як адміністратор кластера, ви можете розглянути можливість вимкнення `DeclarativeValidationBeta`=`false` за певних обставин:

* **Неочікувана поведінка перевірки:** Якщо увімкнення `DeclarativeValidationBeta` призводить до неочікуваних помилок перевірки або дозволяє обʼєкти, які раніше були недійсними.
* **Погіршення продуктивності:** Якщо моніторинг вказує на значне збільшення затримок (наприклад, у `apiserver_request_duration_seconds`), повʼязане з увімкненням цієї функції.
* **Високий рівень невідповідностей:** Якщо метрика `declarative_validation_mismatch_total` показує часті невідповідності, що свідчить про потенційні помилки в декларативних правилах, які впливають на робочі навантаження кластера, навіть якщо `DeclarativeValidationBeta` має значення false.

Щоб повернути правила перевірки `+k8s:beta` у режим тіньової перевірки, вимкніть функціональну можливість `DeclarativeValidationBeta`, наприклад, за допомогою аргументів командного рядка: (`--feature-gates=DeclarativeValidationBeta=false`).

## Міркування щодо пониження версії та відкату {#considerations-for-downgrade-and-rollback}

Вимкнення функціональної можливості `DeclarativeValidationBeta` діє як механізм безпеки. Однак, памʼятайте про потенційний крайній випадок (який вважається малоймовірним завдяки ретельному тестуванню): Якщо помилка у декларативній перевірці (коли `DeclarativeValidationBeta=true`) *неправильно дозволила* зберегти недійсний обʼєкт, вимкнення функціональних можливостей може призвести до блокування подальших оновлень цього конкретного обʼєкта за допомогою тепер авторизованої (і правильної) ручної перевірки. Розвʼязання цієї проблеми може вимагати ручного виправлення збереженого обʼєкта, можливо, за допомогою прямої модифікації etcd у рідкісних випадках.

Докладні відомості про керування функціональними можливостями наведено у статті [Функціональні можливості](/docs/reference/command-line-tools-reference/feature-gates/).

## Довідник теґів декларативної валідації{#declarative-validation-tag-reference}

Цей документ містить вичерпну довідкову інформацію про всі доступні теґи декларативної валідації.

### Каталог теґів {#catalog}

| Теґ | Опис | Рівень стабільності
| --- | --- | --- |
| [`+k8s:alpha`](#tag-alpha) | Переводить теґ у режим тіньової перевірки (тільки метрики). | Stable |
| [`+k8s:beta`](#tag-beta) | Переводить теґ у режим примусової перевірки (можна вимкнути за допомогою `DeclarativeValidationBeta`). | Stable |
| [`+k8s:eachKey`](#tag-eachKey) | Оголошує валідацію для кожного ключа в map. | Alpha |
| [`+k8s:eachVal`](#tag-eachVal) | Оголошує валідацію для кожного значення в map або списку. | Alpha |
| [`+k8s:enum`](#tag-enum) | Вказує, що тип рядка є enum. | Beta |
| [`+k8s:forbidden`](#tag-forbidden) | Вказує, що поле не може бути вказане. | Alpha |
| [`+k8s:format`](#tag-format) | Вказує, що рядкове поле має певний формат. | Stable |
| [`+k8s:ifDisabled`](#tag-ifDisabled) | Оголошує валідацію, яка застосовується, коли опцію вимкнено. | Alpha |
| [`+k8s:ifEnabled`](#tag-ifEnabled) | Оголошує валідацію, яка застосовується, коли опцію увімкнено. | Alpha |
| [`+k8s:isSubresource`](#tag-isSubresource) | Визначає, що валідації в пакеті застосовуються лише до конкретного субресурсу. | Stable |
| [`+k8s:item`](#tag-item) | Оголошує валідацію для елемента зрізу, оголошеного як `+k8s:listType=map`. | Stable |
| [`+k8s:listMapKey`](#tag-listMapKey) | Оголошує іменоване підполе типу значення списку як частину ключа list-map. | Stable |
| [`+k8s:listType`](#tag-listType) | Оголошує семантичний тип поля списку. | Stable |
| [`+k8s:maxItems`](#tag-maxItems) | Вказує, що поле списку має обмеження на розмір. | Stable |
| [`+k8s:maxLength`](#tag-maxLength) | Вказує, що рядкове поле має обмеження на довжину. | Stable |
| [`+k8s:minimum`](#tag-minimum) | Вказує, що числове поле має мінімальне значення. | Stable |
| [`+k8s:neq`](#tag-neq) | Перевіряє, що значення поля не дорівнює конкретному забороненому значенню. | Alpha |
| [`+k8s:opaqueType`](#tag-opaqueType) | Вказує, що будь-які валідації, оголошені для вказаного типу, будуть проігноровані. | Alpha |
| [`+k8s:optional`](#tag-optional) | Вказує, що поле є необовʼязковим для клієнтів. | Stable |
| [`+k8s:required`](#tag-required) | Вказує, що поле має бути вказане клієнтами. | Stable |
| [`+k8s:subfield`](#tag-subfield) | Оголошує валідацію для підполя структури. | Stable |
| [`+k8s:supportsSubresource`](#tag-supportsSubresource) | Оголошує підтримуваний субресурс для типів у пакеті. | Stable |
| [`+k8s:unionDiscriminator`](#tag-unionDiscriminator) | Вказує, що це поле є дискримінатором для обʼєднання. | Stable |
| [`+k8s:unionMember`](#tag-unionMember) | Вказує, що це поле є членом групи обʼєднання. | Stable |
| [`+k8s:zeroOrOneOfMember`](#tag-zeroOrOneOfMember) | Вказує, що це поле є членом групи нуль-або-один-з. | Stable |

---

## Довідник по теґам {#tag-reference}

### `+k8s:alpha` {#tag-alpha}

**Опис:**

Теґ `+k8s:alpha` вмикає *тіньовий режим* для правил валідації. Він представляє першу фазу життєвого циклу валідації для безпечного перенесення поточної ручної логіки валідації до декларативних теґів. Не використовуйте цей теґ для нових полів API, які повинні застосовувати декларативні теґи валідації безпосередньо.

Коли валідація позначена як `+k8s:alpha`, виконувана логіка валідації включає оригінальну ручну логіку валідації, як зазвичай, але додатково запускає тіньову декларативну валідацію в неблокуючому режимі, а потім перевіряє, чи результати збігаються. Будь-які невідповідності або паніки записуються через метрики (наприклад: `declarative_validation_mismatch_total` та `declarative_validation_panic_total`). Цей тіньовий механізм дозволяє учасникам та адміністраторам оцінювати правила декларативної валідації в реальному середовищі без впливу на поведінку кластера. Моніторинг метрик невідповідностей дозволяє перевірити, що декларативні правила поводяться ідентично до наявної ручної логіки перед підвищенням валідації до бета-версії.

**Рівень стабільності:** Stable

**Аргументи:**

* `since` (string, обовʼязково): Версія Kubernetes, в якій валідація вперше була позначена як тіньова.

**Payload:**

* `<validation-tag>`: Стандартний декларативний теґ валідації, який буде позначений як тіньовий (наприклад, `+k8s:minimum=1`).

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:alpha(since:"1.36")=+k8s:minimum=1
    MyField int `json:"myField"`
}
```

### `+k8s:beta` {#tag-beta}

**Опис:**

Теґ `+k8s:beta` вмикає *режим примусового застосування* для правил валідації, що мігрують з ручної логіки, керований через функціональну можливість `DeclarativeValidationBeta`. Не використовуйте цей теґ для нових полів API, які повинні застосовувати декларативні теґи валідації безпосередньо.

Після того, як правило валідації було оцінене в тіньовому режимі (через `+k8s:alpha`), воно підвищується до бета-версії. Коли `DeclarativeValidationBeta` увімкнено (стандартно), правила `+k8s:beta` застосовуються примусово і є авторитетними. Вимкнення функціональної можливості повертає правила `+k8s:beta` до тіньового режиму, забезпечуючи механізм відкату у разі виникнення регресій.

**Рівень стабільності:** Stable

**Аргументи:**

* `since` (string, обовʼязково): Версія Kubernetes, в якій валідація була підвищена до бета-версії.

**Корисне навантаження:**

* `<validation-tag>`: Стандартний декларативний теґ валідації, який буде застосовуватися примусово (наприклад, `+k8s:minimum=1`).

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:beta(since:"1.37")=+k8s:minimum=1
    MyField int `json:"myField"`
}
```

### `+k8s:eachKey` {#tag-eachKey}

**Опис:**

Оголошує валідацію для кожного ключа в map.

**Рівень стабільності:** Alpha

**Корисне навантаження:**

* `<validation-tag>`: Теґ для оцінки кожного ключа.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:eachKey=+k8s:minimum=1
    MyMap map[int]string `json:"myMap"`
}
```

У цьому прикладі `eachKey` використовується для вказівки, що теґ `+k8s:minimum` повинен застосовуватися до кожного ключа `int` в `MyMap`. Це означає, що всі ключі в map повинні бути >= 1.

### `+k8s:eachVal` {#tag-eachVal}

**Опис:**

Оголошує валідацію для кожного значення в map або списку.

**Рівень стабільності:** Alpha

**Корисне навантаження:**

* `<validation-tag>`: Теґ для оцінки для кожного значення.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:eachVal=+k8s:minimum=1
    MyMap map[string]int `json:"myMap"`
}
```

У цьому прикладі `eachVal` використовується для вказівки, що теґ `+k8s:minimum` повинен застосовуватися до кожного елемента в `MyList`. Це означає, що всі поля в `MyStruct` повинні бути >= 1.

### `+k8s:enum` {#tag-enum}

**Опис:**

Вказує, що тип рядка є enum (перерахуванням). Усі константи цього типу вважаються значеннями в перерахуванні.

**Рівень стабільності:** Beta

**Приклад використання:**

Спочатку визначте новий тип рядка та кілька констант цього типу:

```go
// +k8s:enum
type MyEnum string

const (
    MyEnumA MyEnum = "A"
    MyEnumB MyEnum = "B"
)
```

Потім використовуйте цей тип в іншій структурі:

```go
type MyStruct struct {
    MyField MyEnum `json:"myField"`
}
```

Логіка валідації забезпечить те, що `MyField` є одним з визначених значень enum (перерахування) (`"A"` або `"B"`).

### `+k8s:forbidden` {#tag-forbidden}

**Опис:**

Вказує, що поле не може бути вказане.

**Рівень стабільності:** Alpha

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:forbidden
    MyField string `json:"myField"`
}
```

У цьому прикладі `MyField` не може бути надане (воно заборонене) під час створення або оновлення `MyStruct`.

### `+k8s:format` {#tag-format}

**Опис:**

Вказує, що рядкове поле має певний формат.

**Рівень стабільності:** Stable

**Корисне навантаження:**

* `k8s-ip`: Це поле містить значення IPv4 або IPv6 адреси. Октети IPv4 можуть мати нулі на початку.
* `k8s-long-name`: Це поле містить "довгу назву" Kubernetes, також відому як значення "DNS піддомену".
* `k8s-short-name`: Це поле містить "коротку назву" Kubernetes, також відому як значення "DNS мітки".

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:format=k8s-ip
    IPAddress string `json:"ipAddress"`

    // +k8s:format=k8s-long-name
    Subdomain string `json:"subdomain"`

    // +k8s:format=k8s-short-name
    Label string `json:"label"`
}
```

У цьому прикладі:
* `IPAddress` повинен бути дійсною IP-адресою.
* `Subdomain` повинен бути дійсним піддоменом DNS.
* `Label` повинен бути дійсною міткою DNS.

### `+k8s:ifDisabled` {#tag-ifDisabled}

**Опис:**

Оголошує валідацію, яка застосовується, коли опцію вимкнено.

**Рівень стабільності:** Alpha

**Аргументи:**

* `<option>` (рядок, обовʼязково): Імʼя опції.

**Корисне навантаження:**

* `<validation-tag>`: Цей теґ валідації буде оцінюватися лише тоді, коли опцію вимкнено.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:ifDisabled("my-feature")=+k8s:required
    MyField string `json:"myField"`
}
```

У цьому прикладі `MyField` є обовʼязковим лише тоді, коли опція "my-feature" вимкнена.

### `+k8s:ifEnabled` {#tag-ifEnabled}

**Опис:**

Оголошує валідацію, яка застосовується, коли опцію увімкнено.

**Рівень стабільності:** Alpha

**Аргументи:**

* `<option>` (рядок, обовʼязково): Імʼя опції.

**Корисне навантаження:**

* `<validation-tag>`: Цей теґ валідації буде оцінюватися лише тоді, коли опцію увімкнено.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:ifEnabled("my-feature")=+k8s:required
    MyField string `json:"myField"`
}
```

У цьому прикладі `MyField` є обовʼязковим лише тоді, коли опція "my-feature" увімкнена.

### `+k8s:isSubresource` {#tag-isSubresource}

**Рівень стабільності:** Stable

**Опис:**

Теґ `+k8s:isSubresource` є коментарем на рівні пакета, який **обмежує правила валідації в межах цього пакета до конкретного субресурсу**. Він по суті говорить генератору коду: "Логіка валідації, визначена тут, є специфічною реалізацією для цього субресурсу і не повинна застосовуватися до кореневого обʼєкта або будь-якого іншого субресурсу."

**КРИТИЧНА ЗАЛЕЖНІСТЬ:**

Цей теґ є **залежним** від відповідного теґа `+k8s:supportsSubresource`, який повинен бути присутній у пакеті, де визначено основний тип API.

* `+k8s:supportsSubresource` відкриває двері, кажучи диспетчеру, що субресурс є дійсним.
* `+k8s:isSubresource` надає спеціалізовану логіку валідації, яка виконується, коли запит проходить через ці двері.

Якщо ви використовуєте `+k8s:isSubresource` без відповідного оголошення `+k8s:supportsSubresource` для основного типу, спеціалізований код валідації буде згенеровано, але він буде **недоступний**. Основний диспетчер не розпізнає шлях субресурсу і відхилить запит, перш ніж він зможе бути надісланий до вашої специфічної логіки валідації.

Ця залежність дозволяє потужну організацію, таку як розміщення ваших основних типів API в одному пакеті та визначення їх специфічних для субресурсу валідацій у окремих, спеціалізованих пакетах.

**Область дії:** Пакет

**Корисне навантаження:**

* `<subresource-path>`: Шлях субресурсу, до якого повинні застосовуватися валідації в цьому пакеті (наприклад, `"/status"`, `"/scale"`).

**Приклад використання:**

Цей приклад з двох частин демонструє передбачуваний випадок використання розділення обовʼязків.

**1. Оголосити підтримку в основному пакеті API:**
Спочатку оголосіть, що тип `Deployment` підтримує валідацію `/scale` у своєму основному пакеті.

*Файл: `staging/src/k8s.io/api/apps/v1/doc.go`*

```go
// Це дозволяє диспетчеру валідації обробляти запити для "/scale".
// +k8s:supportsSubresource="/scale"
package v1

// ... включає визначення типу Deployment
```

**2. Обмежити логіку валідації в окремому пакеті:**
Далі створіть окремий пакет для правил валідації, які специфічні *тільки* для субресурсу `/scale`.

*Файл: `staging/src/k8s.io/api/apps/v1/validations/scale/doc.go`*

```go
// Це забезпечує те, що правила в цьому пакеті виконуються ТІЛЬКИ для субресурсу "/scale".
// +k8s:isSubresource="/scale"
package scale

import "k8s.io/api/apps/v1"

// Код валідації в цьому пакеті буде посилатися на типи з пакета v1 (наприклад, v1.Scale).
// Згенерована функція валідації буде викликатися лише для запитів до субресурсу "/scale"
// обʼєкта типу, визначеного в пакеті, який підтримує це.
```

### `+k8s:item` {#tag-item}

**Опис:**

Оголошує валідацію для елемента зрізу, оголошеного як `+k8s:listType=map`. Елемент, що має збіг, оголошується шляхом надання аргументів парою поле-значення, де поле є `listMapKey`. Усі поля ключів `listMapKey` повинні бути вказані.

**Рівень стабільності:** Stable

**Використання:**

`+k8s:item(<listMapKey-JSON-field-name>: <value>,...)=<validation-tag>`

`+k8s:item(stringKey: "value", intKey: 42, boolKey: true)=<validation-tag>`

Аргументи повинні бути іменовані за допомогою JSON-імен полів ключів списку-мапи. Значення можуть бути рядками, цілими числами або булевими значеннями.

**Корисне навантаження:**

* `<validation-tag>`: Теґ для оцінки для елемента списку, що має збіг.

**Приклад використання:**

```go
type MyStruct struct {
	// +k8s:listType=map
	// +k8s:listMapKey=type
	// +k8s:item(type: "Approved")=+k8s:zeroOrOneOfMember
	// +k8s:item(type: "Denied")=+k8s:zeroOrOneOfMember
	MyConditions []MyCondition `json:"conditions"`
}

type MyCondition struct {
    Type string `json:"type"`
    Status string `json:"status"`
}
```

У цьому прикладі:

* Умова з `type` "Approved" є частиною групи нуль-або-один-з.
* Умова з `type` "Denied" є частиною групи нуль-або-один-з.

### `+k8s:listMapKey` {#tag-listMapKey}

**Опис:**

Оголошує іменоване підполе типу значення списку як частину ключа list-map. Цей теґ є обовʼязковим, коли використовується `+k8s:listType=map`.  Кілька теґів `+k8s:listMapKey` можуть використовуватися на list-map, щоб вказати, що він є ключем з кількох полів.

**Рівень стабільності:** Stable

**Корисне навантаження:**

* `<field-json-name>`: Імʼя JSON поля, яке буде використовуватися як ключ.

**Приклад використання:**

```go
// +k8s:listType=map
// +k8s:listMapKey=keyFieldOne
// +k8s:listMapKey=keyFieldTwo
type MyList []MyStruct

type MyStruct struct {
    keyFieldOne string `json:"keyFieldOne"`
    keyFieldTwo string `json:"keyFieldTwo"`
    valueField string `json:"valueField"`
}
```

У цьому прикладі `listMapKey` використовується для вказівки, що `keyField` типу `MyStruct` повинен використовуватися як ключ для list-map.

### `+k8s:listType` {#tag-listType}

**Опис:**

Оголошує семантичний тип поля списку. Цей теґ використовується для вказівки того, як список повинен оброблятися, наприклад, як map або set (набір).

**Рівень стабільності:** Stable

**Корисне навантаження:**

* `atomic`: Список обробляється як одне атомарне значення.
* `map`: Список обробляється як map, де кожен елемент має унікальний ключ. Вимагає використання `+k8s:listMapKey`.
* `set`: Список обробляється як set (набір), де кожен елемент є унікальним.

**Приклад використання:**

```go
// +k8s:listType=map
// +k8s:listMapKey=keyField
type MyList []MyStruct

type MyStruct struct {
    keyField string `json:"keyField"`
    valueField string `json:"valueField"`
}
```

У цьому прикладі `MyList` оголошується як список типу `map`, з `keyField` як ключем. Це означає, що логіка валідації забезпечить те, що кожен елемент списку має унікальний `keyField`.

### `+k8s:maxItems` {#tag-maxItems}

**Опис:**

Вказує, що поле списку має обмеження на розмір.

**Рівень стабільності:** Stable

**Корисне навантаження:**

* `<негативне число>`: Це поле не повинно містити більше X елементів.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:maxItems=5
    MyList []string `json:"myList"`
}
```

У цьому прикладі `MyList` не може містити більше 5 елементів.

### `+k8s:maxLength` {#tag-maxLength}

**Опис:**

Вказує, що рядкове поле має обмеження на довжину.

**Рівень стабільності:** Stable

**Корисне навантаження:**

* `<негативне число>`: Це поле не повинно містити більше X символів.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:maxLength=10
    MyString string `json:"myString"`
}
```

У цьому прикладі `MyString` не може бути довшим за 10 символів.

### `+k8s:minimum` {#tag-minimum}

**Опис:**

Вказує, що числове поле має мінімальне значення.

**Рівень стабільності:** Stable

**Корисне навантаження:**

* `<ціле число>`: Це поле повинно бути більшим або рівним x.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:minimum=0
    MyInt int `json:"myInt"`
}
```

У цьому прикладі `MyInt` повинен бути більшим або рівним 0.

### `+k8s:neq` {#tag-neq}

**Опис:**

Перевіряє, що значення поля не дорівнює конкретному забороненому значенню. Підтримує рядкові, цілі та булеві типи.

**Рівень стабільності:** Alpha

**Корисне навантаження:**

* `<значення>`: Заборонене значення. Парсер вгадає тип (рядок, int, bool).

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:neq="disallowed"
    MyString string `json:"myString"`

    // +k8s:neq=0
    MyInt int `json:"myInt"`

    // +k8s:neq=true
    MyBool bool `json:"myBool"`
}
```

У цьому прикладі:

* `MyString` не може дорівнювати `"disallowed"`.
* `MyInt` не може дорівнювати `0`.
* `MyBool` не може дорівнювати `true`.

### `+k8s:opaqueType` {#tag-opaqueType}

**Опис:**

Вказує, що будь-які валідації, оголошені для вказаного типу, будуть проігноровані. Якщо пакет вказаного типу не включено в поточні прапорці генератора, цей теґ повинен бути встановлений, інакше генерація коду завершиться невдачею (запобігаючи тихим помилкам). Якщо валідації не повинні ігноруватися, додайте пакет типу до генератора за допомогою прапорця `--readonly-pkg`.

**Рівень стабільності:** Alpha

**Приклад використання:**

```go
import "some/external/package"

type MyStruct struct {
    // +k8s:opaqueType
    ExternalField package.ExternalType `json:"externalField"`
}
```

У цьому прикладі будь-які теґи валідації на `package.ExternalType` будуть проігноровані.

### `+k8s:optional` {#tag-optional}

**Опис:**

Вказує, що поле є необовʼязковим для клієнтів.

**Рівень стабільності:** Stable

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:optional
    MyField string `json:"myField"`
}
```

У цьому прикладі `MyField` не є обовʼязковим для надання під час створення або оновлення `MyStruct`.

### `+k8s:required` {#tag-required}

**Опис:**

Вказує, що поле має бути вказане клієнтами.

**Рівень стабільності:** Stable

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:required
    MyField string `json:"myField"`
}
```

У цьому прикладі `MyField` повинно бути надане під час створення або оновлення `MyStruct`.

### `+k8s:subfield` {#tag-subfield}

**Опис:**

Оголошує валідацію для підполя структури.

**Рівень стабільності:** Beta

**Аргументи:**

* `<field-json-name>` (рядок, обовʼязково): Імʼя JSON підполя.

**Корисне навантаження:**

* `<validation-tag>`: Теґ для оцінки для підполя.

**Приклад використання:**

```go
type MyStruct struct {
    // +k8s:subfield("mySubfield")=+k8s:required
    MyStruct MyStruct `json:"MyStruct"`
}

type MyStruct struct {
    MySubfield string `json:"mySubfield"`
}
```

У цьому прикладі `MySubfield` всередині `MyStruct` є обовʼязковим.

### `+k8s:supportsSubresource` {#tag-supportsSubresource}

**Рівень стабільності:** Stable

**Опис:**

Теґ `+k8s:supportsSubresource` є коментарем на рівні пакета, який **оголошує, які субресурси є дійсними цілями для валідації** для типів у межах цього пакета. Розглядайте цей теґ як реєстрацію точки доступу; він говорить системі валідації, що конкретний шлях субресурсу визнано і його не слід відхиляти відразу.

Коли генерується код валідації, цей теґ додає вказаний шлях субресурсу до основної функції диспетчера для типу. Це дозволяє вхідним запитам для цього субресурсу бути надісланими до реалізації валідації.

Кілька теґів можуть використовуватися для оголошення підтримки кількох субресурсів. Якщо в пакеті немає жодного теґа `+k8s:supportsSubresource`, валідація увімкнена лише для кореневого ресурсу (наприклад, `.../myresources/myobject`), і будь-які запити до субресурсів будуть відхилені з помилкою "валідація не знайдена".

**Окрема використання:**

Якщо ви використовуєте `+k8s:supportsSubresource` без відповідного теґа `+k8s:isSubresource` для конкретної валідації, стандартно правила валідації для кореневого обʼєкта будуть застосовані до субресурсу.

**Область дії:** Пакет

**Корисне навантаження:**

* `<subresource-path>`: Шлях субресурсу, який потрібно підтримувати (наприклад, `"/status"`, `"/scale"`).

**Приклад використання:**

Додавши ці теґи, ви дозволяєте системі валідації обробляти запити для `/status` та `/scale` субресурсів для типів, визначених у пакеті `v1`.

*Файл: `staging/src/k8s.io/api/core/v1/doc.go`*

```go
// +k8s:supportsSubresource="/status"
// +k8s:supportsSubresource="/scale"
package v1
```

### `+k8s:unionDiscriminator` {#tag-unionDiscriminator}

**Опис:**

Вказує, що це поле є дискримінатором для обʼєднання.

**Рівень стабільності:** Stable

**Аргументи:**

* `union` (рядок, необовʼязково): Імʼя обʼєднання, якщо їх кілька.

**Приклад використання:**

```go
type MyStruct struct {
	TypeMeta int

	// +k8s:unionDiscriminator
	D D `json:"d"`

	// +k8s:unionMember
	// +k8s:optional
	M1 *M1 `json:"m1"`

	// +k8s:unionMember
	// +k8s:optional
	M2 *M2 `json:"m2"`
}

type D string

const (
	DM1 D = "M1"
	DM2 D = "M2"
)

type M1 struct{}

type M2 struct{}
```

У цьому прикладі поле `Type` є дискримінатором для обʼєднання. Значення `Type` визначить, який з членів обʼєднання (`M1` або `M2`) очікується наявним.

### `+k8s:unionMember` {#tag-unionMember}

**Опис:**

Вказує, що це поле є членом обʼєднання.

**Рівень стабільності:** Stable

**Аргументи:**

* `union` (рядок, необовʼязково): Імʼя обʼєднання, якщо їх кілька.
* `memberName` (рядок, необовʼязково): Значення дискримінатора для цього члена. Стандартно використовується імʼя поля.

**Приклад використання:**

```go
type MyStruct struct {
	// +k8s:unionMember(union: "union1")
	// +k8s:optional
	M1 *M1 `json:"u1m1"`

	// +k8s:unionMember(union: "union1")
	// +k8s:optional
	M2 *M2 `json:"u1m2"`
}

type M1 struct{}

type M2 struct{}

```

У цьому прикладі `M1` і `M2` є членами названого обʼєднання `union1`.

### `+k8s:zeroOrOneOfMember` {#tag-zeroOrOneOfMember}

**Опис:**

Вказує, що це поле є членом групи нуль-або-один-з. Група нуль-або-один-з дозволяє встановити не більше ніж одного члена. На відміну від звичайних обʼєднань, відсутність встановлених членів є дійсною.

**Рівень стабільності:** Stable

**Аргументи:**

* `union` (рядок, необовʼязково): Імʼя обʼєднання, якщо їх кілька.
* `memberName` (рядок, необовʼязково): Користувацьке імʼя члена для цього члена. Стандартно використовується імʼя поля.

**Приклад використання:**

```go
type MyStruct struct {
	// +k8s:zeroOrOneOfMember
	// +k8s:optional
	M1 *M1 `json:"m1"`

	// +k8s:zeroOrOneOfMember
	// +k8s:optional
	M2 *M2 `json:"m2"`
}

type M1 struct{}

type M2 struct{}
```

У цьому прикладі не більше ніж один з `A` або `B` може бути встановлений. Також дійсно, що жоден з них не встановлений.
