Automation
Automation

Scripting How-To: Set up an op script that works like an "ezsetup" script

by Cordelia on ‎08-10-2015 09:54 AM - edited on ‎09-11-2017 04:34 PM by Administrator Administrator (1,020 Views)
Overview

Mimic the "ezsetup" script as an op script. This applies to SLAX version 1.0 and higher.

 

Description

 

This example script mimics the "ezsetup" script that ships on some low-end systems. It constructs two styles of configuration. The first part asks questions about the device and builds a stock Junos config. The second asks about the management interface and builds non-Junos config. Then a transformation is run that turns this config into Junos config.


Source Code


GitHub Links


The source code below is also available from GitHub at the following locations:

Example Configuration

 

1	system {
2	    scripts {
3	        op {
4	            file ezsetup.slax {
5	                description "Mimic the "ezsetup" script as an op script";
6	            }
7	        }
8	    }
9	}

 

Example Output

 

01	phil@dent> op ezsetup   
02	*
03	* EZSetup wizard
04	*
05	* Use the EZSetup wizard to configure the identity of the switch.
06	* Once you complete EZSetup, the switch can be accessed over the network.
07	*
08	* To exit the EZSetup wizard press CTRL+C.
09	*
10	* In the wizard, default values are provided for some options.
11	* Press ENTER key to accept the default values.
12	*
13	   Entering data for System Configuration:
14	      Enter Host name (was: dent) [dnsname]: test
15	      Enter Domain name (was: juniper.net) [dnsname]: test.net
16	      Configure Root password? (was: yes) [yes/no]: asdf
17	Please answer 'yes' or 'no'
18	      Configure Root password? (was: yes) [yes/no]: yes
19	         Enter Password [secret]:
20	         Enter Password (re-enter to confirm) :
21	      Entering data for Services:
22	         Configure telnet? [yes/no]: no
23	         Configure Secure Shell (SSH)? (was: yes) [yes/no]: yes
24	   Entering data for Routing options:
25	      Static routes:
26	         Destination:                   152.14.12.0/26
27	            Next hop address:           10.5.1.1
28	            Don't readvertise:          yes
29	         Destination:                   172.25.4.0/24
30	            Next hop address:           10.5.1.1
31	            Don't readvertise:          yes
32	      Enter option (default: continue) [add,delete,list,continue]: add
33	      Enter Destination: 0.0.0.0/0
34	         Enter Next hop address: 10.1.1.1
35	         Enter Don't readvertise [yes/no]: yes
36	      Enter option (default: continue) [add,delete,list,continue]: list
37	      Static routes:
38	         Destination:                   152.14.12.0/26
39	            Next hop address:           10.5.1.1
40	            Don't readvertise:          yes
41	         Destination:                   172.25.4.0/24
42	            Next hop address:           10.5.1.1
43	            Don't readvertise:          yes
44	         Destination:                   0.0.0.0/0
45	            Next hop address:           10.1.1.1
46	            Don't readvertise:          yes
47	      Enter option (default: continue) [add,delete,list,continue]: continue
48	   Configure SNMP? (was: yes) [yes/no]: no
49	   Configure Management interface? [yes/no]: yes
50	      Choose Management interface [default-vlan,named-vlan,out-of-band]: named-vlan
51	         Enter VLAN name: test
52	         Enter VLAN Id [integer]: 401
53	         Enter VLAN IP Prefix (default: 192.168.1.1/24) [ipprefix]: 10.1.2.3/24
54	         Enter Default next-hop (default: 192.168.1.254): 10.1.2.1
55	         Configure Trunk ports? (default: no) [yes/no]: yes
56	            Enter Interface: ge-0/1/2-3
57	            Add another Interface (default: no) [yes/no]: no
58	            Enter option (default: continue) [add,delete,list,continue]: list
59	            Trunk ports:
60	               Interface:               ge-0/1/2-3
61	            Enter option (default: continue) [add,delete,list,continue]: continue
62	 
63	Configuration:
64	   System Configuration:
65	      Host name:                        test
66	      Domain name:                      test.net
67	      Root password:                    yes
68	         Password:                      ********
69	   Routing options:
70	      Static routes:
71	         Destination:                   152.14.12.0/26
72	            Next hop address:           10.5.1.1
73	            Don't readvertise:          yes
74	         Destination:                   172.25.4.0/24
75	            Next hop address:           10.5.1.1
76	            Don't readvertise:          yes
77	         Destination:                   0.0.0.0/0
78	            Next hop address:           10.1.1.1
79	            Don't readvertise:          yes
80	   Management interface:                yes
81	      Management interface:             In-band with named VLAN (vlan.0)
82	         VLAN name:                     test
83	         VLAN Id:                       401
84	         VLAN IP Prefix:                10.1.2.3/24
85	         Default next-hop:              10.1.2.1
86	         Trunk ports:
87	            Interface:                  ge-0/1/2-3
88	Is this configuration accurate? (default: no) [yes/no]: yes
89	...

 

SLAX Script Contents

 

001	version 1.0;
002	 
003	ns junos = "http://xml.juniper.net/junos/*/junos";
004	ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
005	ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
006	ns ext = "http://xmlsoft.org/XSLT/namespace";
007	ns exsl = "http://exslt.org/math";
008	 
009	import "../import/junos.xsl";
010	import "../import/lib-util.slax";
011	import "../import/lib-wizard.slax";
012	 
013	var $vlan-default-prefix = "192.168.1.1/24";
014	var $vlan-default-next-hop = "192.168.1.254";
015	 
016	param $debug;
017	 
018	var $vlan-address-parameters := {
019	    <leaf title="VLAN IP Prefix" path="prefix"
020	          default=$vlan-default-prefix type="ipprefix">;
021	    <leaf title="Default next-hop" path="next-hop"
022	          default=$vlan-default-next-hop>;
023	}
024	 
025	var $vlan-parameters := {
026	    <leaf title="VLAN name" path="vlan">;
027	    <leaf title="VLAN Id" path="id" type="integer" range="2-4096">;
028	    copy-of $vlan-address-parameters;
029	    <list title="Trunk ports" path="interfaces"> {
030	    <key title="Interface">;
031	    }
032	}
033	 
034	var $guide := {
035	    <container title="System Configuration" path="system"> {
036	    <ignore-choice title="Vehicle to drive"> {
037	        <container choice="car" title="Car" path="car"> {
038	        <leaf title="Year of Manufactor" path="year">;
039	        <leaf title="Manufactor" path="make">;
040	        <leaf title="Model" path="model">;
041	        }
042	        <container choice="suv" title="SUV" path="suv"> {
043	        <leaf title="Mile per gallon" path="mpg">;
044	        }
045	    }
046	    <leaf title="Host name" path="host-name" type="dnsname"> {
047	        <help> "The DNS name for this device";
048	    }
049	    <leaf title="Domain name" path="domain-name" type="dnsname"> {
050	        <help> {
051	        <line> "The DNS domain to which this device belongs";
052	        <line> "This will be the default DNS search path";
053	        }
054	    }
055	    <option title="Root password" path="root-authentication"> {
056	        <leaf title="Password" path="plain-text-password-value"
057	              type="secret">;
058	    }
059	    <container title="Services" path="services"> {
060	        <option title="telnet" path="telnet">;
061	        <option title="Secure Shell (SSH)" path="ssh">;
062	    }
063	    <ignore-container path="login"> {
064	        <list title="User accounts" path="user"> {
065	        <key title="User name">;
066	        <leaf title="Full name" path="full-name">;
067	        <leaf title="Class name" path="class">;
068	        }
069	    }
070	    }
071	    <container title="Routing options" path="routing-options"> {
072	    <container path="static"> {
073	        <list title="Static routes" path="route"> {
074	        <key title="Destination">;
075	        <leaf title="Next hop address" path="next-hop">;
076	        <leaf title="Don't readvertise" path="no-readvertise"
077	             type="empty">;
078	        }
079	    }
080	    }
081	    <container ask="yes" title="SNMP" path="snmp"> {
082	        <leaf title="Contact information" path="contact">;
083	        <leaf title="Community name" path="community">;
084	        <leaf title="Physical location of system" path="location">;
085	    }
086	    <option title="Management interface" path="mgmt"> {
087	    <choice title="Management interface"> {
088	        <container choice="default-vlan"
089	               title="In-band with default VLAN (vlan.0)"
090	                   path="default-vlan"> {
091	        copy-of $vlan-address-parameters;
092	        }
093	        <container choice="named-vlan"
094	               title="In-band with named VLAN (vlan.0)"
095	               path="named-vlan"> {
096	        copy-of $vlan-parameters;
097	        }
098	        <container choice="out-of-band"
099	               title="Out of band via managment ethernet (me0)"
100	               path="out-of-band"> {
101	        copy-of $vlan-address-parameters;
102	        }
103	    }
104	    }
105	}
106	 
107	var $banner-message := {
108	    <line> "*";
109	    <line> "* EZSetup wizard";
110	    <line> "*";
111	    <line> "* Use the EZSetup wizard to configure the identity of the switch.";
112	    <line> "* Once you complete EZSetup, "
113	            _ "the switch can be accessed over the network.";
114	    <line> "*";
115	    <line> "* To exit the EZSetup wizard press CTRL+C.";
116	    <line> "*";
117	    <line> "* In the wizard, default values are provided for some options.";
118	    <line> "* Press ENTER key to accept the default values.";
119	    <line> "*";
120	}
121	 
122	var $swinfo = jcs:invoke("get-software-information");
123	var $model = $swinfo/product-model;
124	 
125	var $non-uplnk-ports = {
126	    if (starts-with($model, "ex3200-24")
127	    || starts-with($model, "ex4200-24")) {
128	    expr 23;
129	    } else if (starts-with($model, "ex3200-48")
130	           || starts-with($model, "ex4200-48")) {
131	        expr 47;
132	    }
133	}
134	 
135	var $sys-mgmt-if = {
136	    if (starts-with($model, "ex4200")) {
137	    expr "vme";
138	    } else {
139	    expr "me0";
140	    }
141	}
142	 
143	var $sys-slot-id = jcs:sysctl("hw.re.slotid", "i");
144	 
145	match / {
146	    <op-script-results> {
147	    <out> {
148	        call main;
149	    }
150	    }
151	}
152	 
153	template main
154	{
155	    call banner-message($banner-message);
156	    var $rpc = <get-configuration database="committed" inherit="inherit">;
157	    var $config = jcs:invoke($rpc);
158	 
159	    var $new := {
160	    call wizard-builder($config, $guide, $title = "ezsetup");
161	    }
162	 
163	    if ($debug) {
164	    call jcs:dump($name = "new", $out = $new);
165	    }
166	 
167	    if ($new/node()) {
168	 
169	    var $tconfig := { call transform($new); }
170	    if ($debug) {
171	        call jcs:dump($name = "tconfig", $out = $tconfig);
172	    }
173	 
174	    call commit-config($config = $tconfig);
175	    }
176	}
177	 
178	/*
179	 * This template transforms the user-oriented config in the
180	 * guide into config that is junos-compatible.  The only
181	 * part that's affected is the "mgmt" hierarchy, which is
182	 * transformed into [vlan], [interfaces], and [routing-options]
183	 * configuration.
184	 */
185	template transform ($new)
186	{
187	    var $list := {
188	    call expand-interfaces($input = $new/mgmt/node()/interfaces);
189	    }
190	 
191	    var $rest := $new/node()[name() != "mgmt"];
192	    copy-of $rest;
193	 
194	    if ($new/mgmt) {
195	    if (not($new/mgmt/out-of-band)) {
196	        <vlan> {
197	        if ($new/mgmt/named-vlan) {
198	            var $vlan = $new/mgmt/named-vlan;
199	            <name> $vlan/vlan;
200	            <vlan-id> $vlan/id;
201	            <l3-interface> "vlan.0";
202	 
203	        } else { /* if ($new/mgmt/default-vlan) */
204	            <name> "default";
205	            <l3-interface> "vlan.0";
206	        }
207	        }
208	    }
209	 
210	    var $addr = $new/mgmt/node();
211	 
212	    <interfaces> {
213	        <interface> {
214	        if ($new/mgmt/out-of-band) {
215	            <name> "me0";
216	        } else {
217	            <name> "vlan";
218	        }
219	 
220	        <unit> {
221	            <name> "0";
222	            <family> {
223	            <inet> {
224	                <address> {
225	                <name> jcs:first-of($addr/prefix,
226	                            $vlan-default-prefix);
227	                }
228	            }
229	            }
230	        }
231	        }
232	 
233	        for-each ($list/name) {
234	        <interface> {
235	            <name> .;
236	            <unit> {
237	            <name> "0";
238	            <family> {
239	                <ethernet-switching>;
240	            }
241	            }
242	        }
243	        }
244	    }
245	 
246	    <routing-options> {
247	        <static> {
248	        <route> {
249	            <name> "0.0.0.0/0";
250	            <next-hop> jcs:first-of($addr/next-hop,
251	                        $vlan-default-next-hop);
252	        }
253	        }
254	    }
255	    }
256	}
257	 
258	template expand-interfaces ($input)
259	{
260	    for-each ($input) {
261	    expr jcs:output("expand: ", .);
262	    var $ranges = jcs:split(",", .);
263	    for-each ($ranges) {
264	        var $re = jcs:regex("^(.*)/([0-9]+)-([0-9]+)$", .);
265	        if ($re[1]) {
266	        expr jcs:output("range: ", .);
267	        call generate-interface-range($base = $re[2],
268	                          $min = $re[3], $max = $re[4]);
269	        } else {
270	        expr jcs:output("dull: ", .);
271	        <name> .;
272	        }
273	    }
274	    }
275	}
276	 
277	template generate-interface-range ($base, $min, $max)
278	{
279	    <name> $base _ "/" _ $min;
280	    if ($min < $max) {
281	    call generate-interface-range($base, $min = $min + 1, $max);
282	    }
283	}

 

XML Script Contents

 

01	<?xml version="1.0"?>
02	<script>
03	  <title>ezsetup.slax</title>
04	  <author>phil.shafer</author>
05	  <synopsis>
06	    Mimic the "ezsetup" script as an op script
07	  </synopsis>
08	  <coe>op</coe>
09	  <type>setup</type>
10	 
11	  <description>
12	This example script mimics the "ezsetup" script that ships on some
13	low-end boxes.  It constructs two styles of configuration.  The first
14	part asks questions about the device and builds stock junos config.
15	The second asks about the management interface and builds non-junos
16	config.  Then a transformation is run that turns this config into
17	junos config.
18	 
19	  </description>
20	 
21	  <example>
22	    <title>ezsetup example</title>
23	    <description>sample session</description>
24	    <config>example-1.conf</config>
25	    <output>example-1.output</output>
26	  </example>
27	 
28	  <xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml"
29	                src="../../../../../web/leaf.js"
30	            type="text/javascript"/>
31	</script>