RFC7950 (часть 3)

Please enter banners and links.

image_print

Часть 2


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

     leaf-list allow-user {
       type string;
       description
         "A list of user name patterns to allow.";
     }

Соответствующий экземпляр 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="urn:example: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
         "A list of ciphers.";
     }

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

     <rpc message-id="102"
          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="urn:example:config">
             <services>
               <ssh>
                 <cipher nc:operation="create"
                         yang:insert="after"
                         yang:value="3des-cbc">blowfish-cbc</cipher>
               </ssh>
             </services>
           </system>
         </config>
       </edit-config>
     </rpc>

7.8. Оператор list

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

Записи списка однозначно идентифицируются значениями ключей списка, если эти ключи определены.

7.8.1. Субоператоры для list

Субоператор

Параграф

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

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

config

7.21.1

0..1

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

key

7.8.2

0..1

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

max-elements

7.7.6

0..1

min-elements

7.7.5

0..1

must

7.5.3

0..n

notification

7.16

0..n

ordered-by

7.7.7

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

unique

7.8.3

0..n

uses

7.13

0..n

when

7.21.5

0..1

7.8.2. Оператор key

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

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

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

Все листья ключа в списке должны иметь то же значение config, что и сам список.

Синтаксис строки key формально определен правилом key-arg в разделе 14.

7.8.3. Оператор unique

Оператор unique служит задает ограничения для пригодных элементов списка и принимает аргумент в форме строки с разделенными пробелами идентификаторами узлов из списка схемы, которые должны быть заданы в форме потомков (см. правило descendant-schema-nodeid в разделе 14). Каждый из этих идентификаторов узлов схемы должен указывать лист.

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

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

Синтаксис строки unique формально определен правилом unique-arg из раздела 14.

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

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

     list server {
       key "name";
       unique "ip port";
       leaf name {
         type string;
       }
       leaf ip {
         type inet:ip-address;
       }
       leaf port {
         type inet:port-number;
       }
     }

приведенная ниже конфигурация будет непригодной

     <server>
       <name>smtp</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

     <server>
       <name>http</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

Следующая конфигурация приемлема, поскольку элементы списка http и ftp не имеют значений для всех упомянутых листьев и не будут приняты во внимание при выполнении ограничений данных оператором unique.

     <server>
       <name>smtp</name>
       <ip>192.0.2.1</ip>
       <port>25</port>
     </server>

     <server>
       <name>http</name>
       <ip>192.0.2.1</ip>
     </server>

     <server>
       <name>ftp</name>
       <ip>192.0.2.1</ip>
     </server>

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

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

7.8.5. Правила представления XML

Список представляется набором элементов XML по одному на каждый элемент списка. Локальное имя каждого элемента является идентификатором списка, а пространством имен служит пространство имен XML для модуля (см. параграф 7.1.3). Элемента XML, окружающего список в целом, нет.

Узлы ключей списка представляются в форме субэлементов идентификаторов списка в том же порядке, как они определены в операторе key.

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

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

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

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

Элементы списка можно создавать, удалять, заменять и изменять с помощью операции <edit-config> с использованием атрибута operation в элементе XML для списка. В каждом случае значения всех ключей служат для однозначной идентификации элементов списка. Если для элемента списка не заданы все ключи, возвращается ошибка missing-element.

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

Атрибут оператора insert может принимать значения first, last, before и after. Для значений before и after должен также указываться атрибут key, задающий имеющийся в списке элемент. Значение атрибута key является ключом, задающим полный идентификатор экземпляра (см. параграф 9.13) для элемента списка.

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

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

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

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

  • Если задана операция merge или replace, элемент списка создается при его отсутствии. Если элемент списка уже существует и имеются атрибуты insert и key, элемент перемещается в соответствии со значениями этих атрибутов. Если элемент списка существует, но атрибутов insert и key нет, элемент списка не перемещается.

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

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

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

Для списка

     list user {
       key "name";
       config true;
       description
         "This is a list of users in the system.";

       leaf name {
         type string;
       }
       leaf type {
         type string;
       }
       leaf full-name {
         type string;
       }
     }

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

     <user>
       <name>fred</name>
       <type>admin</type>
       <full-name>Fred Flintstone</full-name>
     </user>

Создание нового пользователя barney

     <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="urn:example:config">
             <user nc:operation="create">
               <name>barney</name>
               <type>admin</type>
               <full-name>Barney Rubble</full-name>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Изменение роли пользователя fred на superuser

     <rpc message-id="102"
          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="urn:example:config">
             <user>
               <name>fred</name>
               <type>superuser</type>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

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

     list user {
       description
         "This is a list of users in the system.";
       ordered-by user;
       config true;

       key "first-name surname";

       leaf first-name {
         type string;
       }
       leaf surname {
         type string;
       }
       leaf type {
         type string;
       }
     }

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

     <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="urn:example:config"
                xmlns:ex="urn:example:config">
             <user nc:operation="create"
                   yang:insert="after"
                   yang:key="[ex:first-name='fred']
                             [ex:surname='flintstone']">
               <first-name>barney</first-name>
               <surname>rubble</surname>
               <type>admin</type>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

Приведенный ниже фрагмент будет служить для размещения пользователя barney перед пользователем fred

     <rpc message-id="102"
          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="urn:example:config"
                xmlns:ex="urn:example:config">
             <user nc:operation="merge"
                   yang:insert="before"
                   yang:key="[ex:name='fred']
                             [ex:surname='flintstone']">
               <first-name>barney</first-name>
               <surname>rubble</surname>
             </user>
           </system>
         </config>
       </edit-config>
     </rpc>

7.9. Оператор choice

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

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

Поскольку в дереве данных в любой момент может действовать только один из вариантов выбора, создание узла в одном из вариантов (case) неявно удаляет все узлы из других вариантов. Если запрос создает узел из case, сервер будет удалять все имеющиеся узлы, определенные другими вариантами в этом операторе choice.

7.9.1. Субоператоры для choice

Субоператор

Параграф

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

anydata

7.10

0..n

anyxml

7.11

0..n

case

7.9.2

0..n

choice

7.9

0..n

config

7.21.1

0..1

container

7.5

0..n

default

7.9.3

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

mandatory

7.9.4

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

when

7.21.5

0..1

7.9.2. Оператор case для выбора

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

Идентификатор служит для указания узла case в дереве схемы. Узлов case не существует в дереве данных.

Внутри case могут применяться операторы anydata, anyxml, choice, container, leaf, list, leaf-list и uses для определения потомков узла case. Идентификаторы всех дочерних узлов должны быть уникальными для всех вариантов case в данном choice. Ниже приведен пример недопустимого выбора.

     choice interface-type {     // Это неприемлемо в YANG
       case a {
         leaf ethernet { ... }
       }
       case b {
         container ethernet { ...}
       }
     }

Для сокращения оператор case может быть опущен, если вариант содержит один оператор anydata, anyxml, choice, container, leaf, list или leaf-list. В таких случаях узел case продолжает существовать в дереве схемы и его идентификатором служит идентификатор дочернего узла. Идентификаторы узлов схемы (параграф 6.5) всегда должны явно включать идентификаторы узлов case. Выражение

     choice interface-type {
       container ethernet { ... }
     }

эквивалентно

     choice interface-type {
       case ethernet {
         container ethernet { ... }
       }
     }

Каждый идентификатор case должен быть уникальным в рамках choice.

7.9.2.1. Субоператоры для case

Субоператор

Параграф

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

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

uses

7.13

0..n

when

7.21.5

0..1

7.9.3. Субоператор default для выбора

Оператор default указывает вариант (case), который следует применять по умолчанию, если нет дочерних узлов ни у одного из вариантов choice. Аргументом служит идентификатор заданного по умолчанию варианта (case). Если оператор default не задан, используемого по умолчанию варианта не будет.

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

Используемый по умолчанию вариант важен лишь при рассмотрении операторов default в дочерних узлах вариантов (т. е. используемых по умолчанию значений leaf и leaf-list, а также используемых по умолчанию вариантов вложенных операторов choice). Принятые по умолчанию значения и варианты вложенных choice в потомках принятого по умолчанию варианта используются при отсутствии узлов в любом из вариантов (case).

Недопустимо наличие обязательных (mandatory) узлов (раздел 3), являющихся непосредственными потомками принятого по умолчанию варианта.

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

В приведенном ниже примере выбор (choice) указывает по умолчанию вариант interval и принятое по умолчанию значение будет использоваться, если нет ни одного из листьев daily, time-of-day и manual. Если узел daily присутствует, будет использовано значение, принятое по умолчанию для узла time-of-day.

     container transfer {
       choice how {
         default interval;
         case interval {
           leaf interval {
             type uint16;
             units minutes;
             default 30;
           }
         }
         case daily {
           leaf daily {
             type empty;
           }
           leaf time-of-day {
             type string;
             units 24-hour-clock;
             default "01.00";
           }
         }
         case manual {
           leaf manual {
             type empty;
           }
         }
       }
     }

7.9.4. Оператор mandatory для выбора

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

Если оператор не задан, по умолчанию предполагается значение false.

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

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

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

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

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

7.9.5. Правила представления XML

Узлы choice и case не видны в XML.

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

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

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

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

     container protocol {
       choice name {
         case a {
           leaf udp {
             type empty;
           }
         }
         case b {
           leaf tcp {
             type empty;
           }
         }
       }
     }

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

     <protocol>
       <tcp/>
     </protocol>

Для смены протокола TCP на UDP может служить приведенный ниже фрагмент.

     <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="urn:example:config">
             <protocol>
               <udp nc:operation="create"/>
             </protocol>
           </system>
         </config>
       </edit-config>
     </rpc>

7.10. Оператор anydata

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

Оператор anydata служит для представления неизвестного набора узлов, который может моделироваться в YANG (исключая anyxml),но для которого модель данный не была известна в момент разработки модуля. Возможно (но не обязательно) получение модели данных для содержимого anydata через протокол сигнализации или иным способом, выходящим за рамки этого документа.

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

Узел anydata не может быть дополнен (см. параграф 7.17).

Узел anydata отсутствует в дереве данных или содержится там в одном экземпляре.

Реализация может не знать модели данных используемой для моделирования конкретного экземпляра узла anydata.

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

7.10.1. Субоператоры для anydata

Субоператор

Параграф

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

config

7.21.1

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

mandatory

7.6.5

0..1

must

7.5.3

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

when

7.21.5

0..1

7.10.2. Правила представления XML

Узел anydata представляется в виде элемента XML. Локальное имя элемента является идентификатором anydata, а пространством имен служит пространство имен XML для модуля (см. параграф 7.1.3). Значением узла anydata является множество узлов, которые представляются субэлементами XML для элемента anydata.

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

Узел anydata рассматривается, как «непрозрачный» (opaque) блок данных. Эти данные могут изменяться лишь целиком.

Любые атрибуты operation, представленные в субэлементах узла anydata, игнорируются сервером NETCONF.

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

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

  • Если задана операция create, узел создается при его отсутствии, а в качестве значения устанавливаются субэлементы узла anydata из данных XML для RPC. В случае наличия узла возвращается ошибка data-exists.

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

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

Ниже приведен пример использования оператора anydata.

     list logged-notification {
       key time;
       leaf time {
         type yang:date-and-time;
       }
       anydata data;
     }

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

     <logged-notification>
       <time>2014-07-29T13:43:12Z</time>
       <data>
         <notification
           xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
           <eventTime>2014-07-29T13:43:01Z</eventTime>
           <event xmlns="urn:example:event">
             <event-class>fault</event-class>
             <reporting-entity>
               <card>Ethernet0</card>
             </reporting-entity>
             <severity>major</severity>
           </event>
         </notification>
       </data>
     </logged-notification>

7.11. Оператор anyxml

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

Оператор anyxml служит для представления неизвестного блока данных XML, на который не накладывается каких-либо ограничений. Это может быть полезно, например, в откликах RPC. Примером может служить параметр <filter> в операции <get-config> протокола NETCONF.

Узел anyxml не может быть дополнен (см. параграф 7.17).

Узел anyxml отсутствует в дереве данных или содержится там в одном экземпляре.

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

Следует отметить, что в YANG версии 1 оператор anyxml был единственным оператором для моделирования неизвестной иерархии данных. Во многих случаях такие неизвестные данные реально моделировались в YANG, но конкретная модель данных YANG не была известна в момент разработки. В таких случаях рекомендуется использовать оператор anydata (параграф 7.10) вместо anyxml.

7.11.1. Субоператоры для anyxml

Субоператор

Параграф

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

config

7.21.1

0..1

description

7.21.3

0..1

if-feature

7.20.2

0..n

mandatory

7.6.5

0..1

must

7.5.3

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

when

7.21.5

0..1

7.11.2. Правила представления XML

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

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

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

Узел anyxml рассматривается, как «непрозрачный» (opaque) блок данных. Эти данные могут изменяться лишь целиком.

Любые атрибуты operation, представленные в субэлементах узла anyxml, игнорируются сервером NETCONF.

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

  • Если задана операция merge или replace, узел создается при его отсутствии, а в качестве значения устанавливается содержимое XML узла anyxml в данных XML для RPC.

  • Если задана операция create, узел создается при его отсутствии, а в качестве значения устанавливается содержимое XML узла anyxml в данных XML для RPC. В случае наличия узла возвращается ошибка data-exists.

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

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

Для оператора anyxml

     anyxml html-info;

ниже приведены два варианта корректного представления одного значения anyxml.

      <html-info>
        <p xmlns="http://www.w3.org/1999/xhtml">
          This is <em>very</em> cool.
        </p>
      </html-info>

      <html-info>
        <x:p xmlns:x="http://www.w3.org/1999/xhtml">
          This is <x:em>very</x:em> cool.
        </x:p>
      </html-info>

7.12. Оператор grouping

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

Оператор grouping не задает определения данных и по этой причине не определяет каких-либо узлов в дереве схемы.

Группировка напоминает структуры (structure) или записи (record) в традиционных языках программирования.

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

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

Группировка – это не просто механизм текстовой подстановки, она также определяет набор узлов. Идентификаторы узлов группировки преобразуются применительно к области, в которой группировка была определена, а не той, где она применяется. Отображения префиксов, имена типов и группировок, использование расширений оцениваются в иерархии, где был применен оператор grouping. Это означает, что расширения, определенные в форме прямых потомков группировки, применяются к самой группировке.

Если группировка определяет узел action или notification в своей иерархии, этот узел не может применяться в любом контексте (см. параграфы 7.15 и 7.16).

7.12.1. Субоператоры для grouping

Субоператор

Параграф

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

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

notification

7.16

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

uses

7.13

0..n

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

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

     grouping endpoint {
       description "A reusable endpoint group.";
       leaf ip {
         type inet:ip-address;
       }
       leaf port {
         type inet:port-number;
       }
     }

7.13. Оператор uses

Оператор uses применяется для ссылок на определения группировок (grouping) и принимает один аргумент, задающий имя группировки.

Эффект ссылки uses на группировку заключается в том, что определенные группировкой узлы копируются в текущее дерево схемы, а затем обновляются в соответствии с операторами refine и augment.

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

7.13.1. Субоператоры для uses

Субоператор

Параграф

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

augment

7.17

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

refine

7.13.2

0..n

status

7.21.2

0..1

when

7.21.5

0..1

7.13.2. Оператор refine

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

Строка аргумента представляет собой идентификатор узла-потомка в схеме (см. параграф 6.5).

Оператор позволяет выполнить перечисленные ниже уточнения.

  • Узел leaf или choice может получить используемое по умолчанию значение или обновить имеющееся.

  • Узел leaf-list может получить набор используемых по умолчанию значений или обновить имеющиеся (т. е. новый набор будет установлен взамен прежнего).

  • Любой узел может получить специализированную строку описания (description).

  • Любой узел может получить специализированную строку ссылки (reference).

  • Любой узел может получить другой оператор config.

  • Узел leaf, anydata, anyxml или choice может получить другой оператор mandatory.

  • Контейнер может получить оператор presence.

  • Узел leaf, leaf-list, list, container, anydata или anyxml может получить дополнительные выражения must.

  • Узел leaf-list или list может получить другие операторы min-elements или max-elements.

  • Узел leaf, leaf-list, list, container, choice, case, anydata или anyxml может получить дополнительные выражения if-feature.

  • Любой узел может получить уточненные расширения, если те поддерживают уточнение (см. параграф 7.19).

7.13.3. Правила представления XML

Каждый узел в группировке представляется, как будто он был определен здесь (inline), даже если он импортирован из другого модуля с иным пространством имен XML.

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

Для использования группировки endpoint, определенной в параграфе 7.12.2, при определении сервера HTTP в каком-то другом модуле можно задать

     import example-system {
       prefix "sys";
     }

     container http-server {
       leaf name {
         type string;
       }
       uses sys:endpoint;
     }

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

     <http-server>
       <name>extern-web</name>
       <ip>192.0.2.1</ip>
       <port>80</port>
     </http-server>

Если на сервере HTTP по умолчанию следует применять порт 80, можно добавить оператор default.

     container http-server {
       leaf name {
         type string;
       }
       uses sys:endpoint {
         refine port {
           default 80;
         }
       }
     }

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

     list server {
       key "ip port";
       leaf name {
         type string;
       }
       uses sys:endpoint;
     }

Ниже приведен пример с ошибкой.

     container http-server {
       uses sys:endpoint;
       leaf ip {          // недопустимо — идентификатор ip применяется дважды
         type string;
       }
     }

7.14. Оператор rpc

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

Оператор rpc определяет узел rpc в дереве схемы. Для узла rpc в схеме также определяются дочерние узлы input и output. Эти узлы определяются в пространстве имен модуля.

7.14.1. Субоператоры для rpc

Субоператор

Параграф

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

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

input

7.14.2

0..1

output

7.14.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

7.14.2. Оператор input

Необязательный оператор input служит для определения входных параметров операции и не имеет аргументов. Субоператоры для input определяют узлы-потомки для узла input добавляемой операции.

Если лист в дереве input имеет оператор mandatory со значением true, этот лист должен присутствовать в вызове RPC.

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

Если узел leaf-list в дереве input имеет одно или несколько принятых по умолчанию значений, сервер должен использовать эти значения в случаях, описанных в параграфе 7.7.2. В таких ситуациях сервер MUST вести себя так, будто узел leaf-list был представлен при вызове RPC с принятыми по умолчанию значениями.

Поскольку дерево input не помещается в какое-либо хранилище данных, все операторы config для узлов этого дерева игнорируются.

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

7.14.2.1. Субоператоры для input

Субоператор

Параграф

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

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

grouping

7.12

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

typedef

7.3

0..n

uses

7.13

0..n

7.14.3. Оператор output

Необязательный оператор output служит для определения выходных значений операции RPC и не имеет аргументов. Субоператоры для output определяют узлы-потомки узла output определяемой операции.

Если лист дерева имеет оператор mandatory со значением true, лист должен присутствовать в отклике RPC.

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

Если узел leaf-list в дереве output имеет одно или несколько принятых по умолчанию значений, клиент должен использовать эти значений в случаях, описанных в параграфе 7.7.2. В таких ситуациях клиент должен вести себя так, будто в выходе RPC присутствует leaf-list с принятыми по умолчанию значениями.

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

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

7.14.3.1. Субоператоры для output

Субоператор

Параграф

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

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

grouping

7.12

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

must

7.5.3

0..n

typedef

7.3

0..n

uses

7.13

0..n

7.14.4. Правила представления NETCONF XML

Узел rpc представляется как дочерний элемент XML элемента <rpc> в соответствии с группой подстановки rpcOperation [RFC6241]. Локальное имя элемента является идентификатором rpc, а его пространство имен — пространством имен XML для моуля (см. параграф 7.1.3).

Входные параметры представляются дочерними элементами XML для элемента XML узла rpc в том же порядке, как они были определены в операторе input.

Если после успешного вызова RPC не было возвращено выходных параметров, <rpc-reply> содержит только элемент <ok/>, определенный в [RFC6241]. Если выходные параметры присутствуют, они кодируются как дочерние элементы элемента <rpc-reply>, определенного в [RFC6241], с тем же порядком, который был определен в операторе output.

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

Приведенный ниже пример определяет операцию RPC.

     module example-rock {
       yang-version 1.1;
       namespace "urn:example:rock";
       prefix "rock";

       rpc rock-the-house {
         input {
           leaf zip-code {
             type string;
           }
         }
       }
     }

Соответствующие экземпляры XML для полных rpc и rpc-reply приведены ниже.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <rock-the-house xmlns="urn:example:rock">
         <zip-code>27606-0100</zip-code>
       </rock-the-house>
     </rpc>

     <rpc-reply message-id="101"
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <ok/>
     </rpc-reply>

7.15. Оператор action

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

Оператор action определяет узел action в дереве схемы. Для узла action определяются также дочерние узлы схемы с именами input и output. Эти узлы определяются в пространстве имен модуля.

Действие недопустимо определять в rpc, другом действии или уведомлении (notification), т. е. узлу action недопустимо иметь в дереве схемы родительский узел типа rpc, action или notification. Это означает, что будет ошибкой, если группировака будет включать узел action в своей иерархии, которая используется для того, чтобы определить уведомление.

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

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

Различие между action и rpc заключается в том, что операция привязанак узлу в хранилище данных, а rpc нет. При вызове операции задается узел в хранилище данных вместе с именем операции и входными параметрами.

7.15.1. Субоператоры для action

Субоператор

Параграф

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

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.2

0..n

input

7.14.2

0..1

output

7.14.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

7.15.2. Правила представления NETCONF XML

При вызове операции элемент с локальным именем action в пространстве имен urn:ietf:params:xml:ns:yang:1 (см. параграф 5.3.1) представляется в виде дочернего элемента XML для элемента <rpc>, определенного в [RFC6241], как указано группой подставновки rpcOperation в [RFC6241].

Элемент <action> содержит иерархию узлов, указывающую узел в хранилище данных. Он должен включать все контейнеры и списки на прямом пути от верхнего уровня до списка или контейнера, включающего операцию (action). Для списков все листья ключей также должны включаться. Внутренний (innermost) контейнер или список содержит элемент XML, который передает имя определенной операции. Внутри этого элемента входные параметры представляются дочерними элементами XML в том же порядке, какой был задан в операторе input.

В одном элементе <rpc> может быть вызвана только одна операция. Если в <rpc> присутствует более одной операции, сервер должен вернуть <rpc-error> с тегом <error-tag>, имеющим значение bad-element.

Если вызов операции завершился успешно и не было возвращено выходных параметров, <rpc-reply> содержит только элемент <ok/>, определенный в [RFC6241]. Если выходные параметры присутствуют, они кодируются как дочерние элементы элемента <rpc-reply>, определенного в [RFC6241], с тем же порядком, который был определен в операторе output.

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

Приведенный ниже пример определяет операцию сброса одного сервера в серверной ферме.

     module example-server-farm {
       yang-version 1.1;
       namespace "urn:example:server-farm";
       prefix "sfarm";

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

       list server {
         key name;
         leaf name {
           type string;
         }
         action reset {
           input {
             leaf reset-at {
               type yang:date-and-time;
               mandatory true;
              }
            }
            output {
              leaf reset-finished-at {
                type yang:date-and-time;
                mandatory true;
              }
            }
          }
        }
      }

Ниже представлены соответствующие экземпляры XML для полных rpc и rpc-reply.

     <rpc message-id="101"
          xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <action xmlns="urn:ietf:params:xml:ns:yang:1">
         <server xmlns="urn:example:server-farm">
           <name>apache-1</name>
           <reset>
             <reset-at>2014-07-29T13:42:00Z</reset-at>
           </reset>
         </server>
       </action>
     </rpc>

     <rpc-reply message-id="101"
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <reset-finished-at xmlns="urn:example:server-farm">
         2014-07-29T13:42:12Z
       </reset-finished-at>
     </rpc-reply>

7.16. Оператор notification

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

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

Уведомления недопустимо определять в rpc, action или другом узле notification, т. е. уведомлениям недопустимо иметь в качестве узла-предка в дереве схемы rpc, action, notification node. Например, это может возникать в случаях, когда группировка (grouping) содержащая уведомление, будет использована при определении rpc.

Уведомлениям недопустимо иметь в качестве предка узел списка (list) без оператора key.

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

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

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

Если leaf-list в дереве уведомления имеет одно или несколько принятых по умолчанию значений, клиент должен использовать эти значения в случаях, описанных в параграфе 7.7.2. В таких ситуациях клиент должен вести себя так, будто leaf-list с принятыми по умолчанию значениями присутствует в экземпляре notification.

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

7.16.1. Субоператоры для notification

Субоператор

Параграф

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

anydata

7.10

0..n

anyxml

7.11

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

grouping

7.12

0..n

if-feature

7.20.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

reference

7.21.4

0..1

status

7.21.2

0..1

typedef

7.3

0..n

uses

7.13

0..n

7.16.2. Правила представления NETCONF XML

Узел notification, определенный на верхнем уровне модуля, кодируется как дочерний элемент XML для элемента <notification>, определенного в NETCONF Event Notifications [RFC5277]. Локальное имя элемента является идентификатором уведомления, а его пространство имен является пространством имен XML для модуля (см. параграф 7.1.3).

Когда узел notification определяется как потомок узла данных, элемент <notification>, определенный в [RFC5277], содержит иерархию узлов, указывающих узел данных в хранилище. Она должна включать включать все контейнеры и списки на прямом пути от верхнего уровня до списка или контейнера, включающего уведомление (notification). Для списков все листья ключей также должны включаться. Внутренний (innermost) контейнер или список содержит элемент XML, который передает имя определенного уведомления.

Дочерние узлы уведомления кодируются как субэлементы элемента XML для узла notification в любом порядке.

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

Приведенный ниже пример определяет уведомление на верхнем уровне модуля.

     module example-event {
       yang-version 1.1;
       namespace "urn:example:event";
       prefix "ev";

       notification event {
         leaf event-class {
           type string;
         }
         leaf reporting-entity {
           type instance-identifier;
         }
         leaf severity {
           type string;
         }
       }
     }

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

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-07-08T00:01:00Z</eventTime>
       <event xmlns="urn:example:event">
         <event-class>fault</event-class>
         <reporting-entity>
           /ex:interface[ex:name='Ethernet0']
         </reporting-entity>
         <severity>major</severity>
       </event>
     </notification>

Следующий пример определяет уведомление в узле данных.

     module example-interface-module {
       yang-version 1.1;
       namespace "urn:example:interface-module";
       prefix "if";

       container interfaces {
         list interface {
           key "name";
           leaf name {
             type string;
           }
           notification interface-enabled {
             leaf by-user {
               type string;
             }
           }
         }
       }
     }

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

     <notification
       xmlns="urn:ietf:params:xml:ns:netconf:notification:1.0">
       <eventTime>2008-07-08T00:01:00Z</eventTime>
       <interfaces xmlns="urn:example:interface-module">
         <interface>
           <name>eth1</name>
           <interface-enabled>
             <by-user>fred</by-user>
           </interface-enabled>
         </interface>
       </interfaces>
     </notification>

7.17. Оператор augment

Оператор augment позволяет модулю или субмодулю добавить узлы к дереву схемы, определенному во внешнем модуле, текущем модуле и его субмодулях, или к узлам из группировки в операторе uses. Аргументом оператора служит строка, указывающая узел в дереве схемы. Этот узел называется целью добавления (augment’s target). Целевой узел должен быть узлом типа container, list, choice, case, input, output и notification. К нему добавляются узлы, указанные с субоператорах, следующих за оператором augment.

Строка дополнения является идентификатором узла схемы (см. параграф 6.5). Если оператор augment относится к верхнему уровню модуля или субмодуля, должна применяться абсолютная форма (определена правилом absolute-schema-nodeid раздела 14) идентификатора узла схемы. Если augment является субоператором для uses, должна применяться наследуемая (descendant) форма (определена правилом descendant-schema-nodeid в разделе 14).

Если целевой узел имеет тип container, list, case, input, output или notification, внутри оператора augment могут применяться субоператоры container, leaf, list, leaf-list, uses и choice.

Если целевой узел является контейнером или списком, внутри оператора augment могут применяться субоператоры action и notification.

Если целевой узел является выбором (choice), внутри оператора augment могут применяться субоператоры case в полной или сокращенной (см. параграф 7.9.2) форме.

Оператору augment недопустимо добавлять множество узлов с одним именем из одного модуля в один целевой узел.

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

В приведенном ниже примере показано корректное добавление узла interface с mandatory-leaf, поскольку дополнение зависит от поддержки some-new-iftype. Старый клиент не знает этого типа, поэтому он не будет выбирать его и, следовательно, не будет добавлять обязательный узел данных.

     module example-augment {
       yang-version 1.1;
       namespace "urn:example:augment";
       prefix mymod;

       import ietf-interfaces {
         prefix if;
       }

       identity some-new-iftype {
          base if:interface-type;
       }

       augment "/if:interfaces/if:interface" {
          when 'derived-from-or-self(if:type, "mymod:some-new-iftype")';

          leaf mandatory-leaf {
             mandatory true;
             type string;
          }
       }
     }

7.17.1. Субоператоры для augment

Субоператор

Параграф

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

action

7.15

0..n

anydata

7.10

0..n

anyxml

7.11

0..n

case

7.9.2

0..n

choice

7.9

0..n

container

7.5

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

leaf

7.6

0..n

leaf-list

7.7

0..n

list

7.8

0..n

notification

7.16

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

uses

7.13

0..n

when

7.21.5

0..1

7.17.2. Правила представления XML

Все узлы данных, определенные в операторе augment, задаются как элементы XML, определенные в пространстве имен XML модуля, где указан оператор augment.

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

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

В пространстве имен urn:example:interface-module

     container interfaces {
       list ifEntry {
         key "ifIndex";

         leaf ifIndex {
           type uint32;
         }
         leaf ifDescr {
           type string;
         }
         leaf ifType {
           type iana:IfType;
         }
         leaf ifMtu {
           type int32;
         }
       }
     }

В пространстве имен urn:example:ds0

     import example-interface-module {
       prefix "if";
     }
     augment "/if:interfaces/if:ifEntry" {
       when "if:ifType='ds0'";
       leaf ds0ChannelNumber {
         type ChannelNumber;
       }
     }

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

     <interfaces xmlns="urn:example:interface-module"
                 xmlns:ds0="urn:example:ds0">
       <ifEntry>
         <ifIndex>1</ifIndex>
         <ifDescr>Flintstone Inc Ethernet A562</ifDescr>
         <ifType>ethernetCsmacd</ifType>
         <ifMtu>1500</ifMtu>
       </ifEntry>
       <ifEntry>
         <ifIndex>2</ifIndex>
         <ifDescr>Flintstone Inc DS0</ifDescr>
         <ifType>ds0</ifType>
         <ds0:ds0ChannelNumber>1</ds0:ds0ChannelNumber>
       </ifEntry>
     </interfaces>

В другом примере предполагается наличие выбора (choice), определенного в параграфе 7.9.6. Приведенная ниже конструкция может использоваться для расширения протокольного определения

     augment /ex:system/ex:protocol/ex:name {
       case c {
         leaf smtp {
           type empty;
         }
       }
     }

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

     <ex:system>
       <ex:protocol>
         <ex:tcp/>
       </ex:protocol>
     </ex:system>

или

     <ex:system>
       <ex:protocol>
         <other:smtp/>
       </ex:protocol>
     </ex:system>

7.18. Оператор identity

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

Для определения отождествлений в модели данных может применяться встроенный типа данных identityref (см. параграф 9.10).

7.18.1. Субоператоры для identity

Субоператор

Параграф

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

base

7.18.2

0..n

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

7.18.2. Оператор base

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

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

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

Создание производных отождествлений имеет следующие свойства:

  • нерефлексивность (отождествление не выводится из самого себя);

  • транзитивность (если отождествление B является производным от A, а C – производным от B, то C является также производным от A).

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

     module example-crypto-base {
       yang-version 1.1;
       namespace "urn:example:crypto-base";
       prefix "crypto";

       identity crypto-alg {
         description
           "Base identity from which all crypto algorithms
            are derived.";
       }

       identity symmetric-key {
         description
           "Base identity used to identify symmetric-key crypto
            algorithms.";
         }

       identity public-key {
         description
           "Base identity used to identify public-key crypto
            algorithms.";
         }
     }

     module example-des {
       yang-version 1.1;
       namespace "urn:example:des";
       prefix "des";

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

       identity des {
         base "crypto:crypto-alg";
         base "crypto:symmetric-key";
         description "DES crypto algorithm.";
       }

       identity des3 {
         base "crypto:crypto-alg";
         base "crypto:symmetric-key";
         description "Triple DES crypto algorithm.";
       }
     }

7.19. Оператор extension

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

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

Расширение может применяться подобно обычным операторам YANG с именем оператора, за которым следует аргумент, если он был определен оператором extension, а также может следовать блок субоператоров. Имя оператора создается путем объединения префикса модуля, в котором было определено расширение, двоеточия (:) и ключевого слова расширения без пробелов между ними. Субоператоры расширения определяются оператором extension, с использованием механизмов, выходящих за рамки данной спецификации. Синтаксически субоператоры должны быть операторами YANG, включая расширения, определенные с использованием операторов extension. Операторы YANG в расширениях должны следовать синтаксическим правила раздела 14.

Расширение может разрешать уточнение (см. параграф 7.13.2) и отклонения (параграф 7.20.3.2), но механизм для этого выходит за рамки спецификации.

7.19.1. Субоператоры для extension

Субоператор

Параграф

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

argument

7.19.2

0..1

description

7.21.3

0..1

reference

7.21.4

0..1

status

7.21.2

0..1

7.19.2. Оператор argument

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

Имя аргумента используется в отображении YIN, где оно служит атрибутом XML или именем элемента в зависимости от субоператора yin-element в этом операторе argument.

7.19.2.1. Субоператор для argument

Субоператор

Параграф

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

yin-element

7.19.2.2

0..1

7.19.2.2. Оператор yin-element

Необязательный оператор yin-element принимает в качестве аргумента строку true или false. Этот оператор показывает отображается ли argument в элемент или атрибут XML при преобразовании в YIN (см. раздел 13).

Если оператор yin-element не задан, по умолчанию предполагается значение false.

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

Определение расширения может иметь вид

     module example-extensions {
       yang-version 1.1;
       ...

       extension c-define {
         description
           "Takes as an argument a name string.
            Makes the code generator use the given name
            in the #define.";
         argument "name";
       }
     }

Использование расширения может иметь вид

     module example-interfaces {
       yang-version 1.1;

       ...
       import example-extensions {
         prefix "myext";
       }
       ...

       container interfaces {
         ...
         myext:c-define "MY_INTERFACES";
       }
     }

7.20. Операторы, связанные с соответствием спецификации

В этом разделе определены операторы, связанные с совместимостью, как описано в параграфе 5.6.

7.20.1. Оператор feature

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

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

В приведенном ниже примере функция local-storage представляет способность сервера локально сохранять сообщения syslog на том или ином его устройстве. Эта функция используется для того, чтобы сделать лист local-storage-limit условным, в зависимости от наличия на сервере локального хранилища. Если сервер не укажет поддержку этой функции, узел local-storage-limit не будет поддерживаться.

     module example-syslog {
       yang-version 1.1;

       ...
       feature local-storage {
         description
           "This feature means that the server supports local
            storage (memory, flash, or disk) that can be used to
            store syslog messages.";
       }

       container syslog {
         leaf local-storage-limit {
           if-feature local-storage;
           type uint64;
           units "kilobyte";
           config false;
           description
             "The amount of local storage that can be
              used to hold syslog messages.";
         }
       }
     }

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

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

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

7.20.1.1. Субоператоры для feature

Субоператор

Параграф

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

description

7.21.3

0..1

if-feature

7.20.2

0..n

reference

7.21.4

0..1

status

7.21.2

0..1

7.20.2. Оператор if-feature

Оператор if-feature делает родительский оператор условным. Аргументом является логическое выражение с именами функций. В этом выражении имя функции считается истинным (true) тогда и только тогда, когда эта функция поддерживается сервером. Родительский оператор выполняется серверами в том случае, когда логическое выражение истинно (true).

Синтаксис логических выражений if-feature формально определен правилом if-feature-expr в разделе 14. Скобки служат для группировки выражений. При вычислении значения используется порядок действий – группировка (скобки), not, and, or.

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

Листу, являющемуся ключом списка, недопустимо включать операторы if-feature.

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

В этом примере контейнер target реализуется в том случае, когда функция outbound-tls или outbound-ssh поддерживается сервером.

     container target {
       if-feature "outbound-tls or outbound-ssh";
       ...
     }

Приведенные ниже примеры эквивалентены.

     if-feature "not foo or bar and baz";
     if-feature "(not foo) or (bar and baz)";

7.20.3. Оператор deviation

Оператор deviation определяет иерархию модуля, которую сервер полностью не реализует. Аргументом оператора служит строка с идентификатором узла в дереве схемы, который отклоняется от заданного модулем поведения. Этот узел называется целевым узлом отклонения. Содержимое оператора deviation указывает детали отклонения.

Строка аргумента указывает абсолютный идентификатор узла схемы (см. параграф 6.5).

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

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

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

Взамен этих вариантов YANG позволяет серверам указать не поддерживаемые части базового модуля или показать использование для их поддержки другого синтаксиса. Делается это с помощью оператора deviation.

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

7.20.3.1. Субоператоры для deviation

Субоператор

Параграф

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

description

7.21.3

0..1

deviate

7.20.3.2

1 – n

reference

7.21.4

0..1

7.20.3.2. Оператор deviate

Оператор deviate указывает отклонение реализации сервера для целевого узла от исходного определения. Аргумент оператора может принимать значение not-supported, add, replace или delete.

Значение not-supported показывает, что целевой узел не реализован на этом сервере.

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

Значение replace заменяет свойства целевого узла. Свойства для замены указываются субоператорами оператора deviate. Заменяемое свойство должно существовать у целевого узла.

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

Субоператор

Параграф

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

config

7.21.1

0..1

default

7.6.4, 7.7.4

0..n

mandatory

7.6.5

0..1

max-elements

7.7.6

0..1

min-elements

7.7.5

0..1

must

7.5.3

0..n

type

7.4

0..1

unique

7.8.3

0..n

units

7.3.3

0..1

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

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

В этом примере сервер информирует клиентское приложение о том, что он не поддерживает службу daytime в стиле RFC 867.

     module example-deviations {
       yang-version 1.1;
       namespace "urn:example:deviations";
       prefix md;

       import example-base {
         prefix base;
       }

       deviation /base:system/base:daytime {
         deviate not-supported;
       }
       ...
     }

Сервер будет анонсировать оба модуля example-base и example-deviations.

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

     deviation /base:system/base:user/base:type {
       deviate add {
         default "admin"; // new users are 'admin' by default
       }
     }

В следующем примере сервер ограничивает число серверов имен до 3.

     deviation /base:system/base:name-server {
       deviate replace {
         max-elements 3;
       }
     }

Если исходное определение имело вид

     container system {
       must "daytime or time";
       ...
     }

сервер может удалить ограничение must

     deviation /base:system {
       deviate delete {
         must "daytime or time";
       }
     }

7.21. Субоператоры общего назначения

В этом разделе описаны субоператоры, используемые несколькими другими операторами.

7.21.1. Оператор config

Оператор config принимает в качестве аргумента строку true или false. Если config имеет аргумент true, определение представляет конфигурацию. Узлы данных, представляющие конфигурацию, являются частью хранилища конфигурации.

Если config имеет аргумент false, определение представляет данные состояния. Узлы данных, представляющих состояние, не входят в хранилище конфигурации.

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

Если верхний узел на включает config, по умолчанию используется значение true.

Если для узла config имеет значение false, ни один из нижележащих узлов не может иметь config со значением true.

7.21.2. Оператор status

Оператор status принимает в качестве аргумента одно из значений current, deprecated или obsolete:

  • current означает, что определений является текущим и действует;

  • deprecated указывает устаревшее определение, которое, тем не менее, разрешено использовать для обеспечения совместимости с имеющимися старыми реализациями;

  • obsolete указывает отмененное определение, которое не следует применять в новых реализациях и/или может быть удалено.

Если оператор status не задан, по умолчанию предполагается значение current.

Определению типа current недопустимо ссылаться на определения типа deprecated или obsolete в том же модуле.

Определению типа deprecated недопустимо ссылаться на определения типа obsolete в том же модуле.

Например, приведенное ниже определение недействительно.

     typedef my-type {
       status deprecated;
       type int32;
     }

     leaf my-leaf {
       status current;
       type my-type; // не пригоден, поскольку my-type отменен
     }

7.21.3. Оператор description

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

7.21.4. Оператор reference

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

Например, typedef для типа данных uri может иметь вид

     typedef uri {
       type string;
       reference
         "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax";
       ...
     }

7.21.5. Оператор when

Оператор when делает условным родительский оператор определения данных. Узел, определенный родительским оператором, будет действительным только при выполнении условия, заданного оператором when. Аргументом оператора является выражением XPath (см. параграф 6.4), которое служит для формального задания условий. Если выражение XPath дает значение true для конкретного экземпляра, узел, определенный родительским оператором, будет действительным.

Листьям, являющимся ключами списка, недопустимо включать оператор when.

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

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

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

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

  • Если оператор when является потомком оператора uses, choice или case, узлом контекста является ближайший предок узла с оператором when, который является узлом данных. Если такого узла нет, узлом контекста будет корневой узел. Доступное дерево предварительно изменяется в процессе обработки выражения XPath путем удаления всех экземпляров (если они имеются) узлов, добавленных оператором uses, choice или case.

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

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

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

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

 


Часть 4

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

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

Or