1# -*- coding: utf-8 -*-
2import re
3
4from .base import CommandTestCase
5from gandi.cli.commands import ip
6from gandi.cli.core.base import GandiContextHelper
7
8
9class IpTestCase(CommandTestCase):
10
11    def test_list(self):
12
13        result = self.invoke_with_exceptions(ip.list, [])
14
15        self.assertEqual(result.output, """\
16ip         : 95.142.160.181
17state      : created
18type       : public
19datacenter : FR-SD2
20----------
21ip         : 2001:4b98:dc2:43:216:3eff:fece:e25f
22state      : created
23type       : public
24datacenter : LU-BI1
25----------
26ip         : 2001:4b98:dc0:47:216:3eff:feb2:3862
27state      : created
28type       : public
29datacenter : FR-SD2
30----------
31ip         : 192.168.232.253
32state      : created
33type       : private
34vlan       : pouet
35datacenter : FR-SD2
36----------
37ip         : 192.168.232.252
38state      : created
39type       : private
40vlan       : pouet
41datacenter : FR-SD2
42""")
43        self.assertEqual(result.exit_code, 0)
44
45    def test_list_details(self):
46        args = ['--id', '--version', '--vm', '--reverse']
47        result = self.invoke_with_exceptions(ip.list, args)
48
49        self.assertEqual(result.output, """\
50ip         : 95.142.160.181
51state      : created
52id         : 203968
53version    : 4
54reverse    : xvm-160-181.dc0.ghst.net
55type       : public
56vm         : server01
57datacenter : FR-SD2
58----------
59ip         : 2001:4b98:dc2:43:216:3eff:fece:e25f
60state      : created
61id         : 204557
62version    : 6
63reverse    : xvm6-dc2-fece-e25f.ghst.net
64type       : public
65datacenter : LU-BI1
66----------
67ip         : 2001:4b98:dc0:47:216:3eff:feb2:3862
68state      : created
69id         : 204558
70version    : 6
71reverse    : xvm6-dc0-feb2-3862.ghst.net
72type       : public
73vm         : server01
74datacenter : FR-SD2
75----------
76ip         : 192.168.232.253
77state      : created
78id         : 2361
79version    : 4
80reverse    :
81type       : private
82vlan       : pouet
83vm         : server02
84datacenter : FR-SD2
85----------
86ip         : 192.168.232.252
87state      : created
88id         : 2361
89version    : 4
90reverse    :
91type       : private
92vlan       : pouet
93vm         : server02
94datacenter : FR-SD2
95""")
96        self.assertEqual(result.exit_code, 0)
97
98    def test_list_attached(self):
99
100        result = self.invoke_with_exceptions(ip.list, ['--attached'])
101
102        self.assertEqual(result.output, """\
103ip         : 95.142.160.181
104state      : created
105type       : public
106datacenter : FR-SD2
107----------
108ip         : 2001:4b98:dc0:47:216:3eff:feb2:3862
109state      : created
110type       : public
111datacenter : FR-SD2
112----------
113ip         : 192.168.232.253
114state      : created
115type       : private
116vlan       : pouet
117datacenter : FR-SD2
118----------
119ip         : 192.168.232.252
120state      : created
121type       : private
122vlan       : pouet
123datacenter : FR-SD2
124""")
125        self.assertEqual(result.exit_code, 0)
126
127    def test_list_detached(self):
128
129        result = self.invoke_with_exceptions(ip.list, ['--detached'])
130
131        self.assertEqual(result.output, """\
132ip         : 2001:4b98:dc2:43:216:3eff:fece:e25f
133state      : created
134type       : public
135datacenter : LU-BI1
136""")
137        self.assertEqual(result.exit_code, 0)
138
139    def test_list_filter_type(self):
140
141        result = self.invoke_with_exceptions(ip.list, ['--type', 'private'])
142
143        self.assertEqual(result.output, """\
144ip         : 2001:4b98:dc2:43:216:3eff:fece:e25f
145state      : created
146type       : public
147datacenter : LU-BI1
148----------
149ip         : 192.168.232.253
150state      : created
151type       : private
152vlan       : pouet
153datacenter : FR-SD2
154----------
155ip         : 192.168.232.252
156state      : created
157type       : private
158vlan       : pouet
159datacenter : FR-SD2
160""")
161        self.assertEqual(result.exit_code, 0)
162
163    def test_list_filter_datacenter(self):
164
165        result = self.invoke_with_exceptions(ip.list, ['--datacenter', 'FR'])
166
167        self.assertEqual(result.output, """\
168ip         : 95.142.160.181
169state      : created
170type       : public
171datacenter : FR-SD2
172----------
173ip         : 2001:4b98:dc0:47:216:3eff:feb2:3862
174state      : created
175type       : public
176datacenter : FR-SD2
177----------
178ip         : 192.168.232.253
179state      : created
180type       : private
181vlan       : pouet
182datacenter : FR-SD2
183----------
184ip         : 192.168.232.252
185state      : created
186type       : private
187vlan       : pouet
188datacenter : FR-SD2
189""")
190        self.assertEqual(result.exit_code, 0)
191
192    def test_list_filter_vlan(self):
193
194        result = self.invoke_with_exceptions(ip.list, ['--vlan', 'pouet'])
195
196        self.assertEqual(result.output, """\
197ip         : 192.168.232.253
198state      : created
199type       : private
200vlan       : pouet
201datacenter : FR-SD2
202----------
203ip         : 192.168.232.252
204state      : created
205type       : private
206vlan       : pouet
207datacenter : FR-SD2
208""")
209        self.assertEqual(result.exit_code, 0)
210
211    def test_list_attached_detached(self):
212        args = ['--detached', '--attached']
213        result = self.invoke_with_exceptions(ip.list, args)
214
215        self.assertEqual(result.output, """\
216You can't set --attached and --detached at the same time.
217""")
218        self.assertEqual(result.exit_code, 0)
219
220    def test_info(self):
221        args = ['95.142.160.181']
222        result = self.invoke_with_exceptions(ip.info, args)
223
224        self.assertEqual(result.output, """\
225ip         : 95.142.160.181
226state      : created
227reverse    : xvm-160-181.dc0.ghst.net
228type       : public
229vm         : server01
230datacenter : FR-SD2
231""")
232        self.assertEqual(result.exit_code, 0)
233
234    def test_update_ko(self):
235        args = ['95.142.160.181']
236        result = self.invoke_with_exceptions(ip.update, args)
237
238        self.assertEqual(result.output, '')
239        self.assertEqual(result.exit_code, 0)
240
241    def test_update_reverse(self):
242        args = ['95.142.160.181', '--reverse', 'plop.bloup.com']
243        result = self.invoke_with_exceptions(ip.update, args)
244
245        self.assertEqual(re.sub(r'\[#+\]', '[###]',
246                                result.output.strip()), """\
247Updating your IP
248\rProgress: [###] 100.00%  00:00:00""")
249
250        self.assertEqual(result.exit_code, 0)
251
252    def test_attach_ko(self):
253        args = ['395.142.160.181', 'vm1426759833']
254        result = self.invoke_with_exceptions(ip.attach, args)
255
256        self.assertTrue("Can't find this ip 395.142.160.181" in result.output)
257        self.assertEqual(result.exit_code, 2)
258
259    def test_attach_already(self):
260        args = ['95.142.160.181', 'server01']
261        result = self.invoke_with_exceptions(ip.attach, args, input='y\n')
262
263        self.assertEqual(result.output, """\
264This ip is already attached to this vm.
265""")
266        self.assertEqual(result.exit_code, 0)
267
268    def test_attach(self):
269        args = ['95.142.160.181', 'vm1426759833']
270        result = self.invoke_with_exceptions(ip.attach, args, input='y\n')
271
272        self.assertEqual(re.sub(r'\[#+\]', '[###]',
273                                result.output.strip()), """\
274Are you sure you want to detach 95.142.160.181 from vm 152967 [y/N]: y
275The iface is still attached to the vm 152967.
276Will detach it.
277\rProgress: [###] 100.00%  00:00:00  \
278\n\rProgress: [###] 100.00%  00:00:00""")
279
280        self.assertEqual(result.exit_code, 0)
281
282    def test_attach_force(self):
283        args = ['95.142.160.181', 'vm1426759833', '--force']
284        result = self.invoke_with_exceptions(ip.attach, args)
285
286        self.assertEqual(re.sub(r'\[#+\]', '[###]',
287                                result.output.strip()), """\
288The iface is still attached to the vm 152967.
289Will detach it.
290\rProgress: [###] 100.00%  00:00:00  \
291\n\rProgress: [###] 100.00%  00:00:00""")
292
293        self.assertEqual(result.exit_code, 0)
294
295    def test_attach_refuse(self):
296        args = ['95.142.160.181', 'vm1426759833']
297        result = self.invoke_with_exceptions(ip.attach, args, input='N\n')
298
299        self.assertEqual(re.sub(r'\[#+\]', '[###]',
300                                result.output.strip()), """\
301Are you sure you want to detach 95.142.160.181 from vm 152967 [y/N]: N""")
302
303        self.assertEqual(result.exit_code, 0)
304
305    def test_attach_background(self):
306        args = ['95.142.160.181', 'vm1426759833', '--force', '--bg']
307        result = self.invoke_with_exceptions(ip.attach, args)
308
309        self.assertEqual(re.sub(r'\[#+\]', '[###]',
310                                result.output.strip()), """\
311The iface is still attached to the vm 152967.
312Will detach it.
313\rProgress: [###] 100.00%  00:00:00""")
314
315        self.assertEqual(result.exit_code, 0)
316
317    def test_create_default(self):
318        args = []
319        result = self.invoke_with_exceptions(ip.create, args,
320                                             obj=GandiContextHelper())
321
322        self.assertEqual(re.sub(r'\[#+\]', '[###]',
323                                result.output.strip()), """\
324Creating your iface.
325\rProgress: [###] 100.00%  00:00:00  \
326\nYour iface has been created with the following IP addresses:
327ip4:\t95.142.160.181
328ip6:\t2001:4b98:dc0:47:216:3eff:feb2:3862""")
329
330        self.assertEqual(result.exit_code, 0)
331        params = self.api_calls['hosting.iface.create'][0][0]
332        self.assertEqual(params['datacenter_id'], 3)
333        self.assertEqual(params['bandwidth'], 102400)
334        self.assertEqual(params['ip_version'], 4)
335
336    def test_create_datacenter_limited(self):
337        args = ['--datacenter', 'FR-SD2', '--bandwidth', '51200',
338                '--ip-version', '6']
339        result = self.invoke_with_exceptions(ip.create, args,
340                                             obj=GandiContextHelper())
341
342        self.assertEqual(re.sub(r'\[#+\]', '[###]',
343                                result.output.strip()), """\
344/!\ Datacenter FR-SD2 will be closed on 25/12/2017, please consider using \
345another datacenter.
346Creating your iface.
347\rProgress: [###] 100.00%  00:00:00  \
348\nYour iface has been created with the following IP addresses:
349ip4:\t95.142.160.181
350ip6:\t2001:4b98:dc0:47:216:3eff:feb2:3862""")
351
352        self.assertEqual(result.exit_code, 0)
353        params = self.api_calls['hosting.iface.create'][0][0]
354        self.assertEqual(params['datacenter_id'], 1)
355        self.assertEqual(params['bandwidth'], 51200)
356        self.assertEqual(params['ip_version'], 6)
357
358    def test_create_datacenter_closed(self):
359        args = ['--datacenter', 'US-BA1', '--bandwidth', '51200',
360                '--ip-version', '6']
361        result = self.invoke_with_exceptions(ip.create, args,
362                                             obj=GandiContextHelper())
363
364        self.assertEqual(re.sub(r'\[#+\]', '[###]',
365                                result.output.strip()), """\
366Error: /!\ Datacenter US-BA1 is closed, please choose another datacenter.""")
367
368        self.assertEqual(result.exit_code, 1)
369
370    def test_create_params(self):
371        args = ['--datacenter', 'FR', '--bandwidth', '51200',
372                '--ip-version', '6']
373        result = self.invoke_with_exceptions(ip.create, args,
374                                             obj=GandiContextHelper())
375
376        self.assertEqual(re.sub(r'\[#+\]', '[###]',
377                                result.output.strip()), """\
378/!\ Datacenter FR will be closed on 25/12/2017, please consider using \
379another datacenter.
380Creating your iface.
381\rProgress: [###] 100.00%  00:00:00  \
382\nYour iface has been created with the following IP addresses:
383ip4:\t95.142.160.181
384ip6:\t2001:4b98:dc0:47:216:3eff:feb2:3862""")
385
386        self.assertEqual(result.exit_code, 0)
387        params = self.api_calls['hosting.iface.create'][0][0]
388        self.assertEqual(params['datacenter_id'], 1)
389        self.assertEqual(params['bandwidth'], 51200)
390        self.assertEqual(params['ip_version'], 6)
391
392    def test_create_params_vlan_ko(self):
393        args = ['--datacenter', 'FR', '--bandwidth', '51200',
394                '--ip-version', '6', '--vlan', 'pouet']
395        result = self.invoke_with_exceptions(ip.create, args,
396                                             obj=GandiContextHelper())
397
398        self.assertEqual(re.sub(r'\[#+\]', '[###]',
399                                result.output.strip()), """\
400You must have an --ip-version to 4 when having a vlan.""")
401        self.assertEqual(result.exit_code, 0)
402
403    def test_create_params_vlan_ok(self):
404        args = ['--datacenter', 'FR', '--bandwidth', '51200',
405                '--ip-version', '4', '--vlan', 'pouet']
406        result = self.invoke_with_exceptions(ip.create, args,
407                                             obj=GandiContextHelper())
408
409        self.assertEqual(re.sub(r'\[#+\]', '[###]',
410                                result.output.strip()), """\
411/!\ Datacenter FR will be closed on 25/12/2017, please consider using \
412another datacenter.
413Creating your iface.
414\rProgress: [###] 100.00%  00:00:00  \
415\nYour iface has been created with the following IP addresses:
416ip4:\t95.142.160.181
417ip6:\t2001:4b98:dc0:47:216:3eff:feb2:3862""")
418        self.assertEqual(result.exit_code, 0)
419        params = self.api_calls['hosting.iface.create'][0][0]
420        self.assertEqual(params['datacenter_id'], 1)
421        self.assertEqual(params['bandwidth'], 51200)
422        self.assertEqual(params['ip_version'], 4)
423        self.assertEqual(params['vlan'], 717)
424
425    def test_create_params_ip_ko(self):
426        args = ['--datacenter', 'FR', '--bandwidth', '51200',
427                '--ip-version', '4', '--ip', '10.50.10.10']
428        result = self.invoke_with_exceptions(ip.create, args,
429                                             obj=GandiContextHelper())
430
431        self.assertEqual(re.sub(r'\[#+\]', '[###]',
432                                result.output.strip()), """\
433You must have a --vlan when giving an --ip.""")
434        self.assertEqual(result.exit_code, 0)
435
436    def test_create_params_ip_ok(self):
437        args = ['--datacenter', 'FR', '--bandwidth', '51200',
438                '--ip-version', '4', '--ip', '10.50.10.10',
439                '--vlan', 'pouet']
440        result = self.invoke_with_exceptions(ip.create, args,
441                                             obj=GandiContextHelper())
442
443        self.assertEqual(re.sub(r'\[#+\]', '[###]',
444                                result.output.strip()), """\
445/!\ Datacenter FR will be closed on 25/12/2017, please consider using \
446another datacenter.
447Creating your iface.
448\rProgress: [###] 100.00%  00:00:00  \
449\nYour iface has been created with the following IP addresses:
450ip4:\t10.50.10.10""")
451        self.assertEqual(result.exit_code, 0)
452        params = self.api_calls['hosting.iface.create'][0][0]
453        self.assertEqual(params['datacenter_id'], 1)
454        self.assertEqual(params['bandwidth'], 51200)
455        self.assertEqual(params['ip_version'], 4)
456        self.assertEqual(params['vlan'], 717)
457        self.assertEqual(params['ip'], '10.50.10.10')
458
459    def test_create_params_attach_ko(self):
460        args = ['--datacenter', 'US', '--bandwidth', '51200',
461                '--ip-version', '4', '--attach', 'server01']
462        result = self.invoke_with_exceptions(ip.create, args,
463                                             obj=GandiContextHelper())
464
465        self.assertEqual(re.sub(r'\[#+\]', '[###]',
466                                result.output.strip()), """\
467The datacenter you provided does not match the datacenter of the \
468vm you want to attach to.""")
469        self.assertEqual(result.exit_code, 0)
470
471    def test_create_params_attach_ok(self):
472        args = ['--datacenter', 'FR', '--bandwidth', '51200',
473                '--ip-version', '4', '--ip', '10.50.10.10',
474                '--vlan', 'pouet', '--attach', 'server01']
475        result = self.invoke_with_exceptions(ip.create, args,
476                                             obj=GandiContextHelper())
477
478        self.assertEqual(re.sub(r'\[#+\]', '[###]',
479                                result.output.strip()), """\
480/!\ Datacenter FR will be closed on 25/12/2017, please consider using \
481another datacenter.
482Creating your iface.
483\rProgress: [###] 100.00%  00:00:00  \
484\nYour iface has been created with the following IP addresses:
485ip4:\t10.50.10.10
486Attaching your iface.
487\rProgress: [###] 100.00%  00:00:00""")
488        self.assertEqual(result.exit_code, 0)
489        params = self.api_calls['hosting.iface.create'][0][0]
490        self.assertEqual(params['datacenter_id'], 1)
491        self.assertEqual(params['bandwidth'], 51200)
492        self.assertEqual(params['ip_version'], 4)
493        self.assertEqual(params['vlan'], 717)
494        self.assertEqual(params['ip'], '10.50.10.10')
495
496    def test_create_background(self):
497        args = ['--datacenter', 'FR', '--bandwidth', '51200',
498                '--ip-version', '4', '--ip', '10.50.10.10',
499                '--vlan', 'pouet', '--attach', 'server01',
500                '--background']
501        self.maxDiff = None
502        result = self.invoke_with_exceptions(ip.create, args,
503                                             obj=GandiContextHelper())
504
505        self.assertEqual(re.sub(r'\[#+\]', '[###]',
506                                result.output.strip()), """\
507/!\ Datacenter FR will be closed on 25/12/2017, please consider using \
508another datacenter.
509Creating your iface.
510\rProgress: [###] 100.00%  00:00:00  \
511\nYour iface has been created with the following IP addresses:
512ip4:\t10.50.10.10""")
513        self.assertEqual(result.exit_code, 0)
514        params = self.api_calls['hosting.iface.create'][0][0]
515        self.assertEqual(params['datacenter_id'], 1)
516        self.assertEqual(params['bandwidth'], 51200)
517        self.assertEqual(params['ip_version'], 4)
518        self.assertEqual(params['vlan'], 717)
519        self.assertEqual(params['ip'], '10.50.10.10')
520
521    def test_detach(self):
522        args = ['95.142.160.181']
523        result = self.invoke_with_exceptions(ip.detach, args, input='y\n')
524
525        self.assertEqual(re.sub(r'\[#+\]', '[###]',
526                                result.output.strip()), """\
527Are you sure you want to detach ip 95.142.160.181? [y/N]: y\
528\nThe iface is still attached to the vm 152967.
529Will detach it.
530\rProgress: [###] 100.00%  00:00:00""")
531
532        self.assertEqual(result.exit_code, 0)
533
534    def test_detach_refuse(self):
535        args = ['95.142.160.181']
536        result = self.invoke_with_exceptions(ip.detach, args, input='N\n')
537
538        self.assertEqual(re.sub(r'\[#+\]', '[###]',
539                                result.output.strip()), """\
540Are you sure you want to detach ip 95.142.160.181? [y/N]: N""")
541
542        self.assertEqual(result.exit_code, 0)
543
544    def test_detach_force(self):
545        args = ['95.142.160.181', '--force']
546        result = self.invoke_with_exceptions(ip.detach, args, input='y\n')
547
548        self.assertEqual(re.sub(r'\[#+\]', '[###]',
549                                result.output.strip()), """\
550The iface is still attached to the vm 152967.
551Will detach it.
552\rProgress: [###] 100.00%  00:00:00""")
553
554        self.assertEqual(result.exit_code, 0)
555
556    def test_delete_unknown(self):
557        args = ['395.142.160.181']
558        result = self.invoke_with_exceptions(ip.delete, args)
559
560        self.assertEqual(re.sub(r'\[#+\]', '[###]',
561                                result.output.strip()), """\
562Sorry interface 395.142.160.181 does not exist
563Please use one of the following: ['203968', '204557', '204558', '2361', \
564'2361', '95.142.160.181', '2001:4b98:dc2:43:216:3eff:fece:e25f', \
565'2001:4b98:dc0:47:216:3eff:feb2:3862', '192.168.232.253', '192.168.232.252'\
566]""")
567
568        self.assertEqual(result.exit_code, 0)
569
570    def test_delete(self):
571        args = ['95.142.160.181']
572        result = self.invoke_with_exceptions(ip.delete, args, input='y\n')
573
574        self.assertEqual(re.sub(r'\[#+\]', '[###]',
575                                result.output.strip()), """\
576Are you sure you want to delete ip(s) 95.142.160.181 [y/N]: y
577The iface is still attached to the vm 152967.
578Will detach it.
579Detaching your iface(s).
580\rProgress: [###] 100.00%  00:00:00  \
581\nDetaching/deleting your iface(s).
582\rProgress: [###] 100.00%  00:00:00""")
583
584        self.assertEqual(result.exit_code, 0)
585
586    def test_delete_refuse(self):
587        args = ['95.142.160.181']
588        result = self.invoke_with_exceptions(ip.delete, args, input='N\n')
589
590        self.assertEqual(re.sub(r'\[#+\]', '[###]',
591                                result.output.strip()), """\
592Are you sure you want to delete ip(s) 95.142.160.181 [y/N]: N""")
593
594        self.assertEqual(result.exit_code, 0)
595
596    def test_delete_force(self):
597        args = ['95.142.160.181', '--force']
598        result = self.invoke_with_exceptions(ip.delete, args)
599
600        self.assertEqual(re.sub(r'\[#+\]', '[###]',
601                                result.output.strip()), """\
602The iface is still attached to the vm 152967.
603Will detach it.
604Detaching your iface(s).
605\rProgress: [###] 100.00%  00:00:00  \
606\nDetaching/deleting your iface(s).
607\rProgress: [###] 100.00%  00:00:00""")
608
609        self.assertEqual(result.exit_code, 0)
610
611    def test_delete_background(self):
612        args = ['95.142.160.181', '--background']
613        result = self.invoke_with_exceptions(ip.delete, args, input='y\n')
614
615        self.assertEqual(re.sub(r'\[#+\]', '[###]',
616                                result.output.strip()), """\
617Are you sure you want to delete ip(s) 95.142.160.181 [y/N]: y
618The iface is still attached to the vm 152967.
619Will detach it.
620Detaching your iface(s).
621\rProgress: [###] 100.00%  00:00:00""")
622
623        self.assertEqual(result.exit_code, 0)
624
625    def test_delete_multiple(self):
626        args = ['95.142.160.181', '2001:4b98:dc2:43:216:3eff:fece:e25f']
627        result = self.invoke_with_exceptions(ip.delete, args, input='y\n')
628
629        self.assertEqual(re.sub(r'\[#+\]', '[###]',
630                                result.output.strip()), """\
631Are you sure you want to delete ip(s) 2001:4b98:dc2:43:216:3eff:fece:e25f, \
63295.142.160.181 [y/N]: y
633The iface is still attached to the vm 152967.
634Will detach it.
635Detaching your iface(s).
636\rProgress: [###] 100.00%  00:00:00  \
637\nDetaching/deleting your iface(s).
638\rProgress: [###] 100.00%  00:00:00""")
639
640        self.assertEqual(result.exit_code, 0)
641