]> git.datanom.net - netconf.git/blame - netconf
Add test for option record
[netconf.git] / netconf
CommitLineData
c947c6e2 1#!/usr/bin/env python
6640d1bf
MR
2#
3# This file and its contents are supplied under the terms of the
4# Common Development and Distribution License ("CDDL"), version 1.0.
5# You may only use this file in accordance with the terms of version
6# 1.0 of the CDDL.
7#
8# A full copy of the text of the CDDL should have accompanied this
0b4b929c 9# source. A copy of the CDDL is also available via the Internet at
6640d1bf
MR
10# http://www.illumos.org/license/CDDL.
11#
c947c6e2 12
6640d1bf
MR
13#
14# Copyright 2017 <Michael Rasmussen>
15#
16
17#
18# The porpuse of this script is to help with basic and/or initial
19# network configuration for Illumos based distribution. However,
20# the script is developed specifically for OmniOS so there is no
21# garaunty that it will work on other Illumos based distributions
22# than Omnios.
23#
24
25import sys, subprocess, getopt
c947c6e2
MR
26
27def runcmd(cmd):
28 process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
29 output, error = process.communicate();
30
31 return (output.rstrip(), error.rstrip())
32
33class ParserError(Exception):
34 pass
35
36class Parser:
37 """ Parse nic information """
38
39 def __init__(self):
40 self.__dladm1 = "dladm show-phys -p -o link,media | sed 's/:/ /g'"
41 self.__dladm2 = "dladm show-phys -p -m -o link,address,inuse | sed 's/:/ /g' | sed 's/\\\[[:space:]]/:/g' | sed 's/\\\//g'"
42
43 def __parse_nics(self, text):
44 nics = {}
45 for line in text.splitlines():
46 parts = line.split()
47 #if parts[1] in ('Ethernet', 'Infiniband'):
48 if parts[1] in ('Ethernet'):
49 nics[parts[0]] = [parts[0], parts[1]]
50
51 return nics
52
53 def __parse_macs(self, obj, text):
54 list = []
55 if obj:
56 for line in text.splitlines():
57 parts = line.split()
58 try:
59 if parts[2] == 'yes':
60 del obj[parts[0]]
61 else:
62 obj[parts[0]].append(parts[1])
63 except KeyError:
64 pass
65 for k, v in obj.items():
66 list.append(v)
67
68 return list
69
70 def parse(self):
71 (nics, error) = runcmd(self.__dladm1)
72 if error:
73 raise ParserError(error)
74
75 (macs, error) = runcmd(self.__dladm2)
76 if error:
77 raise ParserError(error)
78
79 return self.__parse_macs(self.__parse_nics(nics), macs)
80
81def get_terminal_width():
82 try:
83 if sys.version_info >= (2,7):
84 width = int(subprocess.check_output(['tput', 'cols']))
85 else:
86 (out, err) = runcmd('tput cols')
87 if err:
88 raise OSError(err);
89 width = int(out)
90 except OSError as e:
91 print("Invalid Command 'tput cols': exit status ({1})".format(e.errno))
92 except subprocess.CalledProcessError as e:
93 print("Command 'tput cols' returned non-zero exit status: ({1})".format(e.returncode))
94 else:
95 return width
96
97def make_menu(interfaces):
98 res = None
99 while not res:
100 sys.stderr.write("\x1b[2J\x1b[H")
101 cols = get_terminal_width()
102 intro = 'The following unconfigured interfaces was discovered'
103 fill = (cols / 2) - (len(intro) / 2)
104 print '{0:^{cols}}'.format('Simple network interface configuration tool', cols=cols)
105 print
106 print '{0:<{fill}}{1}'.format('', intro, fill=fill)
107 print '{0:<{fill}}{1:>2} {2:^15} {3:^10} {4:^17}'.format('','#','Interface','Media','MAC',fill=fill)
108 print '{0:<{fill}}{1:-^2} {2:-^15} {3:-^10} {4:-^17}'.format('','','','','',fill=fill)
109
110 n = 0
111 for i in interfaces:
112 print '{0:<{fill}}{1:>2} {2:<15} {3:<10} {4:>17}'.format('',n,i[0],i[1],i[2],fill=fill)
113 n += 1
114 print
115 print '{0:<{fill}}{1:<}'.format('','select interface number to configure:',fill=fill),
116 nic = int(raw_input())
117 if nic >= n or nic < 0:
118 print '{0:<{fill}}{1:<} {2:<}'.format('','Error: Interface: 0 <= # <',n,fill=fill),
119 raw_input(' << Hit any key >>')
120 else:
121 res = interfaces[nic]
122
123 return res
124
125def get_config():
126 ip = mask = gw = None
127 nettype = raw_input('dhcp or static [dhcp]: ').lower()
128 if nettype == 'static':
129 while not ip:
130 ip = raw_input('Enter IP: ')
131 mask = raw_input('Enter netmask [24]: ')
132 if not mask:
133 mask = 24
134 gw = raw_input('Enter default route [0=no]: ')
135 if not gw:
136 gw = 0
137
138 return (ip,mask,gw)
139
6640d1bf
MR
140def usage():
141 print 'Usage: %s [options]' % sys.argv[0]
142 print
143 print '%s' % """Options:
144 -h, --help This usage.
145 -a, --address IP for interface. 0 means use DHCP
146 -g, --gateway Default gateway. Optional.
147 -i, --interface Interface to configure.
148 -m, --netmask Netmask to use for interface. Default /24.
db08f9b3
MR
149 -n, --nameserver Nameserver to use. Optional.
150 -r, --record Output create commands to stdout."""
6640d1bf
MR
151
152def parse_input():
153 options = ()
154
155 try:
156 opts, args = getopt.gnu_getopt(sys.argv[1:],
0b4b929c
MR
157 'ha:g:i:m:n:r', ['help', 'address=', 'gateway=',
158 'interface=', 'netmask=', 'nameserver=', 'record'])
6640d1bf
MR
159 except getopt.GetoptError as err:
160 print str(err)
161 usage()
162 sys.exit(2)
163
164 address = gateway = interface = netmask = nameserver = None
0b4b929c 165 record = False
6640d1bf
MR
166
167 if opts:
168 for o, a in opts:
169 if o in ('-h', '--help'):
170 usage()
171 sys.exit(0)
172 if o in ('-a', '--address'):
173 address = a
174 elif o in ('-g', '--gateway'):
175 gateway = a
176 elif o in ('-i', '--interface'):
177 interface = a
178 elif o in ('-m', '--netmask'):
179 netmask = a
180 elif o in ('-n', '--nameserver'):
181 nameserver = a
0b4b929c
MR
182 elif o in ('-r', '--record'):
183 record = True
6640d1bf
MR
184 else:
185 assert False, 'Unhandled option'
e8e90d5a
MR
186
187 if (record):
188 if not (bool(address) ^ bool(interface)):
189 print 'Error: missing options'
190 usage()
191 sys.exit(2)
192 else:
193 if not address or not interface or error:
194 print 'Error: missing options'
195 usage()
196 sys.exit(2)
197
6640d1bf
MR
198 if address == '0':
199 address = None
200 if not netmask:
201 netmask = '24'
202
203 options = (interface, address, netmask, gateway, nameserver)
204
205 return options
206
c947c6e2 207def main():
6640d1bf
MR
208 interactive = True
209
210 options = parse_input()
211 if options:
212 interactive = False
213
c947c6e2
MR
214 p = Parser()
215 try:
216 interfaces = p.parse()
217 if interfaces:
6640d1bf
MR
218 if interactive:
219 nic = make_menu(interfaces)
220 else:
f5cdd655
MR
221 nic = options
222 found = False
223 for i in interfaces:
224 if nic[0] == i[0]:
225 found = True
226 break
227 if not found:
228 err = '%s: No such interface' % nic[0]
229 raise RuntimeError(err)
c947c6e2 230 if nic:
6640d1bf
MR
231 if interactive:
232 (ip,mask,gw) = get_config()
233 else:
234 ip = options[1]
235 mask = options[2]
236 gw = options[3]
c947c6e2 237 cmd = 'ipadm delete-if %s' % nic[0]
0b4b929c
MR
238 if record:
239 print cmd
240 else:
241 runcmd(cmd)
c947c6e2 242 cmd = 'ipadm create-if %s' % nic[0]
0b4b929c
MR
243 if record:
244 print cmd
245 else:
246 (out, err) = runcmd(cmd)
247 if err:
248 raise RuntimeError(err)
c947c6e2
MR
249 if not ip:
250 # use DHCP
251 cmd = 'ipadm create-addr -T dhcp %s/v4' % nic[0]
0b4b929c
MR
252 if record:
253 print cmd
254 else:
255 (out, err) = runcmd(cmd)
256 if err:
257 raise RuntimeError(err)
c947c6e2
MR
258 else:
259 # use STATIC
260 cmd = 'ipadm create-addr -T static -a %s/%s %s/v4' % (ip, mask, nic[0])
0b4b929c
MR
261 if record:
262 print cmd
263 else:
264 (out, err) = runcmd(cmd)
265 if err:
266 raise RuntimeError(err)
c947c6e2
MR
267 if gw:
268 cmd = 'route -p add default %s' % gw
0b4b929c
MR
269 if record:
270 print cmd
271 else:
272 (out, err) = runcmd(cmd)
273 if err:
274 raise RuntimeError(err)
275 if not record:
276 cmd = 'netstat -rn -finet'
277 (out, err) = runcmd(cmd)
278 if err:
279 raise RuntimeError(err)
280 print 'New route table'
281 print out
6640d1bf
MR
282 if interactive:
283 dns = raw_input('Configure DNS [n]? ').lower()
284 else:
285 dns = options[4]
c947c6e2
MR
286 if not dns or dns == 'n':
287 pass
288 else:
6640d1bf
MR
289 if interactive:
290 dns = None
291 print
292 while not dns:
293 dns = raw_input('Enter nameserver: ')
294
6da15cee
MR
295 cmd = "echo 'nameserver %s' >> /etc/resolv.conf " % dns
296 cmd += '&& cp /etc/nsswitch.conf{,.bak} '
c947c6e2 297 cmd += '&& cp /etc/nsswitch.{dns,conf}'
0b4b929c
MR
298 if record:
299 print cmd
300 else:
301 (out, err) = runcmd(cmd)
302 if err:
303 raise RuntimeError(err)
c947c6e2
MR
304 else:
305 print "Found no unassigned interfaces"
306 except ParserError as e:
307 print 'Parse Errror: %s' % e
308 except RuntimeError as e:
309 print 'Runtime Error: %s' % e
310
311if __name__ == '__main__':
312 try:
313 main()
314 except KeyboardInterrupt:
315 sys.stderr.write("\x1b[2J\x1b[H")
316
This page took 0.108662 seconds and 5 git commands to generate.