(bug 650) adding WIM account instantiation parameter.
[osm/osmclient.git] / osmclient / scripts / osm.py
1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
3 #
4 # All Rights Reserved.
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); you may
7 # not use this file except in compliance with the License. You may obtain
8 # a copy of the License at
9 #
10 # http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15 # License for the specific language governing permissions and limitations
16 # under the License.
17 """
18 OSM shell/cli
19 """
20
21 import click
22 from osmclient import client
23 from osmclient.common.exceptions import ClientException
24 from prettytable import PrettyTable
25 import yaml
26 import json
27 import time
28 import pycurl
29
30 def check_client_version(obj, what, version='sol005'):
31 '''
32 Checks the version of the client object and raises error if it not the expected.
33
34 :param obj: the client object
35 :what: the function or command under evaluation (used when an error is raised)
36 :return: -
37 :raises ClientError: if the specified version does not match the client version
38 '''
39 fullclassname = obj.__module__ + "." + obj.__class__.__name__
40 message = 'The following commands or options are only supported with the option "--sol005": {}'.format(what)
41 if version == 'v1':
42 message = 'The following commands or options are not supported when using option "--sol005": {}'.format(what)
43 if fullclassname != 'osmclient.{}.client.Client'.format(version):
44 raise ClientException(message)
45 return
46
47 @click.group()
48 @click.option('--hostname',
49 default="127.0.0.1",
50 envvar='OSM_HOSTNAME',
51 help='hostname of server. ' +
52 'Also can set OSM_HOSTNAME in environment')
53 @click.option('--sol005/--no-sol005',
54 default=True,
55 envvar='OSM_SOL005',
56 help='Use ETSI NFV SOL005 API (default) or the previous SO API. ' +
57 'Also can set OSM_SOL005 in environment')
58 @click.option('--user',
59 default=None,
60 envvar='OSM_USER',
61 help='user (only from Release FOUR, defaults to admin). ' +
62 'Also can set OSM_USER in environment')
63 @click.option('--password',
64 default=None,
65 envvar='OSM_PASSWORD',
66 help='password (only from Release FOUR, defaults to admin). ' +
67 'Also can set OSM_PASSWORD in environment')
68 @click.option('--project',
69 default=None,
70 envvar='OSM_PROJECT',
71 help='project (only from Release FOUR, defaults to admin). ' +
72 'Also can set OSM_PROJECT in environment')
73 @click.option('--so-port',
74 default=None,
75 envvar='OSM_SO_PORT',
76 help='hostname of server. ' +
77 'Also can set OSM_SO_PORT in environment')
78 @click.option('--so-project',
79 default=None,
80 envvar='OSM_SO_PROJECT',
81 help='Project Name in SO. ' +
82 'Also can set OSM_SO_PROJECT in environment')
83 @click.option('--ro-hostname',
84 default=None,
85 envvar='OSM_RO_HOSTNAME',
86 help='hostname of RO server. ' +
87 'Also can set OSM_RO_HOSTNAME in environment')
88 @click.option('--ro-port',
89 default=None,
90 envvar='OSM_RO_PORT',
91 help='hostname of RO server. ' +
92 'Also can set OSM_RO_PORT in environment')
93 @click.pass_context
94 def cli(ctx, hostname, sol005, user, password, project, so_port, so_project, ro_hostname, ro_port):
95 if hostname is None:
96 print((
97 "either hostname option or OSM_HOSTNAME " +
98 "environment variable needs to be specified"))
99 exit(1)
100 kwargs={}
101 if so_port is not None:
102 kwargs['so_port']=so_port
103 if so_project is not None:
104 kwargs['so_project']=so_project
105 if ro_hostname is not None:
106 kwargs['ro_host']=ro_hostname
107 if ro_port is not None:
108 kwargs['ro_port']=ro_port
109 if user is not None:
110 kwargs['user']=user
111 if password is not None:
112 kwargs['password']=password
113 if project is not None:
114 kwargs['project']=project
115
116 ctx.obj = client.Client(host=hostname, sol005=sol005, **kwargs)
117
118
119 ####################
120 # LIST operations
121 ####################
122
123 @cli.command(name='ns-list')
124 @click.option('--filter', default=None,
125 help='restricts the list to the NS instances matching the filter.')
126 @click.pass_context
127 def ns_list(ctx, filter):
128 '''list all NS instances
129
130 \b
131 Options:
132 --filter filterExpr Restricts the list to the NS instances matching the filter
133
134 \b
135 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
136 concatenated using the "&" character:
137
138 \b
139 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
140 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
141 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
142 attrName := string
143 value := scalar value
144
145 \b
146 where:
147 * zero or more occurrences
148 ? zero or one occurrence
149 [] grouping of expressions to be used with ? and *
150 "" quotation marks for marking string constants
151 <> name separator
152
153 \b
154 "AttrName" is the name of one attribute in the data type that defines the representation
155 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
156 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
157 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
158 entries, it means that the operator "op" is applied to the attribute addressed by the last
159 <attrName> entry included in the concatenation. All simple filter expressions are combined
160 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
161 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
162 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
163 prefix". If an attribute referenced in an expression is an array, an object that contains a
164 corresponding array shall be considered to match the expression if any of the elements in the
165 array matches all expressions that have the same attribute prefix.
166
167 \b
168 Filter examples:
169 --filter admin-status=ENABLED
170 --filter nsd-ref=<NSD_NAME>
171 --filter nsd.vendor=<VENDOR>
172 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
173 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
174 '''
175 if filter:
176 check_client_version(ctx.obj, '--filter')
177 resp = ctx.obj.ns.list(filter)
178 else:
179 resp = ctx.obj.ns.list()
180 table = PrettyTable(
181 ['ns instance name',
182 'id',
183 'operational status',
184 'config status',
185 'detailed status'])
186 for ns in resp:
187 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
188 if fullclassname == 'osmclient.sol005.client.Client':
189 nsr = ns
190 nsr_name = nsr['name']
191 nsr_id = nsr['_id']
192 else:
193 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
194 nsr = nsopdata['nsr:nsr']
195 nsr_name = nsr['name-ref']
196 nsr_id = nsr['ns-instance-config-ref']
197 opstatus = nsr['operational-status'] if 'operational-status' in nsr else 'Not found'
198 configstatus = nsr['config-status'] if 'config-status' in nsr else 'Not found'
199 detailed_status = nsr['detailed-status'] if 'detailed-status' in nsr else 'Not found'
200 if configstatus == "config_not_needed":
201 configstatus = "configured (no charms)"
202 table.add_row(
203 [nsr_name,
204 nsr_id,
205 opstatus,
206 configstatus,
207 detailed_status])
208 table.align = 'l'
209 print(table)
210
211
212 def nsd_list(ctx, filter):
213 if filter:
214 check_client_version(ctx.obj, '--filter')
215 resp = ctx.obj.nsd.list(filter)
216 else:
217 resp = ctx.obj.nsd.list()
218 #print yaml.safe_dump(resp)
219 table = PrettyTable(['nsd name', 'id'])
220 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
221 if fullclassname == 'osmclient.sol005.client.Client':
222 for ns in resp:
223 name = ns['name'] if 'name' in ns else '-'
224 table.add_row([name, ns['_id']])
225 else:
226 for ns in resp:
227 table.add_row([ns['name'], ns['id']])
228 table.align = 'l'
229 print(table)
230
231
232 @cli.command(name='nsd-list')
233 @click.option('--filter', default=None,
234 help='restricts the list to the NSD/NSpkg matching the filter')
235 @click.pass_context
236 def nsd_list1(ctx, filter):
237 '''list all NSD/NSpkg in the system'''
238 nsd_list(ctx,filter)
239
240
241 @cli.command(name='nspkg-list')
242 @click.option('--filter', default=None,
243 help='restricts the list to the NSD/NSpkg matching the filter')
244 @click.pass_context
245 def nsd_list2(ctx, filter):
246 '''list all NSD/NSpkg in the system'''
247 nsd_list(ctx,filter)
248
249
250 def vnfd_list(ctx, nf_type, filter):
251 if nf_type:
252 check_client_version(ctx.obj, '--nf_type')
253 elif filter:
254 check_client_version(ctx.obj, '--filter')
255 if nf_type:
256 if nf_type == "vnf":
257 nf_filter = "_admin.type=vnfd"
258 elif nf_type == "pnf":
259 nf_filter = "_admin.type=pnfd"
260 elif nf_type == "hnf":
261 nf_filter = "_admin.type=hnfd"
262 else:
263 raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
264 if filter:
265 filter = '{}&{}'.format(nf_filter, filter)
266 else:
267 filter = nf_filter
268 if filter:
269 resp = ctx.obj.vnfd.list(filter)
270 else:
271 resp = ctx.obj.vnfd.list()
272 #print yaml.safe_dump(resp)
273 table = PrettyTable(['nfpkg name', 'id'])
274 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
275 if fullclassname == 'osmclient.sol005.client.Client':
276 for vnfd in resp:
277 name = vnfd['name'] if 'name' in vnfd else '-'
278 table.add_row([name, vnfd['_id']])
279 else:
280 for vnfd in resp:
281 table.add_row([vnfd['name'], vnfd['id']])
282 table.align = 'l'
283 print(table)
284
285
286 @cli.command(name='vnfd-list')
287 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
288 @click.option('--filter', default=None,
289 help='restricts the list to the NFpkg matching the filter')
290 @click.pass_context
291 def vnfd_list1(ctx, nf_type, filter):
292 '''list all VNFD/VNFpkg in the system'''
293 vnfd_list(ctx, nf_type, filter)
294
295
296 @cli.command(name='vnfpkg-list')
297 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
298 @click.option('--filter', default=None,
299 help='restricts the list to the NFpkg matching the filter')
300 @click.pass_context
301 def vnfd_list2(ctx, nf_type, filter):
302 '''list all VNFD/VNFpkg in the system'''
303 vnfd_list(ctx, nf_type, filter)
304
305
306 @cli.command(name='nfpkg-list')
307 @click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
308 @click.option('--filter', default=None,
309 help='restricts the list to the NFpkg matching the filter')
310 @click.pass_context
311 def nfpkg_list(ctx, nf_type, filter):
312 '''list all NFpkg (VNFpkg, PNFpkg, HNFpkg) in the system'''
313 try:
314 check_client_version(ctx.obj, ctx.command.name)
315 vnfd_list(ctx,nf_type,filter)
316 except ClientException as inst:
317 print((inst.message))
318 exit(1)
319
320
321 def vnf_list(ctx, ns, filter):
322 try:
323 if ns or filter:
324 if ns:
325 check_client_version(ctx.obj, '--ns')
326 if filter:
327 check_client_version(ctx.obj, '--filter')
328 resp = ctx.obj.vnf.list(ns, filter)
329 else:
330 resp = ctx.obj.vnf.list()
331 except ClientException as inst:
332 print((inst.message))
333 exit(1)
334 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
335 if fullclassname == 'osmclient.sol005.client.Client':
336 table = PrettyTable(
337 ['vnf id',
338 'name',
339 'ns id',
340 'vnf member index',
341 'vnfd name',
342 'vim account id',
343 'ip address'])
344 for vnfr in resp:
345 name = vnfr['name'] if 'name' in vnfr else '-'
346 table.add_row(
347 [vnfr['_id'],
348 name,
349 vnfr['nsr-id-ref'],
350 vnfr['member-vnf-index-ref'],
351 vnfr['vnfd-ref'],
352 vnfr['vim-account-id'],
353 vnfr['ip-address']])
354 else:
355 table = PrettyTable(
356 ['vnf name',
357 'id',
358 'operational status',
359 'config status'])
360 for vnfr in resp:
361 if 'mgmt-interface' not in vnfr:
362 vnfr['mgmt-interface'] = {}
363 vnfr['mgmt-interface']['ip-address'] = None
364 table.add_row(
365 [vnfr['name'],
366 vnfr['id'],
367 vnfr['operational-status'],
368 vnfr['config-status']])
369 table.align = 'l'
370 print(table)
371
372
373 @cli.command(name='vnf-list')
374 @click.option('--ns', default=None, help='NS instance id or name to restrict the NF list')
375 @click.option('--filter', default=None,
376 help='restricts the list to the NF instances matching the filter.')
377 @click.pass_context
378 def vnf_list1(ctx, ns, filter):
379 '''list all NF instances'''
380 vnf_list(ctx, ns, filter)
381
382
383 @cli.command(name='nf-list')
384 @click.option('--ns', default=None, help='NS instance id or name to restrict the NF list')
385 @click.option('--filter', default=None,
386 help='restricts the list to the NF instances matching the filter.')
387 @click.pass_context
388 def nf_list(ctx, ns, filter):
389 '''list all NF instances
390
391 \b
392 Options:
393 --ns TEXT NS instance id or name to restrict the VNF list
394 --filter filterExpr Restricts the list to the VNF instances matching the filter
395
396 \b
397 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
398 concatenated using the "&" character:
399
400 \b
401 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
402 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
403 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
404 attrName := string
405 value := scalar value
406
407 \b
408 where:
409 * zero or more occurrences
410 ? zero or one occurrence
411 [] grouping of expressions to be used with ? and *
412 "" quotation marks for marking string constants
413 <> name separator
414
415 \b
416 "AttrName" is the name of one attribute in the data type that defines the representation
417 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
418 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
419 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
420 entries, it means that the operator "op" is applied to the attribute addressed by the last
421 <attrName> entry included in the concatenation. All simple filter expressions are combined
422 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
423 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
424 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
425 prefix". If an attribute referenced in an expression is an array, an object that contains a
426 corresponding array shall be considered to match the expression if any of the elements in the
427 array matches all expressions that have the same attribute prefix.
428
429 \b
430 Filter examples:
431 --filter vim-account-id=<VIM_ACCOUNT_ID>
432 --filter vnfd-ref=<VNFD_NAME>
433 --filter vdur.ip-address=<IP_ADDRESS>
434 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
435 '''
436 vnf_list(ctx, ns, filter)
437
438
439 @cli.command(name='ns-op-list')
440 @click.argument('name')
441 @click.pass_context
442 def ns_op_list(ctx, name):
443 '''shows the history of operations over a NS instance
444
445 NAME: name or ID of the NS instance
446 '''
447 try:
448 check_client_version(ctx.obj, ctx.command.name)
449 resp = ctx.obj.ns.list_op(name)
450 except ClientException as inst:
451 print((inst.message))
452 exit(1)
453
454 table = PrettyTable(['id', 'operation', 'status'])
455 for op in resp:
456 table.add_row([op['id'], op['lcmOperationType'],
457 op['operationState']])
458 table.align = 'l'
459 print(table)
460
461
462 def nsi_list(ctx, filter):
463 '''list all Network Slice Instances'''
464 try:
465 check_client_version(ctx.obj, ctx.command.name)
466 resp = ctx.obj.nsi.list(filter)
467 except ClientException as inst:
468 print((inst.message))
469 exit(1)
470 table = PrettyTable(
471 ['netslice instance name',
472 'id',
473 'operational status',
474 'config status',
475 'detailed status'])
476 for nsi in resp:
477 nsi_name = nsi['name']
478 nsi_id = nsi['_id']
479 opstatus = nsi['operational-status'] if 'operational-status' in nsi else 'Not found'
480 configstatus = nsi['config-status'] if 'config-status' in nsi else 'Not found'
481 detailed_status = nsi['detailed-status'] if 'detailed-status' in nsi else 'Not found'
482 if configstatus == "config_not_needed":
483 configstatus = "configured (no charms)"
484 table.add_row(
485 [nsi_name,
486 nsi_id,
487 opstatus,
488 configstatus,
489 detailed_status])
490 table.align = 'l'
491 print(table)
492
493
494 @cli.command(name='nsi-list')
495 @click.option('--filter', default=None,
496 help='restricts the list to the Network Slice Instances matching the filter')
497 @click.pass_context
498 def nsi_list1(ctx, filter):
499 '''list all Network Slice Instances (NSI)'''
500 nsi_list(ctx,filter)
501
502
503 @cli.command(name='netslice-instance-list')
504 @click.option('--filter', default=None,
505 help='restricts the list to the Network Slice Instances matching the filter')
506 @click.pass_context
507 def nsi_list2(ctx, filter):
508 '''list all Network Slice Instances (NSI)'''
509 nsi_list(ctx,filter)
510
511
512 def nst_list(ctx, filter):
513 try:
514 check_client_version(ctx.obj, ctx.command.name)
515 resp = ctx.obj.nst.list(filter)
516 except ClientException as inst:
517 print((inst.message))
518 exit(1)
519 #print yaml.safe_dump(resp)
520 table = PrettyTable(['nst name', 'id'])
521 for nst in resp:
522 name = nst['name'] if 'name' in nst else '-'
523 table.add_row([name, nst['_id']])
524 table.align = 'l'
525 print(table)
526
527
528 @cli.command(name='nst-list')
529 @click.option('--filter', default=None,
530 help='restricts the list to the NST matching the filter')
531 @click.pass_context
532 def nst_list1(ctx, filter):
533 '''list all Network Slice Templates (NST) in the system'''
534 nst_list(ctx,filter)
535
536
537 @cli.command(name='netslice-template-list')
538 @click.option('--filter', default=None,
539 help='restricts the list to the NST matching the filter')
540 @click.pass_context
541 def nst_list2(ctx, filter):
542 '''list all Network Slice Templates (NST) in the system'''
543 nst_list(ctx,filter)
544
545
546 def nsi_op_list(ctx, name):
547 try:
548 check_client_version(ctx.obj, ctx.command.name)
549 resp = ctx.obj.nsi.list_op(name)
550 except ClientException as inst:
551 print((inst.message))
552 exit(1)
553 table = PrettyTable(['id', 'operation', 'status'])
554 for op in resp:
555 table.add_row([op['id'], op['lcmOperationType'],
556 op['operationState']])
557 table.align = 'l'
558 print(table)
559
560
561 @cli.command(name='nsi-op-list')
562 @click.argument('name')
563 @click.pass_context
564 def nsi_op_list1(ctx, name):
565 '''shows the history of operations over a Network Slice Instance (NSI)
566
567 NAME: name or ID of the Network Slice Instance
568 '''
569 nsi_op_list(ctx,name)
570
571
572 @cli.command(name='netslice-instance-op-list')
573 @click.argument('name')
574 @click.pass_context
575 def nsi_op_list2(ctx, name):
576 '''shows the history of operations over a Network Slice Instance (NSI)
577
578 NAME: name or ID of the Network Slice Instance
579 '''
580 nsi_op_list(ctx,name)
581
582
583 @cli.command(name='pdu-list')
584 @click.option('--filter', default=None,
585 help='restricts the list to the Physical Deployment Units matching the filter')
586 @click.pass_context
587 def pdu_list(ctx, filter):
588 '''list all Physical Deployment Units (PDU)'''
589 try:
590 check_client_version(ctx.obj, ctx.command.name)
591 resp = ctx.obj.pdu.list(filter)
592 except ClientException as inst:
593 print((inst.message))
594 exit(1)
595 table = PrettyTable(
596 ['pdu name',
597 'id',
598 'type',
599 'mgmt ip address'])
600 for pdu in resp:
601 pdu_name = pdu['name']
602 pdu_id = pdu['_id']
603 pdu_type = pdu['type']
604 pdu_ipaddress = "None"
605 for iface in pdu['interfaces']:
606 if iface['mgmt']:
607 pdu_ipaddress = iface['ip-address']
608 break
609 table.add_row(
610 [pdu_name,
611 pdu_id,
612 pdu_type,
613 pdu_ipaddress])
614 table.align = 'l'
615 print(table)
616
617
618 ####################
619 # SHOW operations
620 ####################
621
622 def nsd_show(ctx, name, literal):
623 try:
624 resp = ctx.obj.nsd.get(name)
625 #resp = ctx.obj.nsd.get_individual(name)
626 except ClientException as inst:
627 print((inst.message))
628 exit(1)
629
630 if literal:
631 print(yaml.safe_dump(resp))
632 return
633
634 table = PrettyTable(['field', 'value'])
635 for k, v in list(resp.items()):
636 table.add_row([k, json.dumps(v, indent=2)])
637 table.align = 'l'
638 print(table)
639
640
641 @cli.command(name='nsd-show', short_help='shows the content of a NSD')
642 @click.option('--literal', is_flag=True,
643 help='print literally, no pretty table')
644 @click.argument('name')
645 @click.pass_context
646 def nsd_show1(ctx, name, literal):
647 '''shows the content of a NSD
648
649 NAME: name or ID of the NSD/NSpkg
650 '''
651 nsd_show(ctx, name, literal)
652
653
654 @cli.command(name='nspkg-show', short_help='shows the content of a NSD')
655 @click.option('--literal', is_flag=True,
656 help='print literally, no pretty table')
657 @click.argument('name')
658 @click.pass_context
659 def nsd_show2(ctx, name, literal):
660 '''shows the content of a NSD
661
662 NAME: name or ID of the NSD/NSpkg
663 '''
664 nsd_show(ctx, name, literal)
665
666
667 def vnfd_show(ctx, name, literal):
668 try:
669 resp = ctx.obj.vnfd.get(name)
670 #resp = ctx.obj.vnfd.get_individual(name)
671 except ClientException as inst:
672 print((inst.message))
673 exit(1)
674
675 if literal:
676 print(yaml.safe_dump(resp))
677 return
678
679 table = PrettyTable(['field', 'value'])
680 for k, v in list(resp.items()):
681 table.add_row([k, json.dumps(v, indent=2)])
682 table.align = 'l'
683 print(table)
684
685
686 @cli.command(name='vnfd-show', short_help='shows the content of a VNFD')
687 @click.option('--literal', is_flag=True,
688 help='print literally, no pretty table')
689 @click.argument('name')
690 @click.pass_context
691 def vnfd_show1(ctx, name, literal):
692 '''shows the content of a VNFD
693
694 NAME: name or ID of the VNFD/VNFpkg
695 '''
696 vnfd_show(ctx, name, literal)
697
698
699 @cli.command(name='vnfpkg-show', short_help='shows the content of a VNFD')
700 @click.option('--literal', is_flag=True,
701 help='print literally, no pretty table')
702 @click.argument('name')
703 @click.pass_context
704 def vnfd_show2(ctx, name, literal):
705 '''shows the content of a VNFD
706
707 NAME: name or ID of the VNFD/VNFpkg
708 '''
709 vnfd_show(ctx, name, literal)
710
711
712 @cli.command(name='nfpkg-show', short_help='shows the content of a NF Descriptor')
713 @click.option('--literal', is_flag=True,
714 help='print literally, no pretty table')
715 @click.argument('name')
716 @click.pass_context
717 def nfpkg_show(ctx, name, literal):
718 '''shows the content of a NF Descriptor
719
720 NAME: name or ID of the NFpkg
721 '''
722 vnfd_show(ctx, name, literal)
723
724
725 @cli.command(name='ns-show', short_help='shows the info of a NS instance')
726 @click.argument('name')
727 @click.option('--literal', is_flag=True,
728 help='print literally, no pretty table')
729 @click.option('--filter', default=None)
730 @click.pass_context
731 def ns_show(ctx, name, literal, filter):
732 '''shows the info of a NS instance
733
734 NAME: name or ID of the NS instance
735 '''
736 try:
737 ns = ctx.obj.ns.get(name)
738 except ClientException as inst:
739 print((inst.message))
740 exit(1)
741
742 if literal:
743 print(yaml.safe_dump(ns))
744 return
745
746 table = PrettyTable(['field', 'value'])
747
748 for k, v in list(ns.items()):
749 if filter is None or filter in k:
750 table.add_row([k, json.dumps(v, indent=2)])
751
752 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
753 if fullclassname != 'osmclient.sol005.client.Client':
754 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
755 nsr_optdata = nsopdata['nsr:nsr']
756 for k, v in list(nsr_optdata.items()):
757 if filter is None or filter in k:
758 table.add_row([k, json.dumps(v, indent=2)])
759 table.align = 'l'
760 print(table)
761
762
763 @cli.command(name='vnf-show', short_help='shows the info of a VNF instance')
764 @click.argument('name')
765 @click.option('--literal', is_flag=True,
766 help='print literally, no pretty table')
767 @click.option('--filter', default=None)
768 @click.pass_context
769 def vnf_show(ctx, name, literal, filter):
770 '''shows the info of a VNF instance
771
772 NAME: name or ID of the VNF instance
773 '''
774 try:
775 check_client_version(ctx.obj, ctx.command.name)
776 resp = ctx.obj.vnf.get(name)
777 except ClientException as inst:
778 print((inst.message))
779 exit(1)
780
781 if literal:
782 print(yaml.safe_dump(resp))
783 return
784
785 table = PrettyTable(['field', 'value'])
786 for k, v in list(resp.items()):
787 if filter is None or filter in k:
788 table.add_row([k, json.dumps(v, indent=2)])
789 table.align = 'l'
790 print(table)
791
792
793 @cli.command(name='vnf-monitoring-show')
794 @click.argument('vnf_name')
795 @click.pass_context
796 def vnf_monitoring_show(ctx, vnf_name):
797 try:
798 check_client_version(ctx.obj, ctx.command.name, 'v1')
799 resp = ctx.obj.vnf.get_monitoring(vnf_name)
800 except ClientException as inst:
801 print((inst.message))
802 exit(1)
803
804 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
805 if resp is not None:
806 for monitor in resp:
807 table.add_row(
808 [vnf_name,
809 monitor['name'],
810 monitor['value-integer'],
811 monitor['units']])
812 table.align = 'l'
813 print(table)
814
815
816 @cli.command(name='ns-monitoring-show')
817 @click.argument('ns_name')
818 @click.pass_context
819 def ns_monitoring_show(ctx, ns_name):
820 try:
821 check_client_version(ctx.obj, ctx.command.name, 'v1')
822 resp = ctx.obj.ns.get_monitoring(ns_name)
823 except ClientException as inst:
824 print((inst.message))
825 exit(1)
826
827 table = PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
828 for key, val in list(resp.items()):
829 for monitor in val:
830 table.add_row(
831 [key,
832 monitor['name'],
833 monitor['value-integer'],
834 monitor['units']])
835 table.align = 'l'
836 print(table)
837
838
839 @cli.command(name='ns-op-show', short_help='shows the info of an operation')
840 @click.argument('id')
841 @click.option('--filter', default=None)
842 @click.pass_context
843 def ns_op_show(ctx, id, filter):
844 '''shows the detailed info of an operation
845
846 ID: operation identifier
847 '''
848 try:
849 check_client_version(ctx.obj, ctx.command.name)
850 op_info = ctx.obj.ns.get_op(id)
851 except ClientException as inst:
852 print((inst.message))
853 exit(1)
854
855 table = PrettyTable(['field', 'value'])
856 for k, v in list(op_info.items()):
857 if filter is None or filter in k:
858 table.add_row([k, json.dumps(v, indent=2)])
859 table.align = 'l'
860 print(table)
861
862
863 def nst_show(ctx, name, literal):
864 try:
865 check_client_version(ctx.obj, ctx.command.name)
866 resp = ctx.obj.nst.get(name)
867 #resp = ctx.obj.nst.get_individual(name)
868 except ClientException as inst:
869 print((inst.message))
870 exit(1)
871
872 if literal:
873 print(yaml.safe_dump(resp))
874 return
875
876 table = PrettyTable(['field', 'value'])
877 for k, v in list(resp.items()):
878 table.add_row([k, json.dumps(v, indent=2)])
879 table.align = 'l'
880 print(table)
881
882
883 @cli.command(name='nst-show', short_help='shows the content of a Network Slice Template (NST)')
884 @click.option('--literal', is_flag=True,
885 help='print literally, no pretty table')
886 @click.argument('name')
887 @click.pass_context
888 def nst_show1(ctx, name, literal):
889 '''shows the content of a Network Slice Template (NST)
890
891 NAME: name or ID of the NST
892 '''
893 nst_show(ctx, name, literal)
894
895
896 @cli.command(name='netslice-template-show', short_help='shows the content of a Network Slice Template (NST)')
897 @click.option('--literal', is_flag=True,
898 help='print literally, no pretty table')
899 @click.argument('name')
900 @click.pass_context
901 def nst_show2(ctx, name, literal):
902 '''shows the content of a Network Slice Template (NST)
903
904 NAME: name or ID of the NST
905 '''
906 nst_show(ctx, name, literal)
907
908
909 def nsi_show(ctx, name, literal, filter):
910 try:
911 check_client_version(ctx.obj, ctx.command.name)
912 nsi = ctx.obj.nsi.get(name)
913 except ClientException as inst:
914 print((inst.message))
915 exit(1)
916
917 if literal:
918 print(yaml.safe_dump(nsi))
919 return
920
921 table = PrettyTable(['field', 'value'])
922
923 for k, v in list(nsi.items()):
924 if filter is None or filter in k:
925 table.add_row([k, json.dumps(v, indent=2)])
926
927 table.align = 'l'
928 print(table)
929
930
931 @cli.command(name='nsi-show', short_help='shows the content of a Network Slice Instance (NSI)')
932 @click.argument('name')
933 @click.option('--literal', is_flag=True,
934 help='print literally, no pretty table')
935 @click.option('--filter', default=None)
936 @click.pass_context
937 def nsi_show1(ctx, name, literal, filter):
938 '''shows the content of a Network Slice Instance (NSI)
939
940 NAME: name or ID of the Network Slice Instance
941 '''
942 nsi_show(ctx, name, literal, filter)
943
944
945 @cli.command(name='netslice-instance-show', short_help='shows the content of a Network Slice Instance (NSI)')
946 @click.argument('name')
947 @click.option('--literal', is_flag=True,
948 help='print literally, no pretty table')
949 @click.option('--filter', default=None)
950 @click.pass_context
951 def nsi_show2(ctx, name, literal, filter):
952 '''shows the content of a Network Slice Instance (NSI)
953
954 NAME: name or ID of the Network Slice Instance
955 '''
956 nsi_show(ctx, name, literal, filter)
957
958
959 def nsi_op_show(ctx, id, filter):
960 try:
961 check_client_version(ctx.obj, ctx.command.name)
962 op_info = ctx.obj.nsi.get_op(id)
963 except ClientException as inst:
964 print((inst.message))
965 exit(1)
966
967 table = PrettyTable(['field', 'value'])
968 for k, v in list(op_info.items()):
969 if filter is None or filter in k:
970 table.add_row([k, json.dumps(v, indent=2)])
971 table.align = 'l'
972 print(table)
973
974
975 @cli.command(name='nsi-op-show', short_help='shows the info of an operation over a Network Slice Instance(NSI)')
976 @click.argument('id')
977 @click.option('--filter', default=None)
978 @click.pass_context
979 def nsi_op_show1(ctx, id, filter):
980 '''shows the info of an operation over a Network Slice Instance(NSI)
981
982 ID: operation identifier
983 '''
984 nsi_op_show(ctx, id, filter)
985
986
987 @cli.command(name='netslice-instance-op-show', short_help='shows the info of an operation over a Network Slice Instance(NSI)')
988 @click.argument('id')
989 @click.option('--filter', default=None)
990 @click.pass_context
991 def nsi_op_show2(ctx, id, filter):
992 '''shows the info of an operation over a Network Slice Instance(NSI)
993
994 ID: operation identifier
995 '''
996 nsi_op_show(ctx, id, filter)
997
998
999 @cli.command(name='pdu-show', short_help='shows the content of a Physical Deployment Unit (PDU)')
1000 @click.argument('name')
1001 @click.option('--literal', is_flag=True,
1002 help='print literally, no pretty table')
1003 @click.option('--filter', default=None)
1004 @click.pass_context
1005 def pdu_show(ctx, name, literal, filter):
1006 '''shows the content of a Physical Deployment Unit (PDU)
1007
1008 NAME: name or ID of the PDU
1009 '''
1010 try:
1011 check_client_version(ctx.obj, ctx.command.name)
1012 pdu = ctx.obj.pdu.get(name)
1013 except ClientException as inst:
1014 print((inst.message))
1015 exit(1)
1016
1017 if literal:
1018 print(yaml.safe_dump(pdu))
1019 return
1020
1021 table = PrettyTable(['field', 'value'])
1022
1023 for k, v in list(pdu.items()):
1024 if filter is None or filter in k:
1025 table.add_row([k, json.dumps(v, indent=2)])
1026
1027 table.align = 'l'
1028 print(table)
1029
1030
1031 ####################
1032 # CREATE operations
1033 ####################
1034
1035 def nsd_create(ctx, filename, overwrite):
1036 try:
1037 check_client_version(ctx.obj, ctx.command.name)
1038 ctx.obj.nsd.create(filename, overwrite)
1039 except ClientException as inst:
1040 print((inst.message))
1041 exit(1)
1042
1043
1044 @cli.command(name='nsd-create', short_help='creates a new NSD/NSpkg')
1045 @click.argument('filename')
1046 @click.option('--overwrite', default=None,
1047 help='overwrites some fields in NSD')
1048 @click.pass_context
1049 def nsd_create1(ctx, filename, overwrite):
1050 '''creates a new NSD/NSpkg
1051
1052 FILENAME: NSD yaml file or NSpkg tar.gz file
1053 '''
1054 nsd_create(ctx, filename, overwrite)
1055
1056
1057 @cli.command(name='nspkg-create', short_help='creates a new NSD/NSpkg')
1058 @click.argument('filename')
1059 @click.option('--overwrite', default=None,
1060 help='overwrites some fields in NSD')
1061 @click.pass_context
1062 def nsd_create2(ctx, filename, overwrite):
1063 '''creates a new NSD/NSpkg
1064
1065 FILENAME: NSD yaml file or NSpkg tar.gz file
1066 '''
1067 nsd_create(ctx, filename, overwrite)
1068
1069
1070 def vnfd_create(ctx, filename, overwrite):
1071 try:
1072 check_client_version(ctx.obj, ctx.command.name)
1073 ctx.obj.vnfd.create(filename, overwrite)
1074 except ClientException as inst:
1075 print((inst.message))
1076 exit(1)
1077
1078
1079 @cli.command(name='vnfd-create', short_help='creates a new VNFD/VNFpkg')
1080 @click.argument('filename')
1081 @click.option('--overwrite', default=None,
1082 help='overwrites some fields in VNFD')
1083 @click.pass_context
1084 def vnfd_create1(ctx, filename, overwrite):
1085 '''creates a new VNFD/VNFpkg
1086
1087 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1088 '''
1089 vnfd_create(ctx, filename, overwrite)
1090
1091
1092 @cli.command(name='vnfpkg-create', short_help='creates a new VNFD/VNFpkg')
1093 @click.argument('filename')
1094 @click.option('--overwrite', default=None,
1095 help='overwrites some fields in VNFD')
1096 @click.pass_context
1097 def vnfd_create2(ctx, filename, overwrite):
1098 '''creates a new VNFD/VNFpkg
1099
1100 FILENAME: VNFD yaml file or VNFpkg tar.gz file
1101 '''
1102 vnfd_create(ctx, filename, overwrite)
1103
1104
1105 @cli.command(name='nfpkg-create', short_help='creates a new NFpkg')
1106 @click.argument('filename')
1107 @click.option('--overwrite', default=None,
1108 help='overwrites some fields in NFD')
1109 @click.pass_context
1110 def nfpkg_create(ctx, filename, overwrite):
1111 '''creates a new NFpkg
1112
1113 FILENAME: NF Descriptor yaml file or NFpkg tar.gz file
1114 '''
1115 vnfd_create(ctx, filename, overwrite)
1116
1117
1118 @cli.command(name='ns-create', short_help='creates a new Network Service instance')
1119 @click.option('--ns_name',
1120 prompt=True, help='name of the NS instance')
1121 @click.option('--nsd_name',
1122 prompt=True, help='name of the NS descriptor')
1123 @click.option('--vim_account',
1124 prompt=True, help='default VIM account id or name for the deployment')
1125 @click.option('--wim_account',
1126 default=None, help='default WIM account for intersite connectivity. False to not use a WIM')
1127 @click.option('--admin_status',
1128 default='ENABLED',
1129 help='administration status')
1130 @click.option('--ssh_keys',
1131 default=None,
1132 help='comma separated list of public key files to inject to vnfs')
1133 @click.option('--config',
1134 default=None,
1135 help='ns specific yaml configuration')
1136 @click.option('--config_file',
1137 default=None,
1138 help='ns specific yaml configuration file')
1139 @click.pass_context
1140 def ns_create(ctx,
1141 nsd_name,
1142 ns_name,
1143 vim_account,
1144 wim_account,
1145 admin_status,
1146 ssh_keys,
1147 config,
1148 config_file):
1149 '''creates a new NS instance'''
1150 try:
1151 if config_file:
1152 check_client_version(ctx.obj, '--config_file')
1153 if config:
1154 raise ClientException('"--config" option is incompatible with "--config_file" option')
1155 with open(config_file, 'r') as cf:
1156 config=cf.read()
1157 ctx.obj.ns.create(
1158 nsd_name,
1159 ns_name,
1160 config=config,
1161 ssh_keys=ssh_keys,
1162 account=vim_account,
1163 wim_account=wim_account)
1164 except ClientException as inst:
1165 print((inst.message))
1166 exit(1)
1167
1168
1169 def nst_create(ctx, filename, overwrite):
1170 try:
1171 check_client_version(ctx.obj, ctx.command.name)
1172 ctx.obj.nst.create(filename, overwrite)
1173 except ClientException as inst:
1174 print((inst.message))
1175 exit(1)
1176
1177
1178 @cli.command(name='nst-create', short_help='creates a new Network Slice Template (NST)')
1179 @click.argument('filename')
1180 @click.option('--overwrite', default=None,
1181 help='overwrites some fields in NST')
1182 @click.pass_context
1183 def nst_create1(ctx, filename, overwrite):
1184 '''creates a new Network Slice Template (NST)
1185
1186 FILENAME: NST yaml file or NSTpkg tar.gz file
1187 '''
1188 nst_create(ctx, filename, overwrite)
1189
1190
1191 @cli.command(name='netslice-template-create', short_help='creates a new Network Slice Template (NST)')
1192 @click.argument('filename')
1193 @click.option('--overwrite', default=None,
1194 help='overwrites some fields in NST')
1195 @click.pass_context
1196 def nst_create2(ctx, filename, overwrite):
1197 '''creates a new Network Slice Template (NST)
1198
1199 FILENAME: NST yaml file or NSTpkg tar.gz file
1200 '''
1201 nst_create(ctx, filename, overwrite)
1202
1203
1204 def nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file):
1205 '''creates a new Network Slice Instance (NSI)'''
1206 try:
1207 check_client_version(ctx.obj, ctx.command.name)
1208 if config_file:
1209 if config:
1210 raise ClientException('"--config" option is incompatible with "--config_file" option')
1211 with open(config_file, 'r') as cf:
1212 config=cf.read()
1213 ctx.obj.nsi.create(nst_name, nsi_name, config=config, ssh_keys=ssh_keys,
1214 account=vim_account)
1215 except ClientException as inst:
1216 print(inst.message)
1217 exit(1)
1218
1219
1220 @cli.command(name='nsi-create', short_help='creates a new Network Slice Instance')
1221 @click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance')
1222 @click.option('--nst_name', prompt=True, help='name of the Network Slice Template')
1223 @click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment')
1224 @click.option('--ssh_keys', default=None,
1225 help='comma separated list of keys to inject to vnfs')
1226 @click.option('--config', default=None,
1227 help='Netslice specific yaml configuration:\n'
1228 'netslice_subnet: [\n'
1229 'id: TEXT, vim_account: TEXT,\n'
1230 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1231 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
1232 'additionalParamsForNsi: {param: value, ...}\n'
1233 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
1234 '],\n'
1235 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1236 )
1237 @click.option('--config_file',
1238 default=None,
1239 help='nsi specific yaml configuration file')
1240 @click.pass_context
1241 def nsi_create1(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file):
1242 '''creates a new Network Slice Instance (NSI)'''
1243 nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file)
1244
1245
1246 @cli.command(name='netslice-instance-create', short_help='creates a new Network Slice Instance')
1247 @click.option('--nsi_name', prompt=True, help='name of the Network Slice Instance')
1248 @click.option('--nst_name', prompt=True, help='name of the Network Slice Template')
1249 @click.option('--vim_account', prompt=True, help='default VIM account id or name for the deployment')
1250 @click.option('--ssh_keys', default=None,
1251 help='comma separated list of keys to inject to vnfs')
1252 @click.option('--config', default=None,
1253 help='Netslice specific yaml configuration:\n'
1254 'netslice_subnet: [\n'
1255 'id: TEXT, vim_account: TEXT,\n'
1256 'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
1257 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1258 '],\n'
1259 'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
1260 )
1261 @click.option('--config_file',
1262 default=None,
1263 help='nsi specific yaml configuration file')
1264 @click.pass_context
1265 def nsi_create2(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file):
1266 '''creates a new Network Slice Instance (NSI)'''
1267 nsi_create(ctx, nst_name, nsi_name, vim_account, ssh_keys, config, config_file)
1268
1269
1270 @cli.command(name='pdu-create', short_help='adds a new Physical Deployment Unit to the catalog')
1271 @click.option('--name', help='name of the Physical Deployment Unit')
1272 @click.option('--pdu_type', help='type of PDU (e.g. router, firewall, FW001)')
1273 @click.option('--interface',
1274 help='interface(s) of the PDU: name=<NAME>,mgmt=<true|false>,ip-address=<IP_ADDRESS>'+
1275 '[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
1276 multiple=True)
1277 @click.option('--description', help='human readable description')
1278 @click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple=True)
1279 @click.option('--descriptor_file', default=None, help='PDU descriptor file (as an alternative to using the other arguments')
1280 @click.pass_context
1281 def pdu_create(ctx, name, pdu_type, interface, description, vim_account, descriptor_file):
1282 '''creates a new Physical Deployment Unit (PDU)'''
1283 try:
1284 check_client_version(ctx.obj, ctx.command.name)
1285 pdu = {}
1286 if not descriptor_file:
1287 if not name:
1288 raise ClientException('in absence of descriptor file, option "--name" is mandatory')
1289 if not pdu_type:
1290 raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
1291 if not interface:
1292 raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
1293 if not vim_account:
1294 raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
1295 else:
1296 with open(descriptor_file, 'r') as df:
1297 pdu = yaml.load(df.read())
1298 if name: pdu["name"] = name
1299 if pdu_type: pdu["type"] = pdu_type
1300 if description: pdu["description"] = description
1301 if vim_account: pdu["vim_accounts"] = vim_account
1302 if interface:
1303 ifaces_list = []
1304 for iface in interface:
1305 new_iface={k:v for k,v in [i.split('=') for i in iface.split(',')]}
1306 new_iface["mgmt"] = (new_iface.get("mgmt","false").lower() == "true")
1307 ifaces_list.append(new_iface)
1308 pdu["interfaces"] = ifaces_list
1309 ctx.obj.pdu.create(pdu)
1310 except ClientException as inst:
1311 print((inst.message))
1312 exit(1)
1313
1314
1315 ####################
1316 # UPDATE operations
1317 ####################
1318
1319 def nsd_update(ctx, name, content):
1320 try:
1321 check_client_version(ctx.obj, ctx.command.name)
1322 ctx.obj.nsd.update(name, content)
1323 except ClientException as inst:
1324 print((inst.message))
1325 exit(1)
1326
1327
1328 @cli.command(name='nsd-update', short_help='updates a NSD/NSpkg')
1329 @click.argument('name')
1330 @click.option('--content', default=None,
1331 help='filename with the NSD/NSpkg replacing the current one')
1332 @click.pass_context
1333 def nsd_update1(ctx, name, content):
1334 '''updates a NSD/NSpkg
1335
1336 NAME: name or ID of the NSD/NSpkg
1337 '''
1338 nsd_update(ctx, name, content)
1339
1340
1341 @cli.command(name='nspkg-update', short_help='updates a NSD/NSpkg')
1342 @click.argument('name')
1343 @click.option('--content', default=None,
1344 help='filename with the NSD/NSpkg replacing the current one')
1345 @click.pass_context
1346 def nsd_update2(ctx, name, content):
1347 '''updates a NSD/NSpkg
1348
1349 NAME: name or ID of the NSD/NSpkg
1350 '''
1351 nsd_update(ctx, name, content)
1352
1353
1354 def vnfd_update(ctx, name, content):
1355 try:
1356 check_client_version(ctx.obj, ctx.command.name)
1357 ctx.obj.vnfd.update(name, content)
1358 except ClientException as inst:
1359 print((inst.message))
1360 exit(1)
1361
1362
1363 @cli.command(name='vnfd-update', short_help='updates a new VNFD/VNFpkg')
1364 @click.argument('name')
1365 @click.option('--content', default=None,
1366 help='filename with the VNFD/VNFpkg replacing the current one')
1367 @click.pass_context
1368 def vnfd_update1(ctx, name, content):
1369 '''updates a VNFD/VNFpkg
1370
1371 NAME: name or ID of the VNFD/VNFpkg
1372 '''
1373 vnfd_update(ctx, name, content)
1374
1375
1376 @cli.command(name='vnfpkg-update', short_help='updates a VNFD/VNFpkg')
1377 @click.argument('name')
1378 @click.option('--content', default=None,
1379 help='filename with the VNFD/VNFpkg replacing the current one')
1380 @click.pass_context
1381 def vnfd_update2(ctx, name, content):
1382 '''updates a VNFD/VNFpkg
1383
1384 NAME: VNFD yaml file or VNFpkg tar.gz file
1385 '''
1386 vnfd_update(ctx, name, content)
1387
1388
1389 @cli.command(name='nfpkg-update', short_help='updates a NFpkg')
1390 @click.argument('name')
1391 @click.option('--content', default=None,
1392 help='filename with the NFpkg replacing the current one')
1393 @click.pass_context
1394 def nfpkg_update(ctx, name, content):
1395 '''updates a NFpkg
1396
1397 NAME: NF Descriptor yaml file or NFpkg tar.gz file
1398 '''
1399 vnfd_update(ctx, name, content)
1400
1401
1402 def nst_update(ctx, name, content):
1403 try:
1404 check_client_version(ctx.obj, ctx.command.name)
1405 ctx.obj.nst.update(name, content)
1406 except ClientException as inst:
1407 print((inst.message))
1408 exit(1)
1409
1410
1411 @cli.command(name='nst-update', short_help='updates a Network Slice Template (NST)')
1412 @click.argument('name')
1413 @click.option('--content', default=None,
1414 help='filename with the NST/NSTpkg replacing the current one')
1415 @click.pass_context
1416 def nst_update1(ctx, name, content):
1417 '''updates a Network Slice Template (NST)
1418
1419 NAME: name or ID of the NSD/NSpkg
1420 '''
1421 nst_update(ctx, name, content)
1422
1423
1424 @cli.command(name='netslice-template-update', short_help='updates a Network Slice Template (NST)')
1425 @click.argument('name')
1426 @click.option('--content', default=None,
1427 help='filename with the NST/NSTpkg replacing the current one')
1428 @click.pass_context
1429 def nst_update2(ctx, name, content):
1430 '''updates a Network Slice Template (NST)
1431
1432 NAME: name or ID of the NSD/NSpkg
1433 '''
1434 nst_update(ctx, name, content)
1435
1436
1437 ####################
1438 # DELETE operations
1439 ####################
1440
1441 def nsd_delete(ctx, name, force):
1442 try:
1443 if not force:
1444 ctx.obj.nsd.delete(name)
1445 else:
1446 check_client_version(ctx.obj, '--force')
1447 ctx.obj.nsd.delete(name, force)
1448 except ClientException as inst:
1449 print((inst.message))
1450 exit(1)
1451
1452
1453 @cli.command(name='nsd-delete', short_help='deletes a NSD/NSpkg')
1454 @click.argument('name')
1455 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1456 @click.pass_context
1457 def nsd_delete1(ctx, name, force):
1458 '''deletes a NSD/NSpkg
1459
1460 NAME: name or ID of the NSD/NSpkg to be deleted
1461 '''
1462 nsd_delete(ctx, name, force)
1463
1464
1465 @cli.command(name='nspkg-delete', short_help='deletes a NSD/NSpkg')
1466 @click.argument('name')
1467 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1468 @click.pass_context
1469 def nsd_delete2(ctx, name, force):
1470 '''deletes a NSD/NSpkg
1471
1472 NAME: name or ID of the NSD/NSpkg to be deleted
1473 '''
1474 nsd_delete(ctx, name, force)
1475
1476
1477 def vnfd_delete(ctx, name, force):
1478 try:
1479 if not force:
1480 ctx.obj.vnfd.delete(name)
1481 else:
1482 check_client_version(ctx.obj, '--force')
1483 ctx.obj.vnfd.delete(name, force)
1484 except ClientException as inst:
1485 print((inst.message))
1486 exit(1)
1487
1488
1489 @cli.command(name='vnfd-delete', short_help='deletes a VNFD/VNFpkg')
1490 @click.argument('name')
1491 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1492 @click.pass_context
1493 def vnfd_delete1(ctx, name, force):
1494 '''deletes a VNFD/VNFpkg
1495
1496 NAME: name or ID of the VNFD/VNFpkg to be deleted
1497 '''
1498 vnfd_delete(ctx, name, force)
1499
1500
1501 @cli.command(name='vnfpkg-delete', short_help='deletes a VNFD/VNFpkg')
1502 @click.argument('name')
1503 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1504 @click.pass_context
1505 def vnfd_delete2(ctx, name, force):
1506 '''deletes a VNFD/VNFpkg
1507
1508 NAME: name or ID of the VNFD/VNFpkg to be deleted
1509 '''
1510 vnfd_delete(ctx, name, force)
1511
1512
1513 @cli.command(name='nfpkg-delete', short_help='deletes a NFpkg')
1514 @click.argument('name')
1515 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1516 @click.pass_context
1517 def nfpkg_delete(ctx, name, force):
1518 '''deletes a NFpkg
1519
1520 NAME: name or ID of the NFpkg to be deleted
1521 '''
1522 vnfd_delete(ctx, name, force)
1523
1524
1525 @cli.command(name='ns-delete', short_help='deletes a NS instance')
1526 @click.argument('name')
1527 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1528 @click.pass_context
1529 def ns_delete(ctx, name, force):
1530 '''deletes a NS instance
1531
1532 NAME: name or ID of the NS instance to be deleted
1533 '''
1534 try:
1535 if not force:
1536 ctx.obj.ns.delete(name)
1537 else:
1538 check_client_version(ctx.obj, '--force')
1539 ctx.obj.ns.delete(name, force)
1540 except ClientException as inst:
1541 print((inst.message))
1542 exit(1)
1543
1544
1545 def nst_delete(ctx, name, force):
1546 try:
1547 check_client_version(ctx.obj, ctx.command.name)
1548 ctx.obj.nst.delete(name, force)
1549 except ClientException as inst:
1550 print((inst.message))
1551 exit(1)
1552
1553
1554 @cli.command(name='nst-delete', short_help='deletes a Network Slice Template (NST)')
1555 @click.argument('name')
1556 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1557 @click.pass_context
1558 def nst_delete1(ctx, name, force):
1559 '''deletes a Network Slice Template (NST)
1560
1561 NAME: name or ID of the NST/NSTpkg to be deleted
1562 '''
1563 nst_delete(ctx, name, force)
1564
1565
1566 @cli.command(name='netslice-template-delete', short_help='deletes a Network Slice Template (NST)')
1567 @click.argument('name')
1568 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1569 @click.pass_context
1570 def nst_delete2(ctx, name, force):
1571 '''deletes a Network Slice Template (NST)
1572
1573 NAME: name or ID of the NST/NSTpkg to be deleted
1574 '''
1575 nst_delete(ctx, name, force)
1576
1577
1578 def nsi_delete(ctx, name, force):
1579 try:
1580 check_client_version(ctx.obj, ctx.command.name)
1581 ctx.obj.nsi.delete(name, force)
1582 except ClientException as inst:
1583 print((inst.message))
1584 exit(1)
1585
1586
1587 @cli.command(name='nsi-delete', short_help='deletes a Network Slice Instance (NSI)')
1588 @click.argument('name')
1589 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1590 @click.pass_context
1591 def nsi_delete1(ctx, name, force):
1592 '''deletes a Network Slice Instance (NSI)
1593
1594 NAME: name or ID of the Network Slice instance to be deleted
1595 '''
1596 nsi_delete(ctx, name, force)
1597
1598
1599 @cli.command(name='netslice-instance-delete', short_help='deletes a Network Slice Instance (NSI)')
1600 @click.argument('name')
1601 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1602 @click.pass_context
1603 def nsi_delete2(ctx, name, force):
1604 '''deletes a Network Slice Instance (NSI)
1605
1606 NAME: name or ID of the Network Slice instance to be deleted
1607 '''
1608 nsi_delete(ctx, name, force)
1609
1610
1611 @cli.command(name='pdu-delete', short_help='deletes a Physical Deployment Unit (PDU)')
1612 @click.argument('name')
1613 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1614 @click.pass_context
1615 def pdu_delete(ctx, name, force):
1616 '''deletes a Physical Deployment Unit (PDU)
1617
1618 NAME: name or ID of the PDU to be deleted
1619 '''
1620 try:
1621 check_client_version(ctx.obj, ctx.command.name)
1622 ctx.obj.pdu.delete(name, force)
1623 except ClientException as inst:
1624 print((inst.message))
1625 exit(1)
1626
1627
1628 ####################
1629 # VIM operations
1630 ####################
1631
1632 @cli.command(name='vim-create')
1633 @click.option('--name',
1634 prompt=True,
1635 help='Name to create datacenter')
1636 @click.option('--user',
1637 prompt=True,
1638 help='VIM username')
1639 @click.option('--password',
1640 prompt=True,
1641 hide_input=True,
1642 confirmation_prompt=True,
1643 help='VIM password')
1644 @click.option('--auth_url',
1645 prompt=True,
1646 help='VIM url')
1647 @click.option('--tenant',
1648 prompt=True,
1649 help='VIM tenant name')
1650 @click.option('--config',
1651 default=None,
1652 help='VIM specific config parameters')
1653 @click.option('--account_type',
1654 default='openstack',
1655 help='VIM type')
1656 @click.option('--description',
1657 default='no description',
1658 help='human readable description')
1659 @click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account')
1660 @click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1661 @click.pass_context
1662 def vim_create(ctx,
1663 name,
1664 user,
1665 password,
1666 auth_url,
1667 tenant,
1668 config,
1669 account_type,
1670 description,
1671 sdn_controller,
1672 sdn_port_mapping):
1673 '''creates a new VIM account
1674 '''
1675 try:
1676 if sdn_controller:
1677 check_client_version(ctx.obj, '--sdn_controller')
1678 if sdn_port_mapping:
1679 check_client_version(ctx.obj, '--sdn_port_mapping')
1680 vim = {}
1681 vim['vim-username'] = user
1682 vim['vim-password'] = password
1683 vim['vim-url'] = auth_url
1684 vim['vim-tenant-name'] = tenant
1685 vim['vim-type'] = account_type
1686 vim['description'] = description
1687 vim['config'] = config
1688 if sdn_controller or sdn_port_mapping:
1689 ctx.obj.vim.create(name, vim, sdn_controller, sdn_port_mapping)
1690 else:
1691 ctx.obj.vim.create(name, vim)
1692 except ClientException as inst:
1693 print((inst.message))
1694 exit(1)
1695
1696
1697 @cli.command(name='vim-update', short_help='updates a VIM account')
1698 @click.argument('name')
1699 @click.option('--newname', help='New name for the VIM account')
1700 @click.option('--user', help='VIM username')
1701 @click.option('--password', help='VIM password')
1702 @click.option('--auth_url', help='VIM url')
1703 @click.option('--tenant', help='VIM tenant name')
1704 @click.option('--config', help='VIM specific config parameters')
1705 @click.option('--account_type', help='VIM type')
1706 @click.option('--description', help='human readable description')
1707 @click.option('--sdn_controller', default=None, help='Name or id of the SDN controller associated to this VIM account')
1708 @click.option('--sdn_port_mapping', default=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1709 @click.pass_context
1710 def vim_update(ctx,
1711 name,
1712 newname,
1713 user,
1714 password,
1715 auth_url,
1716 tenant,
1717 config,
1718 account_type,
1719 description,
1720 sdn_controller,
1721 sdn_port_mapping):
1722 '''updates a VIM account
1723
1724 NAME: name or ID of the VIM account
1725 '''
1726 try:
1727 check_client_version(ctx.obj, ctx.command.name)
1728 vim = {}
1729 if newname: vim['name'] = newname
1730 if user: vim['vim_user'] = user
1731 if password: vim['vim_password'] = password
1732 if auth_url: vim['vim_url'] = auth_url
1733 if tenant: vim['vim-tenant-name'] = tenant
1734 if account_type: vim['vim_type'] = account_type
1735 if description: vim['description'] = description
1736 if config: vim['config'] = config
1737 ctx.obj.vim.update(name, vim, sdn_controller, sdn_port_mapping)
1738 except ClientException as inst:
1739 print((inst.message))
1740 exit(1)
1741
1742
1743 @cli.command(name='vim-delete')
1744 @click.argument('name')
1745 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1746 @click.pass_context
1747 def vim_delete(ctx, name, force):
1748 '''deletes a VIM account
1749
1750 NAME: name or ID of the VIM account to be deleted
1751 '''
1752 try:
1753 if not force:
1754 ctx.obj.vim.delete(name)
1755 else:
1756 check_client_version(ctx.obj, '--force')
1757 ctx.obj.vim.delete(name, force)
1758 except ClientException as inst:
1759 print((inst.message))
1760 exit(1)
1761
1762
1763 @cli.command(name='vim-list')
1764 @click.option('--ro_update/--no_ro_update',
1765 default=False,
1766 help='update list from RO')
1767 @click.option('--filter', default=None,
1768 help='restricts the list to the VIM accounts matching the filter')
1769 @click.pass_context
1770 def vim_list(ctx, ro_update, filter):
1771 '''list all VIM accounts'''
1772 if filter:
1773 check_client_version(ctx.obj, '--filter')
1774 if ro_update:
1775 check_client_version(ctx.obj, '--ro_update', 'v1')
1776 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
1777 if fullclassname == 'osmclient.sol005.client.Client':
1778 resp = ctx.obj.vim.list(filter)
1779 else:
1780 resp = ctx.obj.vim.list(ro_update)
1781 table = PrettyTable(['vim name', 'uuid'])
1782 for vim in resp:
1783 table.add_row([vim['name'], vim['uuid']])
1784 table.align = 'l'
1785 print(table)
1786
1787
1788 @cli.command(name='vim-show')
1789 @click.argument('name')
1790 @click.pass_context
1791 def vim_show(ctx, name):
1792 '''shows the details of a VIM account
1793
1794 NAME: name or ID of the VIM account
1795 '''
1796 try:
1797 resp = ctx.obj.vim.get(name)
1798 if 'vim_password' in resp:
1799 resp['vim_password']='********'
1800 except ClientException as inst:
1801 print((inst.message))
1802 exit(1)
1803
1804 table = PrettyTable(['key', 'attribute'])
1805 for k, v in list(resp.items()):
1806 table.add_row([k, json.dumps(v, indent=2)])
1807 table.align = 'l'
1808 print(table)
1809
1810
1811 ####################
1812 # WIM operations
1813 ####################
1814
1815 @cli.command(name='wim-create')
1816 @click.option('--name',
1817 prompt=True,
1818 help='Name for the WIM account')
1819 @click.option('--user',
1820 help='WIM username')
1821 @click.option('--password',
1822 help='WIM password')
1823 @click.option('--url',
1824 prompt=True,
1825 help='WIM url')
1826 # @click.option('--tenant',
1827 # help='wIM tenant name')
1828 @click.option('--config',
1829 default=None,
1830 help='WIM specific config parameters')
1831 @click.option('--wim_type',
1832 help='WIM type')
1833 @click.option('--description',
1834 default='no description',
1835 help='human readable description')
1836 @click.option('--wim_port_mapping', default=None, help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge (WAN service endpoint id and info)")
1837 @click.pass_context
1838 def wim_create(ctx,
1839 name,
1840 user,
1841 password,
1842 url,
1843 # tenant,
1844 config,
1845 wim_type,
1846 description,
1847 wim_port_mapping):
1848 '''creates a new WIM account
1849 '''
1850 try:
1851 check_client_version(ctx.obj, ctx.command.name)
1852 # if sdn_controller:
1853 # check_client_version(ctx.obj, '--sdn_controller')
1854 # if sdn_port_mapping:
1855 # check_client_version(ctx.obj, '--sdn_port_mapping')
1856 wim = {}
1857 if user: wim['user'] = user
1858 if password: wim['password'] = password
1859 if url: wim['wim_url'] = url
1860 # if tenant: wim['tenant'] = tenant
1861 wim['wim_type'] = wim_type
1862 if description: wim['description'] = description
1863 if config: wim['config'] = config
1864 ctx.obj.wim.create(name, wim, wim_port_mapping)
1865 except ClientException as inst:
1866 print((inst.message))
1867 exit(1)
1868
1869
1870 @cli.command(name='wim-update', short_help='updates a WIM account')
1871 @click.argument('name')
1872 @click.option('--newname', help='New name for the WIM account')
1873 @click.option('--user', help='WIM username')
1874 @click.option('--password', help='WIM password')
1875 @click.option('--url', help='WIM url')
1876 @click.option('--config', help='WIM specific config parameters')
1877 @click.option('--wim_type', help='WIM type')
1878 @click.option('--description', help='human readable description')
1879 @click.option('--wim_port_mapping', default=None, help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge (WAN service endpoint id and info)")
1880 @click.pass_context
1881 def wim_update(ctx,
1882 name,
1883 newname,
1884 user,
1885 password,
1886 url,
1887 config,
1888 wim_type,
1889 description,
1890 wim_port_mapping):
1891 '''updates a WIM account
1892
1893 NAME: name or ID of the WIM account
1894 '''
1895 try:
1896 check_client_version(ctx.obj, ctx.command.name)
1897 wim = {}
1898 if newname: wim['name'] = newname
1899 if user: wim['user'] = user
1900 if password: wim['password'] = password
1901 if url: wim['url'] = url
1902 # if tenant: wim['tenant'] = tenant
1903 if wim_type: wim['wim_type'] = wim_type
1904 if description: wim['description'] = description
1905 if config: wim['config'] = config
1906 ctx.obj.wim.update(name, wim, wim_port_mapping)
1907 except ClientException as inst:
1908 print((inst.message))
1909 exit(1)
1910
1911
1912 @cli.command(name='wim-delete')
1913 @click.argument('name')
1914 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
1915 @click.pass_context
1916 def wim_delete(ctx, name, force):
1917 '''deletes a WIM account
1918
1919 NAME: name or ID of the WIM account to be deleted
1920 '''
1921 try:
1922 check_client_version(ctx.obj, ctx.command.name)
1923 ctx.obj.wim.delete(name, force)
1924 except ClientException as inst:
1925 print((inst.message))
1926 exit(1)
1927
1928
1929 @cli.command(name='wim-list')
1930 @click.option('--filter', default=None,
1931 help='restricts the list to the WIM accounts matching the filter')
1932 @click.pass_context
1933 def wim_list(ctx, filter):
1934 '''list all WIM accounts'''
1935 try:
1936 check_client_version(ctx.obj, ctx.command.name)
1937 resp = ctx.obj.wim.list(filter)
1938 table = PrettyTable(['wim name', 'uuid'])
1939 for wim in resp:
1940 table.add_row([wim['name'], wim['uuid']])
1941 table.align = 'l'
1942 print(table)
1943 except ClientException as inst:
1944 print((inst.message))
1945 exit(1)
1946
1947
1948 @cli.command(name='wim-show')
1949 @click.argument('name')
1950 @click.pass_context
1951 def wim_show(ctx, name):
1952 '''shows the details of a WIM account
1953
1954 NAME: name or ID of the WIM account
1955 '''
1956 try:
1957 check_client_version(ctx.obj, ctx.command.name)
1958 resp = ctx.obj.wim.get(name)
1959 if 'password' in resp:
1960 resp['wim_password']='********'
1961 except ClientException as inst:
1962 print((inst.message))
1963 exit(1)
1964
1965 table = PrettyTable(['key', 'attribute'])
1966 for k, v in list(resp.items()):
1967 table.add_row([k, json.dumps(v, indent=2)])
1968 table.align = 'l'
1969 print(table)
1970
1971
1972 ####################
1973 # SDN controller operations
1974 ####################
1975
1976 @cli.command(name='sdnc-create')
1977 @click.option('--name',
1978 prompt=True,
1979 help='Name to create sdn controller')
1980 @click.option('--type',
1981 prompt=True,
1982 help='SDN controller type')
1983 @click.option('--sdn_controller_version',
1984 help='SDN controller username')
1985 @click.option('--ip_address',
1986 prompt=True,
1987 help='SDN controller IP address')
1988 @click.option('--port',
1989 prompt=True,
1990 help='SDN controller port')
1991 @click.option('--switch_dpid',
1992 prompt=True,
1993 help='Switch DPID (Openflow Datapath ID)')
1994 @click.option('--user',
1995 help='SDN controller username')
1996 @click.option('--password',
1997 hide_input=True,
1998 confirmation_prompt=True,
1999 help='SDN controller password')
2000 #@click.option('--description',
2001 # default='no description',
2002 # help='human readable description')
2003 @click.pass_context
2004 def sdnc_create(ctx,
2005 name,
2006 type,
2007 sdn_controller_version,
2008 ip_address,
2009 port,
2010 switch_dpid,
2011 user,
2012 password):
2013 '''creates a new SDN controller
2014 '''
2015 sdncontroller = {}
2016 sdncontroller['name'] = name
2017 sdncontroller['type'] = type
2018 sdncontroller['ip'] = ip_address
2019 sdncontroller['port'] = int(port)
2020 sdncontroller['dpid'] = switch_dpid
2021 if sdn_controller_version:
2022 sdncontroller['version'] = sdn_controller_version
2023 if user:
2024 sdncontroller['user'] = user
2025 if password:
2026 sdncontroller['password'] = password
2027 # sdncontroller['description'] = description
2028 try:
2029 check_client_version(ctx.obj, ctx.command.name)
2030 ctx.obj.sdnc.create(name, sdncontroller)
2031 except ClientException as inst:
2032 print((inst.message))
2033
2034
2035 @cli.command(name='sdnc-update', short_help='updates an SDN controller')
2036 @click.argument('name')
2037 @click.option('--newname', help='New name for the SDN controller')
2038 @click.option('--type', help='SDN controller type')
2039 @click.option('--sdn_controller_version', help='SDN controller username')
2040 @click.option('--ip_address', help='SDN controller IP address')
2041 @click.option('--port', help='SDN controller port')
2042 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
2043 @click.option('--user', help='SDN controller username')
2044 @click.option('--password', help='SDN controller password')
2045 #@click.option('--description', default=None, help='human readable description')
2046 @click.pass_context
2047 def sdnc_update(ctx,
2048 name,
2049 newname,
2050 type,
2051 sdn_controller_version,
2052 ip_address,
2053 port,
2054 switch_dpid,
2055 user,
2056 password):
2057 '''updates an SDN controller
2058
2059 NAME: name or ID of the SDN controller
2060 '''
2061 sdncontroller = {}
2062 if newname: sdncontroller['name'] = newname
2063 if type: sdncontroller['type'] = type
2064 if ip_address: sdncontroller['ip'] = ip_address
2065 if port: sdncontroller['port'] = int(port)
2066 if switch_dpid: sdncontroller['dpid'] = switch_dpid
2067 # sdncontroller['description'] = description
2068 if sdn_controller_version is not None:
2069 if sdn_controller_version=="":
2070 sdncontroller['version'] = None
2071 else:
2072 sdncontroller['version'] = sdn_controller_version
2073 if user is not None:
2074 if user=="":
2075 sdncontroller['user'] = None
2076 else:
2077 sdncontroller['user'] = user
2078 if password is not None:
2079 if password=="":
2080 sdncontroller['password'] = None
2081 else:
2082 sdncontroller['password'] = user
2083 try:
2084 check_client_version(ctx.obj, ctx.command.name)
2085 ctx.obj.sdnc.update(name, sdncontroller)
2086 except ClientException as inst:
2087 print((inst.message))
2088 exit(1)
2089
2090
2091 @cli.command(name='sdnc-delete')
2092 @click.argument('name')
2093 @click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2094 @click.pass_context
2095 def sdnc_delete(ctx, name, force):
2096 '''deletes an SDN controller
2097
2098 NAME: name or ID of the SDN controller to be deleted
2099 '''
2100 try:
2101 check_client_version(ctx.obj, ctx.command.name)
2102 ctx.obj.sdnc.delete(name, force)
2103 except ClientException as inst:
2104 print((inst.message))
2105 exit(1)
2106
2107
2108 @cli.command(name='sdnc-list')
2109 @click.option('--filter', default=None,
2110 help='restricts the list to the SDN controllers matching the filter')
2111 @click.pass_context
2112 def sdnc_list(ctx, filter):
2113 '''list all SDN controllers'''
2114 try:
2115 check_client_version(ctx.obj, ctx.command.name)
2116 resp = ctx.obj.sdnc.list(filter)
2117 except ClientException as inst:
2118 print((inst.message))
2119 exit(1)
2120 table = PrettyTable(['name', 'id'])
2121 for sdnc in resp:
2122 table.add_row([sdnc['name'], sdnc['_id']])
2123 table.align = 'l'
2124 print(table)
2125
2126
2127 @cli.command(name='sdnc-show')
2128 @click.argument('name')
2129 @click.pass_context
2130 def sdnc_show(ctx, name):
2131 '''shows the details of an SDN controller
2132
2133 NAME: name or ID of the SDN controller
2134 '''
2135 try:
2136 check_client_version(ctx.obj, ctx.command.name)
2137 resp = ctx.obj.sdnc.get(name)
2138 except ClientException as inst:
2139 print((inst.message))
2140 exit(1)
2141
2142 table = PrettyTable(['key', 'attribute'])
2143 for k, v in list(resp.items()):
2144 table.add_row([k, json.dumps(v, indent=2)])
2145 table.align = 'l'
2146 print(table)
2147
2148
2149 ####################
2150 # Project mgmt operations
2151 ####################
2152
2153 @cli.command(name='project-create')
2154 @click.argument('name')
2155 #@click.option('--description',
2156 # default='no description',
2157 # help='human readable description')
2158 @click.pass_context
2159 def project_create(ctx, name):
2160 '''Creates a new project
2161
2162 NAME: name of the project
2163 '''
2164 project = {}
2165 project['name'] = name
2166 try:
2167 check_client_version(ctx.obj, ctx.command.name)
2168 ctx.obj.project.create(name, project)
2169 except ClientException as inst:
2170 print(inst.message)
2171
2172
2173 @cli.command(name='project-delete')
2174 @click.argument('name')
2175 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2176 @click.pass_context
2177 def project_delete(ctx, name):
2178 '''deletes a project
2179
2180 NAME: name or ID of the project to be deleted
2181 '''
2182 try:
2183 check_client_version(ctx.obj, ctx.command.name)
2184 ctx.obj.project.delete(name)
2185 except ClientException as inst:
2186 print(inst.message)
2187 exit(1)
2188
2189
2190 @cli.command(name='project-list')
2191 @click.option('--filter', default=None,
2192 help='restricts the list to the projects matching the filter')
2193 @click.pass_context
2194 def project_list(ctx, filter):
2195 '''list all projects'''
2196 try:
2197 check_client_version(ctx.obj, ctx.command.name)
2198 resp = ctx.obj.project.list(filter)
2199 except ClientException as inst:
2200 print(inst.message)
2201 exit(1)
2202 table = PrettyTable(['name', 'id'])
2203 for proj in resp:
2204 table.add_row([proj['name'], proj['_id']])
2205 table.align = 'l'
2206 print(table)
2207
2208
2209 @cli.command(name='project-show')
2210 @click.argument('name')
2211 @click.pass_context
2212 def project_show(ctx, name):
2213 '''shows the details of a project
2214
2215 NAME: name or ID of the project
2216 '''
2217 try:
2218 check_client_version(ctx.obj, ctx.command.name)
2219 resp = ctx.obj.project.get(name)
2220 except ClientException as inst:
2221 print(inst.message)
2222 exit(1)
2223
2224 table = PrettyTable(['key', 'attribute'])
2225 for k, v in resp.items():
2226 table.add_row([k, json.dumps(v, indent=2)])
2227 table.align = 'l'
2228 print(table)
2229
2230
2231 ####################
2232 # User mgmt operations
2233 ####################
2234
2235 @cli.command(name='user-create')
2236 @click.argument('username')
2237 @click.option('--password',
2238 prompt=True,
2239 hide_input=True,
2240 confirmation_prompt=True,
2241 help='user password')
2242 @click.option('--projects',
2243 prompt="Comma separate list of projects",
2244 multiple=True,
2245 callback=lambda ctx, param, value: ''.join(value).split(',') if all(len(x)==1 for x in value) else value,
2246 help='list of project ids that the user belongs to')
2247 #@click.option('--description',
2248 # default='no description',
2249 # help='human readable description')
2250 @click.pass_context
2251 def user_create(ctx, username, password, projects):
2252 '''Creates a new user
2253
2254 USERNAME: name of the user
2255 '''
2256 user = {}
2257 user['username'] = username
2258 user['password'] = password
2259 user['projects'] = projects
2260 try:
2261 check_client_version(ctx.obj, ctx.command.name)
2262 ctx.obj.user.create(username, user)
2263 except ClientException as inst:
2264 print(inst.message)
2265
2266
2267 @cli.command(name='user-delete')
2268 @click.argument('name')
2269 #@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
2270 @click.pass_context
2271 def user_delete(ctx, name):
2272 '''deletes a user
2273
2274 NAME: name or ID of the user to be deleted
2275 '''
2276 try:
2277 check_client_version(ctx.obj, ctx.command.name)
2278 ctx.obj.user.delete(name)
2279 except ClientException as inst:
2280 print(inst.message)
2281 exit(1)
2282
2283
2284 @cli.command(name='user-list')
2285 @click.option('--filter', default=None,
2286 help='restricts the list to the users matching the filter')
2287 @click.pass_context
2288 def user_list(ctx, filter):
2289 '''list all users'''
2290 try:
2291 check_client_version(ctx.obj, ctx.command.name)
2292 resp = ctx.obj.user.list(filter)
2293 except ClientException as inst:
2294 print(inst.message)
2295 exit(1)
2296 table = PrettyTable(['name', 'id'])
2297 for user in resp:
2298 table.add_row([user['username'], user['_id']])
2299 table.align = 'l'
2300 print(table)
2301
2302
2303 @cli.command(name='user-show')
2304 @click.argument('name')
2305 @click.pass_context
2306 def user_show(ctx, name):
2307 '''shows the details of a user
2308
2309 NAME: name or ID of the user
2310 '''
2311 try:
2312 check_client_version(ctx.obj, ctx.command.name)
2313 resp = ctx.obj.user.get(name)
2314 if 'password' in resp:
2315 resp['password']='********'
2316 except ClientException as inst:
2317 print(inst.message)
2318 exit(1)
2319
2320 table = PrettyTable(['key', 'attribute'])
2321 for k, v in resp.items():
2322 table.add_row([k, json.dumps(v, indent=2)])
2323 table.align = 'l'
2324 print(table)
2325
2326
2327 ####################
2328 # Fault Management operations
2329 ####################
2330
2331 @cli.command(name='ns-alarm-create')
2332 @click.argument('name')
2333 @click.option('--ns', prompt=True, help='NS instance id or name')
2334 @click.option('--vnf', prompt=True,
2335 help='VNF name (VNF member index as declared in the NSD)')
2336 @click.option('--vdu', prompt=True,
2337 help='VDU name (VDU name as declared in the VNFD)')
2338 @click.option('--metric', prompt=True,
2339 help='Name of the metric (e.g. cpu_utilization)')
2340 @click.option('--severity', default='WARNING',
2341 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
2342 @click.option('--threshold_value', prompt=True,
2343 help='threshold value that, when crossed, an alarm is triggered')
2344 @click.option('--threshold_operator', prompt=True,
2345 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
2346 @click.option('--statistic', default='AVERAGE',
2347 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
2348 @click.pass_context
2349 def ns_alarm_create(ctx, name, ns, vnf, vdu, metric, severity,
2350 threshold_value, threshold_operator, statistic):
2351 '''creates a new alarm for a NS instance'''
2352 ns_instance = ctx.obj.ns.get(ns)
2353 alarm = {}
2354 alarm['alarm_name'] = name
2355 alarm['ns_id'] = ns_instance['_id']
2356 alarm['correlation_id'] = ns_instance['_id']
2357 alarm['vnf_member_index'] = vnf
2358 alarm['vdu_name'] = vdu
2359 alarm['metric_name'] = metric
2360 alarm['severity'] = severity
2361 alarm['threshold_value'] = int(threshold_value)
2362 alarm['operation'] = threshold_operator
2363 alarm['statistic'] = statistic
2364 try:
2365 check_client_version(ctx.obj, ctx.command.name)
2366 ctx.obj.ns.create_alarm(alarm)
2367 except ClientException as inst:
2368 print((inst.message))
2369 exit(1)
2370
2371
2372 #@cli.command(name='ns-alarm-delete')
2373 #@click.argument('name')
2374 #@click.pass_context
2375 #def ns_alarm_delete(ctx, name):
2376 # '''deletes an alarm
2377 #
2378 # NAME: name of the alarm to be deleted
2379 # '''
2380 # try:
2381 # check_client_version(ctx.obj, ctx.command.name)
2382 # ctx.obj.ns.delete_alarm(name)
2383 # except ClientException as inst:
2384 # print(inst.message)
2385 # exit(1)
2386
2387
2388 ####################
2389 # Performance Management operations
2390 ####################
2391
2392 @cli.command(name='ns-metric-export')
2393 @click.option('--ns', prompt=True, help='NS instance id or name')
2394 @click.option('--vnf', prompt=True,
2395 help='VNF name (VNF member index as declared in the NSD)')
2396 @click.option('--vdu', prompt=True,
2397 help='VDU name (VDU name as declared in the VNFD)')
2398 @click.option('--metric', prompt=True,
2399 help='name of the metric (e.g. cpu_utilization)')
2400 #@click.option('--period', default='1w',
2401 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
2402 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
2403 @click.pass_context
2404 def ns_metric_export(ctx, ns, vnf, vdu, metric, interval):
2405 '''exports a metric to the internal OSM bus, which can be read by other apps
2406 '''
2407 ns_instance = ctx.obj.ns.get(ns)
2408 metric_data = {}
2409 metric_data['ns_id'] = ns_instance['_id']
2410 metric_data['correlation_id'] = ns_instance['_id']
2411 metric_data['vnf_member_index'] = vnf
2412 metric_data['vdu_name'] = vdu
2413 metric_data['metric_name'] = metric
2414 metric_data['collection_unit'] = 'WEEK'
2415 metric_data['collection_period'] = 1
2416 try:
2417 check_client_version(ctx.obj, ctx.command.name)
2418 if not interval:
2419 print('{}'.format(ctx.obj.ns.export_metric(metric_data)))
2420 else:
2421 i = 1
2422 while True:
2423 print('{} {}'.format(ctx.obj.ns.export_metric(metric_data),i))
2424 time.sleep(int(interval))
2425 i+=1
2426 except ClientException as inst:
2427 print((inst.message))
2428 exit(1)
2429
2430
2431 ####################
2432 # Other operations
2433 ####################
2434
2435 @cli.command(name='upload-package')
2436 @click.argument('filename')
2437 @click.pass_context
2438 def upload_package(ctx, filename):
2439 '''uploads a VNF package or NS package
2440
2441 FILENAME: VNF or NS package file (tar.gz)
2442 '''
2443 try:
2444 ctx.obj.package.upload(filename)
2445 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
2446 if fullclassname != 'osmclient.sol005.client.Client':
2447 ctx.obj.package.wait_for_upload(filename)
2448 except ClientException as inst:
2449 print((inst.message))
2450 exit(1)
2451
2452
2453 @cli.command(name='ns-scaling-show')
2454 @click.argument('ns_name')
2455 @click.pass_context
2456 def show_ns_scaling(ctx, ns_name):
2457 '''shows the status of a NS scaling operation
2458
2459 NS_NAME: name of the NS instance being scaled
2460 '''
2461 try:
2462 check_client_version(ctx.obj, ctx.command.name, 'v1')
2463 resp = ctx.obj.ns.list()
2464 except ClientException as inst:
2465 print((inst.message))
2466 exit(1)
2467
2468 table = PrettyTable(
2469 ['group-name',
2470 'instance-id',
2471 'operational status',
2472 'create-time',
2473 'vnfr ids'])
2474
2475 for ns in resp:
2476 if ns_name == ns['name']:
2477 nsopdata = ctx.obj.ns.get_opdata(ns['id'])
2478 scaling_records = nsopdata['nsr:nsr']['scaling-group-record']
2479 for record in scaling_records:
2480 if 'instance' in record:
2481 instances = record['instance']
2482 for inst in instances:
2483 table.add_row(
2484 [record['scaling-group-name-ref'],
2485 inst['instance-id'],
2486 inst['op-status'],
2487 time.strftime('%Y-%m-%d %H:%M:%S',
2488 time.localtime(
2489 inst['create-time'])),
2490 inst['vnfrs']])
2491 table.align = 'l'
2492 print(table)
2493
2494
2495 @cli.command(name='ns-scale')
2496 @click.argument('ns_name')
2497 @click.option('--ns_scale_group', prompt=True)
2498 @click.option('--index', prompt=True)
2499 @click.pass_context
2500 def ns_scale(ctx, ns_name, ns_scale_group, index):
2501 '''scales NS
2502
2503 NS_NAME: name of the NS instance to be scaled
2504 '''
2505 try:
2506 check_client_version(ctx.obj, ctx.command.name, 'v1')
2507 ctx.obj.ns.scale(ns_name, ns_scale_group, index)
2508 except ClientException as inst:
2509 print((inst.message))
2510 exit(1)
2511
2512
2513 @cli.command(name='config-agent-list')
2514 @click.pass_context
2515 def config_agent_list(ctx):
2516 '''list config agents'''
2517 try:
2518 check_client_version(ctx.obj, ctx.command.name, 'v1')
2519 except ClientException as inst:
2520 print((inst.message))
2521 exit(1)
2522 table = PrettyTable(['name', 'account-type', 'details'])
2523 for account in ctx.obj.vca.list():
2524 table.add_row(
2525 [account['name'],
2526 account['account-type'],
2527 account['juju']])
2528 table.align = 'l'
2529 print(table)
2530
2531
2532 @cli.command(name='config-agent-delete')
2533 @click.argument('name')
2534 @click.pass_context
2535 def config_agent_delete(ctx, name):
2536 '''deletes a config agent
2537
2538 NAME: name of the config agent to be deleted
2539 '''
2540 try:
2541 check_client_version(ctx.obj, ctx.command.name, 'v1')
2542 ctx.obj.vca.delete(name)
2543 except ClientException as inst:
2544 print((inst.message))
2545 exit(1)
2546
2547
2548 @cli.command(name='config-agent-add')
2549 @click.option('--name',
2550 prompt=True)
2551 @click.option('--account_type',
2552 prompt=True)
2553 @click.option('--server',
2554 prompt=True)
2555 @click.option('--user',
2556 prompt=True)
2557 @click.option('--secret',
2558 prompt=True,
2559 hide_input=True,
2560 confirmation_prompt=True)
2561 @click.pass_context
2562 def config_agent_add(ctx, name, account_type, server, user, secret):
2563 '''adds a config agent'''
2564 try:
2565 check_client_version(ctx.obj, ctx.command.name, 'v1')
2566 ctx.obj.vca.create(name, account_type, server, user, secret)
2567 except ClientException as inst:
2568 print((inst.message))
2569 exit(1)
2570
2571 @cli.command(name='ro-dump')
2572 @click.pass_context
2573 def ro_dump(ctx):
2574 '''shows RO agent information'''
2575 check_client_version(ctx.obj, ctx.command.name, 'v1')
2576 resp = ctx.obj.vim.get_resource_orchestrator()
2577 table = PrettyTable(['key', 'attribute'])
2578 for k, v in list(resp.items()):
2579 table.add_row([k, json.dumps(v, indent=2)])
2580 table.align = 'l'
2581 print(table)
2582
2583
2584 @cli.command(name='vcs-list')
2585 @click.pass_context
2586 def vcs_list(ctx):
2587 check_client_version(ctx.obj, ctx.command.name, 'v1')
2588 resp = ctx.obj.utils.get_vcs_info()
2589 table = PrettyTable(['component name', 'state'])
2590 for component in resp:
2591 table.add_row([component['component_name'], component['state']])
2592 table.align = 'l'
2593 print(table)
2594
2595
2596 @cli.command(name='ns-action')
2597 @click.argument('ns_name')
2598 @click.option('--vnf_name', default=None)
2599 @click.option('--action_name', prompt=True)
2600 @click.option('--params', prompt=True)
2601 @click.pass_context
2602 def ns_action(ctx,
2603 ns_name,
2604 vnf_name,
2605 action_name,
2606 params):
2607 '''executes an action/primitive over a NS instance
2608
2609 NS_NAME: name or ID of the NS instance
2610 '''
2611 try:
2612 check_client_version(ctx.obj, ctx.command.name)
2613 op_data={}
2614 if vnf_name:
2615 op_data['vnf_member_index'] = vnf_name
2616 op_data['primitive'] = action_name
2617 op_data['primitive_params'] = yaml.load(params)
2618 ctx.obj.ns.exec_op(ns_name, op_name='action', op_data=op_data)
2619
2620 except ClientException as inst:
2621 print((inst.message))
2622 exit(1)
2623
2624
2625 @cli.command(name='vnf-scale')
2626 @click.argument('ns_name')
2627 @click.argument('vnf_name')
2628 @click.option('--scaling-group', prompt=True, help="scaling-group-descriptor name to use")
2629 @click.option('--scale-in', default=False, is_flag=True, help="performs a scale in operation")
2630 @click.option('--scale-out', default=False, is_flag=True, help="performs a scale out operation (by default)")
2631 @click.pass_context
2632 def vnf_scale(ctx,
2633 ns_name,
2634 vnf_name,
2635 scaling_group,
2636 scale_in,
2637 scale_out):
2638 '''executes a VNF scale (adding/removing VDUs)
2639
2640 \b
2641 NS_NAME: name or ID of the NS instance.
2642 VNF_NAME: member-vnf-index in the NS to be scaled.
2643 '''
2644 try:
2645 check_client_version(ctx.obj, ctx.command.name)
2646 if not scale_in and not scale_out:
2647 scale_out = True
2648 ctx.obj.ns.scale_vnf(ns_name, vnf_name, scaling_group, scale_in, scale_out)
2649 except ClientException as inst:
2650 print((inst.message))
2651 exit(1)
2652
2653
2654 if __name__ == '__main__':
2655 try:
2656 cli()
2657 except pycurl.error as e:
2658 print(e)
2659 print('Maybe "--hostname" option or OSM_HOSTNAME' +
2660 'environment variable needs to be specified')
2661 exit(1)
2662