Examples

Global configuration file

[default]
# Location of all ztps boostrap process data files
data_root = /usr/share/ztpserver

# UID used in the /nodes structure (serialnumber or systemmac)
identifier = serialnumber

# Server URL to-be-advertised to clients (via POST replies) during the bootstrap process
server_url = http://172.16.130.10:8080

# Enable local logging
logging = True

# Enable console logging
console_logging = True

# Console logging format
console_logging_format = %(asctime)s:%(levelname)s:[%(module)s:%(lineno)d] %(message)s


# Globally disable topology validation in the bootstrap process
disable_topology_validation = False

[server]
# Note: this section only applies to using the standalone server.  If
# running under a WSGI server, these values are ignored

# Interface to which the server will bind to (0:0:0:0 will bind to
# all available IPv4 addresses on the local machine)
interface = 172.16.130.10

# TCP listening port
port = 8080

[bootstrap]
# Bootstrap filename (file located in <data_root>/bootstrap)
filename = bootstrap

[neighbordb]
# Neighbordb filename (file located in <data_root>)
filename = neighbordb

Dynamic neighbordb or pattern file

---
patterns:
#dynamic sample
  - name: dynamic_sample
    definition: tor1
    interfaces:
      - Ethernet1: spine1:Ethernet1
      - Ethernet2: spine2:Ethernet1
      - any: ztpserver:any

  - name: dynamic_sample2
    definition: tor2
    interfaces:
      - Ethernet1: spine1:Ethernet2
      - Ethernet2: spine2:Ethernet2
      - any: ztpserver:any

Static neighbordb and /node/<unique-id>/pattern file

---
patterns:
#static sample
  - name: static_node
    node: 000c29f3a39g
    interfaces:
      - any: any:any

Sample dynamic definition file

---
actions:
  -
    action: install_image
    always_execute: true
    attributes:
      url: files/images/vEOS.swi
      version: 4.13.5F
    name: "validate image"
  -
    action: add_config
    attributes:
      url: files/templates/ma1.template
      variables:
        ipaddress: allocate('mgmt_subnet')
    name: "configure ma1"
  -
    action: add_config
    attributes:
      url: files/templates/system.template
      variables:
        hostname: allocate('tor_hostnames')
    name: "configure global system"
  -
    action: add_config
    attributes:
      url: files/templates/login.template
    name: "configure auth"
  -
    action: add_config
    attributes:
      url: files/templates/ztpprep.template
    name: "configure ztpprep alias"
  -
    action: add_config
    attributes:
      url: files/templates/snmp.template
      variables: $variables
    name: "configure snmpserver"
  -
    action: add_config
    attributes:
      url: files/templates/configpush.template
      variables: $variables
    name: "configure config push to server"
  -
    action: copy_file
    always_execute: true
    attributes:
      dst_url: /mnt/flash/
      mode: 777
      overwrite: if-missing
      src_url: files/automate/ztpprep
    name: "automate reload"
attributes:
  variables:
    ztpserver: 172.16.130.10
name: tora

Sample templates

#login.template
#::::::::::::::
username admin priv 15 secret admin
#ma1.template
#::::::::::::::
interface Management1
  ip address $ipaddress
  no shutdown
#hostname.template
#::::::::::::::
hostname $hostname

Sample resources

#mgmt_subnet
#::::::::::::::
192.168.100.210/24: null
192.168.100.211/24: null
192.168.100.212/24: null
192.168.100.213/24: null
192.168.100.214/24: null
#tor_hostnames
#::::::::::::::
veos-dc1-pod1-tor1: null
veos-dc1-pod1-tor2: null
veos-dc1-pod1-tor3: null
veos-dc1-pod1-tor4: null
veos-dc1-pod1-tor5: null

Neighbordb pattern examples

Example #1

---
- name: standard leaf definition
  definition: leaf_template
  node: ABC12345678
  interfaces:
    - Ethernet49: pod1-spine1:Ethernet1/1
    - Ethernet50:
        device: pod1-spine2
        port: Ethernet1/1

In example #1, the topology map would only apply to a node with system ID equal to ABC12345678. The following interface map rules apply:

  • Interface Ethernet49 must be connected to node pod1-spine1 on port Ethernet1/1
  • Interface Ethernet50 must be connected to node pod1-spine2 on port Ethernet1/1

Example #2

---
- name: standard leaf definition
  definition: leaf_template
  node: 001c73aabbcc
  interfaces:
    - any: regex('pod\d+-spine\d+'):Ethernet1/$
    - any:
        device: regex('pod\d+-spine1')
        port: Ethernet2/3

In this example, the topology map would only apply to the node with system ID equal to 001c73aabbcc. The following interface map rules apply:

  • At least one interface interface must be connected to node that matches the regular expression ‘pod+-spine+’ on port Ethernet1/$ (any port on module 1)
  • At least one interface and not the interface which matched in the previous step must be connected to a node that matches the regular expression ‘pod+-spine1’ on port Ethernet2/3

Example #3

---
- name: standard leaf definition
  definition: dc-1/pod-1/leaf_template
  variables:
    - not_spine: excludes('spine')
    - any_spine: regex('spine\d+')
    - any_pod: includes('pod')
  interfaces:
    - Ethernet1: $any_spine:Ethernet1/$
    - Ethernet2: $pod1-spine2:any
    - any: excludes('spine1'):Ethernet49
    - any: excludes('spine2'):Ethernet49
    - Ethernet49:
        device: $not_spine
        port: Ethernet49
    - Ethernet50:
        device: excludes('spine')
        port: Ethernet50

This example pattern could apply to any node that matches the interface map. In includes the use of variables for cleaner implementation and pattern re-use.

  • Variable not_spine matches any node name where ‘spine’ doesn’t appear in the string
  • Variable any_spine matches any node name where the regular expression ‘spine+’ matches the name
  • Variable any_pod matches any node name where that includes the name ‘pod’ in it
  • Variable any_pod_spine combines variables any_spine and any_pod into a complex variable that includes any name that matches the regular express ‘spine+’ and the name includes ‘pod’ (not yet supported)
  • Interface Ethernet1 must be connected to a node that matches the any_spine pattern and is connected on Ethernet1/$ (any port on module 1)
  • Interface Ethernet2 must be connected to node ‘pod1-spine2’ on any Ethernet port
  • Interface any must be connected to any node that doesn’t have ‘spine1’ in the name and is connected on Ethernet49
  • Interface any must be connected to any node that doesn’t have ‘spine2’ in the name and wasn’t already used and is connected to Ethernet49
  • Interface Ethernet49 matches if it is connected to any node that matches the not_spine pattern and is connected on port 49
  • Interface Ethernet50 matches if the node is connected to port Ethernet50 on any node whose name does not contain ‘spine’

Example #4

---
- name: sample mlag definition
  definition: mlag_leaf_template
  variables:
    any_spine: includes('spine')
    not_spine: excludes('spine')
  interfaces:
    - Ethernet1: $any_spine:Ethernet1/$
    - Ethernet2: $any_spine:any
- Ethernet3: none
- Ethernet4: any
- Ethernet5:
    device: includes('oob')
    port: any
- Ethernet49: $not_spine:Ethernet49
- Ethernet50: $not_spine:Ethernet50

This is a similar example to #3 that demonstrates how an MLAG pattern might work.

  • Variable any_spine defines a pattern that includes the word ‘spine’ in the name
  • Variable not_spine defines a pattern that matches the inverse of any_spine
  • Interface Ethernet1 matches if it is connected to any_spine on port Ethernet1/$ (any port on module 1)
  • Interface Ethernet2 matches if it is connected to any_spine on any port
  • Interface 3 matches so long as there is nothing attached to it
  • Interface 4 matches so long as something is attached to it
  • Interface 5 matches if the node contains ‘oob’ in the name and is connected on any port
  • Interface49 matches if it is connected to any device that doesn’t have ‘spine’ in the name and is connected on Ethernet50
  • Interface50 matches if it is connected to any device that doesn’t have ‘spine’ in the name and is connected on port Ethernet50

Example #5

---
- name: Connected to Spine 2
  definition: spine2
  variables:
    any_spine: includes('spine')
  interfaces:
    - any: $any_spine:regex('Ethernet[45]/\d+\1')

In this case, the pattern matches if any local interface is connected to a device with spine in the hostname and to the 4th or 5th slot in the chassis.

More examples

Additional ZTPServer file examples are available on GitHub at the ZTPServer Demo.