strict warning: Only variables should be passed by reference in /var/www/sites/www.netomata.com/sites/all/themes/clean/template.php on line 126.

neto file -- Netomata network description

Description

Netomata network description files (which are commonly named with the extension .neto) are used as input by Netomata tools such as ncg, and describe a particular network configuration.

Structure

A neto file yields a tree-structured description of a network. The tree is made up of nodes, keys, values, and strings.

node

A node contains a list of key/value pairs.

value

A value can either be a node or a string.

key

A key is a string that provides the name for a particular value. keys consist of a string of any printable character except whitespace, '#' (which denotes a comment), "!" (which is the separator for composite keys), "(" or ")" (which are used to mark special keys, as described below), and "{" or "}" (which are used to mark metadata keys, as described below).

string

A string is any string of printable characters.

A string containing [%= ... %] is treated as an ERB (Embedded Ruby) block. See the full discussion of ERB blocks below.

(Note that parsing in general, and string parsing in particular, is currently very simple-minded; for example, anything from '#' to end-of-line is going to be ignored, as is leading and trailing whitespace. A future release will include quoting and escape mechanisms to work around these limitations.)

Special Keys

keys may be simple keys (i.e., not containing a "!" separator), or composite keys (a series of simple keys separated by "!").

composite keys that begin with a "!" are absolute keys that are interpreted relative to the root of the current tree of nodes. composite keys that don't begin with a "!" are relative keys that are interepreted relative to the current node in the tree.

Selector Keys

simple keys of the form ( selector ) are selector keys which do various magic with the tree of nodes and keys. The following selector keys are available:

(.)

Maps to the current node (just like "." as part of a UNIX file path). So, an absolute key of the form "!a!b!c!(.)" is the same as "!a!b!c"; if your tree is set up such that "!a!b!c" is a valid path, and the current node is "!a!b!c", then (.) relative to the current node will map to node "!a!b!c". Note that "!a!(.)!b!c", "!a!b!(.)!c", and "!a!(.)!b!(.)!c" will also all map to "!a!b!c".

(..)

Maps to the parent node of the current node (just like ".." as part of a UNIX file path). So, an absolute key of the form "!a!b!c!(..)" is the same as "!a!b"; if your tree is set up such that "!a!b!c" is a valid path, and the current node is "!a!b!c", then (..) relative to the current node will map to node "!a!b"

(...)

Maps to the ancestor of the current node which has keys that match whatever follows to the right of (...). For example, if you have a tree with nodes having keys:

!
!a
!a!b
!a!b!c
!a!b!c!d
!a!b!c!d!e
!a!b!c!x
!a!b!c!x!y
!a!b!c!x!y!z

and you are at node !a!b!c!x!y!z, then the "(...)" in relative key (...)!d!e is going to refer to node !a!b!c (which is the closest ancestor to !a!b!c!x!y!z that has sub-nodes !d!e), and thus (...)!d!e is going to refer to !a!b!c!d!e

(key=value[,key=value,...])

Maps to the child node of the current node having key/value pairs that match all of the key/value pairs specified in the selector. For example, if you have a tree with nodes and keys like so:

! (node)
!a (node)
!a!b1 (node)
!a!b1!k = "v1" (value)
!a!b1!m = "x1" (value)
!a!b2 (node)
!a!b2!k = "v2" (value)
!a!b2!m = "x2" (value)

then "!a!(k=v1)" is going to map to node "!a!b1" and "!a!(k=v2)" is going to map to node "!a!b2". Similarly, "!a!(k=v1)!m" is going to map to the string "x1" (same as "!a!b1!m"), and "!a!(k=v2)!m" is going to map to the string "x2" (same as "!a!b2!m").

Anonymous Keys

In addition to the selector keys defined above, there are also special selector keys which create and operate on anonymous keys. Anonymous keys are simply numbered keys which the software creates as requested, for example when building a list of items. Anonymous keys are all of the form "@NNNNNNNNN" (i.e., "@" followed by a number).

The following selector keys operate only on anonymous keys:

(<)

Maps to the minimum anonymous key of the node. I.e., if the node has anonymous keys "@000000001", "@000000002", and "@000000003" (regardless of any non-anonymous keys it may have), then (<) will map to "@000000001".

(>)

Maps to the maximum anonymous key of the node. I.e., if the node has anonymous keys "@000000001", "@000000002", and "@000000003" (regardless of any non-anonymous keys it may have), then (>) will map to "@000000003".

(+)

Maps to the successor anonymous key of the node, which is whatever would come next after the node's current maximum anonymous key of the node. I.e., if the node has anonymous keys "@000000001", "@000000002", and "@000000003" (regardless of any non-anonymous keys it may have), then (+) will map to "@000000004". This is often used to create a new node with a new anonymous key.

All of the regular selector keys defined above also operate on anonymous keys.

You should never refer to an item directly by an anonymous key, as the anonymous key for that object might be different the next time the software runs; instead, you should use selector keys such as (key=value) to identify the node by some relevant characteristic of it. For example, if you have a list of VLANs stored under !vlans, each with an "id" and "name" attribute defined, you could identify the node for VLAN 3 (the "Lab" VLAN) by "!vlans!(id=3)" or "!vlans!(name=Lab)", rather than "!vlans!@000000009", because the "@000000009" might not refer to the same VLAN entry the next time the program runs.

Metadata Keys

Metadata keys are simple keys (i.e., not containing a "!" separator) of the form "{METADATA_KEY}". They may not be a part of a composite key (a series of simple keys separated by "!").

The following metadata keys are available:

{FILENAME}

Maps to the full name of the file currently being processed.

{BASENAME}

Maps to the basename of the file currently being processed (i.e., the last part of the filename, with all the preceding directory names removed; for example, if {FILENAME} is "sample/templates/cisco.neto", then {BASENAME} will be simply "cisco.neto").

{DIRNAME}

Maps to the directory name of the file currently being processed (i.e., everything except for the last part of the filename; for example, if {FILENAME} is "sample/templates/cisco.neto", then {DIRNAME} will be "sample/templates").

ERB Blocks

A string containing [%= ... %] is treated as an ERB (Embedded Ruby) block. The block is processed through the ERB interpreter as if it were a small file containing just the block with [%= ... %] changed to <%= ... %>. The value placed in the tree for such a string is the ERB interpreter's output, not the ERB block itself.

When the ERB block is executed, the following arguments are made available to the running code as Ruby instance variables:

@target
The current node (a Ruby object of class Netomata::Node)
@target_key
The key that identifies the current node (a Ruby object of class String).

Note that each [%= ... %] block is run through ERB separately, as if each was a separate little file. This is not how ERB is normally used; ERB is normally applied on a whole-file basis, essentially as a preprocessor for the entire file. This difference from normal behavior is why these blocks are marked with [%= ... %] rather than the usual ERB <%= ... %>.

For more information about ERB, as well as about helper methods that are available, see the ncg file format documentation. Note that ERB files, as discussed in that documentation, are a mix of Ruby code (identified in <% ... %> segments) intermixed with template text; ERB blocks, on the other hand, are independent, self-contained blocks of Ruby code, without any template text. Keep in mind that each [%= ... %] ERB block is treated as if it were a separate file, and thus, some of the complex examples in the ncg file format documentation that show Ruby control logic spread across multiple <%= ... %> statements aren't applicable for ERB blocks.

Format

A neto file consists of a series of lines. Lines that end with '\' are treated as if they continued on the next line; before processing continues, the current line is joined with the next, and the '\' and embedded newline characters are removed. Comments begin with a '#' symbol, and proceed to the end of the line. Leading and trailing whitespace on a line are ignored, as are blank lines. Once stripped of comments, leading whitespace, and trailing whitespace, each line must match one of the following formats:

key = string

Sets key to be string in the current node. (If string is empty or "-", then key will not be defined; this provides a way for an ERB block to say "never mind, don't set this key", by returning an empty string or "-" as its result.)

key {

Creates a new (empty) sub-node of the current node, names the new sub-node key, and makes the new sub-node the current node (so that further lines are processed relative to the sub-node, until the matching "}"

key < source_key {

Creates a copy of the node identified by source_key as a new sub-node of the current node, names the new sub-node key, and makes the new sub-node the current node (so that further lines are processed relative to the sub-node, until the matching "}"

}

Ends processing of the current sub-node, and makes the current node whatever it was before processing of the current sub-node began.

include filename [ ... ]

Incorporates a file (or set of files) in neto format into the tree at the current location, as if its contents appeared here in the original file. Each filename can name a specific file, or can be a filename glob pattern (in Ruby Dir.glob format, which is very similar to shell filename glob format), which will be expanded to a sorted list of filenames. If multiple filename arguments are given (either directly, or via a filename glob pattern that expands to multiple filenames), the software behaves as if all those named files had been concatenated together for processing. All filename arguments (whether specified directly or determined as a result of filename glob expansion) are interpreted relative to the current filename (the file in which the include statement appears).

table filename [ ... ]

Incorporates a file (or set of files) in neto_table format into the tree at the current location. Each filename can name a specific file, or can be a filename glob pattern (in Ruby Dir.glob format, which is very similar to shell filename glob format), which will be expanded to a sorted list of filenames. If multiple filename arguments are given (either directly, or via a filename glob pattern that expands to multiple filenames), the software behaves as if all those named files had been concatenated together for processing. All filename arguments (whether specified directly or determined as a result of filename glob expansion) are interpreted relative to the current filename (the file in which the include statement appears).

template filename.ncg

template directives are used to populate the tree with pointers to ERB template files that are referenced elsewhere, and used when ncg begins its config generation pass.

The directive defines two keys within the current node:

name
basename of file (i.e., filename stripped of leading directory path and trailing ".ncg" suffix)
ncg_template
path to file (i.e., the argument to the template directive)

filename.ncg is interpreted relative to the current filename (the file in which the template statement appears). An error is raised if filename.ncg doesn't exist or isn't a file.

Because template works on the current node, rather than creating a new node, you cannot specify multiple filename.ncg arguments (or wildcard arguments) to a template directive; each successive file would simply end up overwriting the name and basename keys defined in the current node. To incorporate multiple templates into the tree, either use multiple template directives or use the template_dir directive.

template_dir dirname

Creates a sub-tree of nodes in the tree at the current location, based on the contents of directory dirname. Depending on the name and type of each entry in directory dirname, the following actions are taken:

file named filename.ncg
A sub-node named filename is created, and a template filename.ncg directive is carried out to populate it. Equivalent to the following:

filename {
    template filename.ncg
}
subdirectory named subdir
A sub-node named subdir is created, and a template_dir subdir directive is carried out (recursively) to populate it. Equivalent to the following:

subdir {
    template_dir subdir
}
Any other file or subdirectory
Any other files or subdirectories are simply skipped.

Example

base_ip         = 10.5.0.0
admin_ip        = [%= ip_union(@target["(...)!base_ip"], "0.0.16.0") %]
syslog_ip       = [%= ip_union(@target["(...)!admin_ip"], "0.0.0.26") %]
syslog_facility = local5
snmp_ip         = [%= ip_union(@target["(...)!admin_ip"], "0.0.0.27") %]
snmp_community  = public
domain          = example.com

table vlans.neto_table

!templates {
    template_dir templates
}

!templates!devices!routers!cisco {
    # add to Cisco router device template
    model       = 4948-10G
    default_route = [%= ip_union(@target["(...)!base_ip"], "0.0.4.9") %]
    domain      = [%= "mgmt." + @target["(...)!domain"] %]
}

devices!(+) < !templates!devices!routers!cisco {
    name        = switch-1
    role        = primary
    # can't put this in the template, because "name" isn't defined there
    ncg_output  = [%= File.join(@target["{DIRNAME}"], \
                                "configs", (@target["name"] + ".config")) %]
}

devices!(+) < !templates!devices!routers!cisco {
    name        = switch-2
    role        = secondary
    # can't put this in the template, because "name" isn't defined there
    ncg_output  = [%= File.join(@target["{DIRNAME}"], \
                                "configs", (@target["name"] + ".config")) %]
}

table interfaces.neto_table

History

ncg was originally written in 2008 by Brent Chapman of Netomata, Inc.

Bugs

Please report any you find by email to bugs@netomata.com.

Author

Brent Chapman of Netomata, Inc.

Copyright

Copyright (C) 2009, 2010 Netomata, Inc. All Rights Reserved.

See Also

ncg program, ncg file format, neto_table file format.

Version

This documentation is for ncg version 0.10.x.