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 keys to inject to vnfs')
708 @click.option('--config',
710 help='ns specific yaml configuration:\nvnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
711 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]')
720 '''creates a new NS instance'''
723 # check_client_version(ctx.obj, '--config', 'v1')
730 except ClientException
as inst
:
731 print((inst
.message
))
739 def nsd_update(ctx
, name
, content
):
741 check_client_version(ctx
.obj
, ctx
.command
.name
)
742 ctx
.obj
.nsd
.update(name
, content
)
743 except ClientException
as inst
:
744 print((inst
.message
))
747 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
748 @click.argument('name')
749 @click.option('--content', default
=None,
750 help='filename with the NSD/NSpkg replacing the current one')
752 def nsd_update1(ctx
, name
, content
):
753 '''updates a NSD/NSpkg
755 NAME: name or ID of the NSD/NSpkg
757 nsd_update(ctx
, name
, content
)
760 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
761 @click.argument('name')
762 @click.option('--content', default
=None,
763 help='filename with the NSD/NSpkg replacing the current one')
765 def nsd_update2(ctx
, name
, content
):
766 '''updates a NSD/NSpkg
768 NAME: name or ID of the NSD/NSpkg
770 nsd_update(ctx
, name
, content
)
773 def vnfd_update(ctx
, name
, content
):
775 check_client_version(ctx
.obj
, ctx
.command
.name
)
776 ctx
.obj
.vnfd
.update(name
, content
)
777 except ClientException
as inst
:
778 print((inst
.message
))
782 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
783 @click.argument('name')
784 @click.option('--content', default
=None,
785 help='filename with the VNFD/VNFpkg replacing the current one')
787 def vnfd_update1(ctx
, name
, content
):
788 '''updates a VNFD/VNFpkg
790 NAME: name or ID of the VNFD/VNFpkg
792 vnfd_update(ctx
, name
, content
)
795 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
796 @click.argument('name')
797 @click.option('--content', default
=None,
798 help='filename with the VNFD/VNFpkg replacing the current one')
800 def vnfd_update2(ctx
, name
, content
):
801 '''updates a VNFD/VNFpkg
803 NAME: VNFD yaml file or VNFpkg tar.gz file
805 vnfd_update(ctx
, name
, content
)
812 def nsd_delete(ctx
, name
, force
):
815 ctx
.obj
.nsd
.delete(name
)
817 check_client_version(ctx
.obj
, '--force')
818 ctx
.obj
.nsd
.delete(name
, force
)
819 except ClientException
as inst
:
820 print((inst
.message
))
824 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
825 @click.argument('name')
826 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
828 def nsd_delete1(ctx
, name
, force
):
829 '''deletes a NSD/NSpkg
831 NAME: name or ID of the NSD/NSpkg to be deleted
833 nsd_delete(ctx
, name
, force
)
836 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
837 @click.argument('name')
838 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
840 def nsd_delete2(ctx
, name
, force
):
841 '''deletes a NSD/NSpkg
843 NAME: name or ID of the NSD/NSpkg to be deleted
845 nsd_delete(ctx
, name
, force
)
848 def vnfd_delete(ctx
, name
, force
):
851 ctx
.obj
.vnfd
.delete(name
)
853 check_client_version(ctx
.obj
, '--force')
854 ctx
.obj
.vnfd
.delete(name
, force
)
855 except ClientException
as inst
:
856 print((inst
.message
))
860 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
861 @click.argument('name')
862 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
864 def vnfd_delete1(ctx
, name
, force
):
865 '''deletes a VNFD/VNFpkg
867 NAME: name or ID of the VNFD/VNFpkg to be deleted
869 vnfd_delete(ctx
, name
, force
)
872 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
873 @click.argument('name')
874 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
876 def vnfd_delete2(ctx
, name
, force
):
877 '''deletes a VNFD/VNFpkg
879 NAME: name or ID of the VNFD/VNFpkg to be deleted
881 vnfd_delete(ctx
, name
, force
)
884 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
885 @click.argument('name')
886 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
888 def ns_delete(ctx
, name
, force
):
889 '''deletes a NS instance
891 NAME: name or ID of the NS instance to be deleted
895 ctx
.obj
.ns
.delete(name
)
897 check_client_version(ctx
.obj
, '--force')
898 ctx
.obj
.ns
.delete(name
, force
)
899 except ClientException
as inst
:
900 print((inst
.message
))
908 @cli.command(name
='vim-create')
909 @click.option('--name',
911 help='Name to create datacenter')
912 @click.option('--user',
915 @click.option('--password',
918 confirmation_prompt
=True,
920 @click.option('--auth_url',
923 @click.option('--tenant',
925 help='VIM tenant name')
926 @click.option('--config',
928 help='VIM specific config parameters')
929 @click.option('--account_type',
932 @click.option('--description',
933 default
='no description',
934 help='human readable description')
935 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
936 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
949 '''creates a new VIM account
953 check_client_version(ctx
.obj
, '--sdn_controller')
955 check_client_version(ctx
.obj
, '--sdn_port_mapping')
957 vim
['vim-username'] = user
958 vim
['vim-password'] = password
959 vim
['vim-url'] = auth_url
960 vim
['vim-tenant-name'] = tenant
961 vim
['vim-type'] = account_type
962 vim
['description'] = description
963 vim
['config'] = config
964 if sdn_controller
or sdn_port_mapping
:
965 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
)
967 ctx
.obj
.vim
.create(name
, vim
)
968 except ClientException
as inst
:
969 print((inst
.message
))
973 @cli.command(name
='vim-update', short_help
='updates a VIM account')
974 @click.argument('name')
975 @click.option('--newname', help='New name for the VIM account')
976 @click.option('--user', help='VIM username')
977 @click.option('--password', help='VIM password')
978 @click.option('--auth_url', help='VIM url')
979 @click.option('--tenant', help='VIM tenant name')
980 @click.option('--config', help='VIM specific config parameters')
981 @click.option('--account_type', help='VIM type')
982 @click.option('--description', help='human readable description')
983 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
984 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
998 '''updates a VIM account
1000 NAME: name or ID of the VIM account
1003 check_client_version(ctx
.obj
, ctx
.command
.name
)
1005 if newname
: vim
['name'] = newname
1006 if user
: vim
['vim_user'] = user
1007 if password
: vim
['vim_password'] = password
1008 if auth_url
: vim
['vim_url'] = auth_url
1009 if tenant
: vim
['vim-tenant-name'] = tenant
1010 if account_type
: vim
['vim_type'] = account_type
1011 if description
: vim
['description'] = description
1012 if config
: vim
['config'] = config
1013 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
)
1014 except ClientException
as inst
:
1015 print((inst
.message
))
1019 @cli.command(name
='vim-delete')
1020 @click.argument('name')
1021 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1023 def vim_delete(ctx
, name
, force
):
1024 '''deletes a VIM account
1026 NAME: name or ID of the VIM account to be deleted
1030 ctx
.obj
.vim
.delete(name
)
1032 check_client_version(ctx
.obj
, '--force')
1033 ctx
.obj
.vim
.delete(name
, force
)
1034 except ClientException
as inst
:
1035 print((inst
.message
))
1039 @cli.command(name
='vim-list')
1040 @click.option('--ro_update/--no_ro_update',
1042 help='update list from RO')
1043 @click.option('--filter', default
=None,
1044 help='restricts the list to the VIM accounts matching the filter')
1046 def vim_list(ctx
, ro_update
, filter):
1047 '''list all VIM accounts'''
1049 check_client_version(ctx
.obj
, '--filter')
1051 check_client_version(ctx
.obj
, '--ro_update', 'v1')
1052 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1053 if fullclassname
== 'osmclient.sol005.client.Client':
1054 resp
= ctx
.obj
.vim
.list(filter)
1056 resp
= ctx
.obj
.vim
.list(ro_update
)
1057 table
= PrettyTable(['vim name', 'uuid'])
1059 table
.add_row([vim
['name'], vim
['uuid']])
1064 @cli.command(name
='vim-show')
1065 @click.argument('name')
1067 def vim_show(ctx
, name
):
1068 '''shows the details of a VIM account
1070 NAME: name or ID of the VIM account
1073 resp
= ctx
.obj
.vim
.get(name
)
1074 if 'vim_password' in resp
:
1075 resp
['vim_password']='********'
1076 except ClientException
as inst
:
1077 print((inst
.message
))
1080 table
= PrettyTable(['key', 'attribute'])
1081 for k
, v
in list(resp
.items()):
1082 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1087 ####################
1088 # SDN controller operations
1089 ####################
1091 @cli.command(name
='sdnc-create')
1092 @click.option('--name',
1094 help='Name to create sdn controller')
1095 @click.option('--type',
1097 help='SDN controller type')
1098 @click.option('--sdn_controller_version',
1099 help='SDN controller username')
1100 @click.option('--ip_address',
1102 help='SDN controller IP address')
1103 @click.option('--port',
1105 help='SDN controller port')
1106 @click.option('--switch_dpid',
1108 help='Switch DPID (Openflow Datapath ID)')
1109 @click.option('--user',
1110 help='SDN controller username')
1111 @click.option('--password',
1113 confirmation_prompt
=True,
1114 help='SDN controller password')
1115 #@click.option('--description',
1116 # default='no description',
1117 # help='human readable description')
1119 def sdnc_create(ctx
,
1122 sdn_controller_version
,
1128 '''creates a new SDN controller
1131 sdncontroller
['name'] = name
1132 sdncontroller
['type'] = type
1133 sdncontroller
['ip'] = ip_address
1134 sdncontroller
['port'] = int(port
)
1135 sdncontroller
['dpid'] = switch_dpid
1136 if sdn_controller_version
:
1137 sdncontroller
['version'] = sdn_controller_version
1139 sdncontroller
['user'] = user
1141 sdncontroller
['password'] = password
1142 # sdncontroller['description'] = description
1144 check_client_version(ctx
.obj
, ctx
.command
.name
)
1145 ctx
.obj
.sdnc
.create(name
, sdncontroller
)
1146 except ClientException
as inst
:
1147 print((inst
.message
))
1150 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
1151 @click.argument('name')
1152 @click.option('--newname', help='New name for the SDN controller')
1153 @click.option('--type', help='SDN controller type')
1154 @click.option('--sdn_controller_version', help='SDN controller username')
1155 @click.option('--ip_address', help='SDN controller IP address')
1156 @click.option('--port', help='SDN controller port')
1157 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1158 @click.option('--user', help='SDN controller username')
1159 @click.option('--password', help='SDN controller password')
1160 #@click.option('--description', default=None, help='human readable description')
1162 def sdnc_update(ctx
,
1166 sdn_controller_version
,
1172 '''updates an SDN controller
1174 NAME: name or ID of the SDN controller
1177 if newname
: sdncontroller
['name'] = newname
1178 if type: sdncontroller
['type'] = type
1179 if ip_address
: sdncontroller
['ip'] = ip_address
1180 if port
: sdncontroller
['port'] = int(port
)
1181 if switch_dpid
: sdncontroller
['dpid'] = switch_dpid
1182 # sdncontroller['description'] = description
1183 if sdn_controller_version
is not None:
1184 if sdn_controller_version
=="":
1185 sdncontroller
['version'] = None
1187 sdncontroller
['version'] = sdn_controller_version
1188 if user
is not None:
1190 sdncontroller
['user'] = None
1192 sdncontroller
['user'] = user
1193 if password
is not None:
1195 sdncontroller
['password'] = None
1197 sdncontroller
['password'] = user
1199 check_client_version(ctx
.obj
, ctx
.command
.name
)
1200 ctx
.obj
.sdnc
.update(name
, sdncontroller
)
1201 except ClientException
as inst
:
1202 print((inst
.message
))
1206 @cli.command(name
='sdnc-delete')
1207 @click.argument('name')
1208 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1210 def sdnc_delete(ctx
, name
, force
):
1211 '''deletes an SDN controller
1213 NAME: name or ID of the SDN controller to be deleted
1216 check_client_version(ctx
.obj
, ctx
.command
.name
)
1217 ctx
.obj
.sdnc
.delete(name
, force
)
1218 except ClientException
as inst
:
1219 print((inst
.message
))
1223 @cli.command(name
='sdnc-list')
1224 @click.option('--filter', default
=None,
1225 help='restricts the list to the SDN controllers matching the filter')
1227 def sdnc_list(ctx
, filter):
1228 '''list all SDN controllers'''
1230 check_client_version(ctx
.obj
, ctx
.command
.name
)
1231 resp
= ctx
.obj
.sdnc
.list(filter)
1232 except ClientException
as inst
:
1233 print((inst
.message
))
1235 table
= PrettyTable(['name', 'id'])
1237 table
.add_row([sdnc
['name'], sdnc
['_id']])
1242 @cli.command(name
='sdnc-show')
1243 @click.argument('name')
1245 def sdnc_show(ctx
, name
):
1246 '''shows the details of an SDN controller
1248 NAME: name or ID of the SDN controller
1251 check_client_version(ctx
.obj
, ctx
.command
.name
)
1252 resp
= ctx
.obj
.sdnc
.get(name
)
1253 except ClientException
as inst
:
1254 print((inst
.message
))
1257 table
= PrettyTable(['key', 'attribute'])
1258 for k
, v
in list(resp
.items()):
1259 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1264 ####################
1265 # Fault Management operations
1266 ####################
1268 @cli.command(name
='ns-alarm-create')
1269 @click.argument('name')
1270 @click.option('--ns', prompt
=True, help='NS instance id or name')
1271 @click.option('--vnf', prompt
=True,
1272 help='VNF name (VNF member index as declared in the NSD)')
1273 @click.option('--vdu', prompt
=True,
1274 help='VDU name (VDU name as declared in the VNFD)')
1275 @click.option('--metric', prompt
=True,
1276 help='Name of the metric (e.g. cpu_utilization)')
1277 @click.option('--severity', default
='WARNING',
1278 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
1279 @click.option('--threshold_value', prompt
=True,
1280 help='threshold value that, when crossed, an alarm is triggered')
1281 @click.option('--threshold_operator', prompt
=True,
1282 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
1283 @click.option('--statistic', default
='AVERAGE',
1284 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
1286 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
1287 threshold_value
, threshold_operator
, statistic
):
1288 '''creates a new alarm for a NS instance'''
1289 ns_instance
= ctx
.obj
.ns
.get(ns
)
1291 alarm
['alarm_name'] = name
1292 alarm
['ns_id'] = ns_instance
['_id']
1293 alarm
['correlation_id'] = ns_instance
['_id']
1294 alarm
['vnf_member_index'] = vnf
1295 alarm
['vdu_name'] = vdu
1296 alarm
['metric_name'] = metric
1297 alarm
['severity'] = severity
1298 alarm
['threshold_value'] = int(threshold_value
)
1299 alarm
['operation'] = threshold_operator
1300 alarm
['statistic'] = statistic
1302 check_client_version(ctx
.obj
, ctx
.command
.name
)
1303 ctx
.obj
.ns
.create_alarm(alarm
)
1304 except ClientException
as inst
:
1305 print((inst
.message
))
1309 #@cli.command(name='ns-alarm-delete')
1310 #@click.argument('name')
1311 #@click.pass_context
1312 #def ns_alarm_delete(ctx, name):
1313 # '''deletes an alarm
1315 # NAME: name of the alarm to be deleted
1318 # check_client_version(ctx.obj, ctx.command.name)
1319 # ctx.obj.ns.delete_alarm(name)
1320 # except ClientException as inst:
1321 # print(inst.message)
1325 ####################
1326 # Performance Management operations
1327 ####################
1329 @cli.command(name
='ns-metric-export')
1330 @click.option('--ns', prompt
=True, help='NS instance id or name')
1331 @click.option('--vnf', prompt
=True,
1332 help='VNF name (VNF member index as declared in the NSD)')
1333 @click.option('--vdu', prompt
=True,
1334 help='VDU name (VDU name as declared in the VNFD)')
1335 @click.option('--metric', prompt
=True,
1336 help='name of the metric (e.g. cpu_utilization)')
1337 #@click.option('--period', default='1w',
1338 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
1339 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
1341 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
1342 '''exports a metric to the internal OSM bus, which can be read by other apps
1344 ns_instance
= ctx
.obj
.ns
.get(ns
)
1346 metric_data
['ns_id'] = ns_instance
['_id']
1347 metric_data
['correlation_id'] = ns_instance
['_id']
1348 metric_data
['vnf_member_index'] = vnf
1349 metric_data
['vdu_name'] = vdu
1350 metric_data
['metric_name'] = metric
1351 metric_data
['collection_unit'] = 'WEEK'
1352 metric_data
['collection_period'] = 1
1354 check_client_version(ctx
.obj
, ctx
.command
.name
)
1356 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
1360 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
1361 time
.sleep(int(interval
))
1363 except ClientException
as inst
:
1364 print((inst
.message
))
1368 ####################
1370 ####################
1372 @cli.command(name
='upload-package')
1373 @click.argument('filename')
1375 def upload_package(ctx
, filename
):
1376 '''uploads a VNF package or NS package
1378 FILENAME: VNF or NS package file (tar.gz)
1381 ctx
.obj
.package
.upload(filename
)
1382 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1383 if fullclassname
!= 'osmclient.sol005.client.Client':
1384 ctx
.obj
.package
.wait_for_upload(filename
)
1385 except ClientException
as inst
:
1386 print((inst
.message
))
1390 @cli.command(name
='ns-scaling-show')
1391 @click.argument('ns_name')
1393 def show_ns_scaling(ctx
, ns_name
):
1394 '''shows the status of a NS scaling operation
1396 NS_NAME: name of the NS instance being scaled
1399 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1400 resp
= ctx
.obj
.ns
.list()
1401 except ClientException
as inst
:
1402 print((inst
.message
))
1405 table
= PrettyTable(
1408 'operational status',
1413 if ns_name
== ns
['name']:
1414 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1415 scaling_records
= nsopdata
['nsr:nsr']['scaling-group-record']
1416 for record
in scaling_records
:
1417 if 'instance' in record
:
1418 instances
= record
['instance']
1419 for inst
in instances
:
1421 [record
['scaling-group-name-ref'],
1422 inst
['instance-id'],
1424 time
.strftime('%Y-%m-%d %H:%M:%S',
1426 inst
['create-time'])),
1432 @cli.command(name
='ns-scale')
1433 @click.argument('ns_name')
1434 @click.option('--ns_scale_group', prompt
=True)
1435 @click.option('--index', prompt
=True)
1437 def ns_scale(ctx
, ns_name
, ns_scale_group
, index
):
1440 NS_NAME: name of the NS instance to be scaled
1443 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1444 ctx
.obj
.ns
.scale(ns_name
, ns_scale_group
, index
)
1445 except ClientException
as inst
:
1446 print((inst
.message
))
1450 @cli.command(name
='config-agent-list')
1452 def config_agent_list(ctx
):
1453 '''list config agents'''
1455 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1456 except ClientException
as inst
:
1457 print((inst
.message
))
1459 table
= PrettyTable(['name', 'account-type', 'details'])
1460 for account
in ctx
.obj
.vca
.list():
1463 account
['account-type'],
1469 @cli.command(name
='config-agent-delete')
1470 @click.argument('name')
1472 def config_agent_delete(ctx
, name
):
1473 '''deletes a config agent
1475 NAME: name of the config agent to be deleted
1478 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1479 ctx
.obj
.vca
.delete(name
)
1480 except ClientException
as inst
:
1481 print((inst
.message
))
1485 @cli.command(name
='config-agent-add')
1486 @click.option('--name',
1488 @click.option('--account_type',
1490 @click.option('--server',
1492 @click.option('--user',
1494 @click.option('--secret',
1497 confirmation_prompt
=True)
1499 def config_agent_add(ctx
, name
, account_type
, server
, user
, secret
):
1500 '''adds a config agent'''
1502 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1503 ctx
.obj
.vca
.create(name
, account_type
, server
, user
, secret
)
1504 except ClientException
as inst
:
1505 print((inst
.message
))
1508 @cli.command(name
='ro-dump')
1511 '''shows RO agent information'''
1512 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1513 resp
= ctx
.obj
.vim
.get_resource_orchestrator()
1514 table
= PrettyTable(['key', 'attribute'])
1515 for k
, v
in list(resp
.items()):
1516 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1521 @cli.command(name
='vcs-list')
1524 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1525 resp
= ctx
.obj
.utils
.get_vcs_info()
1526 table
= PrettyTable(['component name', 'state'])
1527 for component
in resp
:
1528 table
.add_row([component
['component_name'], component
['state']])
1533 @cli.command(name
='ns-action')
1534 @click.argument('ns_name')
1535 @click.option('--vnf_name', default
=None)
1536 @click.option('--action_name', prompt
=True)
1537 @click.option('--params', prompt
=True)
1544 '''executes an action/primitive over a NS instance
1546 NS_NAME: name or ID of the NS instance
1549 check_client_version(ctx
.obj
, ctx
.command
.name
)
1552 op_data
['vnf_member_index'] = vnf_name
1553 op_data
['primitive'] = action_name
1554 op_data
['primitive_params'] = yaml
.load(params
)
1555 ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
)
1557 except ClientException
as inst
:
1558 print((inst
.message
))
1562 if __name__
== '__main__':