Creating a blueprint
A blueprint is a pipeline template. When a network is saved, NanoPing fills in each blueprint with the network's details and deploys the resulting pipelines. A network uses three blueprints:
- Relay: deployed once, to the relay node.
- Relay Client: deployed to the relay node once for every node in the network, including the relay itself.
- Client: deployed to every node in the network, including the relay.
Built-in blueprints
NanoPing comes with a read-only blueprint of each type, named Relay, Relay Client and Client. They are the default blueprints until you choose others, and they are updated automatically when NanoPing is upgraded.
- Relay listens on the relay's carrier with a UDP Local component and passes traffic between clients using Relay Routing Fabric and Relay Network Lookup.
- Relay Client handles the relay's side of one client's connection. It combines all of that client's carriers with Raft.
- Client creates a TUN interface called
tun0with the node's internal IP address, and sends its traffic to the relay over all of the node's carriers with Raft.
The built-in blueprints read one optional parameter, raft_timeout, which sets the Raft stream timeout in milliseconds. The default is 200. A node parameter overrides the network parameter.
To change how the built-in blueprints work, duplicate one and edit the copy.
Duplicating a blueprint
Go to the Networks section and open the Blueprints tab. Open the ⋯ menu on a blueprint's row and choose Duplicate. A copy named Copy of <name> is created and opens in the editor.
To rename it, click its name at the top of the editor, type the new name and click OK. The new name is saved immediately. After editing the template, click Save, or press Ctrl + S.
The ⋯ menu also has:
- Set default …: see Default blueprints.
- Export to library: share the blueprint through the cloud library.
- Delete: remove the blueprint. Built-in blueprints can't be deleted.
Creating a blueprint from scratch
Click + Blueprint in the Networks section. You can then choose to:
- Create Blank Blueprint: start from an empty template.
- Copy Blueprint: copy an existing blueprint, also from another node that keeps networks, under a new name.
- Cloud Library: import a blueprint from the cloud library. This requires signing in.
Using a blueprint in a network
Each network uses the default blueprints unless it has its own. To choose a blueprint for one network, open the network and, under Network Settings, click Set Relay Blueprint, Set Relay Client Blueprint or Set Client Blueprint. Search for the blueprint, pick it, and click Save Network.
To go back to the default, click the bin icon next to the assigned blueprint and save.
Default blueprints
The default blueprints are used by every network that doesn't have its own blueprint of that type. To change a default, open the ⋯ menu on a blueprint in the Blueprints tab and choose Set default Relay, Set default Relay Client or Set default Client. The current defaults are marked with a Default … badge.
Defaults can also be set in the configuration file.
Parameters
A blueprint is written in the Go template language. When the template runs, it receives the following data:
- relay_node_id - ID of the relay node (string)
- blueprint_name - name of the blueprint (string)
- client_node_id - Relay Client blueprint only. ID of the node this Relay Client pipeline serves (string)
- node - the node the pipeline is generated for, with the same fields as an entry in
nodes - nodes - every node in the network, as a map from node ID to node:
- id - node ID (string)
- numeric_id - index of the node in the network, starting at 1
- ip - internal IP address of the node (string)
- carriers - list of carriers:
- numeric_id - index of the carrier
- address
- ip - carrier IP address (string)
- port - carrier port
optionalexternal_ip - carrier external IP address (string)
optionalinterface - interface name (string)optionalbandwidth_priority - bandwidth priority
- the node's own parameters, next to the fields above
- the network's parameters, at the top level
For example, with a network parameter raft_timeout and a node parameter mode:
{{ .raft_timeout }} network parameter
{{ .node.mode }} node parameter of the current node
{{ (index .nodes .relay_node_id).ip }} internal IP address of the relay
{{ (index (index .nodes .relay_node_id).carriers 0).address.port }} port of the relay's carrier
A few things to keep in mind:
- A network parameter named
relay_node_id,nodeornodesis replaced by the value above, and a node parameter named like a node field, such asip, is ignored and reported in the network log. - Optional fields that are empty or zero are left out, so check them with
iforwithbefore using them. - Every number, including
numeric_id,portand numeric parameters, is passed to the template as a floating-point value. It prints normally, butadd,sub,mulanddivonly take whole numbers, so use them withrangeindexes or literal values.
The result must be a valid pipeline configuration in JSON. If a blueprint fails to compile, the error is written to the log of the node the pipeline was meant for, together with the data the template received. You can see it in the network's Log: <node> tab.
Blueprint syntax
A quick reference for the Go template language.
Basic syntax
Actions are wrapped in double curly braces {{ }}.
{{/* this is a comment */}}
{{ .node.id }} output a value
{{- .node.ip -}} output a value and trim the whitespace around it
Variables
{{ $relay := index .nodes .relay_node_id }} declare a variable
{{ $relay.ip }} use it
{{ $relay = .node }} assign a new value
Control flow
if / else
{{ if eq .node.id .relay_node_id }}
this node is the relay
{{ else if .node.mode }}
mode: {{ .node.mode }}
{{ else }}
a client without a mode
{{ end }}
range
{{ range .nodes }}
{{ .ip }}
{{ end }}
{{ range $id, $node := .nodes }}
{{ $id }}: {{ $node.ip }}
{{ end }}
{{ range $i, $carrier := .node.carriers }}
{{ if gt $i 0 }},{{ end }}"carrier-{{ $i }}"
{{ end }}
with
with runs its block only when the value is not empty, and sets . to that value inside the block.
{{ with .node.mode }}
mode: {{ . }}
{{ else }}
no mode set
{{ end }}
Functions
{{ len .nodes }} number of nodes
{{ index .node.carriers 0 }} first carrier of the node
{{ printf "%s has IP %s" .node.id .node.ip }} format a string
{{ add 1 2 }} 3
{{ sub 2 1 }} 1
{{ mul 3 3 }} 9
{{ div 9 3 }} 3
{{ generateUUID }} a random UUID, for example for component names
{{ generateId }} a short random ID
The standard functions of the Go template language, such as eq, ne, gt, and, or and not, are also available.