RFC 9418
A YANG Data Model for Service Assurance
RFC 9418: A YANG Data Model for Service Assurance โจ
okay bestie, this is RFC 9418 ๐ It's a Standards Track doc from July 2023 (ISSN 2070-1721). B. Claise and J. Quilbeuf from Huawei wrote it, along with P. Lucente (NTT), P. Fasano (TIM S.p.A), and T. Arumugam (a consultant). The whole vibe is YANG data models for service assurance, aka making sure the network services people rely on are actually healthy ๐ฆ
Abstract
so this doc specifies YANG modules for representing assurance graphs ๐ง These graphs show how well a service is being assured by breaking it down into tiny assurance elements called subservices. It's giving divide-and-conquer energy ๐ The companion doc, "Service Assurance for Intent-Based Networking Architecture" (RFC 9417), is the one that lays out the architecture for actually doing this assurance.
The YANG data models in this doc conform to the Network Management Datastore Architecture (NMDA) defined in RFC 8342 ๐ธ
Status of This Memo
this is an Internet Standards Track document ๐ฅ
it's a product of the Internet Engineering Task Force (IETF) ๐ซถ It represents the consensus of the IETF community, received public review, and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more info on Internet Standards, check Section 2 of RFC 7841 ๐
for the current status of this doc, any errata, and how to give feedback, go to https://www.rfc-editor.org/info/rfc9418 ๐
Copyright Notice
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved. ๐
this doc is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the date of publication. Please read these carefully, bestie, because they spell out your rights and restrictions for this doc ๐ Code Components pulled out of this doc must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Revised BSD License โจ
Table of Contents
1. Introduction
1.1. Terminology
2. YANG Modules Overview
3. Base IETF Service Assurance YANG Module
3.1. Concepts
3.2. Tree View
3.3. YANG Module
3.4. Rejecting Circular Dependencies
4. Guidelines for Defining New Subservice Types
5. Subservice Augmentation: "ietf-service-assurance-device" YANG
Module
5.1. Tree View
5.2. Concepts
5.3. YANG Module
6. Subservice Augmentation: "ietf-service-assurance-interface"
YANG Module
6.1. Tree View
6.2. Concepts
6.3. YANG Module
7. Security Considerations
8. IANA Considerations
8.1. The IETF XML Registry
8.2. The YANG Module Names Registry
9. References
9.1. Normative References
9.2. Informative References
Appendix A. Vendor-Specific Subservice Augmentation:
"example-service-assurance-device-acme" YANG Module
A.1. Tree View
A.2. Concepts
A.3. YANG Module
Appendix B. Further Augmentations: IP Connectivity and IS-IS
Subservices
B.1. IP Connectivity Module Tree View
B.2. IS-IS Module Tree View
B.3. Global Tree View
B.4. IP Connectivity YANG Module
B.5. IS-IS YANG Module
Appendix C. Example of a YANG Instance
Appendix D. YANG Library for Service Assurance
Acknowledgements
Authors' Addresses
1. Introduction โจ
okay so [RFC9417] describes an architecture plus a bunch of components for service assurance, called Service Assurance for Intent-based Networking (SAIN) ๐ง This doc is the perfect sidekick to that architecture because it specifies a data model for the interfaces between the components. Specifically, it gives you YANG modules for service assurance that are:
- machine readable ๐ค
- vendor independent ๐
- augmentable, so SAIN agents from Figure 1 of [RFC9417] can support and expose new subservices to SAIN orchestrators and collectors ๐
1.1. Terminology
okay, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this doc are interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here ๐ Lowercase versions are just regular words, bestie ๐
the terms used in this doc are defined in [RFC9417] ๐
the meanings of the symbols in the tree diagrams are defined in [RFC8340] ๐ฆ
2. YANG Modules Overview
the main YANG module, "ietf-service-assurance" (Section 3), defines objects for assuring network services based on how they decompose into so-called subservices ๐ธ The subservices are organized hierarchically by their dependencies, and together with those dependencies they form an assurance graph. This module should be supported by an agent that can interact with devices so it can produce the health statuses and symptoms for each subservice in an assurance graph. The module is meant for these use cases:
- Assurance graph configuration:
- Subservices: Configure a set of subservices to assure by specifying their types and parameters.
- Dependencies: Configure the dependencies between the subservices, along with their types.
- Assurance telemetry: Export the assurance graph with health statuses and symptoms for each node ๐
it's also meant to be exported by the SAIN collector that aggregates the output of several SAIN agents to build the global assurance graph ๐ In that case, only the telemetry export use case is considered.
the modules in this doc conform to the Network Management Datastore Architecture (NMDA) defined in [RFC8342] ๐
the second YANG module, "ietf-service-assurance-device" (Section 5), augments the "ietf-service-assurance" module by adding support for the device subservice. Additional subservice types might be added following a similar approach ๐ง
the third YANG module, "ietf-service-assurance-interface" (Section 6), also augments the "ietf-service-assurance" module, this time by adding support for the interface subservice ๐
there are more examples in the appendix ๐ซถ The module "example-service-assurance-device-acme" (Appendix A) augments the "ietf-service-assurance-device" module to customize it for devices of the fictional Acme Corporation ๐ Additional vendor-specific parameters might be added following a similar approach. We also provide the modules "example-service-assurance-ip-connectivity" and "example-service-assurance-is-is" (Appendix B) to model the example in Figure 2 from Section 3.1 of [RFC9417] โจ
3. Base IETF Service Assurance YANG Module
3.1. Concepts
okay so the "ietf-service-assurance" YANG module assumes a set of subservices that get assured independently ๐ A subservice is a feature or a subpart of the network system that a given service instance depends on. Examples of subservice types include the following:
- device: Whether a device is healthy, and if not, what are the symptoms? This kind of subservice might monitor device resources like CPU, RAM, or Ternary Content-Addressable Memory (TCAM) ๐ป Potential symptoms are "CPU overloaded", "Out of RAM", or "Out of TCAM" ๐ฅ
- ip-connectivity: Given two IP addresses bound to two devices, what is the quality of the IP connectivity between them? ๐ Potential symptoms are "No route available" or "Equal-Cost Multipaths (ECMPs) imbalance" ๐
an instance of the device subservice represents a subpart of the network system, namely one specific device ๐ฅ๏ธ An instance of the ip-connectivity subservice represents a feature of the network, namely the connectivity between two specific IP addresses on two devices ๐ฆ In both cases, these subservices might depend on other subservices. For instance, the connectivity might depend on a subservice representing the routing system and on a subservice representing ECMPs ๐ง
the two example subservices above need different sets of parameters to fully characterize one of their instances. An instance of the device subservice is fully characterized by a single parameter that identifies the device to monitor ๐ For the ip-connectivity subservice, at least the device and IP address for both ends of the link are needed to fully characterize an instance ๐
the base model in this section specifies a single type of subservice, which represents service instances. These nodes play a particular role in the assurance graph because they're the starting point, or root, for the assurance graph of the corresponding service instance ๐ The parameters required to fully identify a service instance are the name of the service and the name of the service instance. To support other types of subservices, like device or ip-connectivity, the "ietf-service-assurance" module is intended to be augmented ๐ธ
the dependencies are modeled as a list, meaning each subservice contains a list of references to its dependencies. That list can be empty if the subservice instance doesn't have any dependencies ๐
by specifying service instances and their dependencies in terms of subservices, you define a global assurance graph ๐ That graph is the result of merging all the individual assurance graphs for the assured service instances. Each subservice instance is expected to appear only once in the global assurance graph, even if several service instances depend on it ๐ซถ For example, an instance of the device subservice is a dependency of every service instance that relies on the corresponding device. The assurance graph of a specific service instance is the subgraph you get by traversing the global assurance graph through the dependencies, starting from that service instance โจ
an assurance agent configured with such a graph is expected to produce, for each configured subservice, a health status that shows how healthy the subservice is ๐ If the subservice isn't healthy, the agent is expected to produce a list of symptoms explaining why ๐ญ
3.2. Tree View ๐ณโจ
Okay so bestie, this section is the tree view, and it's giving a whole map of the "ietf-service-assurance" module ๐บ๏ธ๐ . The tree diagram comes from [RFC8340], and honestly it's the cutest way to see how everything nests together ๐ฆ.
module: ietf-service-assurance
+--ro assurance-graph-last-change yang:date-and-time
+--rw subservices
| +--rw subservice* [type id]
| +--rw type identityref
| +--rw id string
| +--ro last-change? yang:date-and-time
| +--ro label? string
| +--rw under-maintenance!
| | +--rw contact string
| +--rw (parameter)
| | +--:(service-instance-parameter)
| | +--rw service-instance-parameter
| | +--rw service string
| | +--rw instance-name string
| +--ro health-score int8
| +--ro symptoms-history-start? yang:date-and-time
| +--ro symptoms
| | +--ro symptom* [start-date-time agent-id symptom-id]
| | +--ro symptom-id leafref
| | +--ro agent-id -> /agents/agent/id
| | +--ro health-score-weight? uint8
| | +--ro start-date-time yang:date-and-time
| | +--ro stop-date-time? yang:date-and-time
| +--rw dependencies
| +--rw dependency* [type id]
| +--rw type
| | -> /subservices/subservice/type
| +--rw id leafref
| +--rw dependency-type? identityref
+--ro agents
| +--ro agent* [id]
| +--ro id string
| +--ro symptoms* [id]
| +--ro id string
| +--ro description string
+--ro assured-services
+--ro assured-service* [service]
+--ro service leafref
+--ro instances* [name]
+--ro name leafref
+--ro subservices* [type id]
+--ro type -> /subservices/subservice/type
+--ro id leafref
So the assurance-graph-last-change leaf is read only, and it's the timestamp that tells you when the graph structure last got a glow-up ๐. It MUST be updated every time the graph structure changes, whether that's adding or deleting subservices and dependencies, or tweaking their configurable attributes (including maintenance statuses) ๐ง. Those count as structural changes to the graph, periodt ๐
. Clients love this one because they can check it quickly to see if they need to refresh their copy of the graph structure ๐ง. Now here's the tea: changes to the health score or symptoms do NOT change the graph's structure, so they have zero effect on this date ๐.
The subservices list holds every subservice instance the server currently knows about (so, a SAIN agent or SAIN collector) ๐. Every subservice declaration MUST provide these two things:
- a subservice type (
type): a reference to an identity that inherits fromsubservice-base, which is the base identity for every subservice type ๐ - an id (
id): a string that uniquely identifies the subservice among ones with the same type ๐ซถ
Together, the type and id uniquely identify a given subservice, so that's your couple goals right there ๐.
The last-change leaf says when the dependencies or maintenance status of that particular subservice were last modified ๐ฐ๏ธ. The label is just a human-readable description of the subservice ๐ธ.
Okay so the under-maintenance container is a big deal ๐ง. When it's present, it stops symptoms from being emitted for that subservice AND for any subservices that depend on it ๐. In that case, a contact MUST be provided to say who or which software is responsible for the maintenance ๐. For a deeper dive, check out Section 3.6 of [RFC9417] ๐.
The parameter choice is meant to be augmented so you can describe parameters specific to whatever subservice type you're working with ๐งฉ. This base module only defines the subservice type for service instances. Service instances MUST be modeled as a particular type of subservice with two parameters: service and instance-name ๐ฏ. The service parameter is the name of the service defined in the network orchestrator, like point-to-point-l2vpn โจ. The instance-name parameter is the name given to the particular instance being assured, like the name of the customer using that instance ๐โโ๏ธ.
The health-score holds a value that's normally between 0 and 100, showing how healthy the subservice is ๐ฏ. As mentioned in the health score definition, the special value -1 can be used to say that no value could be computed, for example if some metric needed for the calculation couldn't be collected ๐.
The symptoms-history-start is the cutoff date for reporting symptoms ๐
. Symptoms that ended before that date are not reported anymore in the model ๐๏ธ.
Each subservice's status contains a list of symptoms, and each symptom is specified by:
- a
symptom-id, which identifies the symptom locally to an agent ๐ - an
agent-id, which identifies the agent raising the symptom ๐ค - a
health-score-weight, which specifies the impact on the health score caused by this symptom ๐ - a
start-date-time, indicating when the symptom became active, and ๐ - a
stop-date-time, indicating when the symptom stopped being active (this field is not present if the symptom is still active) ๐
So for the pair of agent-id and symptom-id to uniquely identify a symptom, two things are necessary:
agent-idMUST be unique among all agents of the system. ๐symptom-idMUST be unique among all symptoms raised by the agent. ๐
Quick heads up: agent-id and symptom-id are leafrefs that point to objects defined later in the document ๐. The combo of symptom-id and agent-id is enough to be a unique key list, but the start-date-time second key is extra helpful for sorting and retrieving the relevant symptoms ๐๏ธโจ.
The dependency list contains the dependencies for the current subservice ๐. Each one is specified by a leafref to both the type and id of the target dependency, and each dependency has a type given in the dependency-type field ๐ซ. The model specifies two types:
- Impacting: such a dependency indicates an impact on the health of the dependent ๐ฅ.
- Informational: such a dependency might explain why the dependent has issues, but it does not impact its health ๐ก.
Let's make this concrete, because it's the best way to get it ๐ง . Picture the interface subservice representing a network interface. If the device that the interface belongs to goes down, the network interface will transition to a "down" state too ๐. So the dependency of the interface subservice on the device subservice is "impacting" ๐ฅ. On the other hand, a dependency on the ecmp-load subservice (which checks that the load between ECMPs stays stable over time) is only "informational" ๐. Services can be perfectly healthy even when the load distribution between ECMPs changes, but that instability can still be a really useful symptom for figuring out the root cause of a problem ๐ต๏ธโโ๏ธ๐.
Within the agents container, the agent list contains the symptoms per agent ๐ค. The key of that list is the id, which MUST be unique among agents of a given assurance system ๐. For each agent, the symptoms-description list maps an id to its description ๐. The id MUST be unique among the symptoms raised by that agent ๐ฏ.
Within the assured-services container, the assured-service list contains the subservices indexed by assured service instances ๐๏ธ. For each service type identified by the service leaf, all instances of that service are listed in the instances list ๐. For each instance identified by the name leaf, the subservices list contains all descendant subservices that are part of the assurance graph for that specific instance ๐ณ. These nested lists are a query optimization, so you can grab all the subservices in that assurance graph in one query, instead of recursively querying the dependencies of each subservice starting from the node that represents the service instance ๐๐
.
The relation between the health score (health-score) and the health-score-weight of the currently active symptoms is not explicitly defined in this document ๐คทโโ๏ธ. The only requirement is that a health score strictly smaller than 100 (the maximal value) must be explained by at least one symptom ๐งพ. One way to enforce that is to first detect symptoms, then compute the health score from the health-score-weight of those detected symptoms ๐. For example, the computation could sum the health-score-weight of the active symptoms, subtract that value from 100, and change the result to 0 if it comes out negative ๐งฎ. The relation between health score and health-score-weight is left up to the implementor (of an agent [RFC9417]) ๐ ๏ธ.
Keeping the history of the graph structure is out of scope for this YANG module ๐. Only the current version of the assurance graph can be fetched ๐ฅ. If you want to keep the history of the graph structure, you MUST use some time-series database (TSDB) or similar storage ๐๏ธ๐.
Heads up: that last sentence is a MUST, so a TSDB or similar storage is required if you want history. Don't skip it ๐ โโ๏ธ.
3.3. YANG Module ๐๐
This model contains references to [RFC6991] ๐.
<CODE BEGINS> file "ietf-service-assurance@2023-07-11.yang"
module ietf-service-assurance {
yang-version 1.1;
namespace "urn:ietf:params:xml:ns:yang:ietf-service-assurance";
prefix sain;
import ietf-yang-types {
prefix yang;
reference
"RFC 6991: Common YANG Data Types";
}
organization
"IETF OPSAWG Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/opsawg/>
WG List: <mailto:opsawg@ietf.org>
Author: Benoit Claise <mailto:benoit.claise@huawei.com>
Author: Jean Quilbeuf <mailto:jean.quilbeu@huawei.com>";
description
"This module defines objects for assuring services based on their
decomposition into so-called subservices, according to the
Service Assurance for Intent-based Networking (SAIN)
architecture.
The subservices hierarchically organized by dependencies
constitute an assurance graph. This module should be supported
by an assurance agent that is able to interact with the devices
in order to produce the health status and symptoms for each
subservice in the assurance graph.
This module is intended for the following use cases:
* Assurance graph configuration:
- Subservices: Configure a set of subservices to assure by
specifying their types and parameters.
- Dependencies: Configure the dependencies between the
subservices, along with their type.
* Assurance telemetry: Export the health statuses of the
subservices, along with the observed symptoms.
Copyright (c) 2023 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Revised BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(https://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 9418; see the
RFC itself for full legal notices. ";
revision 2023-07-11 { description "Initial version."; reference "RFC 9418: YANG Modules for Service Assurance"; }
identity subservice-base { description "Base identity for subservice types."; }
identity service-instance-type { base subservice-base; description "Specific type of subservice that represents a service instance. Instance of this type will depend on other subservices to build the top of the assurance graph."; }
identity dependency-type { description "Base identity for representing dependency types."; }
identity informational { base dependency-type; description "Indicates that symptoms of the dependency might be of interest for the dependent, but the status of the dependency should not have any impact on the dependent."; }
identity impacting { base dependency-type; description "Indicates that the status of the dependency directly impacts the status of the dependent."; }
grouping subservice-reference { description "Reference to a specific subservice identified by its type and identifier. This grouping is only for internal use in this module."; leaf type { type leafref { path "/subservices/subservice/type"; } description "The type of the subservice to refer to (e.g., device)."; } leaf id { type leafref { path "/subservices/subservice[type=current()/../type]/id"; } description "The identifier of the subservice to refer to."; } }
grouping subservice-dependency { description "Represents a dependency to another subservice. This grouping is only for internal use in this module"; uses subservice-reference; leaf dependency-type { type identityref { base dependency-type; } description "Represents the type of dependency (e.g., informational or impacting)."; } }
leaf assurance-graph-last-change { type yang:date-and-time; config false; mandatory true; description "Time and date at which the assurance graph last changed after any structural changes (dependencies and/or maintenance windows parameters) are applied to the subservice(s). The time and date must be the same or more recent than the most recent value of any changed subservices last-change time and date."; } container subservices { description "Root container for the subservices."; list subservice { key "type id"; description "List of configured subservices."; leaf type { type identityref { base subservice-base; } description "Type of the subservice identifying the type of the part or functionality that is being assured by this list entry, for instance, interface, device, or ip-connectivity."; } leaf id { type string; description "Identifier of the subservice instance. Must be unique among subservices of the same type."; } leaf last-change { type yang:date-and-time; config false; description "Date and time at which the structure for this subservice instance last changed, i.e., dependencies and/or maintenance windows parameters."; } leaf label { type string; config false; description "Label of the subservice, i.e., text describing what the subservice is to be displayed on a human interface.
It is not intended for random end users but for network/system/software engineers that are able to interpret it. Therefore, no mechanism for language tagging is needed."; } container under-maintenance { presence "true"; description "The presence of this container indicates that the current subservice is under maintenance."; leaf contact { type string; mandatory true; description "A string used to model an administratively assigned name of the resource that is performing maintenance.
It is suggested that this freeform field, which could be a URI, contains one or more of the following: IP address, management station name, network manager's name, location, and/or phone number. It might even contain the expected maintenance time.
In some cases, the agent itself will be the owner of an entry. In these cases, this string shall be set to a string starting with 'monitor'."; } } choice parameter { mandatory true; description "Specify the required parameters per subservice type. Each module augmenting this module with a new subservice type that is a new identity based on subservice-base should augment this choice as well by adding a container available only if the current subservice type is the newly added identity."; container service-instance-parameter { when "derived-from-or-self(../type, 'sain:service-instance-type')"; description "Specify the parameters of a service instance."; leaf service { type string; mandatory true; description "Name of the service."; } leaf instance-name { type string; mandatory true; description "Name of the instance for that service."; } } // Other modules can augment their own cases into here. } leaf health-score { type int8 { range "-1 .. 100"; } config false; mandatory true; description "Score value of the subservice health. A value of 100 means that the subservice is healthy. A value of 0 means that the subservice is broken. A value between 0 and 100 means that the subservice is degraded. The special value -1 means that the health score could not be computed."; } leaf symptoms-history-start { type yang:date-and-time; config false; description "Date and time at which the symptom's history starts for this subservice instance, either because the subservice instance started at that date and time or because the symptoms before that were removed due to a garbage collection process."; } container symptoms { config false; description "Symptoms for the subservice."; list symptom { key "start-date-time agent-id symptom-id"; unique "agent-id symptom-id"; description "List of symptoms of the subservice. While the start-date-time key is not necessary per se, this would get the entries sorted by start-date-time for easy consumption."; leaf symptom-id { type leafref { path "/agents/agent[id=current()/../agent-id]"
- "/symptoms/id"; } description "Identifier of the symptom to be interpreted according to the agent identified by the agent-id."; } leaf agent-id { type leafref { path "/agents/agent/id"; } description "Identifier of the agent raising the current symptom."; } leaf health-score-weight { type uint8 { range "0 .. 100"; } description "The weight to the health score incurred by this symptom. The higher the value, the more of an impact this symptom has. If a subservice health score is not 100, there must be at least one symptom with a health-score-weight larger than 0."; } leaf start-date-time { type yang:date-and-time; description "Date and time at which the symptom was detected."; } leaf stop-date-time { type yang:date-and-time; description "Date and time at which the symptom stopped being detected. Must be after the start-date-time. If the symptom is ongoing, this field should not be populated."; } } } container dependencies { description "Indicates the set of dependencies of the current subservice, along with their types."; list dependency { key "type id"; description "List of dependencies of the subservice."; uses subservice-dependency; } } } } container agents { config false; description "Container for the list of agents' symptoms."; list agent { key "id"; description "Contains symptoms of each agent involved in computing the health status of the current graph. This list acts as a glossary for understanding the symptom ids returned by each agent."; leaf id { type string; description "Id of the agent for which we are defining the symptoms. This identifier must be unique among all agents."; } list symptoms { key "id"; description "List of symptoms raised by the current agent that is identified by the symptom-id."; leaf id { type string; description "Id of the symptom for the current agent. The agent must guarantee the unicity of this identifier."; } leaf description { type string; mandatory true; description "Description of the symptom, i.e., text describing what the symptom is, is to be computer consumable and displayed on a human interface.
It is not intended for random end users but for
network/system/software engineers that are able to
interpret it. Therefore, no mechanism for language
tagging is needed.";
}
}
}
}
container assured-services {
config false;
description
"Container for the index of assured services.";
list assured-service {
key "service";
description
"Service instances that are currently part of the assurance
graph. The list must contain an entry for every service
that is currently present in the assurance graph. This list
presents an alternate access to the graph stored in
subservices that optimizes querying the assurance graph of
a specific service instance.";
leaf service {
type leafref {
path "/subservices/subservice/service-instance-parameter/"
+ "service";
}
description
"Name of the service.";
}
list instances {
key "name";
description
"Instances of the service. The list must contain
an entry for every instance of the parent service.";
leaf name {
type leafref {
path "/subservices/subservice/service-instance-parameter"
+ "/instance-name";
}
description
"Name of the service instance. The leafref must point to
a service-instance-parameter whose service leaf matches
the parent service.";
}
list subservices {
key "type id";
description
"Subservices that appear in the assurance graph of the
current service instance.
The list must contain the subservice corresponding to
the service instance, i.e., the subservice that
matches the service and instance-name keys.
For every subservice in the list, all subservices listed
as dependencies must also appear in the list.";
uses subservice-reference;
}
}
}
}
}
<CODE ENDS>
3.4. Rejecting Circular Dependencies
okay so this bit is all about circles ๐ and the kind we definitely do not want bestie ๐ The statuses of services and subservices are worked out from the statuses of their dependencies, so if things depend on each other in a loop, the statuses just can't get computed (it's giving infinite scroll with no bottom ๐). Section 3.1.1 of the SAIN architecture document [RFC9417] talks about how these dependencies sneak in and how they could be removed โจ Avoiding them is basically the job of the SAIN orchestrator. Still, this section spells out what a server running the "ietf-service-assurance" module should do when it gets a data instance that has circular dependencies in it.
Trying to enforce "no circles" as a YANG constraint means you'd end up writing a graph traversal algorithm in XPath and checking that the current node can't be reached from its own dependencies ๐ง Even with that constraint, merging two graphs that each have no dependency loops doesn't guarantee the merged graph is loop-free. Section 3.1.1 of [RFC9417] actually has an example where exactly that happens, and the merge creates a loop ๐ญ
So, a server implementing the "ietf-service-assurance" module MUST check that there is no dependency loop whenever the graph is modified. And a modification that creates a dependency loop MUST be rejected ๐ซ no exceptions, bestie.
4. Guidelines for Defining New Subservice Types โจ
The base YANG module defined in Section 3.3 only defines a single type of subservice that represents service instances. As explained above, this model is meant to be augmented so that a variety of subservices can be used in the assurance graph. In this section, we propose some guidelines for specifying such extensions at IETF ๐
The mechanism to add a new subservice type is to define a new module for that subservice. The module name should start with ietf-service-assurance-. The namespace of the module should start with urn:ietf:params:xml:ns:yang:ietf-service-assurance-. The prefix of the module should start with sain-. For instance, the subservice type representing the assurance of a device should have:
- the name
ietf-service-assurance-device, - the namespace
urn:ietf:params:xml:ns:yang:ietf-service-assurance-device, and - the prefix
sain-device.
The new module should define:
- a new identity to represent the new type and
- the parameters fully specifying an instance of the new subservice type.
The new identity should be based on the subservice-base identity. The name of the identity should end with -type, for instance, device-type ๐ฆ
The parameters should be defined in a container named parameters that augments the choice /subservices/subservice/parameter from the main module. The augmentation should be restricted to cases where the type of the subservice matches the identity representing the new service type.
We define two subservice types in the next sections: the "device" subservice type is defined in Section 5 and the "interface" subservice type is defined in Section 6. These subservices can be taken as examples of the rules defined in this section ๐
Vendors can specify their own subservice types by defining the corresponding modules in their own namespace. An example of such a vendor-specific module is specified in Appendix A. Vendors can also augment existing IETF-specified subservices to add their own vendor-specific information ๐
5. Subservice Augmentation: "ietf-service-assurance-device" YANG Module
5.1. Tree View
The following tree diagram [RFC8340] gives you the overview of the "ietf-service-assurance-device" module ๐ธ
module: ietf-service-assurance-device
augment /sain:subservices/sain:subservice/sain:parameter:
+--rw parameters
+--rw device string
A complete tree view of the base module with all augmenting modules presented in this document is available in Appendix B.3.
5.2. Concepts
As the number of subservices grows over time, the YANG module is designed to be extensible. A new subservice type requires precise specifications of its type and expected parameters. Let's illustrate this with the new device subservice type. As the name implies, it monitors and reports the device health, along with some symptoms in case of degradation ๐ฉบ
For our device subservice definition, the new identity "device-type" is specified as an inheritance from the base identity for subservices. This indicates to the assurance agent that we are now assuring the health of a device. Iconic behaviour, honestly ๐
The typical parameter for the configuration of the device subservice is the name of the device that we want to assure. By augmenting the parameter choice from the "ietf-service-assurance" YANG module for the case of the "device-type" subservice type, this new parameter is specified ๐
5.3. YANG Module
<CODE BEGINS> file "ietf-service-assurance-device@2023-07-11.yang"
module ietf-service-assurance-device {
yang-version 1.1;
namespace
"urn:ietf:params:xml:ns:yang:ietf-service-assurance-device";
prefix sain-device;
import ietf-service-assurance {
prefix sain;
reference
"RFC 9418: YANG Modules for Service Assurance";
}
organization
"IETF OPSAWG Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/opsawg/>
WG List: <mailto:opsawg@ietf.org>
Author: Benoit Claise <mailto:benoit.claise@huawei.com>
Author: Jean Quilbeuf <mailto:jean.quilbeuf@huawei.com>";
description
"This module augments the ietf-service-assurance module with
support of the device subservice.
Copyright (c) 2023 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Revised BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(https://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 9418; see the
RFC itself for full legal notices. ";
revision 2023-07-11 {
description
"Initial revision.";
reference
"RFC 9418: YANG Modules for Service Assurance";
}
identity device-type {
base sain:subservice-base;
description
"Identity of device subservice.";
}
augment "/sain:subservices/sain:subservice/sain:parameter" {
when "derived-from-or-self(sain:type, 'device-type')";
description
"Augments the parameter choice from the ietf-service-assurance
module with a case specific to the device subservice.";
container parameters {
description
"Parameters for the device subservice type.";
leaf device {
type string;
mandatory true;
description
"Identifier of the device to monitor. The
identifier (e.g., device id, hostname, or management IP)
depends on the context.";
}
}
}
}
<CODE ENDS>
6. Subservice Augmentation: "ietf-service-assurance-interface" YANG Module
6.1. Tree View
The following tree diagram [RFC8340] gives you the overview of the "ietf-service-assurance-interface" data model ๐ฆ
module: ietf-service-assurance-interface
augment /sain:subservices/sain:subservice/sain:parameter:
+--rw parameters
+--rw device string
+--rw interface string
A complete tree view of the base module with all augmenting modules presented in this document is available in Appendix B.3.
6.2. Concepts
For the interface subservice definition, the new interface-type is specified as an inheritance from the base identity for subservices. This indicates to the assurance agent that we are now assuring the health of an interface ๐ง
The parameters for the configuration of the interface subservice are the name of the device and, on that specific device, a specific interface. These parameters are aligned with the ietf-interfaces model described in [RFC8343], where the name of the interface is the only key needed to identify an interface on a given device. By augmenting the parameter choice from the "ietf-service-assurance" YANG module for the case of the interface-type subservice type, those two new parameters are specified ๐ซถ
6.3. YANG Module โจ
okay bestie, here's the whole module, every single line, so nothing gets lost ๐
<CODE BEGINS> file "ietf-service-assurance-interface@2023-07-11.yang"
module ietf-service-assurance-interface {
yang-version 1.1;
namespace
"urn:ietf:params:xml:ns:yang:ietf-service-assurance-interface";
prefix sain-interface;
import ietf-service-assurance {
prefix sain;
reference
"RFC 9418: YANG Modules for Service Assurance";
}
organization
"IETF OPSAWG Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/opsawg/>
WG List: <mailto:opsawg@ietf.org>
Author: Benoit Claise <mailto:benoit.claise@huawei.com>
Author: Jean Quilbeuf <mailto:jean.quilbeuf@huawei.com>";
description
"This module extends the ietf-service-assurance module to add
support for the interface subservice.
It checks whether an interface is healthy.
Copyright (c) 2023 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Revised BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(https://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 9418; see the
RFC itself for full legal notices. ";
revision 2023-07-11 {
description
"Initial revision.";
reference
"RFC 9418: YANG Modules for Service Assurance";
}
identity interface-type {
base sain:subservice-base;
description
"Checks whether an interface is healthy.";
}
augment "/sain:subservices/sain:subservice/sain:parameter" {
when "derived-from-or-self(sain:type, 'interface-type')";
description
"Augments the parameter choice from ietf-service-assurance
module with a case specific to the interface subservice.";
container parameters {
description
"Parameters for the interface subservice type.";
leaf device {
type string;
mandatory true;
description
"Device supporting the interface.";
}
leaf interface {
type string;
mandatory true;
description
"Name of the interface.";
}
}
}
}
<CODE ENDS>
7. Security Considerations ๐
okay this section is serious, so we're not skipping it ๐ The YANG modules in this document define schema for data that's meant to be reached over network management protocols like NETCONF [RFC6241] or RESTCONF [RFC8040]. The bottom layer of NETCONF is the secure transport layer, and its mandatory-to-implement secure transport is Secure Shell (SSH) [RFC6242]. The bottom layer of RESTCONF is HTTPS, and its mandatory-to-implement secure transport is TLS [RFC8446] ๐
The Network Configuration Access Control Model (NACM) [RFC8341] is how you restrict access for particular NETCONF or RESTCONF users. It lets you limit them to a preconfigured subset of all the available NETCONF or RESTCONF protocol operations and content, which is giving gatekeeper energy ๐ง
There are a bunch of data nodes in these modules that you can write, create, and delete (that's config true, which is the default). These nodes may be considered sensitive or vulnerable in some network environments. Write operations (for example, edit-config) to these nodes without proper protection can have a negative effect on network operations. Here are the subtrees and data nodes, plus why they're sensitive:
/subservices/subservice: By modifying this subtree, someone can change the structure of the assurance graph, and that can change the status of the services the assurance framework reports. If they make the system report a service as broken when it's actually healthy (a false positive), engineers or automation software lose time and might even cause real issues by making unnecessary changes to the network. If they stop the assurance system from reporting actual issues (a false negative), failures that could have been avoided go unnoticed. Depending on the service, those avoidable failures could mean Service-Level Agreement (SLA) violation fees or disruption of emergency calls ๐ฑ
Some readable data nodes in these modules may also be considered sensitive or vulnerable in some network environments, so it's important to control read access to them (for example, via get, get-config, or notification). Here are those subtrees and data nodes:
/subservices/subservice/agents/agent/assured-services/assured-service
Each of these subtrees holds information about services, subservices, or possible symptoms raised by the agents. That information might reveal details about the underlying network, as well as the services deployed for customers. For instance, a customer might be given access to monitor their own service status (for example, via model-driven telemetry). In that case, customer access should be restricted to the nodes representing their services, so it doesn't reveal the underlying network structure or other customers' services ๐ซฃ
8. IANA Considerations ๐ธ
8.1. The IETF XML Registry ๐งพ
IANA has registered the following three URIs in the "IETF XML Registry" [RFC3688]:
URI: urn:ietf:params:xml:ns:yang:ietf-service-assurance
Registrant Contact: The OPSAWG WG of the IETF.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:ietf-service-assurance-device
Registrant Contact: The OPSAWG WG of the IETF.
XML: N/A; the requested URI is an XML namespace.
URI: urn:ietf:params:xml:ns:yang:ietf-service-assurance-interface
Registrant Contact: The OPSAWG WG of the IETF.
XML: N/A; the requested URI is an XML namespace.
8.2. The YANG Module Names Registry ๐
IANA has registered the following three YANG modules in the "YANG Module Names" registry [RFC7950]:
name: ietf-service-assurance
namespace: urn:ietf:params:xml:ns:yang:ietf-service-assurance
prefix: sain
reference: RFC 9418
name: ietf-service-assurance-device
namespace: urn:ietf:params:xml:ns:yang:ietf-service-assurance-device
prefix: sain-device
reference: RFC 9418
name: ietf-service-assurance-interface
namespace: urn:ietf:params:xml:ns:yang:ietf-service-assurance-
interface
prefix: sain-interface
reference: RFC 9418
These modules are not maintained by IANA.
9. References ๐
9.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC3688] Mealling, M., "The IETF XML Registry", BCP 81, RFC 3688,
DOI 10.17487/RFC3688, January 2004,
<https://www.rfc-editor.org/info/rfc3688>.
[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed.,
and A. Bierman, Ed., "Network Configuration Protocol
(NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011,
<https://www.rfc-editor.org/info/rfc6241>.
[RFC6242] Wasserman, M., "Using the NETCONF Protocol over Secure
Shell (SSH)", RFC 6242, DOI 10.17487/RFC6242, June 2011,
<https://www.rfc-editor.org/info/rfc6242>.
[RFC6991] Schoenwaelder, J., Ed., "Common YANG Data Types",
RFC 6991, DOI 10.17487/RFC6991, July 2013,
<https://www.rfc-editor.org/info/rfc6991>.
[RFC7950] Bjorklund, M., Ed., "The YANG 1.1 Data Modeling Language",
RFC 7950, DOI 10.17487/RFC7950, August 2016,
<https://www.rfc-editor.org/info/rfc7950>.
[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, "RESTCONF
Protocol", RFC 8040, DOI 10.17487/RFC8040, January 2017,
<https://www.rfc-editor.org/info/rfc8040>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8341] Bierman, A. and M. Bjorklund, "Network Configuration
Access Control Model", STD 91, RFC 8341,
DOI 10.17487/RFC8341, March 2018,
<https://www.rfc-editor.org/info/rfc8341>.
[RFC8342] Bjorklund, M., Schoenwaelder, J., Shafer, P., Watsen, K.,
and R. Wilton, "Network Management Datastore Architecture
(NMDA)", RFC 8342, DOI 10.17487/RFC8342, March 2018,
<https://www.rfc-editor.org/info/rfc8342>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/info/rfc8446>.
[RFC9417] Claise, B., Quilbeuf, J., Lopez, D., Voyer, D., and T.
Arumugam, "Service Assurance for Intent-Based Networking
Architecture", RFC 9417, DOI 10.17487/RFC9417, July 2023,
<https://www.rfc-editor.org/info/rfc9417>.
9.2. Informative References
[RFC8340] Bjorklund, M. and L. Berger, Ed., "YANG Tree Diagrams",
BCP 215, RFC 8340, DOI 10.17487/RFC8340, March 2018,
<https://www.rfc-editor.org/info/rfc8340>.
[RFC8343] Bjorklund, M., "A YANG Data Model for Interface
Management", RFC 8343, DOI 10.17487/RFC8343, March 2018,
<https://www.rfc-editor.org/info/rfc8343>.
[RFC8525] Bierman, A., Bjorklund, M., Schoenwaelder, J., Watsen, K.,
and R. Wilton, "YANG Library", RFC 8525,
DOI 10.17487/RFC8525, March 2019,
<https://www.rfc-editor.org/info/rfc8525>.
Appendix A. Vendor-Specific Subservice Augmentation: "example-service-assurance-device-acme" YANG Module ๐งช
A.1. Tree View ๐ณ
The following tree diagram [RFC8340] gives you an overview of the "example-service-assurance-device-acme" module:
module: example-service-assurance-device-acme
augment /sain:subservices/sain:subservice/sain:parameter:
+--rw parameters
+--rw device string
+--rw acme-specific-parameter string
A complete tree view of the base module with all augmenting modules presented in this document is available in Appendix B.3.
A.2. Concepts ๐ก
sometimes you just need a vendor-specific subservice type, and that's totally valid ๐ This section shows how to augment the "ietf-service-assurance-device" module to add custom support for the device subservice, specific to the Acme Corporation. The specific version adds a new parameter called "acme-specific-parameter". Now, you have a choice here: you can either derive a new specific identity from the "subservice-base" identity defined in the "ietf-service-assurance" module, or augment the parameters from the "ietf-service-assurance-device" module. This example goes with creating a new identity โจ
A.3. YANG Module โจ
okay bestie, this is the Acme device module ๐
it's a whole example of how a vendor can bolt its own bits onto the device subservice. it extends the device module, adds an identity called device-acme-type (based on the device type), and gives it its own parameters container with a device leaf and an acme-specific-parameter leaf. no cap, it's giving extensibility ๐ฆ
module example-service-assurance-device-acme {
yang-version 1.1;
namespace "urn:example:example-service-assurance-device-acme";
prefix example-device-acme;
import ietf-service-assurance {
prefix sain;
reference
"RFC 9418: YANG Modules for Service Assurance";
}
import ietf-service-assurance-device {
prefix sain-device;
reference
"RFC 9418: YANG Modules for Service Assurance";
}
organization
"IETF OPSAWG Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/opsawg/>
WG List: <mailto:opsawg@ietf.org>
Author: Benoit Claise <mailto:benoit.claise@huawei.com>
Author: Jean Quilbeuf <mailto:jean.quilbeuf@huawei.com>";
description
"This example module extends the ietf-service-assurance-device
module to add specific support for devices of the Acme
Corporation. ";
revision 2023-07-11 {
description
"Initial revision.";
reference
"RFC 9418: YANG Modules for Service Assurance";
}
identity device-acme-type {
base sain-device:device-type;
description
"Network device is healthy.";
}
augment "/sain:subservices/sain:subservice/sain:parameter" {
when "derived-from-or-self(sain:type, 'device-acme-type')";
description
"Augments the parameter choice from the ietf-service-assurance
module with a case specific to the device-acme subservice.";
container parameters {
description
"Parameters for the device-acme subservice type.";
leaf device {
type string;
mandatory true;
description
"The device to monitor.";
}
leaf acme-specific-parameter {
type string;
mandatory true;
description
"The Acme-Corporation-specific parameter.";
}
}
}
}
Appendix B. Further Augmentations: IP Connectivity and IS-IS Subservices ๐
okay so this last appendix is the glow-up ๐ง it covers the two subservices that were still missing from the Figure 2 example in Section 3.1 of [RFC9417]: IP connectivity and the Intermediate System to Intermediate System (IS-IS) routing protocol. these modules are just examples, and the text says more future work is needed for a more complete version ๐ซถ
B.1. IP Connectivity Module Tree View ๐ฆ
that subservice represents the unicast connectivity between two IP addresses sitting on two different devices. it could report symptoms like "No route found" ๐ here's the tree diagram from [RFC8340] for the example-service-assurance-ip-connectivity module:
module: example-service-assurance-ip-connectivity
augment /sain:subservices/sain:subservice/sain:parameter:
+--rw parameters
+--rw device1 string
+--rw address1 inet:ip-address
+--rw device2 string
+--rw address2 inet:ip-address
to specify the connectivity you care about, you give two IP addresses and two devices. the subservice then assures that the connectivity between IP address 1 on device 1 and IP address 2 on device 2 is healthy ๐
B.2. IS-IS Module Tree View ๐
here's the tree diagram from [RFC8340] for the example-service-assurance-is-is module ๐ธ
module: example-service-assurance-is-is
augment /sain:subservices/sain:subservice/sain:parameter:
+--rw parameters
+--rw instance-name string
the parameter for this subservice is the name of the IS-IS instance you want to assure. simple, clean, iconic โจ
B.3. Global Tree View ๐
this is the big picture, the whole family at once ๐ the following tree diagram from [RFC8340] gives an overview of the "ietf-service-assurance", "ietf-service-assurance-device", "example-service-assurance-device-acme", "example-service-assurance-ip-connectivity", and "example-service-assurance-is-is" modules. ngl, it's a lot, but it's all connected ๐
module: ietf-service-assurance
+--ro assurance-graph-last-change yang:date-and-time
+--rw subservices
| +--rw subservice* [type id]
| +--rw type identityref
| +--rw id string
| +--ro last-change?
| | yang:date-and-time
| +--ro label? string
| +--rw under-maintenance!
| | +--rw contact string
| +--rw (parameter)
| | +--:(service-instance-parameter)
| | | +--rw service-instance-parameter
| | | +--rw service string
| | | +--rw instance-name string
| | +--:(example-ip-connectivity:parameters)
| | | +--rw example-ip-connectivity:parameters
| | | +--rw example-ip-connectivity:device1 string
| | | +--rw example-ip-connectivity:address1
| | | | inet:ip-address
| | | +--rw example-ip-connectivity:device2 string
| | | +--rw example-ip-connectivity:address2
| | | inet:ip-address
| | +--:(example-is-is:parameters)
| | | +--rw example-is-is:parameters
| | | +--rw example-is-is:instance-name string
| | +--:(sain-device:parameters)
| | | +--rw sain-device:parameters
| | | +--rw sain-device:device string
| | +--:(example-device-acme:parameters)
| | | +--rw example-device-acme:parameters
| | | +--rw example-device-acme:device
| | | | string
| | | +--rw example-device-acme:acme-specific-parameter
| | | string
| | +--:(sain-interface:parameters)
| | +--rw sain-interface:parameters
| | +--rw sain-interface:device string
| | +--rw sain-interface:interface string
| +--ro health-score int8
| +--ro symptoms-history-start?
| | yang:date-and-time
| +--ro symptoms
| | +--ro symptom* [start-date-time agent-id symptom-id]
| | +--ro symptom-id leafref
| | +--ro agent-id -> /agents/agent/id
| | +--ro health-score-weight? uint8
| | +--ro start-date-time yang:date-and-time
| | +--ro stop-date-time? yang:date-and-time
| +--rw dependencies
| +--rw dependency* [type id]
| +--rw type
| | -> /subservices/subservice/type
| +--rw id leafref
| +--rw dependency-type? identityref
+--ro agents
| +--ro agent* [id]
| +--ro id string
| +--ro symptoms* [id]
| +--ro id string
| +--ro description string
+--ro assured-services
+--ro assured-service* [service]
+--ro service leafref
+--ro instances* [name]
+--ro name leafref
+--ro subservices* [type id]
+--ro type -> /subservices/subservice/type
+--ro id leafref
B.4. IP Connectivity YANG Module ๐
and now the full IP connectivity module, the one that actually brings the subservice to life ๐ง
module example-service-assurance-ip-connectivity {
yang-version 1.1;
namespace "urn:example:example-service-assurance-ip-connectivity";
prefix example-ip-connectivity;
import ietf-inet-types {
prefix inet;
reference
"RFC 6991: Common YANG Data Types";
}
import ietf-service-assurance {
prefix sain;
reference
"RFC 9418: YANG Modules for Service Assurance";
}
organization
"IETF OPSAWG Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/opsawg/>
WG List: <mailto:opsawg@ietf.org>
Author: Benoit Claise <mailto:benoit.claise@huawei.com>
Author: Jean Quilbeuf <mailto:jean.quilbeuf@huawei.com>";
description
"This example module augments the ietf-service-assurance module
to add support for the subservice ip-connectivity.
It checks whether the IP connectivity between two IP addresses
belonging to two network devices is healthy.";
revision 2023-07-11 {
description
"Initial version.";
reference
"RFC 9418: YANG Modules for Service Assurance";
}
identity ip-connectivity-type {
base sain:subservice-base;
description
"Checks connectivity between two IP addresses.";
}
augment "/sain:subservices/sain:subservice/sain:parameter" {
when "derived-from-or-self(sain:type, 'ip-connectivity-type')";
description
"Augments the parameter choice from the ietf-service-assurance
module with a case specific to the ip-connectivity
subservice.";
container parameters {
description
"Parameters for the ip-connectivity subservice type.";
leaf device1 {
type string;
mandatory true;
description
"Device at the first end of the connection.";
}
leaf address1 {
type inet:ip-address;
mandatory true;
description
"Address at the first end of the connection.";
}
leaf device2 {
type string;
mandatory true;
description
"Device at the second end of the connection.";
}
leaf address2 {
type inet:ip-address;
mandatory true;
description
"Address at the second end of the connection.";
}
}
}
}
B.5. IS-IS YANG Module ๐
last but not least, the IS-IS module ๐ it's the same vibe: augment the subservice parameters, give it an instance-name leaf, and you're done ๐
module example-service-assurance-is-is {
yang-version 1.1;
namespace "urn:example:example-service-assurance-is-is";
prefix example-is-is;
import ietf-service-assurance {
prefix sain;
reference
"RFC 9418: YANG Modules for Service Assurance";
}
organization
"IETF OPSAWG Working Group";
contact
"WG Web: <https://datatracker.ietf.org/wg/opsawg/>
WG List: <mailto:opsawg@ietf.org>
Author: Benoit Claise <mailto:benoit.claise@huawei.com>
Author: Jean Quilbeuf <mailto:jean.quilbeuf@huawei.com>";
description
"This example module augments the ietf-service-assurance module
to add support for the subservice is-is.
It checks whether an IS-IS instance is healthy.";
revision 2023-07-11 {
description
"Initial version.";
reference
"RFC 9418: YANG Modules for Service Assurance";
}
identity is-is-type {
base sain:subservice-base;
description
"Health of IS-IS routing protocol.";
}
augment "/sain:subservices/sain:subservice/sain:parameter" {
when "derived-from-or-self(sain:type, 'is-is-type')";
description
"Augments the parameter choice from the ietf-service-assurance
module with a case specific to the is-is subservice.";
container parameters {
description
"Parameters for the is-is subservice type.";
leaf instance-name {
type string;
mandatory true;
description
"The instance to monitor.";
}
}
}
}
Appendix C. Example of a YANG Instance
This section is the big payoff, bestie ๐ It has an example of a YANG instance that conforms to the YANG modules. The validity of this data instance was checked using yangson <https://yangson.labs.nic.cz/> ๐ Yangson needs a YANG library [RFC8525] to define the complete model the data instance gets validated against. In Appendix D, we provide the JSON library file named "ietf-service-assurance-library.json", which is what we used for validation ๐
Below, we've got the contents of the file "example_configuration_instance.json" โจ It holds the configuration data that models Figure 2 from Section 3.1 of [RFC9417] ๐ฆ The instance can be validated with yangson by using the invocation "yangson -v example_configuration_instance.json ietf-service-assurance-library.json", assuming all the files (YANG and JSON) defined in this document reside in the current folder ๐ (the invocation is wrapped below, but type it as one line!)
{
"ietf-service-assurance:subservices": {
"subservice": [
{
"type": "service-instance-type",
"id": "simple-tunnel/example",
"service-instance-parameter": {
"service": "simple-tunnel",
"instance-name": "example"
},
"dependencies": {
"dependency": [
{
"type":
"ietf-service-assurance-interface:interface-type",
"id": "interface/peer1/tunnel0",
"dependency-type": "impacting"
},
{
"type":
"ietf-service-assurance-interface:interface-type",
"id": "interface/peer2/tunnel9",
"dependency-type": "impacting"
},
{
"type":
"example-service-assurance-ip-connectivity:ip-connectivity-type",
"id":
"connectivity/peer1/2001:db8::1/peer2/2001:db8::2",
"dependency-type": "impacting"
}
]
}
},
{
"type":
"example-service-assurance-ip-connectivity:ip-connectivity-type",
"id": "connectivity/peer1/2001:db8::1/peer2/2001:db8::2",
"example-service-assurance-ip-connectivity:parameters": {
"device1": "Peer1",
"address1": "2001:db8::1",
"device2": "Peer2",
"address2": "2001:db8::2"
},
"dependencies": {
"dependency": [
{
"type":
"ietf-service-assurance-interface:interface-type",
"id": "interface/peer1/physical0",
"dependency-type": "impacting"
},
{
"type":
"ietf-service-assurance-interface:interface-type",
"id": "interface/peer2/physical5",
"dependency-type": "impacting"
},
{
"type": "example-service-assurance-is-is:is-is-type",
"id": "is-is/instance1",
"dependency-type": "impacting"
}
]
}
},
{
"type": "example-service-assurance-is-is:is-is-type",
"id": "is-is/instance1",
"example-service-assurance-is-is:parameters": {
"instance-name": "instance1"
}
},
{
"type": "ietf-service-assurance-interface:interface-type",
"id": "interface/peer1/tunnel0",
"ietf-service-assurance-interface:parameters": {
"device": "Peer1",
"interface": "tunnel0"
},
"dependencies": {
"dependency": [
{
"type":
"ietf-service-assurance-interface:interface-type",
"id": "interface/peer1/physical0",
"dependency-type": "impacting"
}
]
}
},
{
"type": "ietf-service-assurance-interface:interface-type",
"id": "interface/peer1/physical0",
"ietf-service-assurance-interface:parameters": {
"device": "Peer1",
"interface": "physical0"
},
"dependencies": {
"dependency": [
{
"type": "ietf-service-assurance-device:device-type",
"id": "interface/peer1",
"dependency-type": "impacting"
}
]
}
},
{
"type": "ietf-service-assurance-device:device-type",
"id": "interface/peer1",
"ietf-service-assurance-device:parameters": {
"device": "Peer1"
}
},
{
"type": "ietf-service-assurance-interface:interface-type",
"id": "interface/peer2/tunnel9",
"ietf-service-assurance-interface:parameters": {
"device": "Peer2",
"interface": "tunnel9"
},
"dependencies": {
"dependency": [
{
"type":
"ietf-service-assurance-interface:interface-type",
"id": "interface/peer2/physical5",
"dependency-type": "impacting"
}
]
}
},
{
"type": "ietf-service-assurance-interface:interface-type",
"id": "interface/peer2/physical5",
"ietf-service-assurance-interface:parameters": {
"device": "Peer2",
"interface": "physical5"
},
"dependencies": {
"dependency": [
{
"type": "ietf-service-assurance-device:device-type",
"id": "interface/peer2",
"dependency-type": "impacting"
}
]
}
},
{
"type": "ietf-service-assurance-device:device-type",
"id": "interface/peer2",
"ietf-service-assurance-device:parameters": {
"device": "Peer2"
}
}
]
}
}
Appendix D. YANG Library for Service Assurance ๐
This section gives you the JSON encoding of the YANG library [RFC8525] that lists all modules defined in this document and their dependencies ๐ You can use this library to validate data instances with yangson, like the previous section explained ๐ธ
{
"ietf-yang-library:modules-state": {
"module-set-id": "ietf-service-assurance@2023-07-11",
"module": [
{
"name": "ietf-service-assurance",
"namespace":
"urn:ietf:params:xml:ns:yang:ietf-service-assurance",
"revision": "2023-07-11",
"conformance-type": "implement"
},
{
"name": "ietf-service-assurance-device",
"namespace":
"urn:ietf:params:xml:ns:yang:ietf-service-assurance-device",
"revision": "2023-07-11",
"conformance-type": "implement"
},
{
"name": "ietf-service-assurance-interface",
"namespace":
"urn:ietf:params:xml:ns:yang:ietf-service-assurance-interface",
"revision": "2023-07-11",
"conformance-type": "implement"
},
{
"name": "example-service-assurance-device-acme",
"namespace":
"urn:example:example-service-assurance-device-acme",
"revision": "2023-07-11",
"conformance-type": "implement"
},
{
"name": "example-service-assurance-is-is",
"namespace": "urn:example:example-service-assurance-is-is",
"revision": "2023-07-11",
"conformance-type": "implement"
},
{
"name": "example-service-assurance-ip-connectivity",
"namespace":
"urn:example:example-service-assurance-ip-connectivity",
"revision": "2023-07-11",
"conformance-type": "implement"
},
{
"name": "ietf-yang-types",
"namespace": "urn:ietf:params:xml:ns:yang:ietf-yang-types",
"revision": "2013-07-05",
"conformance-type": "import"
},
{
"name": "ietf-inet-types",
"namespace": "urn:ietf:params:xml:ns:yang:ietf-inet-types",
"revision": "2013-07-05",
"conformance-type": "import"
}
]
}
}
Acknowledgements ๐ซถ
The authors would like to thank Jan Lindblad for his help during the design of these YANG modules ๐ The authors would also like to thank Stephane Litkowski, Charles Eckel, Mohamed Boucadair, Tom Petch, Dhruv Dhody, and Rob Wilton for their reviews ๐
Authors' Addresses ๐ฆ
Benoit Claise Huawei Email: benoit.claise@huawei.com
Jean Quilbeuf Huawei Email: jean.quilbeuf@huawei.com
Paolo Lucente NTT Siriusdreef 70-72 2132 Hoofddorp Netherlands Email: paolo@ntt.net
Paolo Fasano TIM S.p.A via G. Reiss Romoli, 274 10148 Torino Italy Email: paolo2.fasano@telecomitalia.it
Thangavelu Arumugam Consultant Milpitas, California United States of America Email: thangavelu@yahoo.com
That's the whole spec, bestie ๐๐ฆ Every example checked, every author accounted for, and the YANG library is ready to go. You did it, you absolute legend ๐๐
๐ฆ where this page comes from
- ietf: rfc9418 2023-07
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms