RFC 6020 (часть 4)

Please enter banners and links.

image_print

Часть 3


8. Ограничения

8.1. Ограничения для данных

Некоторые операторы YANG задают ограничения для данных. Эти ограничения реализуются разными способами в зависимости от от типа данных, определяемого оператором.

  • Если ограничение задано для данных конфигурации, оно должно выполняться в дереве данных конфигурации.

  • Если ограничение задано для данных состояния, оно должно выполняться в откликах на операции <get> без фильтра.

  • Если ограничение задано для содержимого уведомления, оно должно выполняться в любом экземпляре уведомления.

  • Если ограничение задано для входных параметров RPC, оно должно выполняться при вызове RPC.

  • Если ограничение задано для выходных параметров RPC, оно должно выполняться в откликах RPC.

8.2. Иерархия ограничений

Условия на родительских узлах влияют на ограничения дочерних узлов как естественное следствие иерархии узлов. Ограничения must, mandatory, min-elements и max-elements не применяются, если родительский узел имеет условие when или if-feature, которое не выполняется на устройстве.

В приведенном примере ограничение mandatory для листа longitude не будет применяться на устройствах без функции has-gps.

       container location {
           if-feature has-gps;
           leaf longitude {
               mandatory true;
               ...
           }
       }

8.3. Модель применения ограничений

Для данных конфигурации имеется три «окна», где ограничения должны применяться:

  • в процессе анализа содержимого (payload) RPC;

  • в процессе выполнения операций NETCONF;

  • в процессе проверки пригодности (validation).

Каждый из этих вариантов рассматривается в последующих параграфах.

8.3.1. Анализ данных

Полученное содержимое RPC должно иметь корректный формат XML, а также следовать иерархии и правилам, определяемым моделями, которые устройство реализует.

  • Если значение данных листа (leaf) не соответствует ограничениям для листа, включая определенные свойствами range, length и pattern, сервер должен ответить сообщением <rpc-error> с тегом <error-tag> invalid-value, а также error-app-tag (параграф 7.5.4.2) и error-message (параграф 7.5.4.1), связанными с ограничениями, если они имеются.

  • Если все ключи элемента списка отсутствуют, сервер должен передать <error-tag> с missing-element в сообщении <rpc-error>.

  • Если присутствуют данные для нескольких вариантов (case) оператора выбора choice, сервер должен передать <error-tag> с bad-element в сообщении <rpc-error>.

  • Если данные для узла имеют метку if-feature, а выражение if-feature дает значение false на устройстве, сервер должен передать <error-tag> с unknown-element в сообщении <rpc-error>.

  • Если присутствуют данные для узла с оператором when, который дает значение false, сервер должен передать <error-tag> с unknown-element в сообщении <rpc-error>.

  • Если при обработке вставки узла значения атрибутов before и after не подходят для типа ключевых листьев, сервер должен передать <error-tag> с bad-attribute в сообщении <rpc-error>.

  • Если атрибуты before и after появляются в каком-либо списке, для которого свойство ordered-by имеет значение user, сервер должен передать <error-tag> с unknown- attribute в сообщении <rpc-error>.

8.3.2. Обработка NETCONF <edit-config>

После анализа входных данных сервер NETCONF выполняет операцию <edit-config>, применяя данные к хранилищу конфигурации. В течение этой обработки должны детектироваться следующие ошибки:

  • запросы на удаление не существующих данных;

  • запросы на создание уже имеющихся данных;

  • запросы вставки с параметрами before или after, указывающими отсутствующие элементы.

В процессе обработки <edit-config> выполняются описанные ниже условия.

  • Если операция NETCONF создает узлы данных от оператора выбора choice, все существующие узлы из других вариантов case удаляются сервером.

  • Если операция NETCONF меняет узлы данных так, что выражение when на каком-либо узле принимает значения false, такой узел удаляется сервером.

8.3.3. Проверка пригодности

По завершении обработки хранилища данных окончательное содержимое должно соответствовать всем ограничениям пригодности. Эта проверка выполняется в разное время в зависимости от хранилища данных. Если хранилище является рабочим (<running/>) или стартовым (<startup/>), ограничения должны применяться в конце операции <edit-config> или <copy-config>. Если хранилище является «кандидатом» (<candidate/>), применение ограничений откладывается до вызова операции <commit> или <validate>.

  • Все ограничения must должны давать значение true.

  • Все ограничения ссылочной целостности, определенные операторами path должны выполняться.

  • Все ограничения unique для списков должны выполняться.

  • Ограничения min-elements и max-elements применяются для узлов list и leaf-list.

9. Встроенные типы

Язык YANG имеет набор встроенных типов, похожий на используемые в языках программирования, но с некоторыми отличиями, обусловленными специальными требованиями управления информационными моделями.

Могут определяться дополнительные производные типы на основе встроенных и других производных типов. Производные типы могут использовать субтипы для формального ограничения возможных значений.

Различные встроенные типы и производные от них позволяют организовать разные субтипы для ограничения размера и соответствия строкам регулярных выражений (параграфы 9.4.4 и 9.4.6), а также ограничения диапазонов числовых значений (параграф 9.2.4).

Лексическое представление значений некоторых типов применяется в сообщениях NETCONF и при задании принятых по умолчанию значений и числовых диапазонов в модулях YANG.

9.1. Каноническое представление

Для большинства типов существует одно каноническое представление значений данного типа. Некоторые типы разрешают множество лексических представлений одного и того же значения, например, положительное число 17 можно записать как +17 или 17. Реализации должны поддерживать все лексические представления, заданные в этом документе.

Когда сервер передает NETCONF данные, он должен использовать каноническую форму.

Некоторые типы имеют лексическое представление, которое зависит от контекста XML, в котором они появляются. Такие типы не имеют канонической формы.

9.2. Целочисленные встроенные типы

Язык YANG использует встроенные целочисленные типы int8, int16, int32, int64, uint8, uint16, uint32 и uint64. Они представляют числа разной размерности со знаком или без него:

int8 представляет целые числа от -128 до 127, включительно;

int16 представляет целые числа от -32768 до 32767, включительно;

int32 представляет целые числа от -2147483648 до 2147483647, включительно;

int64 представляет целые числа от -9223372036854775808 до 9223372036854775807, включительно;

uint8 представляет целые числа от 0 до 255, включительно;

uint16 представляет целые числа от 0 до 65535, включительно;

uint32 представляет целые числа от 0 до 4294967295, включительно;

uint64 представляет целые числа от 0 до 18446744073709551615, включительно.

9.2.1. Лексическое представление

Целое число лексически представляется необязательным знаком (+ или -), за которым следуют десятичные цифры. Если знак не указан, предполагается +.

Для удобства при задании используемого по умолчанию целочисленного значения в модуле YANG может применяться другое лексическое представление с использованием шестнадцатеричной или восьмеричной записи. Шестнадцатеричное представление начинается с необязательного знака (+ или -), за которым следует пара символов 0x, а далее последовательность шестнадцатеричных цифр, в которой могут использоваться символы верхнего или нижнего регистра (a – f, A – F). Восьмеричное представления начинается с необязательного знака (+ или -), за которым следует символ 0 и последовательность восьмеричных цифр (0 – 7).

Отметим, что принятое по умолчанию значение в модуле YANG, которое начинается с нуля (0), интерпретируется как восьмеричное число. В представлении XML все числа считаются десятичными и нули в начале значение допускаются.

Примеры:

     // пригодные значения
     +4711                       // допустимое положительное значение
     4711                        // допустимое положительное значение
     -123                        // допустимое отицательное значение
     0xf00f                      // допустимое положительное шестнадцатеричное значение
     -0xf                        // допустимое отицательное шестнадцатеричное значение
     052                         // допустимое положительное восьмеричное значение

     // непригодные значения
     - 1                         // недопустимый пробел

9.2.2. Каноническая форма

Каноническая форма положительного целого числа не включает знака +. Нули в начале последовательности цифр не допускаются. Нулевое значение представляется одним символом 0.

9.2.3. Ограничения

Все целые числа могут ограничиваться с помощью оператора range (параграф 9.2.4).

9.2.4. Оператор range

Оператор range, является необязательным субоператором для оператора type и принимает в качестве аргумента строку, выражающую диапазон. Субоператор служит для ограничения диапазонов значений целых и десятичных встроенных типов и производных от них.

Диапазон задается явным значением или включительной нижней границей, за которой следуют два символа точки (..) и включительное значение верхней границы. Возможно задание множества значений или диапазонов, разделенных символом |. При задании множеств диапазонов они должны быть не пересекающимися и должны указываться в порядке роста значений. Если ограничение range применяется к типу, который уже имеет такие ограничения, новое ограничение должно соответствовать имеющемуся или быть более сильным (т. е. повышающим нижнюю или/и снижающим верхнюю границу, удаляющим явно заданные значения или расщепляющим диапазон на поддиапазоны с зазорами между ними). Каждое явное значение и граница диапазона в выражении range должно соответствовать ограничиваемому типу или быть одним из специальных значений min или max (минимальное и максимальное допустимые значения для типа, соответственно).

Синтаксис выражения range формально определяется правилом range-arg в разделе 12.

9.2.4.1. Субоператоры для range

Субоператор

Параграф

Число элементов

description

7.19.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

reference

7.19.4

0..1

9.2.5. Пример использования
     typedef my-base-int32-type {
         type int32 {
             range "1..4 | 10..20";
         }
     }
     typedef my-type1 {
       type my-base-int32-type {
         // допустимое ограничение диапазона
         range "11..max"; // 11..20
       }
     }
     typedef my-type2 {
       type my-base-int32-type {
         // недопустимое ограничение диапазона
         range "11..100";
       }
     }

9.3. Встроенный тип decimal64

Встроенный тип decimal64 представляет подмножество действительных чисел, которые могут быть выражены последовательностями десятичных цифр. Пространство значений decimal64 представляет собой подмножество значений, которые могут быть получены путем умножения 64-битового целого числа со знаком на отрицательную степень числа 10 (т. е. значения вида i * 10-n, где i – значение типа integer64, n – целое число от 1 до 18, включительно).

9.3.1. Лексическое представление

Значение decimal64 лексически представляется необязательным знаком (+ или -), за которым следует набор десятичных цифр, а за ним может следовать символ точки (.) в качестве разделителя целой и дробной части и цепочка десятичных цифр дробной части. Если знак не указан, по умолчанию предполагается +.

9.3.2. Каноническая форма

Каноническая форма положительного значения decimal64 не включает знак +. Десятичная точка обязательна. Нули в начале и в конце (дробной части) числа использовать запрещено с учетом того, что перед десятичной точкой и после нее должна присутствовать хотя бы одна цифра. Нулевое значение представляется в виде 0.0.

9.3.3. Ограничения

Тип decimal64 может быть ограничен с помощью оператора range (параграф 9.2.4).

9.3.4. Оператор fraction-digits

Оператор fraction-digits, который служит субоператором для type, должен присутствовать для типа decimal64. Он принимает в качестве аргумента целое число от 1 до 18, включительно. Это значение управляет разностью между смежными значениями decimal64 путем ограничения пространства значений, которое выражается как i * 10-n, n – число цифр дробной части.

В таблице представлены минимальные и максимальные значения для каждого размера дробной части.

Цифр после запятой

Минимум

Максимум

1

-922337203685477580.8

922337203685477580.7

2

-92233720368547758.08

92233720368547758.07

3

-9223372036854775.808

9223372036854775.807

4

-922337203685477.5808

922337203685477.5807

5

-92233720368547.75808

92233720368547.75807

6

-9223372036854.775808

9223372036854.775807

7

-922337203685.4775808

922337203685.4775807

8

-92233720368.54775808

92233720368.54775807

9

-9223372036.854775808

9223372036.854775807

10

-922337203.6854775808

922337203.6854775807

11

-92233720.36854775808

92233720.36854775807

12

-9223372.036854775808

9223372.036854775807

13

-922337.2036854775808

922337.2036854775807

14

-92233.72036854775808

92233.72036854775807

15

-9223.372036854775808

9223.372036854775807

16

-922.3372036854775808

922.3372036854775807

17

-92.23372036854775808

92.23372036854775807

18

-9.223372036854775808

9.223372036854775807

9.3.5. Пример использования

     typedef my-decimal {
       type decimal64 {
         fraction-digits 2;
         range "1 .. 3.14 | 10 | 20..max";
       }
     }

9.4. Встроенный тип string

Встроенный тип string представляет в языке YANG текстовые строки, предназначенные для человека. Допустимо использование символов кодировок Unicode и ISO/IEC 10646 [ISO.10646], включая табуляцию, возврат каретки и перевод строки.

     ;; любой символ Unicode за исключением суррогатных блоков FFFE и FFFF.
     string = *char
     char = %x9 / %xA / %xD / %x20-D7FF / %xE000-FFFD /
            %x10000-10FFFF

9.4.1. Лексическое представление

Значение string лексически представляется символьными данными в документах экземпляров XML.

9.4.2. Каноническая форма

Каноническая форма совпадает с лексическим представлением. Нормализация Unicode для string не применяется.

9.4.3. Ограничения

Строка (string) может быть ограничена операторами length (параграф 9.4.4) и pattern (параграф 9.4.6).

9.4.4. Оператор length

Оператор length, который является необязательным субоператором для type, принимает в качестве аргумента строку с выражением размера. Оператор служит для ограничения встроенного типа string, а также производных от него.

Оператор length ограничивает число символов Unicode в строке.

Диапазон размеров задается явным значением или включительной нижней границей, за которой следуют два символа точки (..) и включительное значение верхней границы. Возможно задание множества значений или диапазонов, разделенных символом |. При задании множеств диапазонов они должны быть не пересекающимися и должны указываться в порядке роста значений. Использование отрицательных значений недопустимо. Если ограничение диапазона применяется к типу, который уже имеет такие ограничения, новое ограничение должно соответствовать имеющемуся или быть более сильным (т. е. повышающим нижнюю или/и снижающим верхнюю границу, удаляющим явно заданные значения или расщепляющим диапазон на поддиапазоны с зазорами между ними). Значение размера представляет собой неотрицательное целое число или одно из специальных значений min или max (минимальное и максимальное допустимые значения для типа, соответственно). От реализаций не требуется поддержка размеров больше 18446744073709551615.

Синтаксис выражения length формально описывается правилом length-arg в разделе 12.

9.4.4.1. Субоператоры для length

Субоператор

Параграф

Число элементов

description

7.19.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

reference

7.19.4

0..1

9.4.5. Пример использования

     typedef my-base-str-type {
         type string {
             length "1..255";
         }
     }

     type my-base-str-type {
         // действительное ограничение размера
         length "11 | 42..max"; // 11 | 42..255
     }

     type my-base-str-type {
         // недопустимое ограничение размера
         length "1..999";
     }

9.4.6. Оператор pattern

Оператор pattern, который является необязательным субоператором для type, принимает в качестве аргумента строку регулярного выражения, в соответствии с определением [XSD-TYPES]. Он служит для ограничения встроенного типа string и производных от него типов, значениями, которые соответствуют шаблону pattern.

Если тип (type) имеет множество операторов pattern, выражения объединяются логической операцией AND (И), т. е. строка должна соответствовать всем выражениям.

Если шаблонные ограничения применяются к типу, который уже имеет ограничения по шаблонам, значения должны соответствовать всем шаблонам базового типа в дополнение к новым шаблонам.

9.4.6.1. Субоператоры для pattern

Субоператор

Параграф

Число элементов

description

7.19.3

0..1

error-app-tag

7.5.4.2

0..1

error-message

7.5.4.1

0..1

reference

7.19.4

0..1

9.4.7. Пример использования

Для показанного ниже типа

     type string {
         length "0..4";
         pattern "[0-9a-fA-F]*";
     }

следующие строки соответствуют

     AB          // действительно
     9A00        // действительно

а следующие строки не соответствуют

     00ABAB      // слишком длинная
     xx00        // непригодные символы

9.5. Встроенный тип boolean

Встроенный тип boolean представляет логические значения.

9.5.1. Лексическое представление

Лексическое представление типа boolean имеет два значения true и false, которые должны указываться символами нижнего регистра.

9.5.2. Каноническая форма

Каноническая форма совпадает с лексическим представлением.

9.5.3. Ограничения

Тип boolean не может быть ограничен.

9.6. Встроенный тип enumeration

Встроенный тип enumeration представляет значения из набора заданных имен.

9.6.1. Лексическое представление

Лексическим представлением значения enumeration является строка назначенного имени.

9.6.2. Каноническая форма

Канонической формой является строка назначенного имени.

9.6.3. Ограничения

Тип enumeration может быть ограничен с помощью одного или нескольких операторов enum (параграф 9.6.4), которые указывают подмножество значений базового типа.

9.6.4. Оператор enum

Оператор enum, который является субоператором для type, должен присутствовать для типа enumeration. Он может использоваться несколько раз для задания каждого назначенного имени типа enumeration. Оператор принимает в качестве аргумента строку назначенного имени. Недопустимо указание пустых строк (нулевой размер), а также недопустимо добавление пробельных символов в начале или в конце назначенного имени. Следует избегать использования в именах управляющих кодов Unicode.

Оператор может включать необязательный блок субоператоров с дополнительной информацией.

Назначенные имена в enumeration должны быть уникальными.

При ограничении типа enumeration набор имен нового типа должен быть подмножеством базового набора назначенных имен. Недопустимо изменять эти назначенные имена.

9.6.4.1. Субоператоры для enum

Субоператор

Параграф

Число элементов

description

7.19.3

0..1

reference

7.19.4

0..1

status

7.19.2

0..1

value

9.6.4.2

0..1

9.6.4.2. Оператор value

Необязательный оператор value используется для связывания целочисленного значения с назначенным именем для enum. Это должно быть целое число из диапазона от -2147483648 до 2147483647 и значение должно быть уникальным в рамках типа enumeration. Значение не используется в YANG и XML, но передается для удобства разработчиков.

Если значение не задано, оно будет назначаться автоматически. В таких случаях при первом определении будет назначаться значение (0), а противном случае – значение, превышающее на единицу максимальное из использованных значений enum.

Если текущее максимальное значение составляет 2147483647, значение enum должно быть задано для субоператоров enum, следующих за текущим максимальным значением.

9.6.5. Пример использования

     leaf myenum {
         type enumeration {
             enum zero;
             enum one;
             enum seven {
                 value 7;
             }
         }
     }

Лексическое представление листа myenum со значением seven будет иметь вид

     <myenum>seven</myenum>

9.7. Встроенный тип bits

Встроенный тип bits представляет набор битов. Т. е. значение bits служит набором флагов, указанных целочисленными значениями позиции с отсчетом от 0. Каждому биту назначено имя.

9.7.1. Ограничения

Тип bits может быть ограничен с помощью оператора bit (параграф 9.7.4).

9.7.2. Лексическое представление

Лексическое представление типа bits является списком разделенных пробелами назначенных имен флагов bits. Пустая строка говорит об отсутствии установленных флагов.

9.7.3. Каноническая форма

В канонической форме значения битов разделяются одним символом пробела и упорядочиваются по их позициям (см. параграф 9.7.4.2).

9.7.4. Оператор bit

Оператор bit, который служит субоператором для type, должен присутствовать для типа bits. Он используется многократно для каждого именованного бита типа bits. Оператор принимает в качестве аргумента строку с назначенным именем бита, за которой следует блок субоператоров с дополнительной информацией. Для назначенных имен используется такой же синтаксис, как для идентификаторов (см. параграф 6.2).

Назначенные имена в типе bits должны быть уникальными.

9.7.4.1. Субоператоры для bit

Субоператор

Параграф

Число элементов

description

7.19.3

0..1

position

9.7.4.2

0..1

reference

7.19.4

0..1

status

7.19.2

0..1

9.7.4.2. Оператор position

Необязательный оператор position принимает в качестве аргумента неотрицательное целое число, которое задает позицию бита в предполагаемом битовом поле. Значение position должно лежать в диапазоне от 0 до 4294967295 и должно быть уникальным в данном типе bits. Значение не используется в YANG и NETCONF, но передается для удобства разработчиков.

Если позиция бита не задана, она назначается автоматически. Если субоператор bit задан в первый раз, присваивается значение 0, в противном случае присваивается значение на 1 больше текущего максимального значения битовой позиции.

Если текущее максимальное значение составляет 4294967295, битовая позиция должна быть задана для субоператоров bit, следующих за текущим максимальным значением.

9.7.5. Пример использования

Для приведенного ниже leaf

     leaf mybits {
         type bits {
             bit disable-nagle {
                 position 0;
             }
             bit auto-sense-speed {
                 position 1;
             }
             bit 10-Mb-only {
                 position 2;
             }
         }
         default "auto-sense-speed";
     }

Лексическое представление листа с битовыми полями disable-nagle и 10-mb-only будет иметь вид

     <mybits>disable-nagle 10-Mb-only</mybits>

9.8. Встроенный тип binary

Встроенный тип binary представляет любые двоичные данные, т. е. последовательность октетов.

9.8.1. Ограничения

Тип binary может быть ограничен с помощью оператора length (параграф 9.4.4). Размер значения типа binary указывает число октетов.

9.8.2. Лексическое представление

Значения binary представляются с использованием схемы кодирования base64 (см. раздел 4 в [RFC4648]).

9.8.3. Каноническая форма

Каноническая форма значения binary следует правилам кодирования base64 [RFC4648].

9.9. Встроенный тип leafref

Тип leafref служит для ссылки на конкретный экземпляр leaf в дереве данных. Субоператор path (параграф 9.9.2) служит для выбора набора экземпляров leaf и пространством значений leafref является набор значений экземпляров leaf.

Если свойство require-instance (параграф 9.9.3) имеет значение true, должен существовать узел в дереве данных, или узел, использующий принятое по умолчанию значение (см. параграфы 7.6.1 и 7.7.2), для указанного узла leaf или leaf-list в дереве схемы с таким же значением, как leafref в действительном дереве данных.

Если лист с типом leafref представляет данные конфигурации, указанный ссылкой узел также должен представлять конфигурацию. Такой лист задает ограничения для пригодных данных. Все узлы leafref должны указывать на имеющиеся экземпляры leaf или листья, с принятыми по умолчанию значениями (см. параграф 7.6.1), чтобы данные были действительны. Это ограничение применяется в соответствии с правилами раздела 8.

Недопустимы замкнутые цепочки ссылок leafrefs.

Если лист, на который указывает leafref, зависит от одной или нескольких функций (см. параграф 7.20.2), узел leaf с типом leafref должен зависеть от того же набора функций.

9.9.1. Ограничения

Тип leafref не может быть ограничен.

9.9.2. Оператор path

Оператор path, являющийся субоператором для type, должен присутствовать для типа leafref. Оператор принимает в качестве аргумента строку, которая должна указывать на узел leaf или leaf-list.

Синтаксис аргумента path является подмножеством сокращенного синтаксиса XPath. Предикаты служат лишь для ограничения значений узлов ключей для элементов списка. Каждый предикат содержит в точности одну проверку равенства на ключ и может присутствовать множество смежных предикатов, если список имеет множество ключей. Синтаксис формально определен правилом path-arg в разделе 12.

Предикаты используются лишь в тех случаях, когда требуется более одной ссылки на ключ для однозначной идентификации экземпляра листа. Это происходит, если список имеет имеет множество ключей или нужна ссылка на лист, отличающаяся от ключа в списке. В таких случаях обычно задается множество leafref, а предикаты служат для их связывания воедино.

Выражение path дает набор узлов (возможно пустой). Если свойство require-instance имеет значение true, набор узлов должен быть непустым.

Выражение XPath в операторе path концептуально оценивается в указанном ниже варианте контекста в дополнение к приведенному в параграфе 6.4.1 определению.

  • Узлом контекста является узел в дереве данных для которого определен оператор path.

Доступное дерево зависит от узла контекста.

  • Если узел контекста представляет данные конфигурации, дерево будет данными в хранилище NETCONF, где существует узел контекста. Корневой узел XPath имеет в качестве потомков все узлы конфигурационных данных верхнего уровня во всех модулях.

  • В остальных случаях дерево будет данными состояния на устройстве и в хранилище <running/>. Корневой узел XPath имеет в качестве потомков все узлы данных верхнего уровня во всех модулях.

9.9.3. Лексическое представление

Значение leafref лексически представляется так же, как представляет свое значение узел leaf, на который указывает ссылка.

9.9.4. Каноническая форма

Каноническая форма leafref совпадает с канонической формой листа (leaf) на который указывает ссылка.

9.9.5. Пример использования

Для приведенного ниже списка

     list interface {
         key "name";
         leaf name {
             type string;
         }
         leaf admin-status {
             type admin-status;
         }
         list address {
             key "ip";
             leaf ip {
                 type yang:ip-address;
             }
         }
     }

leafref указывает на существующий интерфейс

     leaf mgmt-interface {
         type leafref {
             path "../interface/name";
         }
     }

Ниже представлен соответствующий фрагмент XML.

     <interface>
       <name>eth0</name>
     </interface>
     <interface>
       <name>lo</name>
     </interface>

     <mgmt-interface>eth0</mgmt-interface>

Приведенный ниже оператор leafrefs указывает на существующий адрес интерфейса.

     container default-address {
         leaf ifname {
             type leafref {
                 path "../../interface/name";
             }
         }
         leaf address {
             type leafref {
                 path "../../interface[name = current()/../ifname]"
                    + "/address/ip";
             }
         }
     }

Соответствующий фрагмент XML имеет вид

     <interface>
       <name>eth0</name>
       <admin-status>up</admin-status>
       <address>
         <ip>192.0.2.1</ip>
       </address>
       <address>
         <ip>192.0.2.2</ip>
       </address>
     </interface>
     <interface>
       <name>lo</name>
       <admin-status>up</admin-status>
       <address>
         <ip>127.0.0.1</ip>
       </address>
     </interface>

     <default-address>
       <ifname>eth0</ifname>
       <address>192.0.2.2</address>
     </default-address>

Приведенный ниже список использует leafref для одного из своих ключей. Это похоже на внешний ключ в реляционной базе данных.

     list packet-filter {
         key "if-name filter-id";
         leaf if-name {
             type leafref {
                 path "/interface/name";
             }
         }
         leaf filter-id {
             type uint32;
         }
         ...
     }

Соответствующий фрагмент XML имеет вид

     <interface>
       <name>eth0</name>
       <admin-status>up</admin-status>
       <address>
         <ip>192.0.2.1</ip>
       </address>
       <address>
         <ip>192.0.2.2</ip>
       </address>
     </interface>

     <packet-filter>
       <if-name>eth0</if-name>
       <filter-id>1</filter-id>
       ...
     </packet-filter>
     <packet-filter>
       <if-name>eth0</if-name>
       <filter-id>2</filter-id>
       ...
     </packet-filter>

Приведенное ниже уведомление определяет два leafrefs для ссылки на существующий лист admin-status

     notification link-failure {
         leaf if-name {
             type leafref {
                 path "/interface/name";
             }
         }
         leaf admin-status {
             type leafref {
                 path
                   "/interface[name = current()/../if-name]"
                 + "/admin-status";
             }
         }
     }

Ниже приведен пример соответствующего уведомления XML.

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-04-01T00:01:00Z</eventTime>
       <link-failure xmlns="http://acme.example.com/system">
         <if-name>eth0</if-name>
         <admin-status>up</admin-status>
       </link-failure>
     </notification>

9.10. Встроенный тип identityref

Встроенный тип identityref служит для ссылок на существующие отождествления (см. параграф 7.16).

9.10.1. Ограничения

Тип identityref не может быть ограничен.

9.10.2. Оператор base для identityref

Оператор base, который является субоператором для type, должен присутствовать хотя бы однократно для типа identityref. Аргументом служит имя отождествления, определенное оператором identity. Если в имени отождествления имеется префикс, это говорит о том, что отождествление определено в модуле, который импортирован с этим префиксом. В остальных случаях отождествление с совпадающим именем должно быть определено в текущем модуле или включенном в него субмодуле.

Допустимыми значениями для identityref являются любые отождествления, произведенные из базового отождествления identityref. На конкретном сервере пригодные значения могут быть дополнительно ограничены набором отождествлений, определенных в модулях, которые поддерживаются сервером.

9.10.3. Лексическое представление

Тип identityref лексически представляется как полное имя указанной ссылки в соответствии с [XML-NAMES]. Если префикс отсутствует, пространством имен identityref будет принятое по умолчанию пространство имен для элемента, содержащего значение identityref.

Когда identityref присваивается принятое по умолчанию значение с использованием оператора default, имя отождествления в принятом по умолчанию значении может включать префикс. Если префикс присутствует в имени отождествления, он указывает на отождествление, определенное в модуле, который был импортирован с этим префиксом, или префикс текущего модуля, если префикс указывает текущий модуль или один из его субмодулей. В остальных случаях отождествление с совпадающим именем должно быть определено в текущем модуле или включенном субмодуле.

9.10.4. Каноническая форма

Поскольку лексическая форма зависит от контекста XML, в котором это значение имеет место, этот тип не имеет канонической формы.

9.10.5. Пример использования

С определениями отождествлений из параграфа 7.16.3 и приведенным ниже модулем

     module my-crypto {

         namespace "http://example.com/my-crypto";
         prefix mc;

         import "crypto-base" {
             prefix "crypto";
         }

         identity aes {
             base "crypto:crypto-alg";
         }

         leaf crypto {
             type identityref {
                 base "crypto:crypto-alg";
             }
         }
     }

Пример кодирования листа crypto для отождествления des3, определенного в модуле des будет иметь вид

     <crypto xmlns:des="http://example.com/des">des:des3</crypto>

Все префиксы, использованные в представлении, являются локальными для каждого экземпляра представления. Это значит, что один и тот же identityref может по разному кодироваться разными реализациями. Ниже представлен другой пример кодирования того же листа.

     <crypto xmlns:x="http://example.com/des">x:des3</crypto>

Если значение листа crypto вместо модуля aes определено в модуле my-crypto, кодирование может иметь вид

     <crypto xmlns:mc="http://example.com/my-crypto">mc:aes</crypto>

или с использованием принятого по умолчанию пространства имен

     <crypto>aes</crypto>

9.11. Встроенный тип empty

Встроенный тип empty представляет лист, не имеющий какого-либо значения, он лишь дает информацию о наличии или отсутствии.

Тип empty не может иметь принятого по умолчанию значения.

9.11.1. Ограничения

Тип empty не может быть ограничен.

9.11.2. Лексическое представление

Не применимо.

9.11.3. Каноническая форма

Не применима.

9.11.4. Пример использования

Для показанного ниже листа

     leaf enable-qos {
         type empty;
     }

примером пригодного представления существования листа может быть

     <enable-qos/>

9.12. Встроенный тип union

Встроенный тип union представляет значение, которое соответствует типу одного из членов объединения.

Когда указан тип union, должен присутствовать оператор type (параграф 7.4). Он используется многократно для задания типа каждого члена объединения. Оператор принимает один аргумент, являющийся строкой с именам типа.

В объединение могут входить встроенные и производные типы, однако недопустимо использование встроенных типов empty и leafref.

При проверке пригодности строки, представляющей тип данных union проверка осуществляется для каждого типа, являющегося членом объединения, в порялке, заданном оператором type, пока не будет найдено совпадение.

Любое значение, принятое по умолчанию, или свойство units, определенное в типах членов, не наследуется типом union.

Например,

     type union {
         type int32;
         type enumeration {
             enum "unbounded";
         }
     }

9.12.1. Ограничения

Тип union не может иметь ограничений. Однако каждый из входящих в объединение типов может иметь ограничения, определенные в разделе 9.

9.12.2. Лексическое представление

Лексическим представлением типа union является значение, которое соответствует представлению одного (любого) из входящих в объединение типов.

9.12.3. Каноническая форма

Каноническая форма значения union совпадает с канонической формой значения типа, входящего в объединение.

9.13. Встроенный тип instance-identifier

Встроенный тип instance-identifier служит для однозначной идентификации конкретного экземпляра узла в дереве данных.

Синтаксис для instance-identifier является подмножеством сокращенного синтаксиса XPath и формально определен правилом instance-identifier в разделе 12. Тип применяется для однозначной идентификации узлов в дереве данных. Предикаты применяются только для задания значений ключевых узлов элементов списка, значений элементов leaf-list или позиционных индексов в списках без ключей. Для идентификации элементов списка с ключами каждый предикат состоит из одной проверки равенства на ключ и каждый ключ должен иметь соответствующие предикат.

Если лист типа instance-identifier представляет данные конфигурации и свойство require-instance (параграф 9.13.2) имеет значение true, узел, на который он ссылается, также должен представлять конфигурацию. Такой лист ограничивает пригодные данные. Узлы всех таких листьев должны указывать существующие узлы или узлы leaf, использующие принятые по умолчанию значения (см. параграфы 7.6.1), для того, чтобы данные были пригодны. Это ограничение применяется в соответствии с правилами раздела 8.

Выражение instance-identifier XPath концепитально проверяется в контексте корневого узла доступного дерева в дополнение к определению параграфа 6.4.1.

  • Узлом контекста является корневой узел в доступном дереве.

Доступное дерево зависит от листа с типом instance-identifier.

  • Если узел контекста представляет данные конфигурации, дерево будет данными в хранилище NETCONF, где существует узел контекста. Корневой узел XPath имеет в качестве потомков все узлы конфигурационных данных верхнего уровня во всех модулях.

  • В остальных случаях дерево будет данными состояния на устройстве и в хранилище <running/>. Корневой узел XPath имеет в качестве потомков все узлы данных верхнего уровня во всех модулях.

9.13.1. Ограничения

Тип instance-identifier может быть ограничен с помощью оператора require-instance (параграф 9.13.2).

9.13.2. Оператор require-instance

Оператор require-instance, который является субоператором для type, может присутствовать для типа instance-identifier. Он принимает в качестве аргумента значение true или false. Если оператор отсутствует, по умолчанию принимается значение true.

Если require-instance имеет значение true, это означает, что экземпляр, на который указывается ссылка, должен существовать, чтобы данные были действительны. Ограничения применяются в соответствии с правилами раздела 8.

Если require-instance имеет значение false, это значит, что экземпляр, на который указывает ссылка, может существовать в действительных данных.

9.13.2. Лексическое представление

Значение instance-identifier лексически представляется в форме строки. Все имена узлов в значении instance-identifier должны быть полными с явными префиксами пространства имен и эти префиксы должны быть заявлены в области действия пространства имен XML в элементе XML для instance-identifier.

Все префиксы, используемые в представлении, являются локальными для каждого экземпляра кодирования. Это означает, что instance-identifier может по разному кодироваться разными реализациями.

9.13.3. Каноническая форма

Поскольку лексическая форма зависит от контекста XML, в котором значение имеет место, для этого типа нет канонической формы.

9.13.4. Пример использования

Ниже приведены примеры использования идентификаторов экземпляра.

     /* instance-identifier для container */
     /ex:system/ex:services/ex:ssh

     /* instance-identifier для leaf */
     /ex:system/ex:services/ex:ssh/ex:port

     /* instance-identifier для записи list */
     /ex:system/ex:user[ex:name='fred']

     /* instance-identifier для leaf в записи list */
     /ex:system/ex:user[ex:name='fred']/ex:type

     /* instance-identifier зля записи list с двумя ключами */
     /ex:system/ex:server[ex:ip='192.0.2.1'][ex:port='80']

     /* instance-identifier для записи leaf-list */
     /ex:system/ex:services/ex:ssh/ex:cipher[.='blowfish-cbc']

     /* instance-identifier для записи list без ключей */
     /ex:stats/ex:port[3]

10. Обновление модулей


По мере использования модуля может возникнуть потребность в его обновлении. Однако обновление опубликованных модулей не допускается, если это может вызвать проблемы взаимодействия между клиентами, использующими исходную спецификацию, и сервером, использующим обновленную спецификацию.

При публикации обновленияе должен использоваться новый оператор revision (параграф 7.1.9), помещаемый перед имеющимися операторами revision. Если в модуле нет операторов revision, такой оператор должен просто добавляться для обозначения нового выпуска. Кроме того, должны быть внесены все требуемые изменения в операторы metadata, включая organization и contact (см. параграфы 7.1.7 и 7.1.8).

Отметим, что содержащиеся в модуле определения доступны для импорта любому другому модулю путем указания имени данного модуля в операторе import. По этой причине менять имя модуля недопустимо. Кроме того, недопустимо менять оператор namespace, поскольку все элементы XML привязаны к пространству имен.

Устаревшие определения недопустимо удалять из опубликованных модулей, поскольку их идентификаторы еще могут применяться другими модулями.

Определение в опубликованном модуле может быть пересмотрено любым из приведенных ниже способов.

  • Для типа enumeration могут быть добавлены новые элементы enum с сохранением значения для существующих элементов.

  • Для типа bits могут быть добавлены новые флаги с сохранением позиций имеющихся флагов.

  • Операторы range, length или pattern могут расширять пространство разрешенных значений.

  • Может быть добавлен оператор default для листа (leaf), который не имел принятого по умолчанию значения (напрямую или опосредовано через его тип).

  • Может быть добавлен оператор units.

  • Может быть добавлен или изменен оператор reference.

  • Оператор must может быть удален или его ограничения ослаблены.

  • Оператор when может быть удален или его ограничения ослаблены.

  • Оператор mandatory может быть удален или значение true заменено на false.

  • Оператор min-elements может быть удален или изменен, чтобы требовать меньше элементов.

  • Оператор max-elements может быть удален или изменен, чтобы разрешить больше элементов.

  • Оператор description может быть добавлен или уточнен без изменения семантики определения.

  • Могут быть добавлены новые операторы typedef, grouping, rpc, notification, extension, feature и identity.

  • Могут быть добавлены операторы определения данных, если они не добавляют обязательных узлов (параграф 3.1) к имеющимся узлам или на верхнем уровне модуля или субмодуля, а также не создают для тех условных зависимостей от новой функции (т. е. if-feature с указанием новой функции).

  • Могут быть добавлены варианты case.

  • Узел, представляющий данные состояния, может быть изменен для представления данных конфигурации, если он не является обязательным (параграф 3.1).

  • Оператор if-feature может быть удален, если его узел не является обязательным (параграф 3.1).

  • Оператор status может быть добавлен или значение его изменено с current на deprecated или obsolete, а также с deprecated на obsolete.

  • Оператор type может быть заменен другим оператором type, который не меняет синтаксис и семантику типа. Например, определение типа inline может быть заменено на typedef, но тип int8 нельзя заменить на int16, поскольку это меняет синтаксис.

  • Любой набор узлов определения данных может быть заменен другим набором синтаксически и семантически эквивалентных узлов. Например, набор узлов может быть заменен оператором uses группировки с тем же набором листьев.

  • Модуль может быть разделен на несколько субмодулей или часть субмодулей может быть удалена, если определения модуля не изменятся (за исключением разрешенных здесь изменений).

  • Оператор prefix может быть изменен при условии корректировки всех локальных применений этого префикса.

В остальных случаях при изменении семантики прежнего определения (т. е. внесении изменений, выходящих за рамки перечисленного выше) должно создаваться новое определение с новым идентификатором.

В операторах, включающих какие-либо операторы определения данных в качестве своих субоператоров, недопустимо менять порядок этих субоператоров с определениями.

11. YIN

Модуль YANG может быть преобразован в другой основанный на XML формат, называемый YIN. Преобразованный модуль называется модулем YIN. В этом разделе описаны правила прямого и обратного преобразования между двумя форматами.

Форматы YANG и YIN содержат эквивалентную информацию, но используют разные обозначения. Нотация YIN позволяет разработчикам представлять модули данных YANG в формате XML, что дает возможность использования богатого набора инструментов XML для фильтрации и проверки данных, автоматизированной генерации кода и других задач. Могут применяться инструменты типа XSLT или валидаторов XML.

Преобразование между YANG и YIN не меняет информационного содержимого модели. Комментарии и пробельные символы не сохраняются.

11.1. Формальное определение YIN

Между ключевыми словами YANG и элементами YIN существует взаимно-однозначное соответствие. Локальное имя элемента YIN идентично соответствующему ключевому слову YANG. Это означает, в частности, что корневым элементом документа YIN всегда будет <module> или <submodule>.

Элементы YIN, соответствующие ключевым словам YANG, отоносятся к пространству имен, идентификатор URI которого имеет значение urn:ietf:params:xml:ns:yang:yin:1.

Элементы YIN, соответствующие ключевым словам расширений, относятся к пространству имен модуля YANG, в котором ключевое слово было объявлено с помощью оператора extension.

Имена всех элементов YIN должны быть надлежащим образом определены в их пространствах имен (см. выше) с использованием стандартных механизмов [XML-NAMES], т. е. атрибутов xmlns и xmlns:xxx.

Аргумент оператора YANG представляется в YIN атрибутом XML или субэлементом элемента keyword. Отображения для ключевых слов YANG приведены в таблице 1. Для расширений отображение аргумента задается оператором extension (см. параграф 7.17) и приведенными ниже правилами.

  • Если аргумент представлен атрибутом, этот атрибут не имеет пространства имен.

  • Если аргумент представлен элементом, он определяется тем же пространством имен, что и его родительский элемент keyword.

  • Если аргумент представлен как элемент, он должен быть первым потомком элемента keyword.

Субоператоры операторов YANG представляются как (дополнительные) потомки элемента keyword, а их относительный порядок должен совпадать с порядком субоператоров в YANG.

Комментарии YANG могут преобразовываться в комментарии XML.

Таблица 1. Отображение аргументов операторов YANG.

Ключевое слово

Имя аргумента

yin-element

anyxml

name

false

argument

name

false

augment

target-node

false

base

name

false

belongs-to

module

false

bit

name

false

case

name

false

choice

name

false

config

value

false

contact

text

true

container

name

false

default

value

false

description

text

true

deviate

value

false

deviation

target-node

false

enum

name

false

error-app-tag

value

false

error-message

value

true

extension

name

false

feature

name

false

fraction-digits

value

false

grouping

name

false

identity

name

false

if-feature

name

false

import

module

false

include

module

false

input

<no argument>

n/a

key

value

false

leaf

name

false

leaf-list

name

false

length

value

false

list

name

false

mandatory

value

false

max-elements

value

false

min-elements

value

false

module

name

false

must

condition

false

namespace

uri

false

notification

name

false

ordered-by

value

false

organization

text

true

output

<no argument>

n/a

path

value

false

pattern

value

false

position

value

false

prefix

value

false

presence

value

false

range

value

false

reference

text

true

refine

target-node

false

require-instance

value

false

revision

date

false

revision-date

date

false

rpc

name

false

status

value

false

submodule

name

false

type

name

false

typedef

name

false

unique

tag

false

units

name

false

uses

name

false

value

value

false

when

condition

false

yang-version

value

false

yin-element

value

false

11.1.1. Пример использования

Приведенный ниже модуль YANG

     module acme-foo {
         namespace "http://acme.example.com/foo";
         prefix "acfoo";

         import my-extensions {
             prefix "myext";
         }

         list interface {
             key "name";
             leaf name {
                 type string;
             }

             leaf mtu {
                 type uint32;
                 description "MTU для интерфейса.";
                 myext:c-define "MY_MTU";
             }
         }
     }

где расширение c-define определено в параграфе 7.17.3, преобразуется в YIN вида

     <module name="acme-foo"
             xmlns="urn:ietf:params:xml:ns:yang:yin:1"
             xmlns:acfoo="http://acme.example.com/foo"
             xmlns:myext="http://example.com/my-extensions">

       <namespace uri="http://acme.example.com/foo"/>
       <prefix value="acfoo"/>

       <import module="my-extensions">
         <prefix value="myext"/>
       </import>

       <list name="interface">
         <key value="name"/>
         <leaf name="name">
           <type name="string"/>
         </leaf>
         <leaf name="mtu">
           <type name="uint32"/>
           <description>
             <text>MTU для интерфейса.</text>
           </description>
           <myext:c-define name="MY_MTU"/>
         </leaf>
       </list>
     </module>

Часть 5

Запись опубликована в рубрике RFC. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Or