Use gRPC Protocol to Define Network Operations with Data Models

XR devices ship with the YANG files that define the data models they support. Using a management protocol such as NETCONF or gRPC, you can programmatically query a device for the list of models it supports and retrieve the model files.

gRPC is an open-source RPC framework. It is based on Protocol Buffers (Protobuf), which is an open source binary serialization protocol. gRPC provides a flexible, efficient, automated mechanism for serializing structured data, like XML, but is smaller and simpler to use. You define the structure using protocol buffer message types in .proto files. Each protocol buffer message is a small logical record of information, containing a series of name-value pairs.

gRPC encodes requests and responses in binary. gRPC is extensible to other content types along with Protobuf. The Protobuf binary data object in gRPC is transported over HTTP/2.

gRPC supports distributed applications and services between a client and server. gRPC provides the infrastructure to build a device management service to exchange configuration and operational data between a client and a server. The structure of the data is defined by YANG models.


Note

All 64-bit IOS XR platforms support gRPC and TCP protocols. All 32-bit IOS XR platforms support only TCP protocol.


Cisco gRPC IDL uses the protocol buffers interface definition language (IDL) to define service methods, and define parameters and return types as protocol buffer message types. The gRPC requests are encoded and sent to the router using JSON. Clients can invoke the RPC calls defined in the IDL to program the router.

The following example shows the syntax of the proto file for a gRPC configuration:
syntax = "proto3";
 
package IOSXRExtensibleManagabilityService;
 
service gRPCConfigOper {
 
    rpc GetConfig(ConfigGetArgs) returns(stream ConfigGetReply) {};
  
    rpc MergeConfig(ConfigArgs) returns(ConfigReply) {};
 
    rpc DeleteConfig(ConfigArgs) returns(ConfigReply) {};
 
    rpc ReplaceConfig(ConfigArgs) returns(ConfigReply) {};
 
    rpc CliConfig(CliConfigArgs) returns(CliConfigReply) {};
 
    rpc GetOper(GetOperArgs) returns(stream GetOperReply) {};
 
    rpc CommitReplace(CommitReplaceArgs) returns(CommitReplaceReply) {};
} 
message ConfigGetArgs {
     int64 ReqId = 1;
     string yangpathjson = 2;
}
 
message ConfigGetReply {
    int64 ResReqId = 1;
    string yangjson = 2;
    string errors = 3;
}
 
message GetOperArgs {
     int64 ReqId = 1;
     string yangpathjson = 2;
}
 
message GetOperReply {
    int64 ResReqId = 1;
    string yangjson = 2;
    string errors = 3;
}
 
message ConfigArgs {
    int64 ReqId = 1;
    string yangjson = 2;
 
}
 
message ConfigReply {
    int64 ResReqId = 1;
    string errors = 2;
}
 
message CliConfigArgs {
    int64 ReqId = 1;
    string cli = 2;
}
 
message CliConfigReply {
    int64 ResReqId = 1;
    string errors = 2;
}

message CommitReplaceArgs {
     int64 ReqId = 1;
     string cli = 2;
     string yangjson = 3;
}

message CommitReplaceReply {
     int64 ResReqId = 1;
     string errors = 2;
}
Example for gRPCExec configuration:

service gRPCExec {
    rpc ShowCmdTextOutput(ShowCmdArgs) returns(stream ShowCmdTextReply) {};
    rpc ShowCmdJSONOutput(ShowCmdArgs) returns(stream ShowCmdJSONReply) {};
    
}

message ShowCmdArgs {
     int64 ReqId = 1;
     string cli = 2;
}
 
message ShowCmdTextReply {
    int64 ResReqId =1;
    string output = 2;
    string errors = 3;
}



Example for OpenConfiggRPC configuration:
service OpenConfiggRPC {
     rpc SubscribeTelemetry(SubscribeRequest) returns (stream SubscribeResponse) {};
     rpc UnSubscribeTelemetry(CancelSubscribeReq) returns (SubscribeResponse) {};
     rpc GetModels(GetModelsInput) returns (GetModelsOutput) {};
}

message GetModelsInput {
     uint64  requestId   = 1;
     string  name        = 2;
    string  namespace   = 3;
    string  version     = 4;
    enum MODLE_REQUEST_TYPE {
         SUMMARY = 0;
         DETAIL  = 1;
     }
     MODLE_REQUEST_TYPE requestType = 5;
}

message GetModelsOutput {
     uint64  requestId   = 1;
     message ModelInfo {
         string  name        = 1;
         string  namespace   = 2;
        string  version     = 3;
         GET_MODEL_TYPE  modelType = 4;
         string modelData = 5;
     }
     repeated ModelInfo models = 2;
     OC_RPC_RESPONSE_TYPE responseCode = 3;
     string msg = 4;
}

This article describes, with a use case to configure interfaces on a router, how data models helps in a faster programmatic and standards-based configuration of a network, as comapared to CLI.

gRPC Operations

You can issue the following gRPC operations:

gRPC Operation

Description

GetConfig

Retrieves a configuration

GetModels

Gets the supported Yang models on the router

MergeConfig

Appends to an existing configuration

DeleteConfig

Deletes a configuration

ReplaceConfig

Modifies a part of an existing configuration

CommitReplace

Replaces existing configuration with the new configuration file provided

GetOper

Gets operational data using JSON

CliConfig

Invokes the CLI configuration

ShowCmdTextOutput

Displays the output of show command

ShowCmdJSONOutput

Displays the JSON output of show command

gRPC Operation to Get Configuration

This example shows how a gRPC GetConfig request works for LLDP feature.

The client initiates a message to get the current configuration of LLDP running on the router. The router responds with the current LLDP configuration.

gRPC Request (Client to Router)

gRPC Response (Router to Client)

rpc GetConfig
  {
   "Cisco-IOS-XR-ethernet-lldp-cfg:lldp": [
    "lldp": "running-configuration"
    ]
  }
 
{
"Cisco-IOS-XR-ethernet-lldp-cfg:lldp": {
  "timer": 60,
  "enable": true,
  "reinit": 3,
  "holdtime": 150
}
}

gRPC over UNIX Domain Sockets

Table 1. Feature History Table

Feature Name

Release Information

Description

gRPC Connections over UNIX domain sockets for Enhanced Security and Control

Release 7.5.1

This feature allows local containers and scripts on the router to establish gRPC connections over UNIX domain sockets. These sockets provide better inter-process communication eliminating the need to manage passwords for local communications. Configuring communication over UNIX domain sockets also gives you better control of permissions and security because UNIX file permissions come into force.

This feature introduces the grpc local-connection command.

You can use local containers to establish gRPC connections via a TCP protocol where authentication using username and password is mandatory. This functionality is extended to establish gRPC connections over UNIX domain sockets, eliminating the need to manage password rotations for local communications.

When gRPC is configured on the router, the gRPC server starts and then registers services such as gNMI and gNOI. After all the gRPC server registrations are complete, the listening socket is opened to listen to incoming gRPC connection requests. Currently, a TCP listen socket is created with the IP address, VRF, or gRPC listening port. With this feature, the gRPC server listens over UNIX domain sockets that must be accessible from within the container via a local connection by default. With the UNIX socket enabled, the server listens on both TCP and UNIX sockets. However, if disable the UNIX socket, the server listens only on the TCP socket. The socket file is located at /var/lib/docker/ems/grpc.sock directory.

The following process shows the configuration changes required to enable or disable gRPC over UNIX domain sockets.

Procedure


Step 1

Configure the gRPC server.

Example:

Router(config)#grpc
Router(config-grpc)#local-connection
Router(config-grpc)#commit
To disable the UNIX socket use the following command.
Router(config-grpc)#no local-connection

The gRPC server restarts after you enable or disable the UNIX socket. If you disable the socket, any active gRPC sessions are dropped and the gRPC data store is reset.

The scale of gRPC requests remains the same and is split between the TCP and Unix socket connections. The maximum session limit is 256, if you utilize the 256 sessions on Unix sockets, further connections on either TCP or UNIX sockets is rejected.

Step 2

Verify that the local-connection is successfully enabled.

Example:

Router#show grpc status
Thu Nov 25 16:51:30.382 UTC
*************************show gRPC status**********************
---------------------------------------------------------------
transport                       :     grpc
access-family                   :     tcp4
TLS                             :     enabled
trustpoint                      :     
listening-port                  :     57400
local-connection                :     enabled
max-request-per-user            :     10
max-request-total               :     128
max-streams                     :     32
max-streams-per-user            :     32
vrf-socket-ns-path              :     global-vrf
min-client-keepalive-interval   :     300
_______________________________________________________________

A gRPC client must dial into the socket to send connection requests.

The following is an example of a Go client connecting to UNIX socket:

const sockAddr = 
"/var/lib/docker/ems/grpc.sock"
...
func UnixConnect(addr string, t time.Duration) (net.Conn, error) {
    unix_addr, err := net.ResolveUnixAddr("unix", sockAddr)
    conn, err := net.DialUnix("unix", nil, unix_addr)
    return conn, err
}
 
 
func main() {
...
    opts = append(opts, grpc.WithTimeout(time.Second*time.Duration(*operTimeout)))
    opts = append(opts, grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(math.MaxInt32)))
    ...
    opts = append(opts, grpc.WithDialer(UnixConnect))
    conn, err := grpc.Dial(sockAddr, opts...)
    ...
}

gRPC Network Management Interface

gRPC Network Management Interface (gNMI) is a gRPC-based network management protocol used to modify, install or delete configuration from network devices. It is also used to view operational data, control and generate telemetry streams from a target device to a data collection system. It uses a single protocol to manage configurations and stream telemetry data from network devices.

The subscription in a gNMI does not require prior sensor path configuration on the target device. Sensor paths are requested by the collector (such as pipeline), and the subscription mode can be specified for each path.

gNMI uses gRPC as the transport protocol and the configuration is same as that of gRPC. These gNMI RPCs are supported:

gNMI RPC

gNMI RPC Request

Description

Capabilities

Initial handshake between the network device (server) and the client to exchange capability information such as supported data models

Set

message SetRequest {}

Modifies data associated with a model on a network device from a client

Get

message GetRequest {}

Retrieves data from a network device

Subscribe

message SubscribeRequest {}

Control data subscriptions on server

gNMI defines 3 modes for a streaming subscription that indicates how the router must return data in a subscription:
  • A SAMPLE mode is cadence-based subscription supported for all the operational models.

  • An ON_CHANGE mode is event-based subscription. In this mode, only the state leaf supports on_change events.

  • A TARGET_DEFINED mode allows the target to determine the best type of subscription to be created on a per-leaf basis.

When a client creates a subscription specifying the TARGET_DEFINED mode, the target, here the router, determine the best type of subscription to be created on a per-leaf basis. If the path specified within the message refers to some leaves which are event-driven, then an ON_CHANGE subscription is created. Else, a SAMPLE subscription is created.


Note

In Cisco IOS XR Release 6.3.1, the TARGET_DEFINED subscription mode is supported only for sensor paths of OpenConfig model; native model is not supported. The supported models are: OC Interfaces, OC Telemetry, OC Shell Util, OC System NTP and OC Platform.


For more information about gNMI, see Github.

gRPC Network Operations Interface

gRPC Network Operations Interface (gNOI) defines a set of gRPC-based microservices for executing operational commands on network devices. Extensible Manageability Services (EMS) gNOI is the Cisco IOS XR implementation of gNOI.

gNOI uses gRPC as the transport protocol and the configuration is same as that of gRPC. These gNOI RPCs are supported:

GNOI supports the following remote procedure calls (RPCs):
  • System:
    • Reboot

    • RebootStatus

    • SetPackage

    • SetPackageRemote

    • Ping

    • Traceroute

    • Time

    • SwitchControlProcessor

  • File
    • Get

    • Remove

    • Stat

    • Put

    • TransferToRemote

  • Cert
    • Rotate

    • Install

    • GetCertificates

    • RevokeCertificates

    • CanGenerateCSR

  • Interface
    • SetLoopbackMode

    • GetLoopbackMode

    • ClearInterfaceCounters

  • Layer2
    • ClearLLDPInterface

  • BGP
    • ClearBGPNeighbor

  • BERT
    • StartBERT

    • StopBERT

    • GetBERTResult

The following examples show the representation of few gNOI RPCs:

Get RPC

Streams the contents of a file from the target.

RPC to 10.105.57.106:57900
RPC start time: 20:58:27.513638
---------------------File Get Request---------------------
RPC start time: 20:58:27.513668
remote_file: "harddisk:/giso_image_repo/test.log"

---------------------File Get Response---------------------
RPC end time: 20:58:27.518413
contents: "GNOI \n\n"

hash {
method: MD5
hash: "D\002\375h\237\322\024\341\370\3619k\310\333\016\343"
}

Remove RPC

Remove the specified file from the target.

RPC to 10.105.57.106:57900
RPC start time: 21:07:57.089554
---------------------File Remove Request---------------------
remote_file: "harddisk:/sample.txt"

---------------------File Remove Response---------------------
RPC end time: 21:09:27.796217
File removal harddisk:/sample.txt successful

Reboot RPC

Reloads a requested target.

RPC to 10.105.57.106:57900
RPC start time: 21:12:49.811536
---------------------Reboot Request---------------------
RPC start time: 21:12:49.811561
method: COLD
message: "Test Reboot"
subcomponents {
origin: "openconfig-platform"
elem {
name: "components"
}
elem {
name: "component"
key {
key: "name"
value: "0/RP0"
}
}
elem {
name: "state"
}
elem {
name: "location"
}
}
---------------------Reboot Request---------------------
RPC end time: 21:12:50.023604

Set Package RPC

Places software package on the target.

RPC to 10.105.57.106:57900
RPC start time: 21:12:49.811536
---------------------Set Package Request---------------------
RPC start time: 15:33:34.378745
Sending SetPackage RPC
package {
filename: "harddisk:/giso_image_repo/<platform-version>-giso.iso"
activate: true
}
method: MD5
hash: "C\314\207\354\217\270=\021\341y\355\240\274\003\034\334"
RPC end time: 15:47:00.928361

Reboot Status RPC

Returns the status of reboot for the target.

RPC to 10.105.57.106:57900
RPC start time: 22:27:34.209473
---------------------Reboot Status Request---------------------
subcomponents {
origin: "openconfig-platform"
elem {
name: "components"
}
elem {
name: "component"
key {
key: "name"
value: "0/RP0"
}
}
elem {
name: "state"
}
elem 
name: "location"
}
}

RPC end time: 22:27:34.319618

---------------------Reboot Status Response---------------------
Active : False
Wait : 0
When : 0
Reason : Test Reboot
Count : 0

To send gNOI RPC requests, user needs a client that implements the gNOI client interface for each RPC.

All messages within the gRPC service definition are defined as protocol buffers (proto files). gNOI OpenConfig proto files are located in Github repository.

Configure Interfaces Using Data Models in a gRPC Session

Google-defined remote procedure call (gRPC) is an open-source RPC framework. gRPC supports IPv4 and IPv6 address families. The client applications use this protocol to request information from the router, and make configuration changes to the router.

The process for using data models involves:
  • Obtain the data models.

  • Establish a connection between the router and the client using gRPC communication protocol.

  • Manage the configuration of the router from the client using data models.


Note

Configure AAA authorization to restrict users from uncontrolled access. If AAA authorization is not configured, the command and data rules associated to the groups that are assigned to the user are bypassed. An IOS-XR user can have full read-write access to the IOS-XR configuration through Network Configuration Protocol (NETCONF), google-defined Remote Procedure Calls (gRPC) or any YANG-based agents. In order to avoid granting uncontrolled access, enable AAA authorization using aaa authorization exec command before setting up any configuration. For more information about configuring AAA authorization, see the System Security Configuration Guide for Cisco 8000 Series Routers.


In this section, you use native data models to configure loopback and ethernet interfaces on a router using a gRPC session.

Consider a network topology with four routers and one controller. The network consists of label edge routers (LER) and label switching routers (LSR). Two routers LER1 and LER2 are label edge routers, and two routers LSR1 and LSR2 are label switching routers. A host is the controller with a gRPC client. The controller communicates with all routers through an out-of-band network. All routers except LER1 are pre-configured with proper IP addressing and routing behavior. Interfaces between routers have a point-to-point configuration with /31 addressing. Loopback prefixes use the format 172.16.255.x/32.

The following image illustrates the network topology:
Figure 1. Network Topology for gRPC session

You use Cisco IOS XR native model Cisco-IOS-XR-ifmgr-cfg.yang to programmatically configure router LER1.

Before you begin

  • Retrieve the list of YANG modules on the router using NETCONF monitoring RPC. For more information, see Access the Data Models.

  • Configure Transport Layer Security (TLS). Enabling gRPC protocol uses the default HTTP/2 transport with no TLS. gRPC mandates AAA authentication and authorization for all gRPC requests. If TLS is not configured, the authentication credentials are transferred over the network unencrypted. Enabling TLS ensures that the credentials are secure and encrypted. Non-TLS mode can only be used in secure internal network.

Enable gRPC Protocol

To configure network devices and view operational data, gRPC proptocol must be enabled on the server. In this example, you enable gRPC protocol on LER1, the server.


Note

Cisco IOS XR 64-bit platforms support gRPC protocol. The 32-bit platforms do not support gRPC protocol.


Procedure


Step 1

Enable gRPC over an HTTP/2 connection.

Example:


Router#configure
Router(config)#grpc
Router(config-grpc)#port <port-number>

The port number ranges from 57344 to 57999. If a port number is unavailable, an error is displayed.

Step 2

Set the session parameters.

Example:

Router(config)#grpc{ address-family | dscp | max-request-per-user | max-request-total | max-streams | 
max-streams-per-user | no-tls | service-layer | tls-cipher | tls-mutual | tls-trustpoint | vrf }
where:
  • address-family: set the address family identifier type

  • dscp: set QoS marking DSCP on transmitted gRPC

  • max-request-per-user: set the maximum concurrent requests per user

  • max-request-total: set the maximum concurrent requests in total

  • max-streams: set the maximum number of concurrent gRPC requests. The maximum subscription limit is 128 requests. The default is 32 requests

  • max-streams-per-user: set the maximum concurrent gRPC requests for each user. The maximum subscription limit is 128 requests. The default is 32 requests

  • no-tls: disable transport layer security (TLS). The TLS is enabled by default.

  • service-layer: enable the grpc service layer configuration

  • tls-cipher: enable the gRPC TLS cipher suites

  • tls-mutual: set the mutual authentication

  • tls-trustpoint: configure trustpoint

  • server-vrf: enable server vrf

After gRPC is enabled, use the YANG data models to manage network configurations.

Configure Interfaces

In this example, you configure interfaces using Cisco IOS XR native model Cisco-IOS-XR-ifmgr-cfg.yang. You gain an understanding about the various gRPC operations while you configure the interface. For the complete list of operations, see gRPC Operations. In this example, you merge configurations with merge-config RPC, retreive operational statistics using get-oper RPC, and delete a configuration using delete-config RPC. You can explore the structure of the data model using YANG validator tools such as pyang.

LER1 is the gRPC server, and a command line utility grpcc is used as a client on the controller. This utility does not support YANG and, therefore, does not validate the data model. The server, LER1, validates the data mode.


Note

The OC interface maps all IP configurations for parent interface under a VLAN with index 0. Hence, do not configure a sub interface with tag 0.


Procedure


Step 1

Explore the XR configuration model for interfaces and its IPv4 augmentation.

Example:


controller:grpc$ pyang --format tree --tree-depth 3 Cisco-IOS-XR-ifmgr-cfg.yang
Cisco-IOS-XR-ipv4-io-cfg.yang 
module: Cisco-IOS-XR-ifmgr-cfg 
    +--rw global-interface-configuration 
    | +--rw link-status? Link-status-enum 
    +--rw interface-configurations 
        +--rw interface-configuration* [active interface-name] 
            +--rw dampening 
            | ... 
            +--rw mtus 
            | ... 
            +--rw encapsulation 
            | ... 
            +--rw shutdown? empty 
            +--rw interface-virtual? empty 
            +--rw secondary-admin-state? Secondary-admin-state-enum 
            +--rw interface-mode-non-physical? Interface-mode-enum 
            +--rw bandwidth? uint32 
            +--rw link-status? empty 
            +--rw description? string 
            +--rw active Interface-active 
            +--rw interface-name xr:Interface-name 
            +--rw ipv4-io-cfg:ipv4-network 
            | ... 
            +--rw ipv4-io-cfg:ipv4-network-forwarding ...
Step 2

Configure a loopback0 interface on LER1.

  1. Configure loopback interface Loopback0 and assign an IP address.

    Example:

    controller:grpc$ more xr-interfaces-lo0-cfg.json 
    { 
     "Cisco-IOS-XR-ifmgr-cfg:interface-configurations": 
      { "interface-configuration": [ 
        { 
          "active": "act", 
          "interface-name": "Loopback0", 
          "description": "LOCAL TERMINATION ADDRESS", 
          "interface-virtual": [ 
            null 
           ], 
           "Cisco-IOS-XR-ipv4-io-cfg:ipv4-network": { 
            "addresses": { 
                "primary": { 
                  "address": "172.16.255.1", 
                  "netmask": "255.255.255.255" 
           } 
          } 
         } 
        } 
       ] 
     } 
    }
  2. Merge the configuration.

    Example:

    
    controller:grpc$ grpcc -username admin -password admin -oper merge-config 
    -server_addr 198.18.1.11:57400 -json_in_file xr-interfaces-lo0-cfg.json 
    emsMergeConfig: Sending ReqId 1 
    emsMergeConfig: Received ReqId 1, Response ' 
    '
    
Step 3

Configure the ethernet interface on LER1.

  1. Configure interface GigabitEthernet0/0/0/0 on LER1.

    Example:

    
    controller:grpc$ more xr-interfaces-gi0-cfg.json 
    { 
     "Cisco-IOS-XR-ifmgr-cfg:interface-configurations": { 
       "interface-configuration": [ 
        { 
         "active": "act", 
         "interface-name": "GigabitEthernet0/0/0/0", 
         "description": "CONNECTS TO LSR1 (g0/0/0/0)", 
         "Cisco-IOS-XR-ipv4-io-cfg:ipv4-network": { 
            "addresses": { 
             "primary": { 
                "address": "172.16.1.0", 
                "netmask": "255.255.255.254" 
          } 
         } 
        } 
       } 
      ] 
     } 
    } 
  2. Merge the configuration.

    Example:

    
    controller:grpc$ grpcc -username admin -password admin -oper merge-config 
    -server_addr 198.18.1.11:57400 -json_in_file xr-interfaces-gi0-cfg.json 
    emsMergeConfig: Sending ReqId 1 
    emsMergeConfig: Received ReqId 1, Response ' 
    '
Step 4

Enable the ethernet interface GigabitEthernet 0/0/0/0 on LER1 to bring up the interface. To do this, delete shutdown configuration for the interface.

Example:


controller:grpc$ grpcc -username admin -password admin -oper delete-config 
-server_addr 198.18.1.11:57400 -yang_path "$(< xr-interfaces-gi0-shutdown-cfg.json )" 
emsDeleteConfig: Sending ReqId 1, yangJson { 
 "Cisco-IOS-XR-ifmgr-cfg:interface-configurations": { 
   "interface-configuration": [ 
   { 
    "active": "act", 
    "interface-name": "GigabitEthernet0/0/0/0", 
    "shutdown": [ 
      null 
    ] 
   } 
  ] 
 } 
} 
emsDeleteConfig: Received ReqId 1, Response ''

Verify the Interface State

Verify that the loopback interface and the ethernet interface on router LER1 are operational.


controller:grpc$ grpcc -username admin -password admin -oper get-oper 
-server_addr 198.18.1.11:57400 -oper_yang_path "$(< xr-interfaces-briefs-oper-filter.json )" 
emsGetOper: Sending ReqId 1, yangPath { 
  "Cisco-IOS-XR-pfi-im-cmd-oper:interfaces": { 
    "interface-briefs": [ 
      null 
     ] 
  } 
}
{ "Cisco-IOS-XR-pfi-im-cmd-oper:interfaces": { 
  "interface-briefs": { 
    "interface-brief": [ 
    { 
      "interface-name": "GigabitEthernet0/0/0/0", 
      "interface": "GigabitEthernet0/0/0/0", 
      "type": "IFT_GETHERNET", 
      "state": "im-state-up", 
      "actual-state": "im-state-up", 
      "line-state": "im-state-up", 
      "actual-line-state": "im-state-up", 
      "encapsulation": "ether", 
      "encapsulation-type-string": "ARPA", 
      "mtu": 1514, 
      "sub-interface-mtu-overhead": 0, 
      "l2-transport": false, 
      "bandwidth": 1000000 
     },
     { 
      "interface-name": "GigabitEthernet0/0/0/1", 
      "interface": "GigabitEthernet0/0/0/1", 
      "type": "IFT_GETHERNET", 
      "state": "im-state-up", 
      "actual-state": "im-state-up", 
      "line-state": "im-state-up", 
      "actual-line-state": "im-state-up", 
      "encapsulation": "ether", 
      "encapsulation-type-string": "ARPA", 
      "mtu": 1514, 
      "sub-interface-mtu-overhead": 0, 
      "l2-transport": false, 
      "bandwidth": 1000000 
     },
     { 
      "interface-name": "Loopback0", 
      "interface": "Loopback0", 
      "type": "IFT_LOOPBACK", 
      "state": "im-state-up", 
      "actual-state": "im-state-up", 
      "line-state": "im-state-up", 
      "actual-line-state": "im-state-up", 
      "encapsulation": "loopback", 
      "encapsulation-type-string": "Loopback", 
      "mtu": 1500, 
      "sub-interface-mtu-overhead": 0, 
      "l2-transport": false, 
      "bandwidth": 0 
   },
   { 
      "interface-name": "MgmtEth0/RP0/CPU0/0", 
      "interface": "MgmtEth0/RP0/CPU0/0", 
      "type": "IFT_ETHERNET", 
      "state": "im-state-up", 
      "actual-state": "im-state-up", 
      "line-state": "im-state-up", 
      "actual-line-state": "im-state-up", 
      "encapsulation": "ether", 
      "encapsulation-type-string": "ARPA", 
      "mtu": 1514, 
      "sub-interface-mtu-overhead": 0, 
      "l2-transport": false, 
      "bandwidth": 1000000 
   },
   { 
      "interface-name": "Null0", 
      "interface": "Null0", 
      "type": "IFT_NULL", 
      "state": "im-state-up", 
      "actual-state": "im-state-up", 
      "line-state": "im-state-up", 
      "actual-line-state": "im-state-up", 
      "encapsulation": "null", 
      "encapsulation-type-string": "Null", 
      "mtu": 1500, 
      "sub-interface-mtu-overhead": 0, 
      "l2-transport": false, 
      "bandwidth": 0 
    } 
   ] 
  } 
 } 
} 
emsGetOper: ReqId 1, byteRecv: 2325

In summary, router LER1, which had minimal configuration, is now programmatically configured using data models with an ethernet interface and is assigned a loopback address. Both these interfaces are operational and ready for network provisioning operations.