[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How does XML help Network Operators
"Wijnen, Bert (Bert)" wr ites:
>In the above I see a lot of "xxxx can be made...."
>That sounds great... but I think I;d like to see the concrete proposals
>to actually "make it" and then to get discussion going on:
>
>- does the proposed solution indeed address the operator needs
>- does the proposed solution seem to be implementable by vendors
> (and I mean kind of as easy and/or as quickly as CLI is done today)
>- can we all agree that this is the path to go forward.
Let me supply some concrete details from our Junoscript API. I'll try
to give examples for each primitives on your original list, but I've
given more details in:
http://www.ietf.org/internet-drafts/draft-shafer-js-xml-api-00.txt
First some details about the protocol. It's a very light-weight
XML-based RPC. RPC calls are encoded in an <rpc> element containing a
method element which in turn contains zero or more arguments.
<rpc>
<method-name>
<foo>15</foo>
<bar>yes</bar>
<flag/>
</method-name>
</rpc>
For operational-mode CLI commands, the mapping from command line
syntax to XML is fairly straight-forward:
show ospf database lsa-id 152.1.4.128 \
advertising-router 152.1.255.163 \
summary area 152.14.0.0 instance big
<rpc>
<get-ospf-database-information>
<!-- order of elements under an rpc does not matter -->
<summary/>
<lsa-id>152.1.4.128</lsa-id>
<advertising-router>152.1.255.163</advertising-router>
<area>152.14.0.0</area>
<instance>big</instance>
</get-ospf-database-information>
</rpc>
For configuration-mode, a set of defined RPC methods manipulate the
same structure used by configuration commands (set, delete, edit,
show) but with a more RPC-oriented tone:
<rpc>
<load-configuration>
<configuration>
<!-- configuration content goes here -->
</configuration>
</load-configuration>
</rpc>
The results of an RPC are returned in an <rpc-reply> element:
<!-- The results of a <get-ospf-neighbor-information> RPC -->
<rpc-reply>
<ospf-neighbor-information>
<ospf-neighbor>
<neighbor-address>192.168.33.34</neighbor-address>
<interface-name>at-1/2/1.0</interface-name>
<ospf-neighbor-state>Full</ospf-neighbor-state>
<neighbor-id>192.168.4.250</neighbor-id>
<neighbor-priority>128</neighbor-priority>
<activity-timer>36</activity-timer>
</ospf-neighbor>
</ospf-neighbor-information>
</rpc-reply>
In operational mode, we use the convention that the method <get-foo>
returns the element <foo>.
More details are available in the draft.
>- dump/save configuration
Fetch the complete configuration:
<rpc>
<get-configuration/>
</rpc>
<get-configuration> defaults to the candidate/scratchpad configuration
Use the 'database' attribute to choose the committed/running
configuration:
<rpc>
<get-configuration database="committed"/>
</rpc>
Content is returned in XML under a <configuration> element.
<rpc-reply>
<configuration>
<system>
<!-- ... -->
</system>
<routing-options>
<static>
<route>
<name>10.2.0.0/16</name>
<next-hop>10.1.2.3</next-hop>
<retain/>
<no-readvertise/>
</route>
</static>
</routing-options>
<!-- ... -->
</configuration>
</rpc-reply>
We allow access to our native configuration text using the format
attribute on <get-configuration>. The default value for this attribute
is 'xml', but using the value 'text' will cause the
<get-configuration> RPC to return the native configuration data in the
<configuration-text> element:
<rpc-reply>
<configuration-text>
system {
# ...
}
routing-options {
static {
route 10.2.0.0/16 {
next-hop 10.1.2.3;
retain;
no-readvertise;
}
}
}
# ...
</configuration-text>
</rpc-reply>
Partial configurations can be retrieved by placing a path of elements
inside <get-configuration>'s <configuration> element:
<rpc>
<get-configuration>
<configuration>
<routing-options>
<static/>
</routing-options>
</configuration>
</get-configuration>
</rpc-reply>
>- load/restore configuration
Full or partial configurations can be loaded with the
<load-configuration> RPC:
<rpc>
<load-configuration>
<system>
<host-name>flubber</host-name>
</system>
</load-configuration>
</rpc>
By default, the configuration is merged into the candidate
configuration. Use the 'action' attribute to change this behaviour.
Using the 'override' value completely replaces the existing
configuration with that provided in the <configuration> element:
<rpc>
<load-configuration action="override">
<system>
<host-name>flubber</host-name>
</system>
</load-configuration>
</rpc>
(At this point, the only statement in your configuration would be the
system host-name.)
In addition, using the value 'replace' for the 'action' allows
subhierarchies of the configuration to be replaced. Any element
containing the 'replace' attribute set to the value 'replace' will be
replaced by the incoming configuration data, while other elements will
be merged into the existing data:
<rpc>
<load-configuration action="replace">
<system>
<host-name>flubber</host-name>
</system>
<routing-options replace="replace">
<static>
<route>
<name>10.2.0.0/16</name>
<next-hop>10.1.2.3</next-hop>
<retain/>
<no-readvertise/>
</route>
</static>
</routing-options>
</load-configuration>
</rpc>
This RPC will merge the system data into the existing configuration
but replace the entire routing-options statement with the data
provided.
>- activate a new configuration at time X or at reboot
The 'at time X' is performed using the <commit-configuration> RPC's
<at-time> element:
<rpc>
<commit-configuration>
<at-time>3am</at-time>
</commit-configuration>
</rpc>
'at reboot' is encoded as <at-time>reboot</at-time>.
>- rollback a configuration
Rollback is supported via the 'rollback' attribute on the
<load-configuration> RPC. We support ten levels of rollback, numbered
0 thru 9 with 0 being the most recently committed configuration.
This RPC sets the candidate configuration to the last committed
one, effectively discarding uncommitted changes.
<rpc>
<load-configuration rollback="0"/>
</rpc>
Using rollback="1" would reload the confiration from before the last
commit, continueing backwards through time to 'rollback="9"'.
>- network level configuration, as in the following points
> - mutli-device transactions (e.g. activate a specific
> configuration at mutliple devices in sync
> - rollback at multiple devices in sync
The Junoscript API offers the following primitives to support
multi-device operations:
The <lock-configuration> RPC acquires an exclusive lock on the
configuration database, preventing unintended interactions between
scripts and humans.
The <lock-configuration> supports a 'rollback="automatic"' which will
cause any uncommitted configuration changes to be discarded when the
lock is released (via the <unlock-configuration> RPC) or lost due to
session failure (lose of connectivity or client failure).
The commit model allows configuration changes to be grouped, checked,
and committed in parellel across multiple devices.
In addition, the API supports a 'confirmed' commit which allows the
device to revert to the previous configuration if the client (manager,
script, application) does not contact the device within a given time
period with a confirming commit.
Operationally, this translates into:
# Perform a multi-device configuration change (in psuedo code)
foreach $device (@targets) {
$handle = open($device);
$handles{ $device } = $handle;
# Acquire a lock on the device's configuration database
$handle->lock_configuration(rollback => "automatic") || mumble();
# Load the configuration onto the device
$handle->load_configuration($config{ $device }) || mumble();
# Issue a 'commit check' to see that the commit will succeed
$handle->check_configuration() || mumble();
}
# If the script fails at this point, the automatic rollback will
# restore the state of the network immediately.
foreach $device (@targets) {
$handle = $handles{ $device };
# Issue a 'commit confirmed'; default confirmation period
# is ten minutes. If a follow-up commit is not done inside
# this window, the configuration reverts to its previous content.
$handle->commit(confirmed => 1) || mumble();
# Test to make sure the box is reachable
test_reachability($device, $handle) || mumble();
}
# If the script fails at this point, the confirmation period
# will expire and the configuration will revert to the previous
# configuration, restoring the state of the network.
foreach $device (@targets) {
$handle = $handles{ $device };
# Issue the confirming commit
$handle->commit() || mumble();
# Done.
$handle->close();
}
mumble() is outside the scope of this email. ;^)
>- who can do what on which devices, as in the
> following points
> - what are the identities of who can do what
> - how can they be grouped
> - how do we do access control fo such groups
Our AAA model (and code) is identical to the CLI's. We have
both course-grained (by area of interest) and fine-grained (by command
regex) authorization that are specified by login class, with each user
belonging to one login class.
[edit system login]
root@poi# show
class cool {
permissions [ interface-control routing-control snmp ];
allow-commands "show ospf summary";
deny-commands "show ospf .*";
deny-configuration "protocols bgp";
}
user phil {
full-name "Phil Shafer";
class cool;
authentication {
encrypted-password "1$1BLAHBLAHBLAH"; # SECRET-DATA
ssh-dsa "ssh-dss 1024 32 123...321 phil"; # SECRET-DATA
}
}
>- transport security
> - how is the transport properly secured
We support operations over SSH, SSL, or direct console access. Users
can be configured local, via radius or tacplus, with passwords or ssh
keys (v1 or v2). In addition, a X.509 certificate can be configured
for SSL connections.
Sorry this turned out to be so long. Hope you made it through the
whole bit. Please holler if you want more details on any area.
Also, I've skipped a number of XML issues like namespaces and
schemas. These are handled with xmlns and schemaLocation attributes on
the rpc, rpc-reply, method-name, and results elements. They are
omitted here for brevity and readability.
Thanks,
Phil
--
to unsubscribe send a message to xmlconf-request@ops.ietf.org with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://ops.ietf.org/lists/xmlconf/>