RFC 6020 (часть 2)

Please enter banners and links.

image_print

Часть 1


6. Синтаксис YANG

Синтаксис YANG похож на применяемый в SMIng [RFC3780] и языках программирования типа C или C++. Синтаксис в стиле C был осознанно выбран для удобочитаемости, поскольку YANG считает более важным фактором время и усилия читателей моделей YANG, нежели разработчиков модулей и инструментальных средств. Этот раздел посвящен описанию синтаксиса YANG.

Модули YANG используют кодировку символов UTF-8 [RFC3629].

6.1. Лексические маркеры

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

6.1.1. Комментарии

Для комментариев применяется стиль C++. Одиночная строка комментария начинается символами // и заканчивается как все строки. Комментарий блока строк начинается с последовательности /* и завершается последовательностью */.

6.1.2. Маркеры

Маркером (token) в YANG считается ключевое слово, строка, точка с запятой (;) и фигурные скобки ({ и }). Строка может быть заключена в кавычки. Ключевое слово – это одно из ключевых слов YANG, определенных в этом документе, или идентификатор префикса, за которым следует двоеточие (:) и ключевое слово расширения языка. Регистр символов в ключевых словах принимается во внимание. Формальное определение идентификаторов дано в параграфе 6.2.

6.1.3. Кавычки

Если строка содержит пробелы, символы табуляции, точку с запятой (;), скобки ({ или }) или последовательности для обозначения комментариев (//, /*, */), она должна заключаться в двойные или одинарные кавычки.

Если строка в двойных кавычках включает символы завершения строки, за которыми следуют пробелы или табуляторы, используемые для задания отступа в соответствии с макетом файла YANG, эти пробельные символы в начале строк вырезаются вплоть до столбца с открывающей двойной кавычкой (включая его) или первого непробельного символа (что встретится раньше). Любой символ табуляции перед проверкой преобразуется в 8 символов пробела.

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

Строка в одинарных кавычках (‘ ‘) сохраняет значение каждого символа. Символ одинарных кавычек не может использоваться в таких строках даже вместе с символом \.

Внутри строк в двойных кавычках (” “) символ \ имеет специальное значение, которое зависит от следующего непосредственно за ним символа:

\n новая строка;

\t символ табуляции;

\” символ двойной кавычки;

\\ одиночный символ \.

Если после строки в кавычках следует символ сложения (+) и другая строка в кавычках, эти строки объединяются в одну (конкатенация), что позволяет собирать одну большую строку из множества строк ограниченной длины. Перед конкатенацией строк выполняется удаление пробельных символов в начале и замена последовательностей специального назначения с \.

6.1.3.1. Примеры кавычек

Ниже приведен набор эквивалентных строк.

     hello
     "hello"
     'hello'
     "hel" + "lo"
     'hel' + "lo"

Далее показаны несколько строк специального назначения.

     "\""  - строка, содержащая двойную кавычку
     '"'   - строка, содержащая двойную кавычку
     "\n"  - строка, содержащая символы новой строки
     '\n'  - строка, содержащая символ \, за которым следует символ n

Ниже приведены два примера недопустимых строк.

     ''''  - строка в одинарных кавычках не может включать одинарные кавычки
     """   - символ двойных кавычек должен использовать префикс \

Две приведенных ниже строки эквивалентны.

         "first line
            second line"

     "first line\n" + "  second line"

6.2. Идентификаторы

Идентификаторы служат для обозначения различных элементов YANG по именам. Каждый идентификатор начинается с буквы кода ASCII (в верхнем или нижнем регистре) или символа подчеркивания, а далее могут следовать дополнительные буквы, цифры, символы подчеркивания, дефиса и точки в кодировке ASCII. Реализации должны поддерживать идентификаторы размером до 64 символов. Регистр символов в идентификаторах принимается во внимание. Синтаксис идентификаторов формально определен правилом identifier в разделе 12. Идентификаторы могут задаваться в форме строк в кавычках и без кавычек.

6.2.1. Идентификаторы и их пространства имен

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

  • Все имена модулей и субмодулей используют общее глобальное пространство имен модулей.

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

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

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

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

  • Все имена группировок, определенных в родительском узле или на верхнем уровне модуля и его субмодулей, используют общее пространство имен группировок. Это пространство имен охватывает все дочерние узлы модуля или родительского узла. Это означает, что любой узел-потомок может использовать данное группировку (grouping), а использование этого же имени для других группировок недопустимо.

  • Все узлы типа leaf, leaf-list, list, container, choice, rpc, notification и anyxml, определенные (напрямую или с помощью оператора uses) в родительском узле или на верхнем уровне модуля и его субмодулей определенных в модуле и его субмодулях, используют общее пространство имен. Это пространство охватывает родительский узел или модуль, если родительский узел не относится к типу case. В последнем случае пространство имен охватывает ближайшего предка, не являющегося узлом типа case или choice.

  • Все узлы case внутри choice используют общее пространство имен идентификаторов. Это пространство охватывает родительский узел choice.

В YANG разрешены ссылки вперед (упреждающие).

6.3. Операторы

Модуль YANG содержит последовательность операторов. Каждый оператор начинается с ключевого слова, за которым могут следовать аргументы, а затем символ ; или блок субоператоров, заключенный в фигурные скобки ({ })

     statement = keyword [argument] (";" / "{" *statement "}")

Аргумент является строкой (см. параграф 6.1.2).

6.3.1. Расширения языка

Модуль может задавать расширения языка YANG с помощью ключевого слова extension (см. параграф 7.17). Расширения могут импортироваться другими модулями с помощью оператора import (см. параграф 7.1.5). При использовании импортированного расширения ключевое слово расширения должно указываться с префиксом, который применялся для импорта модуля расширения. Если расширение применяется в определившем его модуле, ключевое слово расширения должно указываться с префиксом этого модуля.

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

Если компилятор YANG не поддерживает того или иного расширения, которое присутствует в модуле YANG как неизвестный оператор (см. раздел 12), такой оператор можно игнорировать целиком.

6.4. Вычисление XPath

Язык YANG опирается на язык путей XML (XPath1) 1.0 [XPATH] в качестве нотации для задания множества связей и зависимостей между узлами. Клиенты и серверы NETCONF не обязаны включать интерпретатор XPath, но они должны гарантировать выполнение требований, представленных в модели данных. Способ исполнения этого зависит от реализации. Выражения XPath должны быть корректны синтаксически, а все используемые префиксы должны присутствовать в контексте XPath (см. параграф 6.4.1). Реализация может сделать это вручную вместо использования выражения XPath напрямую.

Модель данных, применяемая в выражении XPath, совпадает с используемой в XPath 1.0 [XPATH] с тем же расширением для потомка корневого узла, что применяется в XSLT 1.0 (см. параграф 3.1 в [XSLT]). Это означает, в частности, что корневой узел может иметь любое число элементов в качестве своих потомков.

6.4.1. Контекст XPath

Все выражения YANG XPath используют приведенное ниже определение контекста XPath.

  • Набор деклараций пространства имен представляет собой набор всех пар префиксов операторов import и пространств имен в модуле, где задано выражение XPath, и всех префиксов операторов prefix для пространства имен URI оператора.

  • Имена без префикса пространства имен относятся к тому же пространству, что идентификатор текущего узла. Внутри группировки это пространство зависит от того, где группировка используется (см. параграф 7.12).

  • Библиотека функций – это основная библиотека, определенная в [XPATH], и функция current(), которая возвращает набор узлов с начальным узлом контекста.

  • Набор привязок переменных пуст.

Механизм обработки имен без префиксов приспособлен из XPath 2.0 [XPATH2.0] и помогает упростить выражения XPath в YANG. Неоднозначностей возникать не может, поскольку идентификаторы узлов YANG всегда являются квалифицированными именами с непустым URI пространства имен.

Узел контекста меняется в зависимости от выражения YANG XPath и указывается там, где определен оператор YANG с выражением XPath.

6.5. Идентификатор узла схемы

Идентификатор узла схемы представляет собой строку, указывающую узел в дереве схемы. Он имеет две формы – абсолютную и наследуемую (descendant), которые определены правилами absolute-schema-nodeid и descendant-schema-nodeid в разделе 12. Идентификатор узла схемы состоит из пути идентификаторов, разделенных символами дробной черты (/). В абсолютном идентификаторе первым символом является /, а за ним следует узел схемы верхнего уровня в локальном или всех импортированных модулях.

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

Например, для указания дочернего узла b узла верхнего уровня a может использоваться строка /a/b.

7. Операторы YANG

В этом разделе описаны все операторы YANG.

Отметим, что даже операторы, не имеющие каких-либо субоператоров, определенных в YANG, могут иметь в качестве субоператоров фирменные расширения. Например, оператор description не имеет расширений в YANG, но возможен показанный ниже вариант субоператора.

     description "Некий текст" {
         acme:documentation-flag 5;
     }

7.1. Оператор module

Оператор module определяет имя модуля и собирает воедино все относящиеся к модулю операторы. Аргументом оператора module является имя модуля, за которым следует блок субоператоров с дополнительной информацией о модуле. Имя модуля следует правилам для идентификаторов (см. параграф 6.2).

Имена модулей, публикуемые в RFC [RFC4844], должны выделяться IANA (см. раздел 14).

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

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

     module <module-name> {

         // информация заголовка
         <оператор yang-version>
         <оператор namespace>
         <оператор prefix>

         // данные о привязках
         <операторы import>
         <операторы include>

         // матаданные
         <оператор organization>
         <оператор contact>
         <оператор description>
         <оператор reference>

         // история выпуской
         <операторы revision>

         // определения модуля
         <другие операторы>
     }

7.1.1. Субоператоры для module

Субоператор

Параграф

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

anyxml

7.10

0..n

augment

7.15

0..n

choice

7.9

0..n

contact

7.1.8

0..1

container

7.5

0..n

description

7.19.3

0..1

deviation

7.18.3

0..n

extension

7.17

0..n

feature

7.18.1

0..n

grouping

7.11

0..n

identity

7.16

0..n

import

7.1.5

0..n

include

7.1.6

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

namespace

7.1.3

1

notification

7.16

0..n

organization

7.1.7

0..1

prefix

7.1.4

1

reference

7.19.4

0..1

revision

7.1.9

0..n

rpc

7.13

0..n

typedef

7.3

0..n

uses

7.12

0..n

yang-version

7.1.2

1

7.1.2. Оператор yang-version

Необязательный оператор yang-version указывает версию языка YANG, использованную при разработке модуля. Аргументом оператора является строка. Для модулей YANG, определенных на основе данной спецификации, она должна иметь значение1.

Обработка операторов yang-version со значением версии, отличающимся от 1 (определена здесь), выходит за рамки данной спецификации. Любой документ, определяющий более высокий номер версии должен определять совместимость этой версии с более ранними.

7.1.3. Оператор namespace

Оператор namespace определяет пространство имен XML, в котором все определенные модулем идентификаторы представляются в XML (за исключением идентификаторов узлов данных внутри группировок – см. параграф 7.13). Аргументом оператора namespace служит идентификатор URI пространства имен.

См. также параграф 5.3.

7.1.4. Оператор prefix

Оператор prefix служит для определения префикса, связанного с модулем и его пространством имен. Аргументом оператора prefix является строка префикса, которая применяется для доступа к модулю. Строка префикса может использоваться в модуле для ссылок на содержащиеся в нем определения (например, if:ifName). Для префиксов применяются такие же правила, как для идентификаторов (см. параграф 6.2).

При использовании в операторе module субоператор prefix определяет префикс, предлагаемый для использования при импорте этого модуля. Для удобочитаемости NETCONF XML клиенту или серверу NETCONF, генерирующему XML или or XPath с использованием префиксов, следует применять определенный в модулей префикс в качестве префикса пространства имен XML, если это не вызывает конфликтов.

При использовании в операторе import субоператор prefix определяет префикс, используемый для доступа к определениям в импортируемом модуле. При использовании ссылок на операторы из импортируемого модуля за строкой префикса этого модуля следует двоеточие (:) и идентификатор (например if:ifIndex). Для удобочитаемости модулей YANG определенный модулем префикс следует использовать при импорте модуля, если это не вызывает конфликтов. При возникновении конфликта когда импортируются два разных модуля, имеющих одинаковые префиксы, хотя бы один из них должен импортироваться с другим префиксом.

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

7.1.5. Оператор import

Оператор import делает доступными операторы из другого модуля или субмодуля. Аргументом оператора служит имя импортируемого модуля, за которым следует блок субоператоров с данными импорта. Импортирующий модуль может:

  • использовать любые группировки (grouping) и определения типов (typedef), заданные на верхнем уровне импортированного модуля и его субмодулей;

  • применять любые расширения, функции и отождествления из импортированного из модуля и его субмодулей;

  • использовать любой узел из дерева схемы импортированного модуля в операторах must, path и when или в качестве целевого узла в операторах augment и deviation.

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

При наличии необязательного субоператора revision-date любые typedef, grouping, extension, feature и identity, указанные в определениях локального модуля, берутся из заданного выпуска импортируемого модуля. Если указанного выпуска импортируемого модуля не существует, возникает ошибка. При отсутствии субоператора revision-date выпуск импортируемого модуля будет не известен.

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


Субоператор

Параграф

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

prefix

7.1.4

1

revision-date

7.1.5.1

0..1

7.1.5.1. Оператор revision-date для оператора import

Субоператор revision-date используется в операторе import для указания выпуска импортируемого модуля. Оператор revision-date должен соответствовать наиболее свежему оператору revision в импортируемом модуля.

7.1.6. Оператор include

Оператор include делает содержимое субмодуля доступным в родительском модуле или другом субмодуле родительского модуля. Аргументом оператора служит имя включаемого субмодуля. В модули можно включать лишь относящиеся к ним субмодули, указанные оператором belongs-to (см. параграф 7.2.2). В субмодули можно включать лишь другие субмодули того же модуля.

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

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

Недопустимо включение в модуль множества выпусков одного субмодуля.

Субоператор

Параграф

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

revision-date

7.1.5.1

0..1

7.1.7. Оператор organization

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

7.1.8. Оператор contact

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

7.1.9. Оператор revision

Оператор revision указывает историю изменения модуля, включая его начальный выпуск. Последовательность операторов revision детализирует изменения в определении модуля. Аргументом оператора служит строка даты в формате YYYY-MM-DD (год-месяц-число), за которой следует блок субоператоров с информацией о выпуске. Модулю следует включать по крайней мере один оператор revision. Для каждого опубликованного выпуска следует добавлять новый оператор в начале последовательности, чтобы все выпуски перечислялись в обратном хронологическом порядке.

7.1.9.1. Субоператоры для revision

Субоператор

Параграф

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

description

7.19.3

0..1

reference

7.19.4

0..1

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

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

         import ietf-yang-types {
             prefix "yang";
         }

         include acme-types;

         organization "ACME Inc.";
         contact
             "Joe L. User

              ACME, Inc.
              42 Anywhere Drive
              Nowhere, CA 95134
              USA

              Phone: +1 800 555 0100
              EMail: joe@acme.example.com";

         description
             "Модуль для объектов, реализующих протокол ACME.";

         revision "2007-06-09" {
             description "Первый выпуск.";
         }

         // определения ...
     }

7.2. Оператор submodule

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

Оператор submodule задает имя субмодуля и группирует все операторы, относящиеся к этому субмодулю. Аргументом оператора submodule является имя субмодуля, за которым следует блок операторов с информацией о субмодуле. Имя субмодуля является идентификатором (см. параграф 6.2).

Имена субмодулей, публикуемые в RFC [RFC4844], должны выделяться IANA (см. раздел 14).

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

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

     submodule <module-name> {
         <оператор yang-version>
         // идентификация модуля
         <оператор belongs-to>
         // операторы привязки
         <операторы import>
         <операторы include>
         // метаданные
         <оператор organization>
         <оператор contact>
         <оператор description>
         <оператор reference>
         // история выпусков
         <операторы revision>
         // определения субмодуля
         <другие операторы>
     }

7.2.1. Субоператоры для submodule


Субоператор

Параграф

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

anyxml

7.10

0..n

augment

7.15

0..n

belongs-to

7.2.2

1

choice

7.9

0..n

contact

7.1.8

0..1

container

7.5

0..n

description

7.19.3

0..1

deviation

7.18.3

0..n

extension

7.17

0..n

feature

7.18.1

0..n

grouping

7.11

0..n

identity

7.16

0..n

import

7.1.5

0..n

include

7.1.6

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

notification

7.14

0..n

organization

7.1.7

0..1

reference

7.19.4

0..1

revision

7.1.9

0..n

rpc

7.13

0..n

typedef

7.3

0..n

uses

7.12

0..n

yang-version

7.1.2

0..1

7.2.2. Оператор belongs-to

Оператор belongs-to указывает модуль, к которому субмодуль относится. Аргументом оператора является имя модуля.

Субмодуль должен включаться только в модуль, к которому он относится или в его субмодули.

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

Субоператор

Параграф

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

prefix

7.1.4

1

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

     submodule acme-types {

         belongs-to "acme-system" {
             prefix "acme";
         }

         import ietf-yang-types {
             prefix "yang";
         }

         organization "ACME Inc.";
         contact
             "Joe L. User

              ACME, Inc.
              42 Anywhere Drive
              Nowhere, CA 95134
              USA

              Phone: +1 800 555 0100
              EMail: joe@acme.example.com";

         description
             "Этот субмодуль определяет общие типы ACME.";

         revision "2007-06-09" {
             description "Первый выпуск.";
         }

         // далее следуют определеия ...
     }

7.3. Оператор typedef

Оператор typedef определяет новый тип, который может применяться локально в модуле или субмодуле, а также в других модулях, импортирующих данный, в соответствии с правилами, описанными в параграфе 5.5. Новый тип называется производным (derived), а тип, на основе которого он создан, – базовым. Все производные типы можно отследить по цепочке до встроенного типа YANG.

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

В качестве имени производного типа недопустимо использовать какое-либо из имен встроенных типов YANG. Если typedef определяется на верхнем уровне модуля или субмодуля YANG, имя определяемого типа должно быть уникальным в данном модуле.

7.3.1. Субоператоры для typedef


Субоператор

Параграф

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

default

7.3.4

0..1

description

7.19.3

0..1

reference

7.19.4

0..1

status

7.19.2

0..1

type

7.3.2

1

units

7.3.3

0..1

7.3.2. Оператор type

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

7.3.3. Оператор units

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

7.3.4. Оператор default

Оператор default принимает аргумент в виде строки с принятым по умолчанию значением для нового типа.

Заданное оператором default значение должно быть пригодным для типа, указанного в операторе type.

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

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

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

     typedef listen-ipv4-address {
       type inet:ipv4-address;
       default "0.0.0.0";
     }

7.4. Оператор type

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

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

7.4.1. Субоператоры для type

Субоператор

Параграф

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

bit

9.7.4

0..n

enum

9.6.4

0..n

length

9.4.4

0..1

path

9.9.2

0..1

pattern

9.4.6

0..n

range

9.2.4

0..1

require-instance

9.13.2

0..1

type

7.4

0..n

7.5. Оператор container

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

Узел-контейнер на имеет значения, но имеет список дочерних узлов дерева данных. Дочерние узлы определяются в субоператорах контейнера.

7.5.1. Контейнеры с presence

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

В первом случае контейнер не имеет своего значения и существует лишь для организации дочерних узлов. В частности. Этот стиль применяется по умолчанию.

Например, набор опций скрэмблирования для интерфейсов SONET2 может помещаться в контейнер scrambling для более эффективной организации конфигурационной иерархии и совместного хранения этих узлов. Сам узел scrambling не имеет значения (смысла), поэтому удаление узла, когда он становится пустым, освобождает пользователя от выполнения этой задачи.

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

YANG называет контейнеры этого типа контейнерами присутствия (presence container) и они обозначаются оператором presence, который принимает в качестве аргумента текстовую строку, указывающую смысл присутствия узла.

Например, контейнер ssh может включать возможность входа на сервер по протоколу SSH3, но может также включать любые связанные с SSH конфигурационные элементы типа скорости соединения или числа попыток.

Оператор presence (см. параграф 7.5.5) служит для представления смысла наличия контейнера в дереве данных.

7.5.2. Субоператоры для container

Субоператор

Параграф

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

anyxml

7.10

0..n

choice

7.9

0..n

config

7.19.1

0..1

container

7.5

0..n

description

7.19.3

0..1

grouping

7.11

0..n

if-feature

7.18.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

presence

7.5.5

0..1

reference

7.19.4

0..1

status

7.19.2

0..1

typedef

7.3

0..n

uses

7.12

0..n

when

7.19.5

0..1

7.5.3. Оператор must

Необязательный оператор must принимает один аргумент в виде строки с выражением XPath (см. параграф 6.4). Он используется для формального выражения ограничений на пригодные данные. Ограничение применяется в соответствии с правилами, указанными в разделе 8.

При проверке хранилища данных на пригодность, все ограничения must концептуально проверяются один раз для каждого узла в дереве данных и для всех используемых листьев с принятыми по умолчанию значениями (см. параграф 6.4.1). Если узла нет в дереве данных или лист не имеет принятого по умолчанию значения, оператор must не оценивается.

Чтобы данные считались пригодными проверка всех таких ограничений должна давать значение true.

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

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

  • Доступное дерево состоит из всех узлов в дереве данных и всех листьев с используемыми значениями, которые приняты по умолчанию (параграф 7.6.1).

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

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

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

  • Если узел контекста представляет содержимое уведомления, дерево является документом экземпляра XML для уведомления. Корневой узел XPath имеет в качестве единственного потомка элемент, представляющий уведомление.

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

  • Если узел контекста представляет выходные параметры RPC, дерево является экземпляром документа отклика RPC. Корневой узел XPath имеет в качестве потомков элементы, представляющие выходные параметры RPC.

Результат выражения XPath преобразуется в логическое значение с использованием стандартных правил XPath.

Поскольку все значения листьев в дереве данных концептуально хранятся в канонической форме (см. параграфы 7.6 и 7.7), любые сравнение XPath также выполняются для канонических значений.

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

7.5.4. Субоператоры для must

Субоператор

Параграф

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

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

7.5.4.1. Оператор error-message

Необязательный оператор error-message принимает в качестве аргумента строку. Если оценка ограничений дает значение false, строка передается как <error-message> в <rpc-error>.

7.5.4.2. Оператор error-app-tag

Необязательный оператор error-app-tag принимает в качестве аргумента строку. Если оценка ограничений дает значение false, строка передается как <error-app-tag> в <rpc-error>.

7.5.4.3. Пример использования must и error-message
     container interface {
         leaf ifType {
             type enumeration {
                 enum ethernet;
                 enum atm;
             }
         }
         leaf ifMTU {
             type uint32;
         }
         must "ifType != 'ethernet' or " +
              "(ifType = 'ethernet' and ifMTU = 1500)" {
             error-message "Значение MTU для Ethernet должно быть 1500";
         }
         must "ifType != 'atm' or " +
              "(ifType = 'atm' and ifMTU <= 17966 and ifMTU >= 64)" {
             error-message " Значение MTU для ATM должно быть 64 .. 17966";
         }
     }

7.5.5. Оператор presence

Оператор presence указывает смысл присутствия оператора container в дереве данных. Он принимает в качестве аргумента строку с текстовым описанием смысла присутствия узла.

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

Дополнительная информация приведена в параграфе 7.5.1.

7.5.6. Операторы дочерних узлов контейнера

Внутри контейнеры операторы container, leaf, list, leaf-list, uses, choice и anyxmls могут применяться для определения дочерних узлов контейнера.

7.5.7. Правила отображения XML

Узел container представляется в виде элемента XML. Локальное имя элемента служит идентификатором контейнера, а его пространство имен совпадает с пространством имен XML для модуля (см. параграф 7.1.3).

Дочерние узлы контейнера представляются как субэлементы элемента container. Если контейнер определяет входные или выходные параметры RPC или операции (action), эти субэлементы представляются в том же порядке, в котором они определены в операторе container. В остальных случаях субэлементы могут представляться в любом порядке.

Сервер NETCONF, отвечающий на запрос <get> или <get-config>, может отказаться от передачи элемента container, если узел контейнера не имеет оператора presence и дочерних узлов. Поэтому клиент, принявший <rpc-reply> для запроса <get> или <get-config>, должен быть готов обрабатывать ситуации, когда узел контейнера без оператора presence не присутствует в XML.

7.5.8. Операции NETCONF <edit-config>

Контейнеры могут создаваться, удаляться, заменяться и изменяться с помощью операции <edit-config> с атрибутом operation (см. параграф 7.2 в [RFC4741]) в элементе XML этого контейнера.

Если конейнер не имеет оператора presence и последний дочерний узел удален, сервер NETCONF может удалить этот контейнер.

При обработке сервером NETCONF запроса <edit-config> выполняются следующие правила:

  • если задана операция merge или replace, узел создается при его отсутствии;

  • если задана операция create, узел создается при его отсутствии, а в случае наличия узла возвращается ошибка data-exists;

  • если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

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

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

     container system {
         description "Содержит различные параметры системы";
         container services {
             description "Настройка доступных извне служб";
             container "ssh" {
                 presence "Включает SSH";
                 description "Настройки службы SSH";
                 // дополнительные листья, контейнеры и т. п. ...
             }
         }
     }

Соответствующий экземпляр XML будет иметь вид

     <system>
       <services>
         <ssh/>
       </services>
     </system>

Присутствие элемента <ssh> разрешает использовать SSH.

Удаление контейнера с помощью <edit-config> имеет вид

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="http://example.com/schema/config">
             <services>
               <ssh nc:operation="delete"/>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

7.6. Оператор leaf

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

Узел leaf имеет значение, но не имеет дочерних узлов в дереве данных. Понятно, что значение в дереве данных всегда имеет каноническую форму (см. параграф 9.1).

Узлы типа leaf являются необязательными и могут присутствовать во множестве экземпляров.

Оператор leaf используется для определения скалярных переменных конкретного встроенного или производного типа.

7.6.1. Значение листа по умолчанию

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

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

  • В противном случае, если предок является узлом case, принятое по умолчанию значение должно использоваться, когда любой узел из case существует в дереве данных или узел case является используемым по умолчанию для choice и нет узлов от других вариантов case в дереве данных.

  • В остальных случаях принятое по умолчанию значение должно использоваться при наличии предка в дереве данных.

В этих случаях говорят, что используется принятое по умолчанию значение.

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

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

7.6.2. Субоператоры для leaf

Субоператор

Параграф

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

config

7.19.1

0..1

default

7.6.4

0..1

description

7.19.3

0..1

if-feature

7.18.2

0..n

mandatory

7.6.5

0..1

must

7.5.3

0..n

reference

7.19.4

0..1

status

7.19.2

0..1

type

7.6.3

1

units

7.3.3

0..1

when

7.19.5

0..1

7.6.3. Оператор type

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

7.6.4. Оператор default

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

Значение оператора default должно соответствовать типу листа, заданному оператором type.

Оператор default недопустимо включать для узлов, где в качестве значения mandatory установлено true.

Определение принятого по умолчанию значение недопустимо помечать оператором if-feature. Например, ниже представлено неприемлемое определение.

7.6.5. Оператор mandatory

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

Если для mandatory установлено значение true, поведение ограничений зависит от типа ближайшего предка leaf в дереве схемы, который не является контейнером отсутствия (см. параграф 7.5.1):

  • если такого предка нет в дереве схемы, leaf должен существовать;

  • в противном случае, если предок имеет тип case leaf должен существовать при наличии в дереве данных хотя бы одного узла из case;

  • в остальных случаях leaf должен существовать, если узел-предок существует в дереве данных.

Эти ограничения применяются в соответствии с правилами раздела 8.

7.6.6. Правила отображения XML

Узел leaf представляется в виде элемента XML. Локальное имя элемента является идентификатором листа, а его пространством имен является пространство имен XML для модуля (см. параграф 7.1.3).

Значение узла leaf представляется в XML в соответствии с типом и передается в элемент в виде символов.

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

Пример представления дан в параграфе 7.6.8.

7.6.7. Операции NETCONF <edit-config>

При обработке сервером NETCONF запроса <edit-config> для узла leaf выполняются следующие правила:

  • если задана операция merge или replace, узел создается при его отсутствии и для него устанавливается значение, найденное в данных XML RPC;

  • если задана операция create, узел создается при его отсутствии, а в случае наличия узла возвращается ошибка data-exists;

  • если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

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

Ниже приведен оператор leaf, помещенный в определенный выше контейнер ssh (см. параграф 7.5.9):

     leaf port {
         type inet:port-number;
         default 22;
         description "Порт, который прослушивает сервер SSH."
     }

Пример соответствующего экземпляра XML будет иметь вид

     <port>2022</port>

Для установки значения leaf с помощью <edit-config> служит

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="http://example.com/schema/config">
             <services>
               <ssh>
                 <port>2022</port>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

7.7. Оператор leaf-list

Оператор leaf служит для определения простой скалярной переменной того или иного типа, а оператор leaf-list – для определения массива определенного типа. Оператор leaf-list принимает в качестве параметра идентификатор, за которым следует блок субоператоров с детальной информацией о leaf-list.

В данных конфигурации все значения в leaf-list должны быть уникальными.

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

Если тип, указанный leaf-list, имеет принятое по умолчанию значение, он не оказывает влияния на leaf-list.

7.7.1. Упорядочение

YANG поддерживает два стиля упорядочения элементов в узлах list и leaf-list. Во многих списках порядок элементов не влияет на реализацию конфигурации списка и устройство может сортировать элементы по своему усмотрению. Строка description для списка может предложить порядок для разработчиков реализации сервера. В языке YANG такой стиль называется системным упорядочением (system ordered), а списки помечаются оператором ordered-by system.

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

В другом стиле списков порядок имеет значение для реализации конфигурации списка и пользователь отвечает за упорядочение элементов, а устройство этот порядок поддерживает. В YANG такие списки называются упорядоченными пользователем (user ordered) и указываются оператором ordered-by user.

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

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

Оператор ordered-by описан в параграфе 7.7.57.

7.7.2. Субоператоры для leaf-list


Субоператор

Параграф

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

config

7.19.1

0..1

description

7.19.3

0..1

if-feature

7.18.2

0..n

max-elements

7.7.4

0..1

min-elements

7.7.3

0..1

must

7.5.3

0..n

ordered-by

7.7.5

0..1

reference

7.19.4

0..1

status

7.19.2

0..1

type

7.4

1

units

7.3.3

0..1

when

7.19.5

0..1

7.7.3. Оператор min-elements

Необязательный оператор min-elements принимает в качестве аргумента неотрицательное целое число, которое задает ограничения для количества элементов списка. Действительный список leaf-list или list должен иметь по меньшей мере min-elements элементов

Если оператор min-elements не присутствует, по умолчанию принимается значение 0.

Поведение ограничений зависит от типа ближайшего предка leaf-list или list в дереве схемы, который не является контейнером отсутствия (см. параграф 7.5.1):

  • если такого предка нет в дереве схемы, ограничения применяются;

  • в противном случае, если предок является узлом case, ограничения применяются при наличии любого другого узла от этого case;

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

Далее ограничения применяются в соответствии с правилами раздела 8.

7.7.4. Оператор max-elements

Необязательный оператор max-elements принимает в качестве аргумента положительное целое число или строку unbounded (не ограничено), которые ограничивают число пригодных элементов списка. Действительный список leaf-list или list всегда имеет не более max-elements элементов.

При отсутствии оператора max-elements по умолчанию используется значение unbounded.

Ограничения оператора max-elements применяются в соответствии с правилами раздела 8.

7.7.5. Оператор ordered-by

Оператор ordered-by определяет источник упорядочения элементов списка – пользователь или система. Аргументом оператора может быть строка system или user. При отсутствии оператора по умолчанию применяется system.

Этот оператор игнорируется, если список представляет данные состояния, выходные параметры RPC или содержимое уведомления.

Дополнительная информация приведена в параграфе 7.7.1.

7.7.5.1. Системное упорядочение

Порядок сортировки элементов списка не задан. Реализация может сортировать элементы в удобном для нее порядке. упорядочиваются системой (ordered-by system). Реализациям следует применять для одинаковых данных один и тот же порядок, независимо от места расположения данных. Использование определенного порядка позволяет выполнять сравнение с использованием простых средств типа diff.

Этот порядок применяется по умолчанию.

7.7.5.2. Упорядочение пользователем

Элементы списка сортируются в соответствии с порядком, заданным пользователем. Этот порядок устанавливается с помощью специальных атрибутов XML в запросе <edit-config> (см. параграф 7.7.7).

7.7.6. Правила отображения XML

Узел leaf-list представляется последовательностью элементов XML. Локальное имя каждого элемента служит идентификатором leaf-list, а пространством имен служит пространство имен XML модуля (см. параграф 7.1.3).

Значение каждого элемента leaf-list представляется в XML в соответствии с типом и передается в элемент XML как символьные данные.

Элементы XML, представляющие элементы leaf-list, должны размещаться в порядке, заданном пользователем, если leaf-list имеет атрибут ordered-by user. В противном случае порядок зависит от реализации. Элементы XML, представляющие элементы leaf-list, могут чередоваться с элементами братских (sibling) leaf-list, если leaf-list не определяет входные или выходные параметры RPC.

Пример представлен в параграфе 7.7.8.

7.7.7. Операции NETCONF <edit-config>

Элементы leaf-list можно создавать и удалять, но нельзя изменить с помощью <edit-config> путем использования атрибута operation в элементе XML узла leaf-list.

В упорядоченном пользователем leaf-list атрибуты insert и value в пространстве имен YANG XML (параграф 5.3.1) могут служить для управления местом вставки элемента в leaf-list. Они могут применяться в операции create для создания нового элемента в leaf-list, а также в операциях merge или replace для вставки или перемещения элемента.

Атрибут оператора insert может принимать значения first, last, before и after. Для значений before и after должен также указываться атрибут value, задающий имеющуюся в leaf-list запись.

Если атрибут insert не задан для операции create, по умолчанию элемент добавляется в конец списка (last).

Если несколько элементов упорядоченного пользователем leaf-list меняются в одном запросе <edit-config>, элементы изменяются по одному в порядке размещения элементов XML в запросе.

В командах <copy-config> и <edit-config> с операцией replace, покрывающей весь список leaf-list, порядок в leaf-list совпадает с порядком элементов XML в запросе.

При обработке сервером NETCONF запроса <edit-config> для узла leaf-list выполняются следующие правила:

  • если задана операция merge или replace, узел создается при его отсутствии;

  • если задана операция create, узел создается при его отсутствии, а в случае наличия узла возвращается ошибка data-exists;

  • если задана операция delete, узел удаляется при его наличии, а в случае отсутствия узла возвращается ошибка data-missing.

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

     leaf-list allow-user  {
         type string;
         description "Список шаблонов имен пользователей для разрешения.";
     }

Соответствующий экземпляр XML имеет вид

     <allow-user>alice</allow-user>
     <allow-user>bob</allow-user>

Для создания в списке нового элемента с использованием принятой по умолчанию для <edit-config> операции merge

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="http://example.com/schema/config">
             <services>
               <ssh>
                 <allow-user>eric</allow-user>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

Для упорядоченного пользователем списка leaf-list

     leaf-list cipher  {
         type string;
         ordered-by user;
         description "Список шифров";
     }

Приведенный ниже фрагмент может служить для вставки нового шифра blowfish-cbc после 3des-cbc

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0"
          xmlns:yang="urn:ietf:params:xml:ns:yang:1">
       <edit-config>
         <target>
           <running/>
         </target>
         <config>
           <system xmlns="http://example.com/schema/config">
             <services>
               <ssh>
                 <cipher nc:operation="create"
                         yang:insert="after"
                         yang:value="3des-cbc">blowfish-cbc</cipher>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

1XML Path Language – язык путей XML.

2Synchronous Optical Network – синхронная оптическая сеть.

3Secure SHell – защищенная командная оболочка.


Часть 3

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

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

Or