1 # Copyright 2017-2018 Sandvine
2 # Copyright 2018 Telefonica
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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
22 from osmclient
import client
23 from osmclient
.common
.exceptions
import ClientException
24 from prettytable
import PrettyTable
29 def check_client_version(obj
, what
, version
='sol005'):
31 Checks the version of the client object and raises error if it not the expected.
33 :param obj: the client object
34 :what: the function or command under evaluation (used when an error is raised)
36 :raises ClientError: if the specified version does not match the client version
38 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
39 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
41 message
= 'The following commands or options are not supported when using option "--sol005": {}'.format(what
)
42 if fullclassname
!= 'osmclient.{}.client.Client'.format(version
):
43 raise ClientException(message
)
47 @click.option('--hostname',
49 envvar
='OSM_HOSTNAME',
50 help='hostname of server. ' +
51 'Also can set OSM_HOSTNAME in environment')
52 @click.option('--so-port',
55 help='hostname of server. ' +
56 'Also can set OSM_SO_PORT in environment')
57 @click.option('--so-project',
59 envvar
='OSM_SO_PROJECT',
60 help='Project Name in SO. ' +
61 'Also can set OSM_SO_PROJECT in environment')
62 @click.option('--ro-hostname',
64 envvar
='OSM_RO_HOSTNAME',
65 help='hostname of RO server. ' +
66 'Also can set OSM_RO_HOSTNAME in environment')
67 @click.option('--ro-port',
70 help='hostname of RO server. ' +
71 'Also can set OSM_RO_PORT in environment')
72 @click.option('--sol005/--no-sol005',
75 help='Use ETSI NFV SOL005 API (default) or the previous SO API')
77 def cli(ctx
, hostname
, so_port
, so_project
, ro_hostname
, ro_port
, sol005
):
80 "either hostname option or OSM_HOSTNAME " +
81 "environment variable needs to be specified"))
84 if so_port
is not None:
85 kwargs
['so_port']=so_port
86 if so_project
is not None:
87 kwargs
['so_project']=so_project
88 if ro_hostname
is not None:
89 kwargs
['ro_host']=ro_hostname
90 if ro_port
is not None:
91 kwargs
['ro_port']=ro_port
93 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
100 @cli.command(name
='ns-list')
101 @click.option('--filter', default
=None,
102 help='restricts the list to the NS instances matching the filter.')
104 def ns_list(ctx
, filter):
105 '''list all NS instances
109 --filter filterExpr Restricts the list to the NS instances matching the filter
112 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
113 concatenated using the "&" character:
116 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
117 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
118 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
120 value := scalar value
124 * zero or more occurrences
125 ? zero or one occurrence
126 [] grouping of expressions to be used with ? and *
127 "" quotation marks for marking string constants
131 "AttrName" is the name of one attribute in the data type that defines the representation
132 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
133 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
134 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
135 entries, it means that the operator "op" is applied to the attribute addressed by the last
136 <attrName> entry included in the concatenation. All simple filter expressions are combined
137 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
138 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
139 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
140 prefix". If an attribute referenced in an expression is an array, an object that contains a
141 corresponding array shall be considered to match the expression if any of the elements in the
142 array matches all expressions that have the same attribute prefix.
146 --filter admin-status=ENABLED
147 --filter nsd-ref=<NSD_NAME>
148 --filter nsd.vendor=<VENDOR>
149 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
150 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
153 check_client_version(ctx
.obj
, '--filter')
154 resp
= ctx
.obj
.ns
.list(filter)
156 resp
= ctx
.obj
.ns
.list()
160 'operational status',
164 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
165 if fullclassname
== 'osmclient.sol005.client.Client':
167 nsr_name
= nsr
['name']
170 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
171 nsr
= nsopdata
['nsr:nsr']
172 nsr_name
= nsr
['name-ref']
173 nsr_id
= nsr
['ns-instance-config-ref']
174 opstatus
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
175 configstatus
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
176 detailed_status
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
177 if configstatus
== "config_not_needed":
178 configstatus
= "configured (no charms)"
189 def nsd_list(ctx
, filter):
191 check_client_version(ctx
.obj
, '--filter')
192 resp
= ctx
.obj
.nsd
.list(filter)
194 resp
= ctx
.obj
.nsd
.list()
195 #print yaml.safe_dump(resp)
196 table
= PrettyTable(['nsd name', 'id'])
197 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
198 if fullclassname
== 'osmclient.sol005.client.Client':
200 name
= ns
['name'] if 'name' in ns
else '-'
201 table
.add_row([name
, ns
['_id']])
204 table
.add_row([ns
['name'], ns
['id']])
209 @cli.command(name
='nsd-list')
210 @click.option('--filter', default
=None,
211 help='restricts the list to the NSD/NSpkg matching the filter')
213 def nsd_list1(ctx
, filter):
214 '''list all NSD/NSpkg in the system'''
218 @cli.command(name
='nspkg-list')
219 @click.option('--filter', default
=None,
220 help='restricts the list to the NSD/NSpkg matching the filter')
222 def nsd_list2(ctx
, filter):
223 '''list all NSD/NSpkg in the system'''
227 def vnfd_list(ctx
, filter):
229 check_client_version(ctx
.obj
, '--filter')
230 resp
= ctx
.obj
.vnfd
.list(filter)
232 resp
= ctx
.obj
.vnfd
.list()
233 #print yaml.safe_dump(resp)
234 table
= PrettyTable(['vnfd name', 'id'])
235 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
236 if fullclassname
== 'osmclient.sol005.client.Client':
238 name
= vnfd
['name'] if 'name' in vnfd
else '-'
239 table
.add_row([name
, vnfd
['_id']])
242 table
.add_row([vnfd
['name'], vnfd
['id']])
247 @cli.command(name
='vnfd-list')
248 @click.option('--filter', default
=None,
249 help='restricts the list to the VNFD/VNFpkg matching the filter')
251 def vnfd_list1(ctx
, filter):
252 '''list all VNFD/VNFpkg in the system'''
253 vnfd_list(ctx
,filter)
256 @cli.command(name
='vnfpkg-list')
257 @click.option('--filter', default
=None,
258 help='restricts the list to the VNFD/VNFpkg matching the filter')
260 def vnfd_list2(ctx
, filter):
261 '''list all VNFD/VNFpkg in the system'''
262 vnfd_list(ctx
,filter)
265 @cli.command(name
='vnf-list')
266 @click.option('--ns', default
=None, help='NS instance id or name to restrict the VNF list')
267 @click.option('--filter', default
=None,
268 help='restricts the list to the VNF instances matching the filter.')
270 def vnf_list(ctx
, ns
, filter):
271 '''list all VNF instances
275 --ns TEXT NS instance id or name to restrict the VNF list
276 --filter filterExpr Restricts the list to the VNF instances matching the filter
279 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
280 concatenated using the "&" character:
283 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
284 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
285 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
287 value := scalar value
291 * zero or more occurrences
292 ? zero or one occurrence
293 [] grouping of expressions to be used with ? and *
294 "" quotation marks for marking string constants
298 "AttrName" is the name of one attribute in the data type that defines the representation
299 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
300 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
301 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
302 entries, it means that the operator "op" is applied to the attribute addressed by the last
303 <attrName> entry included in the concatenation. All simple filter expressions are combined
304 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
305 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
306 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
307 prefix". If an attribute referenced in an expression is an array, an object that contains a
308 corresponding array shall be considered to match the expression if any of the elements in the
309 array matches all expressions that have the same attribute prefix.
313 --filter vim-account-id=<VIM_ACCOUNT_ID>
314 --filter vnfd-ref=<VNFD_NAME>
315 --filter vdur.ip-address=<IP_ADDRESS>
316 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
321 check_client_version(ctx
.obj
, '--ns')
323 check_client_version(ctx
.obj
, '--filter')
324 resp
= ctx
.obj
.vnf
.list(ns
, filter)
326 resp
= ctx
.obj
.vnf
.list()
327 except ClientException
as inst
:
328 print((inst
.message
))
330 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
331 if fullclassname
== 'osmclient.sol005.client.Client':
341 name
= vnfr
['name'] if 'name' in vnfr
else '-'
346 vnfr
['member-vnf-index-ref'],
348 vnfr
['vim-account-id'],
354 'operational status',
357 if 'mgmt-interface' not in vnfr
:
358 vnfr
['mgmt-interface'] = {}
359 vnfr
['mgmt-interface']['ip-address'] = None
363 vnfr
['operational-status'],
364 vnfr
['config-status']])
368 @cli.command(name
='ns-op-list')
369 @click.argument('name')
371 def ns_op_list(ctx
, name
):
372 '''shows the history of operations over a NS instance
374 NAME: name or ID of the NS instance
377 check_client_version(ctx
.obj
, ctx
.command
.name
)
378 resp
= ctx
.obj
.ns
.list_op(name
)
379 except ClientException
as inst
:
380 print((inst
.message
))
383 table
= PrettyTable(['id', 'operation', 'status'])
385 table
.add_row([op
['id'], op
['lcmOperationType'],
386 op
['operationState']])
394 def nsd_show(ctx
, name
, literal
):
396 resp
= ctx
.obj
.nsd
.get(name
)
397 #resp = ctx.obj.nsd.get_individual(name)
398 except ClientException
as inst
:
399 print((inst
.message
))
403 print(yaml
.safe_dump(resp
))
406 table
= PrettyTable(['field', 'value'])
407 for k
, v
in list(resp
.items()):
408 table
.add_row([k
, json
.dumps(v
, indent
=2)])
413 @cli.command(name
='nsd-show', short_help
='shows the content of a NSD')
414 @click.option('--literal', is_flag
=True,
415 help='print literally, no pretty table')
416 @click.argument('name')
418 def nsd_show1(ctx
, name
, literal
):
419 '''shows the content of a NSD
421 NAME: name or ID of the NSD/NSpkg
423 nsd_show(ctx
, name
, literal
)
426 @cli.command(name
='nspkg-show', short_help
='shows the content of a NSD')
427 @click.option('--literal', is_flag
=True,
428 help='print literally, no pretty table')
429 @click.argument('name')
431 def nsd_show2(ctx
, name
, literal
):
432 '''shows the content of a NSD
434 NAME: name or ID of the NSD/NSpkg
436 nsd_show(ctx
, name
, literal
)
439 def vnfd_show(ctx
, name
, literal
):
441 resp
= ctx
.obj
.vnfd
.get(name
)
442 #resp = ctx.obj.vnfd.get_individual(name)
443 except ClientException
as inst
:
444 print((inst
.message
))
448 print(yaml
.safe_dump(resp
))
451 table
= PrettyTable(['field', 'value'])
452 for k
, v
in list(resp
.items()):
453 table
.add_row([k
, json
.dumps(v
, indent
=2)])
458 @cli.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
459 @click.option('--literal', is_flag
=True,
460 help='print literally, no pretty table')
461 @click.argument('name')
463 def vnfd_show1(ctx
, name
, literal
):
464 '''shows the content of a VNFD
466 NAME: name or ID of the VNFD/VNFpkg
468 vnfd_show(ctx
, name
, literal
)
471 @cli.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
472 @click.option('--literal', is_flag
=True,
473 help='print literally, no pretty table')
474 @click.argument('name')
476 def vnfd_show2(ctx
, name
, literal
):
477 '''shows the content of a VNFD
479 NAME: name or ID of the VNFD/VNFpkg
481 vnfd_show(ctx
, name
, literal
)
484 @cli.command(name
='ns-show', short_help
='shows the info of a NS instance')
485 @click.argument('name')
486 @click.option('--literal', is_flag
=True,
487 help='print literally, no pretty table')
488 @click.option('--filter', default
=None)
490 def ns_show(ctx
, name
, literal
, filter):
491 '''shows the info of a NS instance
493 NAME: name or ID of the NS instance
496 ns
= ctx
.obj
.ns
.get(name
)
497 except ClientException
as inst
:
498 print((inst
.message
))
502 print(yaml
.safe_dump(ns
))
505 table
= PrettyTable(['field', 'value'])
507 for k
, v
in list(ns
.items()):
508 if filter is None or filter in k
:
509 table
.add_row([k
, json
.dumps(v
, indent
=2)])
511 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
512 if fullclassname
!= 'osmclient.sol005.client.Client':
513 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
514 nsr_optdata
= nsopdata
['nsr:nsr']
515 for k
, v
in list(nsr_optdata
.items()):
516 if filter is None or filter in k
:
517 table
.add_row([k
, json
.dumps(v
, indent
=2)])
522 @cli.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
523 @click.argument('name')
524 @click.option('--literal', is_flag
=True,
525 help='print literally, no pretty table')
526 @click.option('--filter', default
=None)
528 def vnf_show(ctx
, name
, literal
, filter):
529 '''shows the info of a VNF instance
531 NAME: name or ID of the VNF instance
534 check_client_version(ctx
.obj
, ctx
.command
.name
)
535 resp
= ctx
.obj
.vnf
.get(name
)
536 except ClientException
as inst
:
537 print((inst
.message
))
541 print(yaml
.safe_dump(resp
))
544 table
= PrettyTable(['field', 'value'])
545 for k
, v
in list(resp
.items()):
546 if filter is None or filter in k
:
547 table
.add_row([k
, json
.dumps(v
, indent
=2)])
552 @cli.command(name
='vnf-monitoring-show')
553 @click.argument('vnf_name')
555 def vnf_monitoring_show(ctx
, vnf_name
):
557 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
558 resp
= ctx
.obj
.vnf
.get_monitoring(vnf_name
)
559 except ClientException
as inst
:
560 print((inst
.message
))
563 table
= PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
569 monitor
['value-integer'],
575 @cli.command(name
='ns-monitoring-show')
576 @click.argument('ns_name')
578 def ns_monitoring_show(ctx
, ns_name
):
580 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
581 resp
= ctx
.obj
.ns
.get_monitoring(ns_name
)
582 except ClientException
as inst
:
583 print((inst
.message
))
586 table
= PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
587 for key
, val
in list(resp
.items()):
592 monitor
['value-integer'],
597 @cli.command(name
='ns-op-show', short_help
='shows the info of an operation')
598 @click.argument('id')
599 @click.option('--filter', default
=None)
601 def ns_op_show(ctx
, id, filter):
602 '''shows the detailed info of an operation
604 ID: operation identifier
607 check_client_version(ctx
.obj
, ctx
.command
.name
)
608 op_info
= ctx
.obj
.ns
.get_op(id)
609 except ClientException
as inst
:
610 print((inst
.message
))
613 table
= PrettyTable(['field', 'value'])
614 for k
, v
in list(op_info
.items()):
615 if filter is None or filter in k
:
616 table
.add_row([k
, json
.dumps(v
, indent
=2)])
625 def nsd_create(ctx
, filename
, overwrite
):
627 check_client_version(ctx
.obj
, ctx
.command
.name
)
628 ctx
.obj
.nsd
.create(filename
, overwrite
)
629 except ClientException
as inst
:
630 print((inst
.message
))
634 @cli.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
635 @click.argument('filename')
636 @click.option('--overwrite', default
=None,
637 help='overwrites some fields in NSD')
639 def nsd_create1(ctx
, filename
, overwrite
):
640 '''creates a new NSD/NSpkg
642 FILENAME: NSD yaml file or NSpkg tar.gz file
644 nsd_create(ctx
, filename
, overwrite
)
647 @cli.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
648 @click.argument('filename')
649 @click.option('--overwrite', default
=None,
650 help='overwrites some fields in NSD')
652 def nsd_create2(ctx
, filename
, overwrite
):
653 '''creates a new NSD/NSpkg
655 FILENAME: NSD yaml file or NSpkg tar.gz file
657 nsd_create(ctx
, filename
, overwrite
)
660 def vnfd_create(ctx
, filename
, overwrite
):
662 check_client_version(ctx
.obj
, ctx
.command
.name
)
663 ctx
.obj
.vnfd
.create(filename
, overwrite
)
664 except ClientException
as inst
:
665 print((inst
.message
))
669 @cli.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
670 @click.argument('filename')
671 @click.option('--overwrite', default
=None,
672 help='overwrites some fields in VNFD')
674 def vnfd_create1(ctx
, filename
, overwrite
):
675 '''creates a new VNFD/VNFpkg
677 FILENAME: VNFD yaml file or VNFpkg tar.gz file
679 vnfd_create(ctx
, filename
, overwrite
)
682 @cli.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
683 @click.argument('filename')
684 @click.option('--overwrite', default
=None,
685 help='overwrites some fields in VNFD')
687 def vnfd_create2(ctx
, filename
, overwrite
):
688 '''creates a new VNFD/VNFpkg
690 FILENAME: VNFD yaml file or VNFpkg tar.gz file
692 vnfd_create(ctx
, filename
, overwrite
)
695 @cli.command(name
='ns-create')
696 @click.option('--ns_name',
698 @click.option('--nsd_name',
700 @click.option('--vim_account',
702 @click.option('--admin_status',
704 help='administration status')
705 @click.option('--ssh_keys',
707 help='comma separated list of public key files to inject to vnfs')
708 @click.option('--config',
710 help='ns specific yaml configuration')
711 @click.option('--config_file',
713 help='ns specific yaml configuration file')
723 '''creates a new NS instance'''
726 check_client_version(ctx
.obj
, '--config_file')
728 raise ClientException('"--config" option is incompatible with "--config_file" option')
729 with
open(config_file
, 'r') as cf
:
737 except ClientException
as inst
:
738 print((inst
.message
))
746 def nsd_update(ctx
, name
, content
):
748 check_client_version(ctx
.obj
, ctx
.command
.name
)
749 ctx
.obj
.nsd
.update(name
, content
)
750 except ClientException
as inst
:
751 print((inst
.message
))
754 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
755 @click.argument('name')
756 @click.option('--content', default
=None,
757 help='filename with the NSD/NSpkg replacing the current one')
759 def nsd_update1(ctx
, name
, content
):
760 '''updates a NSD/NSpkg
762 NAME: name or ID of the NSD/NSpkg
764 nsd_update(ctx
, name
, content
)
767 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
768 @click.argument('name')
769 @click.option('--content', default
=None,
770 help='filename with the NSD/NSpkg replacing the current one')
772 def nsd_update2(ctx
, name
, content
):
773 '''updates a NSD/NSpkg
775 NAME: name or ID of the NSD/NSpkg
777 nsd_update(ctx
, name
, content
)
780 def vnfd_update(ctx
, name
, content
):
782 check_client_version(ctx
.obj
, ctx
.command
.name
)
783 ctx
.obj
.vnfd
.update(name
, content
)
784 except ClientException
as inst
:
785 print((inst
.message
))
789 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
790 @click.argument('name')
791 @click.option('--content', default
=None,
792 help='filename with the VNFD/VNFpkg replacing the current one')
794 def vnfd_update1(ctx
, name
, content
):
795 '''updates a VNFD/VNFpkg
797 NAME: name or ID of the VNFD/VNFpkg
799 vnfd_update(ctx
, name
, content
)
802 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
803 @click.argument('name')
804 @click.option('--content', default
=None,
805 help='filename with the VNFD/VNFpkg replacing the current one')
807 def vnfd_update2(ctx
, name
, content
):
808 '''updates a VNFD/VNFpkg
810 NAME: VNFD yaml file or VNFpkg tar.gz file
812 vnfd_update(ctx
, name
, content
)
819 def nsd_delete(ctx
, name
, force
):
822 ctx
.obj
.nsd
.delete(name
)
824 check_client_version(ctx
.obj
, '--force')
825 ctx
.obj
.nsd
.delete(name
, force
)
826 except ClientException
as inst
:
827 print((inst
.message
))
831 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
832 @click.argument('name')
833 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
835 def nsd_delete1(ctx
, name
, force
):
836 '''deletes a NSD/NSpkg
838 NAME: name or ID of the NSD/NSpkg to be deleted
840 nsd_delete(ctx
, name
, force
)
843 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
844 @click.argument('name')
845 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
847 def nsd_delete2(ctx
, name
, force
):
848 '''deletes a NSD/NSpkg
850 NAME: name or ID of the NSD/NSpkg to be deleted
852 nsd_delete(ctx
, name
, force
)
855 def vnfd_delete(ctx
, name
, force
):
858 ctx
.obj
.vnfd
.delete(name
)
860 check_client_version(ctx
.obj
, '--force')
861 ctx
.obj
.vnfd
.delete(name
, force
)
862 except ClientException
as inst
:
863 print((inst
.message
))
867 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
868 @click.argument('name')
869 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
871 def vnfd_delete1(ctx
, name
, force
):
872 '''deletes a VNFD/VNFpkg
874 NAME: name or ID of the VNFD/VNFpkg to be deleted
876 vnfd_delete(ctx
, name
, force
)
879 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
880 @click.argument('name')
881 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
883 def vnfd_delete2(ctx
, name
, force
):
884 '''deletes a VNFD/VNFpkg
886 NAME: name or ID of the VNFD/VNFpkg to be deleted
888 vnfd_delete(ctx
, name
, force
)
891 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
892 @click.argument('name')
893 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
895 def ns_delete(ctx
, name
, force
):
896 '''deletes a NS instance
898 NAME: name or ID of the NS instance to be deleted
902 ctx
.obj
.ns
.delete(name
)
904 check_client_version(ctx
.obj
, '--force')
905 ctx
.obj
.ns
.delete(name
, force
)
906 except ClientException
as inst
:
907 print((inst
.message
))
915 @cli.command(name
='vim-create')
916 @click.option('--name',
918 help='Name to create datacenter')
919 @click.option('--user',
922 @click.option('--password',
925 confirmation_prompt
=True,
927 @click.option('--auth_url',
930 @click.option('--tenant',
932 help='VIM tenant name')
933 @click.option('--config',
935 help='VIM specific config parameters')
936 @click.option('--account_type',
939 @click.option('--description',
940 default
='no description',
941 help='human readable description')
942 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
943 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
956 '''creates a new VIM account
960 check_client_version(ctx
.obj
, '--sdn_controller')
962 check_client_version(ctx
.obj
, '--sdn_port_mapping')
964 vim
['vim-username'] = user
965 vim
['vim-password'] = password
966 vim
['vim-url'] = auth_url
967 vim
['vim-tenant-name'] = tenant
968 vim
['vim-type'] = account_type
969 vim
['description'] = description
970 vim
['config'] = config
971 if sdn_controller
or sdn_port_mapping
:
972 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
)
974 ctx
.obj
.vim
.create(name
, vim
)
975 except ClientException
as inst
:
976 print((inst
.message
))
980 @cli.command(name
='vim-update', short_help
='updates a VIM account')
981 @click.argument('name')
982 @click.option('--newname', help='New name for the VIM account')
983 @click.option('--user', help='VIM username')
984 @click.option('--password', help='VIM password')
985 @click.option('--auth_url', help='VIM url')
986 @click.option('--tenant', help='VIM tenant name')
987 @click.option('--config', help='VIM specific config parameters')
988 @click.option('--account_type', help='VIM type')
989 @click.option('--description', help='human readable description')
990 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
991 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1005 '''updates a VIM account
1007 NAME: name or ID of the VIM account
1010 check_client_version(ctx
.obj
, ctx
.command
.name
)
1012 if newname
: vim
['name'] = newname
1013 if user
: vim
['vim_user'] = user
1014 if password
: vim
['vim_password'] = password
1015 if auth_url
: vim
['vim_url'] = auth_url
1016 if tenant
: vim
['vim-tenant-name'] = tenant
1017 if account_type
: vim
['vim_type'] = account_type
1018 if description
: vim
['description'] = description
1019 if config
: vim
['config'] = config
1020 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
)
1021 except ClientException
as inst
:
1022 print((inst
.message
))
1026 @cli.command(name
='vim-delete')
1027 @click.argument('name')
1028 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1030 def vim_delete(ctx
, name
, force
):
1031 '''deletes a VIM account
1033 NAME: name or ID of the VIM account to be deleted
1037 ctx
.obj
.vim
.delete(name
)
1039 check_client_version(ctx
.obj
, '--force')
1040 ctx
.obj
.vim
.delete(name
, force
)
1041 except ClientException
as inst
:
1042 print((inst
.message
))
1046 @cli.command(name
='vim-list')
1047 @click.option('--ro_update/--no_ro_update',
1049 help='update list from RO')
1050 @click.option('--filter', default
=None,
1051 help='restricts the list to the VIM accounts matching the filter')
1053 def vim_list(ctx
, ro_update
, filter):
1054 '''list all VIM accounts'''
1056 check_client_version(ctx
.obj
, '--filter')
1058 check_client_version(ctx
.obj
, '--ro_update', 'v1')
1059 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1060 if fullclassname
== 'osmclient.sol005.client.Client':
1061 resp
= ctx
.obj
.vim
.list(filter)
1063 resp
= ctx
.obj
.vim
.list(ro_update
)
1064 table
= PrettyTable(['vim name', 'uuid'])
1066 table
.add_row([vim
['name'], vim
['uuid']])
1071 @cli.command(name
='vim-show')
1072 @click.argument('name')
1074 def vim_show(ctx
, name
):
1075 '''shows the details of a VIM account
1077 NAME: name or ID of the VIM account
1080 resp
= ctx
.obj
.vim
.get(name
)
1081 if 'vim_password' in resp
:
1082 resp
['vim_password']='********'
1083 except ClientException
as inst
:
1084 print((inst
.message
))
1087 table
= PrettyTable(['key', 'attribute'])
1088 for k
, v
in list(resp
.items()):
1089 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1094 ####################
1095 # SDN controller operations
1096 ####################
1098 @cli.command(name
='sdnc-create')
1099 @click.option('--name',
1101 help='Name to create sdn controller')
1102 @click.option('--type',
1104 help='SDN controller type')
1105 @click.option('--sdn_controller_version',
1106 help='SDN controller username')
1107 @click.option('--ip_address',
1109 help='SDN controller IP address')
1110 @click.option('--port',
1112 help='SDN controller port')
1113 @click.option('--switch_dpid',
1115 help='Switch DPID (Openflow Datapath ID)')
1116 @click.option('--user',
1117 help='SDN controller username')
1118 @click.option('--password',
1120 confirmation_prompt
=True,
1121 help='SDN controller password')
1122 #@click.option('--description',
1123 # default='no description',
1124 # help='human readable description')
1126 def sdnc_create(ctx
,
1129 sdn_controller_version
,
1135 '''creates a new SDN controller
1138 sdncontroller
['name'] = name
1139 sdncontroller
['type'] = type
1140 sdncontroller
['ip'] = ip_address
1141 sdncontroller
['port'] = int(port
)
1142 sdncontroller
['dpid'] = switch_dpid
1143 if sdn_controller_version
:
1144 sdncontroller
['version'] = sdn_controller_version
1146 sdncontroller
['user'] = user
1148 sdncontroller
['password'] = password
1149 # sdncontroller['description'] = description
1151 check_client_version(ctx
.obj
, ctx
.command
.name
)
1152 ctx
.obj
.sdnc
.create(name
, sdncontroller
)
1153 except ClientException
as inst
:
1154 print((inst
.message
))
1157 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
1158 @click.argument('name')
1159 @click.option('--newname', help='New name for the SDN controller')
1160 @click.option('--type', help='SDN controller type')
1161 @click.option('--sdn_controller_version', help='SDN controller username')
1162 @click.option('--ip_address', help='SDN controller IP address')
1163 @click.option('--port', help='SDN controller port')
1164 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1165 @click.option('--user', help='SDN controller username')
1166 @click.option('--password', help='SDN controller password')
1167 #@click.option('--description', default=None, help='human readable description')
1169 def sdnc_update(ctx
,
1173 sdn_controller_version
,
1179 '''updates an SDN controller
1181 NAME: name or ID of the SDN controller
1184 if newname
: sdncontroller
['name'] = newname
1185 if type: sdncontroller
['type'] = type
1186 if ip_address
: sdncontroller
['ip'] = ip_address
1187 if port
: sdncontroller
['port'] = int(port
)
1188 if switch_dpid
: sdncontroller
['dpid'] = switch_dpid
1189 # sdncontroller['description'] = description
1190 if sdn_controller_version
is not None:
1191 if sdn_controller_version
=="":
1192 sdncontroller
['version'] = None
1194 sdncontroller
['version'] = sdn_controller_version
1195 if user
is not None:
1197 sdncontroller
['user'] = None
1199 sdncontroller
['user'] = user
1200 if password
is not None:
1202 sdncontroller
['password'] = None
1204 sdncontroller
['password'] = user
1206 check_client_version(ctx
.obj
, ctx
.command
.name
)
1207 ctx
.obj
.sdnc
.update(name
, sdncontroller
)
1208 except ClientException
as inst
:
1209 print((inst
.message
))
1213 @cli.command(name
='sdnc-delete')
1214 @click.argument('name')
1215 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1217 def sdnc_delete(ctx
, name
, force
):
1218 '''deletes an SDN controller
1220 NAME: name or ID of the SDN controller to be deleted
1223 check_client_version(ctx
.obj
, ctx
.command
.name
)
1224 ctx
.obj
.sdnc
.delete(name
, force
)
1225 except ClientException
as inst
:
1226 print((inst
.message
))
1230 @cli.command(name
='sdnc-list')
1231 @click.option('--filter', default
=None,
1232 help='restricts the list to the SDN controllers matching the filter')
1234 def sdnc_list(ctx
, filter):
1235 '''list all SDN controllers'''
1237 check_client_version(ctx
.obj
, ctx
.command
.name
)
1238 resp
= ctx
.obj
.sdnc
.list(filter)
1239 except ClientException
as inst
:
1240 print((inst
.message
))
1242 table
= PrettyTable(['name', 'id'])
1244 table
.add_row([sdnc
['name'], sdnc
['_id']])
1249 @cli.command(name
='sdnc-show')
1250 @click.argument('name')
1252 def sdnc_show(ctx
, name
):
1253 '''shows the details of an SDN controller
1255 NAME: name or ID of the SDN controller
1258 check_client_version(ctx
.obj
, ctx
.command
.name
)
1259 resp
= ctx
.obj
.sdnc
.get(name
)
1260 except ClientException
as inst
:
1261 print((inst
.message
))
1264 table
= PrettyTable(['key', 'attribute'])
1265 for k
, v
in list(resp
.items()):
1266 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1271 ####################
1272 # Fault Management operations
1273 ####################
1275 @cli.command(name
='ns-alarm-create')
1276 @click.argument('name')
1277 @click.option('--ns', prompt
=True, help='NS instance id or name')
1278 @click.option('--vnf', prompt
=True,
1279 help='VNF name (VNF member index as declared in the NSD)')
1280 @click.option('--vdu', prompt
=True,
1281 help='VDU name (VDU name as declared in the VNFD)')
1282 @click.option('--metric', prompt
=True,
1283 help='Name of the metric (e.g. cpu_utilization)')
1284 @click.option('--severity', default
='WARNING',
1285 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
1286 @click.option('--threshold_value', prompt
=True,
1287 help='threshold value that, when crossed, an alarm is triggered')
1288 @click.option('--threshold_operator', prompt
=True,
1289 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
1290 @click.option('--statistic', default
='AVERAGE',
1291 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
1293 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
1294 threshold_value
, threshold_operator
, statistic
):
1295 '''creates a new alarm for a NS instance'''
1296 ns_instance
= ctx
.obj
.ns
.get(ns
)
1298 alarm
['alarm_name'] = name
1299 alarm
['ns_id'] = ns_instance
['_id']
1300 alarm
['correlation_id'] = ns_instance
['_id']
1301 alarm
['vnf_member_index'] = vnf
1302 alarm
['vdu_name'] = vdu
1303 alarm
['metric_name'] = metric
1304 alarm
['severity'] = severity
1305 alarm
['threshold_value'] = int(threshold_value
)
1306 alarm
['operation'] = threshold_operator
1307 alarm
['statistic'] = statistic
1309 check_client_version(ctx
.obj
, ctx
.command
.name
)
1310 ctx
.obj
.ns
.create_alarm(alarm
)
1311 except ClientException
as inst
:
1312 print((inst
.message
))
1316 #@cli.command(name='ns-alarm-delete')
1317 #@click.argument('name')
1318 #@click.pass_context
1319 #def ns_alarm_delete(ctx, name):
1320 # '''deletes an alarm
1322 # NAME: name of the alarm to be deleted
1325 # check_client_version(ctx.obj, ctx.command.name)
1326 # ctx.obj.ns.delete_alarm(name)
1327 # except ClientException as inst:
1328 # print(inst.message)
1332 ####################
1333 # Performance Management operations
1334 ####################
1336 @cli.command(name
='ns-metric-export')
1337 @click.option('--ns', prompt
=True, help='NS instance id or name')
1338 @click.option('--vnf', prompt
=True,
1339 help='VNF name (VNF member index as declared in the NSD)')
1340 @click.option('--vdu', prompt
=True,
1341 help='VDU name (VDU name as declared in the VNFD)')
1342 @click.option('--metric', prompt
=True,
1343 help='name of the metric (e.g. cpu_utilization)')
1344 #@click.option('--period', default='1w',
1345 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
1346 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
1348 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
1349 '''exports a metric to the internal OSM bus, which can be read by other apps
1351 ns_instance
= ctx
.obj
.ns
.get(ns
)
1353 metric_data
['ns_id'] = ns_instance
['_id']
1354 metric_data
['correlation_id'] = ns_instance
['_id']
1355 metric_data
['vnf_member_index'] = vnf
1356 metric_data
['vdu_name'] = vdu
1357 metric_data
['metric_name'] = metric
1358 metric_data
['collection_unit'] = 'WEEK'
1359 metric_data
['collection_period'] = 1
1361 check_client_version(ctx
.obj
, ctx
.command
.name
)
1363 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
1367 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
1368 time
.sleep(int(interval
))
1370 except ClientException
as inst
:
1371 print((inst
.message
))
1375 ####################
1377 ####################
1379 @cli.command(name
='upload-package')
1380 @click.argument('filename')
1382 def upload_package(ctx
, filename
):
1383 '''uploads a VNF package or NS package
1385 FILENAME: VNF or NS package file (tar.gz)
1388 ctx
.obj
.package
.upload(filename
)
1389 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1390 if fullclassname
!= 'osmclient.sol005.client.Client':
1391 ctx
.obj
.package
.wait_for_upload(filename
)
1392 except ClientException
as inst
:
1393 print((inst
.message
))
1397 @cli.command(name
='ns-scaling-show')
1398 @click.argument('ns_name')
1400 def show_ns_scaling(ctx
, ns_name
):
1401 '''shows the status of a NS scaling operation
1403 NS_NAME: name of the NS instance being scaled
1406 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1407 resp
= ctx
.obj
.ns
.list()
1408 except ClientException
as inst
:
1409 print((inst
.message
))
1412 table
= PrettyTable(
1415 'operational status',
1420 if ns_name
== ns
['name']:
1421 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1422 scaling_records
= nsopdata
['nsr:nsr']['scaling-group-record']
1423 for record
in scaling_records
:
1424 if 'instance' in record
:
1425 instances
= record
['instance']
1426 for inst
in instances
:
1428 [record
['scaling-group-name-ref'],
1429 inst
['instance-id'],
1431 time
.strftime('%Y-%m-%d %H:%M:%S',
1433 inst
['create-time'])),
1439 @cli.command(name
='ns-scale')
1440 @click.argument('ns_name')
1441 @click.option('--ns_scale_group', prompt
=True)
1442 @click.option('--index', prompt
=True)
1444 def ns_scale(ctx
, ns_name
, ns_scale_group
, index
):
1447 NS_NAME: name of the NS instance to be scaled
1450 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1451 ctx
.obj
.ns
.scale(ns_name
, ns_scale_group
, index
)
1452 except ClientException
as inst
:
1453 print((inst
.message
))
1457 @cli.command(name
='config-agent-list')
1459 def config_agent_list(ctx
):
1460 '''list config agents'''
1462 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1463 except ClientException
as inst
:
1464 print((inst
.message
))
1466 table
= PrettyTable(['name', 'account-type', 'details'])
1467 for account
in ctx
.obj
.vca
.list():
1470 account
['account-type'],
1476 @cli.command(name
='config-agent-delete')
1477 @click.argument('name')
1479 def config_agent_delete(ctx
, name
):
1480 '''deletes a config agent
1482 NAME: name of the config agent to be deleted
1485 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1486 ctx
.obj
.vca
.delete(name
)
1487 except ClientException
as inst
:
1488 print((inst
.message
))
1492 @cli.command(name
='config-agent-add')
1493 @click.option('--name',
1495 @click.option('--account_type',
1497 @click.option('--server',
1499 @click.option('--user',
1501 @click.option('--secret',
1504 confirmation_prompt
=True)
1506 def config_agent_add(ctx
, name
, account_type
, server
, user
, secret
):
1507 '''adds a config agent'''
1509 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1510 ctx
.obj
.vca
.create(name
, account_type
, server
, user
, secret
)
1511 except ClientException
as inst
:
1512 print((inst
.message
))
1515 @cli.command(name
='ro-dump')
1518 '''shows RO agent information'''
1519 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1520 resp
= ctx
.obj
.vim
.get_resource_orchestrator()
1521 table
= PrettyTable(['key', 'attribute'])
1522 for k
, v
in list(resp
.items()):
1523 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1528 @cli.command(name
='vcs-list')
1531 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1532 resp
= ctx
.obj
.utils
.get_vcs_info()
1533 table
= PrettyTable(['component name', 'state'])
1534 for component
in resp
:
1535 table
.add_row([component
['component_name'], component
['state']])
1540 @cli.command(name
='ns-action')
1541 @click.argument('ns_name')
1542 @click.option('--vnf_name', default
=None)
1543 @click.option('--action_name', prompt
=True)
1544 @click.option('--params', prompt
=True)
1551 '''executes an action/primitive over a NS instance
1553 NS_NAME: name or ID of the NS instance
1556 check_client_version(ctx
.obj
, ctx
.command
.name
)
1559 op_data
['vnf_member_index'] = vnf_name
1560 op_data
['primitive'] = action_name
1561 op_data
['primitive_params'] = yaml
.load(params
)
1562 ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
)
1564 except ClientException
as inst
:
1565 print((inst
.message
))
1569 if __name__
== '__main__':