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
30 def check_client_version(obj
, what
, version
='sol005'):
32 Checks the version of the client object and raises error if it not the expected.
34 :param obj: the client object
35 :what: the function or command under evaluation (used when an error is raised)
37 :raises ClientError: if the specified version does not match the client version
39 fullclassname
= obj
.__module
__ + "." + obj
.__class
__.__name
__
40 message
= 'The following commands or options are only supported with the option "--sol005": {}'.format(what
)
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
)
48 @click.option('--hostname',
50 envvar
='OSM_HOSTNAME',
51 help='hostname of server. ' +
52 'Also can set OSM_HOSTNAME in environment')
53 @click.option('--so-port',
56 help='hostname of server. ' +
57 'Also can set OSM_SO_PORT in environment')
58 @click.option('--so-project',
60 envvar
='OSM_SO_PROJECT',
61 help='Project Name in SO. ' +
62 'Also can set OSM_SO_PROJECT in environment')
63 @click.option('--ro-hostname',
65 envvar
='OSM_RO_HOSTNAME',
66 help='hostname of RO server. ' +
67 'Also can set OSM_RO_HOSTNAME in environment')
68 @click.option('--ro-port',
71 help='hostname of RO server. ' +
72 'Also can set OSM_RO_PORT in environment')
73 @click.option('--sol005/--no-sol005',
76 help='Use ETSI NFV SOL005 API (default) or the previous SO API')
78 def cli(ctx
, hostname
, so_port
, so_project
, ro_hostname
, ro_port
, sol005
):
81 "either hostname option or OSM_HOSTNAME " +
82 "environment variable needs to be specified"))
85 if so_port
is not None:
86 kwargs
['so_port']=so_port
87 if so_project
is not None:
88 kwargs
['so_project']=so_project
89 if ro_hostname
is not None:
90 kwargs
['ro_host']=ro_hostname
91 if ro_port
is not None:
92 kwargs
['ro_port']=ro_port
94 ctx
.obj
= client
.Client(host
=hostname
, sol005
=sol005
, **kwargs
)
101 @cli.command(name
='ns-list')
102 @click.option('--filter', default
=None,
103 help='restricts the list to the NS instances matching the filter.')
105 def ns_list(ctx
, filter):
106 '''list all NS instances
110 --filter filterExpr Restricts the list to the NS instances matching the filter
113 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
114 concatenated using the "&" character:
117 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
118 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
119 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
121 value := scalar value
125 * zero or more occurrences
126 ? zero or one occurrence
127 [] grouping of expressions to be used with ? and *
128 "" quotation marks for marking string constants
132 "AttrName" is the name of one attribute in the data type that defines the representation
133 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
134 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
135 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
136 entries, it means that the operator "op" is applied to the attribute addressed by the last
137 <attrName> entry included in the concatenation. All simple filter expressions are combined
138 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
139 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
140 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
141 prefix". If an attribute referenced in an expression is an array, an object that contains a
142 corresponding array shall be considered to match the expression if any of the elements in the
143 array matches all expressions that have the same attribute prefix.
147 --filter admin-status=ENABLED
148 --filter nsd-ref=<NSD_NAME>
149 --filter nsd.vendor=<VENDOR>
150 --filter nsd.vendor=<VENDOR>&nsd-ref=<NSD_NAME>
151 --filter nsd.constituent-vnfd.vnfd-id-ref=<VNFD_NAME>
154 check_client_version(ctx
.obj
, '--filter')
155 resp
= ctx
.obj
.ns
.list(filter)
157 resp
= ctx
.obj
.ns
.list()
161 'operational status',
165 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
166 if fullclassname
== 'osmclient.sol005.client.Client':
168 nsr_name
= nsr
['name']
171 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
172 nsr
= nsopdata
['nsr:nsr']
173 nsr_name
= nsr
['name-ref']
174 nsr_id
= nsr
['ns-instance-config-ref']
175 opstatus
= nsr
['operational-status'] if 'operational-status' in nsr
else 'Not found'
176 configstatus
= nsr
['config-status'] if 'config-status' in nsr
else 'Not found'
177 detailed_status
= nsr
['detailed-status'] if 'detailed-status' in nsr
else 'Not found'
178 if configstatus
== "config_not_needed":
179 configstatus
= "configured (no charms)"
190 def nsd_list(ctx
, filter):
192 check_client_version(ctx
.obj
, '--filter')
193 resp
= ctx
.obj
.nsd
.list(filter)
195 resp
= ctx
.obj
.nsd
.list()
196 #print yaml.safe_dump(resp)
197 table
= PrettyTable(['nsd name', 'id'])
198 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
199 if fullclassname
== 'osmclient.sol005.client.Client':
201 name
= ns
['name'] if 'name' in ns
else '-'
202 table
.add_row([name
, ns
['_id']])
205 table
.add_row([ns
['name'], ns
['id']])
210 @cli.command(name
='nsd-list')
211 @click.option('--filter', default
=None,
212 help='restricts the list to the NSD/NSpkg matching the filter')
214 def nsd_list1(ctx
, filter):
215 '''list all NSD/NSpkg in the system'''
219 @cli.command(name
='nspkg-list')
220 @click.option('--filter', default
=None,
221 help='restricts the list to the NSD/NSpkg matching the filter')
223 def nsd_list2(ctx
, filter):
224 '''list all NSD/NSpkg in the system'''
228 def vnfd_list(ctx
, filter):
230 check_client_version(ctx
.obj
, '--filter')
231 resp
= ctx
.obj
.vnfd
.list(filter)
233 resp
= ctx
.obj
.vnfd
.list()
234 #print yaml.safe_dump(resp)
235 table
= PrettyTable(['vnfd name', 'id'])
236 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
237 if fullclassname
== 'osmclient.sol005.client.Client':
239 name
= vnfd
['name'] if 'name' in vnfd
else '-'
240 table
.add_row([name
, vnfd
['_id']])
243 table
.add_row([vnfd
['name'], vnfd
['id']])
248 @cli.command(name
='vnfd-list')
249 @click.option('--filter', default
=None,
250 help='restricts the list to the VNFD/VNFpkg matching the filter')
252 def vnfd_list1(ctx
, filter):
253 '''list all VNFD/VNFpkg in the system'''
254 vnfd_list(ctx
,filter)
257 @cli.command(name
='vnfpkg-list')
258 @click.option('--filter', default
=None,
259 help='restricts the list to the VNFD/VNFpkg matching the filter')
261 def vnfd_list2(ctx
, filter):
262 '''list all VNFD/VNFpkg in the system'''
263 vnfd_list(ctx
,filter)
266 @cli.command(name
='vnf-list')
267 @click.option('--ns', default
=None, help='NS instance id or name to restrict the VNF list')
268 @click.option('--filter', default
=None,
269 help='restricts the list to the VNF instances matching the filter.')
271 def vnf_list(ctx
, ns
, filter):
272 '''list all VNF instances
276 --ns TEXT NS instance id or name to restrict the VNF list
277 --filter filterExpr Restricts the list to the VNF instances matching the filter
280 filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
281 concatenated using the "&" character:
284 filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
285 simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
286 op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
288 value := scalar value
292 * zero or more occurrences
293 ? zero or one occurrence
294 [] grouping of expressions to be used with ? and *
295 "" quotation marks for marking string constants
299 "AttrName" is the name of one attribute in the data type that defines the representation
300 of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
301 <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
302 "Op" stands for the comparison operator. If the expression has concatenated <attrName>
303 entries, it means that the operator "op" is applied to the attribute addressed by the last
304 <attrName> entry included in the concatenation. All simple filter expressions are combined
305 by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
306 the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
307 concatenation of all "attrName" entries except the leaf attribute is called the "attribute
308 prefix". If an attribute referenced in an expression is an array, an object that contains a
309 corresponding array shall be considered to match the expression if any of the elements in the
310 array matches all expressions that have the same attribute prefix.
314 --filter vim-account-id=<VIM_ACCOUNT_ID>
315 --filter vnfd-ref=<VNFD_NAME>
316 --filter vdur.ip-address=<IP_ADDRESS>
317 --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
322 check_client_version(ctx
.obj
, '--ns')
324 check_client_version(ctx
.obj
, '--filter')
325 resp
= ctx
.obj
.vnf
.list(ns
, filter)
327 resp
= ctx
.obj
.vnf
.list()
328 except ClientException
as inst
:
329 print((inst
.message
))
331 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
332 if fullclassname
== 'osmclient.sol005.client.Client':
342 name
= vnfr
['name'] if 'name' in vnfr
else '-'
347 vnfr
['member-vnf-index-ref'],
349 vnfr
['vim-account-id'],
355 'operational status',
358 if 'mgmt-interface' not in vnfr
:
359 vnfr
['mgmt-interface'] = {}
360 vnfr
['mgmt-interface']['ip-address'] = None
364 vnfr
['operational-status'],
365 vnfr
['config-status']])
369 @cli.command(name
='ns-op-list')
370 @click.argument('name')
372 def ns_op_list(ctx
, name
):
373 '''shows the history of operations over a NS instance
375 NAME: name or ID of the NS instance
378 check_client_version(ctx
.obj
, ctx
.command
.name
)
379 resp
= ctx
.obj
.ns
.list_op(name
)
380 except ClientException
as inst
:
381 print((inst
.message
))
384 table
= PrettyTable(['id', 'operation', 'status'])
386 table
.add_row([op
['id'], op
['lcmOperationType'],
387 op
['operationState']])
395 def nsd_show(ctx
, name
, literal
):
397 resp
= ctx
.obj
.nsd
.get(name
)
398 #resp = ctx.obj.nsd.get_individual(name)
399 except ClientException
as inst
:
400 print((inst
.message
))
404 print(yaml
.safe_dump(resp
))
407 table
= PrettyTable(['field', 'value'])
408 for k
, v
in list(resp
.items()):
409 table
.add_row([k
, json
.dumps(v
, indent
=2)])
414 @cli.command(name
='nsd-show', short_help
='shows the content of a NSD')
415 @click.option('--literal', is_flag
=True,
416 help='print literally, no pretty table')
417 @click.argument('name')
419 def nsd_show1(ctx
, name
, literal
):
420 '''shows the content of a NSD
422 NAME: name or ID of the NSD/NSpkg
424 nsd_show(ctx
, name
, literal
)
427 @cli.command(name
='nspkg-show', short_help
='shows the content of a NSD')
428 @click.option('--literal', is_flag
=True,
429 help='print literally, no pretty table')
430 @click.argument('name')
432 def nsd_show2(ctx
, name
, literal
):
433 '''shows the content of a NSD
435 NAME: name or ID of the NSD/NSpkg
437 nsd_show(ctx
, name
, literal
)
440 def vnfd_show(ctx
, name
, literal
):
442 resp
= ctx
.obj
.vnfd
.get(name
)
443 #resp = ctx.obj.vnfd.get_individual(name)
444 except ClientException
as inst
:
445 print((inst
.message
))
449 print(yaml
.safe_dump(resp
))
452 table
= PrettyTable(['field', 'value'])
453 for k
, v
in list(resp
.items()):
454 table
.add_row([k
, json
.dumps(v
, indent
=2)])
459 @cli.command(name
='vnfd-show', short_help
='shows the content of a VNFD')
460 @click.option('--literal', is_flag
=True,
461 help='print literally, no pretty table')
462 @click.argument('name')
464 def vnfd_show1(ctx
, name
, literal
):
465 '''shows the content of a VNFD
467 NAME: name or ID of the VNFD/VNFpkg
469 vnfd_show(ctx
, name
, literal
)
472 @cli.command(name
='vnfpkg-show', short_help
='shows the content of a VNFD')
473 @click.option('--literal', is_flag
=True,
474 help='print literally, no pretty table')
475 @click.argument('name')
477 def vnfd_show2(ctx
, name
, literal
):
478 '''shows the content of a VNFD
480 NAME: name or ID of the VNFD/VNFpkg
482 vnfd_show(ctx
, name
, literal
)
485 @cli.command(name
='ns-show', short_help
='shows the info of a NS instance')
486 @click.argument('name')
487 @click.option('--literal', is_flag
=True,
488 help='print literally, no pretty table')
489 @click.option('--filter', default
=None)
491 def ns_show(ctx
, name
, literal
, filter):
492 '''shows the info of a NS instance
494 NAME: name or ID of the NS instance
497 ns
= ctx
.obj
.ns
.get(name
)
498 except ClientException
as inst
:
499 print((inst
.message
))
503 print(yaml
.safe_dump(ns
))
506 table
= PrettyTable(['field', 'value'])
508 for k
, v
in list(ns
.items()):
509 if filter is None or filter in k
:
510 table
.add_row([k
, json
.dumps(v
, indent
=2)])
512 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
513 if fullclassname
!= 'osmclient.sol005.client.Client':
514 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
515 nsr_optdata
= nsopdata
['nsr:nsr']
516 for k
, v
in list(nsr_optdata
.items()):
517 if filter is None or filter in k
:
518 table
.add_row([k
, json
.dumps(v
, indent
=2)])
523 @cli.command(name
='vnf-show', short_help
='shows the info of a VNF instance')
524 @click.argument('name')
525 @click.option('--literal', is_flag
=True,
526 help='print literally, no pretty table')
527 @click.option('--filter', default
=None)
529 def vnf_show(ctx
, name
, literal
, filter):
530 '''shows the info of a VNF instance
532 NAME: name or ID of the VNF instance
535 check_client_version(ctx
.obj
, ctx
.command
.name
)
536 resp
= ctx
.obj
.vnf
.get(name
)
537 except ClientException
as inst
:
538 print((inst
.message
))
542 print(yaml
.safe_dump(resp
))
545 table
= PrettyTable(['field', 'value'])
546 for k
, v
in list(resp
.items()):
547 if filter is None or filter in k
:
548 table
.add_row([k
, json
.dumps(v
, indent
=2)])
553 @cli.command(name
='vnf-monitoring-show')
554 @click.argument('vnf_name')
556 def vnf_monitoring_show(ctx
, vnf_name
):
558 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
559 resp
= ctx
.obj
.vnf
.get_monitoring(vnf_name
)
560 except ClientException
as inst
:
561 print((inst
.message
))
564 table
= PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
570 monitor
['value-integer'],
576 @cli.command(name
='ns-monitoring-show')
577 @click.argument('ns_name')
579 def ns_monitoring_show(ctx
, ns_name
):
581 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
582 resp
= ctx
.obj
.ns
.get_monitoring(ns_name
)
583 except ClientException
as inst
:
584 print((inst
.message
))
587 table
= PrettyTable(['vnf name', 'monitoring name', 'value', 'units'])
588 for key
, val
in list(resp
.items()):
593 monitor
['value-integer'],
598 @cli.command(name
='ns-op-show', short_help
='shows the info of an operation')
599 @click.argument('id')
600 @click.option('--filter', default
=None)
602 def ns_op_show(ctx
, id, filter):
603 '''shows the detailed info of an operation
605 ID: operation identifier
608 check_client_version(ctx
.obj
, ctx
.command
.name
)
609 op_info
= ctx
.obj
.ns
.get_op(id)
610 except ClientException
as inst
:
611 print((inst
.message
))
614 table
= PrettyTable(['field', 'value'])
615 for k
, v
in list(op_info
.items()):
616 if filter is None or filter in k
:
617 table
.add_row([k
, json
.dumps(v
, indent
=2)])
626 def nsd_create(ctx
, filename
, overwrite
):
628 check_client_version(ctx
.obj
, ctx
.command
.name
)
629 ctx
.obj
.nsd
.create(filename
, overwrite
)
630 except ClientException
as inst
:
631 print((inst
.message
))
635 @cli.command(name
='nsd-create', short_help
='creates a new NSD/NSpkg')
636 @click.argument('filename')
637 @click.option('--overwrite', default
=None,
638 help='overwrites some fields in NSD')
640 def nsd_create1(ctx
, filename
, overwrite
):
641 '''creates a new NSD/NSpkg
643 FILENAME: NSD yaml file or NSpkg tar.gz file
645 nsd_create(ctx
, filename
, overwrite
)
648 @cli.command(name
='nspkg-create', short_help
='creates a new NSD/NSpkg')
649 @click.argument('filename')
650 @click.option('--overwrite', default
=None,
651 help='overwrites some fields in NSD')
653 def nsd_create2(ctx
, filename
, overwrite
):
654 '''creates a new NSD/NSpkg
656 FILENAME: NSD yaml file or NSpkg tar.gz file
658 nsd_create(ctx
, filename
, overwrite
)
661 def vnfd_create(ctx
, filename
, overwrite
):
663 check_client_version(ctx
.obj
, ctx
.command
.name
)
664 ctx
.obj
.vnfd
.create(filename
, overwrite
)
665 except ClientException
as inst
:
666 print((inst
.message
))
670 @cli.command(name
='vnfd-create', short_help
='creates a new VNFD/VNFpkg')
671 @click.argument('filename')
672 @click.option('--overwrite', default
=None,
673 help='overwrites some fields in VNFD')
675 def vnfd_create1(ctx
, filename
, overwrite
):
676 '''creates a new VNFD/VNFpkg
678 FILENAME: VNFD yaml file or VNFpkg tar.gz file
680 vnfd_create(ctx
, filename
, overwrite
)
683 @cli.command(name
='vnfpkg-create', short_help
='creates a new VNFD/VNFpkg')
684 @click.argument('filename')
685 @click.option('--overwrite', default
=None,
686 help='overwrites some fields in VNFD')
688 def vnfd_create2(ctx
, filename
, overwrite
):
689 '''creates a new VNFD/VNFpkg
691 FILENAME: VNFD yaml file or VNFpkg tar.gz file
693 vnfd_create(ctx
, filename
, overwrite
)
696 @cli.command(name
='ns-create')
697 @click.option('--ns_name',
699 @click.option('--nsd_name',
701 @click.option('--vim_account',
703 @click.option('--admin_status',
705 help='administration status')
706 @click.option('--ssh_keys',
708 help='comma separated list of public key files to inject to vnfs')
709 @click.option('--config',
711 help='ns specific yaml configuration')
712 @click.option('--config_file',
714 help='ns specific yaml configuration file')
724 '''creates a new NS instance'''
727 check_client_version(ctx
.obj
, '--config_file')
729 raise ClientException('"--config" option is incompatible with "--config_file" option')
730 with
open(config_file
, 'r') as cf
:
738 except ClientException
as inst
:
739 print((inst
.message
))
747 def nsd_update(ctx
, name
, content
):
749 check_client_version(ctx
.obj
, ctx
.command
.name
)
750 ctx
.obj
.nsd
.update(name
, content
)
751 except ClientException
as inst
:
752 print((inst
.message
))
755 @cli.command(name
='nsd-update', short_help
='updates a NSD/NSpkg')
756 @click.argument('name')
757 @click.option('--content', default
=None,
758 help='filename with the NSD/NSpkg replacing the current one')
760 def nsd_update1(ctx
, name
, content
):
761 '''updates a NSD/NSpkg
763 NAME: name or ID of the NSD/NSpkg
765 nsd_update(ctx
, name
, content
)
768 @cli.command(name
='nspkg-update', short_help
='updates a NSD/NSpkg')
769 @click.argument('name')
770 @click.option('--content', default
=None,
771 help='filename with the NSD/NSpkg replacing the current one')
773 def nsd_update2(ctx
, name
, content
):
774 '''updates a NSD/NSpkg
776 NAME: name or ID of the NSD/NSpkg
778 nsd_update(ctx
, name
, content
)
781 def vnfd_update(ctx
, name
, content
):
783 check_client_version(ctx
.obj
, ctx
.command
.name
)
784 ctx
.obj
.vnfd
.update(name
, content
)
785 except ClientException
as inst
:
786 print((inst
.message
))
790 @cli.command(name
='vnfd-update', short_help
='updates a new VNFD/VNFpkg')
791 @click.argument('name')
792 @click.option('--content', default
=None,
793 help='filename with the VNFD/VNFpkg replacing the current one')
795 def vnfd_update1(ctx
, name
, content
):
796 '''updates a VNFD/VNFpkg
798 NAME: name or ID of the VNFD/VNFpkg
800 vnfd_update(ctx
, name
, content
)
803 @cli.command(name
='vnfpkg-update', short_help
='updates a VNFD/VNFpkg')
804 @click.argument('name')
805 @click.option('--content', default
=None,
806 help='filename with the VNFD/VNFpkg replacing the current one')
808 def vnfd_update2(ctx
, name
, content
):
809 '''updates a VNFD/VNFpkg
811 NAME: VNFD yaml file or VNFpkg tar.gz file
813 vnfd_update(ctx
, name
, content
)
820 def nsd_delete(ctx
, name
, force
):
823 ctx
.obj
.nsd
.delete(name
)
825 check_client_version(ctx
.obj
, '--force')
826 ctx
.obj
.nsd
.delete(name
, force
)
827 except ClientException
as inst
:
828 print((inst
.message
))
832 @cli.command(name
='nsd-delete', short_help
='deletes a NSD/NSpkg')
833 @click.argument('name')
834 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
836 def nsd_delete1(ctx
, name
, force
):
837 '''deletes a NSD/NSpkg
839 NAME: name or ID of the NSD/NSpkg to be deleted
841 nsd_delete(ctx
, name
, force
)
844 @cli.command(name
='nspkg-delete', short_help
='deletes a NSD/NSpkg')
845 @click.argument('name')
846 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
848 def nsd_delete2(ctx
, name
, force
):
849 '''deletes a NSD/NSpkg
851 NAME: name or ID of the NSD/NSpkg to be deleted
853 nsd_delete(ctx
, name
, force
)
856 def vnfd_delete(ctx
, name
, force
):
859 ctx
.obj
.vnfd
.delete(name
)
861 check_client_version(ctx
.obj
, '--force')
862 ctx
.obj
.vnfd
.delete(name
, force
)
863 except ClientException
as inst
:
864 print((inst
.message
))
868 @cli.command(name
='vnfd-delete', short_help
='deletes a VNFD/VNFpkg')
869 @click.argument('name')
870 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
872 def vnfd_delete1(ctx
, name
, force
):
873 '''deletes a VNFD/VNFpkg
875 NAME: name or ID of the VNFD/VNFpkg to be deleted
877 vnfd_delete(ctx
, name
, force
)
880 @cli.command(name
='vnfpkg-delete', short_help
='deletes a VNFD/VNFpkg')
881 @click.argument('name')
882 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
884 def vnfd_delete2(ctx
, name
, force
):
885 '''deletes a VNFD/VNFpkg
887 NAME: name or ID of the VNFD/VNFpkg to be deleted
889 vnfd_delete(ctx
, name
, force
)
892 @cli.command(name
='ns-delete', short_help
='deletes a NS instance')
893 @click.argument('name')
894 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
896 def ns_delete(ctx
, name
, force
):
897 '''deletes a NS instance
899 NAME: name or ID of the NS instance to be deleted
903 ctx
.obj
.ns
.delete(name
)
905 check_client_version(ctx
.obj
, '--force')
906 ctx
.obj
.ns
.delete(name
, force
)
907 except ClientException
as inst
:
908 print((inst
.message
))
916 @cli.command(name
='vim-create')
917 @click.option('--name',
919 help='Name to create datacenter')
920 @click.option('--user',
923 @click.option('--password',
926 confirmation_prompt
=True,
928 @click.option('--auth_url',
931 @click.option('--tenant',
933 help='VIM tenant name')
934 @click.option('--config',
936 help='VIM specific config parameters')
937 @click.option('--account_type',
940 @click.option('--description',
941 default
='no description',
942 help='human readable description')
943 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
944 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
957 '''creates a new VIM account
961 check_client_version(ctx
.obj
, '--sdn_controller')
963 check_client_version(ctx
.obj
, '--sdn_port_mapping')
965 vim
['vim-username'] = user
966 vim
['vim-password'] = password
967 vim
['vim-url'] = auth_url
968 vim
['vim-tenant-name'] = tenant
969 vim
['vim-type'] = account_type
970 vim
['description'] = description
971 vim
['config'] = config
972 if sdn_controller
or sdn_port_mapping
:
973 ctx
.obj
.vim
.create(name
, vim
, sdn_controller
, sdn_port_mapping
)
975 ctx
.obj
.vim
.create(name
, vim
)
976 except ClientException
as inst
:
977 print((inst
.message
))
981 @cli.command(name
='vim-update', short_help
='updates a VIM account')
982 @click.argument('name')
983 @click.option('--newname', help='New name for the VIM account')
984 @click.option('--user', help='VIM username')
985 @click.option('--password', help='VIM password')
986 @click.option('--auth_url', help='VIM url')
987 @click.option('--tenant', help='VIM tenant name')
988 @click.option('--config', help='VIM specific config parameters')
989 @click.option('--account_type', help='VIM type')
990 @click.option('--description', help='human readable description')
991 @click.option('--sdn_controller', default
=None, help='Name or id of the SDN controller associated to this VIM account')
992 @click.option('--sdn_port_mapping', default
=None, help="File describing the port mapping between compute nodes' ports and switch ports")
1006 '''updates a VIM account
1008 NAME: name or ID of the VIM account
1011 check_client_version(ctx
.obj
, ctx
.command
.name
)
1013 if newname
: vim
['name'] = newname
1014 if user
: vim
['vim_user'] = user
1015 if password
: vim
['vim_password'] = password
1016 if auth_url
: vim
['vim_url'] = auth_url
1017 if tenant
: vim
['vim-tenant-name'] = tenant
1018 if account_type
: vim
['vim_type'] = account_type
1019 if description
: vim
['description'] = description
1020 if config
: vim
['config'] = config
1021 ctx
.obj
.vim
.update(name
, vim
, sdn_controller
, sdn_port_mapping
)
1022 except ClientException
as inst
:
1023 print((inst
.message
))
1027 @cli.command(name
='vim-delete')
1028 @click.argument('name')
1029 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1031 def vim_delete(ctx
, name
, force
):
1032 '''deletes a VIM account
1034 NAME: name or ID of the VIM account to be deleted
1038 ctx
.obj
.vim
.delete(name
)
1040 check_client_version(ctx
.obj
, '--force')
1041 ctx
.obj
.vim
.delete(name
, force
)
1042 except ClientException
as inst
:
1043 print((inst
.message
))
1047 @cli.command(name
='vim-list')
1048 @click.option('--ro_update/--no_ro_update',
1050 help='update list from RO')
1051 @click.option('--filter', default
=None,
1052 help='restricts the list to the VIM accounts matching the filter')
1054 def vim_list(ctx
, ro_update
, filter):
1055 '''list all VIM accounts'''
1057 check_client_version(ctx
.obj
, '--filter')
1059 check_client_version(ctx
.obj
, '--ro_update', 'v1')
1060 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1061 if fullclassname
== 'osmclient.sol005.client.Client':
1062 resp
= ctx
.obj
.vim
.list(filter)
1064 resp
= ctx
.obj
.vim
.list(ro_update
)
1065 table
= PrettyTable(['vim name', 'uuid'])
1067 table
.add_row([vim
['name'], vim
['uuid']])
1072 @cli.command(name
='vim-show')
1073 @click.argument('name')
1075 def vim_show(ctx
, name
):
1076 '''shows the details of a VIM account
1078 NAME: name or ID of the VIM account
1081 resp
= ctx
.obj
.vim
.get(name
)
1082 if 'vim_password' in resp
:
1083 resp
['vim_password']='********'
1084 except ClientException
as inst
:
1085 print((inst
.message
))
1088 table
= PrettyTable(['key', 'attribute'])
1089 for k
, v
in list(resp
.items()):
1090 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1095 ####################
1096 # SDN controller operations
1097 ####################
1099 @cli.command(name
='sdnc-create')
1100 @click.option('--name',
1102 help='Name to create sdn controller')
1103 @click.option('--type',
1105 help='SDN controller type')
1106 @click.option('--sdn_controller_version',
1107 help='SDN controller username')
1108 @click.option('--ip_address',
1110 help='SDN controller IP address')
1111 @click.option('--port',
1113 help='SDN controller port')
1114 @click.option('--switch_dpid',
1116 help='Switch DPID (Openflow Datapath ID)')
1117 @click.option('--user',
1118 help='SDN controller username')
1119 @click.option('--password',
1121 confirmation_prompt
=True,
1122 help='SDN controller password')
1123 #@click.option('--description',
1124 # default='no description',
1125 # help='human readable description')
1127 def sdnc_create(ctx
,
1130 sdn_controller_version
,
1136 '''creates a new SDN controller
1139 sdncontroller
['name'] = name
1140 sdncontroller
['type'] = type
1141 sdncontroller
['ip'] = ip_address
1142 sdncontroller
['port'] = int(port
)
1143 sdncontroller
['dpid'] = switch_dpid
1144 if sdn_controller_version
:
1145 sdncontroller
['version'] = sdn_controller_version
1147 sdncontroller
['user'] = user
1149 sdncontroller
['password'] = password
1150 # sdncontroller['description'] = description
1152 check_client_version(ctx
.obj
, ctx
.command
.name
)
1153 ctx
.obj
.sdnc
.create(name
, sdncontroller
)
1154 except ClientException
as inst
:
1155 print((inst
.message
))
1158 @cli.command(name
='sdnc-update', short_help
='updates an SDN controller')
1159 @click.argument('name')
1160 @click.option('--newname', help='New name for the SDN controller')
1161 @click.option('--type', help='SDN controller type')
1162 @click.option('--sdn_controller_version', help='SDN controller username')
1163 @click.option('--ip_address', help='SDN controller IP address')
1164 @click.option('--port', help='SDN controller port')
1165 @click.option('--switch_dpid', help='Switch DPID (Openflow Datapath ID)')
1166 @click.option('--user', help='SDN controller username')
1167 @click.option('--password', help='SDN controller password')
1168 #@click.option('--description', default=None, help='human readable description')
1170 def sdnc_update(ctx
,
1174 sdn_controller_version
,
1180 '''updates an SDN controller
1182 NAME: name or ID of the SDN controller
1185 if newname
: sdncontroller
['name'] = newname
1186 if type: sdncontroller
['type'] = type
1187 if ip_address
: sdncontroller
['ip'] = ip_address
1188 if port
: sdncontroller
['port'] = int(port
)
1189 if switch_dpid
: sdncontroller
['dpid'] = switch_dpid
1190 # sdncontroller['description'] = description
1191 if sdn_controller_version
is not None:
1192 if sdn_controller_version
=="":
1193 sdncontroller
['version'] = None
1195 sdncontroller
['version'] = sdn_controller_version
1196 if user
is not None:
1198 sdncontroller
['user'] = None
1200 sdncontroller
['user'] = user
1201 if password
is not None:
1203 sdncontroller
['password'] = None
1205 sdncontroller
['password'] = user
1207 check_client_version(ctx
.obj
, ctx
.command
.name
)
1208 ctx
.obj
.sdnc
.update(name
, sdncontroller
)
1209 except ClientException
as inst
:
1210 print((inst
.message
))
1214 @cli.command(name
='sdnc-delete')
1215 @click.argument('name')
1216 @click.option('--force', is_flag
=True, help='forces the deletion bypassing pre-conditions')
1218 def sdnc_delete(ctx
, name
, force
):
1219 '''deletes an SDN controller
1221 NAME: name or ID of the SDN controller to be deleted
1224 check_client_version(ctx
.obj
, ctx
.command
.name
)
1225 ctx
.obj
.sdnc
.delete(name
, force
)
1226 except ClientException
as inst
:
1227 print((inst
.message
))
1231 @cli.command(name
='sdnc-list')
1232 @click.option('--filter', default
=None,
1233 help='restricts the list to the SDN controllers matching the filter')
1235 def sdnc_list(ctx
, filter):
1236 '''list all SDN controllers'''
1238 check_client_version(ctx
.obj
, ctx
.command
.name
)
1239 resp
= ctx
.obj
.sdnc
.list(filter)
1240 except ClientException
as inst
:
1241 print((inst
.message
))
1243 table
= PrettyTable(['name', 'id'])
1245 table
.add_row([sdnc
['name'], sdnc
['_id']])
1250 @cli.command(name
='sdnc-show')
1251 @click.argument('name')
1253 def sdnc_show(ctx
, name
):
1254 '''shows the details of an SDN controller
1256 NAME: name or ID of the SDN controller
1259 check_client_version(ctx
.obj
, ctx
.command
.name
)
1260 resp
= ctx
.obj
.sdnc
.get(name
)
1261 except ClientException
as inst
:
1262 print((inst
.message
))
1265 table
= PrettyTable(['key', 'attribute'])
1266 for k
, v
in list(resp
.items()):
1267 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1272 ####################
1273 # Fault Management operations
1274 ####################
1276 @cli.command(name
='ns-alarm-create')
1277 @click.argument('name')
1278 @click.option('--ns', prompt
=True, help='NS instance id or name')
1279 @click.option('--vnf', prompt
=True,
1280 help='VNF name (VNF member index as declared in the NSD)')
1281 @click.option('--vdu', prompt
=True,
1282 help='VDU name (VDU name as declared in the VNFD)')
1283 @click.option('--metric', prompt
=True,
1284 help='Name of the metric (e.g. cpu_utilization)')
1285 @click.option('--severity', default
='WARNING',
1286 help='severity of the alarm (WARNING, MINOR, MAJOR, CRITICAL, INDETERMINATE)')
1287 @click.option('--threshold_value', prompt
=True,
1288 help='threshold value that, when crossed, an alarm is triggered')
1289 @click.option('--threshold_operator', prompt
=True,
1290 help='threshold operator describing the comparison (GE, LE, GT, LT, EQ)')
1291 @click.option('--statistic', default
='AVERAGE',
1292 help='statistic (AVERAGE, MINIMUM, MAXIMUM, COUNT, SUM)')
1294 def ns_alarm_create(ctx
, name
, ns
, vnf
, vdu
, metric
, severity
,
1295 threshold_value
, threshold_operator
, statistic
):
1296 '''creates a new alarm for a NS instance'''
1297 ns_instance
= ctx
.obj
.ns
.get(ns
)
1299 alarm
['alarm_name'] = name
1300 alarm
['ns_id'] = ns_instance
['_id']
1301 alarm
['correlation_id'] = ns_instance
['_id']
1302 alarm
['vnf_member_index'] = vnf
1303 alarm
['vdu_name'] = vdu
1304 alarm
['metric_name'] = metric
1305 alarm
['severity'] = severity
1306 alarm
['threshold_value'] = int(threshold_value
)
1307 alarm
['operation'] = threshold_operator
1308 alarm
['statistic'] = statistic
1310 check_client_version(ctx
.obj
, ctx
.command
.name
)
1311 ctx
.obj
.ns
.create_alarm(alarm
)
1312 except ClientException
as inst
:
1313 print((inst
.message
))
1317 #@cli.command(name='ns-alarm-delete')
1318 #@click.argument('name')
1319 #@click.pass_context
1320 #def ns_alarm_delete(ctx, name):
1321 # '''deletes an alarm
1323 # NAME: name of the alarm to be deleted
1326 # check_client_version(ctx.obj, ctx.command.name)
1327 # ctx.obj.ns.delete_alarm(name)
1328 # except ClientException as inst:
1329 # print(inst.message)
1333 ####################
1334 # Performance Management operations
1335 ####################
1337 @cli.command(name
='ns-metric-export')
1338 @click.option('--ns', prompt
=True, help='NS instance id or name')
1339 @click.option('--vnf', prompt
=True,
1340 help='VNF name (VNF member index as declared in the NSD)')
1341 @click.option('--vdu', prompt
=True,
1342 help='VDU name (VDU name as declared in the VNFD)')
1343 @click.option('--metric', prompt
=True,
1344 help='name of the metric (e.g. cpu_utilization)')
1345 #@click.option('--period', default='1w',
1346 # help='metric collection period (e.g. 20s, 30m, 2h, 3d, 1w)')
1347 @click.option('--interval', help='periodic interval (seconds) to export metrics continuously')
1349 def ns_metric_export(ctx
, ns
, vnf
, vdu
, metric
, interval
):
1350 '''exports a metric to the internal OSM bus, which can be read by other apps
1352 ns_instance
= ctx
.obj
.ns
.get(ns
)
1354 metric_data
['ns_id'] = ns_instance
['_id']
1355 metric_data
['correlation_id'] = ns_instance
['_id']
1356 metric_data
['vnf_member_index'] = vnf
1357 metric_data
['vdu_name'] = vdu
1358 metric_data
['metric_name'] = metric
1359 metric_data
['collection_unit'] = 'WEEK'
1360 metric_data
['collection_period'] = 1
1362 check_client_version(ctx
.obj
, ctx
.command
.name
)
1364 print('{}'.format(ctx
.obj
.ns
.export_metric(metric_data
)))
1368 print('{} {}'.format(ctx
.obj
.ns
.export_metric(metric_data
),i
))
1369 time
.sleep(int(interval
))
1371 except ClientException
as inst
:
1372 print((inst
.message
))
1376 ####################
1378 ####################
1380 @cli.command(name
='upload-package')
1381 @click.argument('filename')
1383 def upload_package(ctx
, filename
):
1384 '''uploads a VNF package or NS package
1386 FILENAME: VNF or NS package file (tar.gz)
1389 ctx
.obj
.package
.upload(filename
)
1390 fullclassname
= ctx
.obj
.__module
__ + "." + ctx
.obj
.__class
__.__name
__
1391 if fullclassname
!= 'osmclient.sol005.client.Client':
1392 ctx
.obj
.package
.wait_for_upload(filename
)
1393 except ClientException
as inst
:
1394 print((inst
.message
))
1398 @cli.command(name
='ns-scaling-show')
1399 @click.argument('ns_name')
1401 def show_ns_scaling(ctx
, ns_name
):
1402 '''shows the status of a NS scaling operation
1404 NS_NAME: name of the NS instance being scaled
1407 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1408 resp
= ctx
.obj
.ns
.list()
1409 except ClientException
as inst
:
1410 print((inst
.message
))
1413 table
= PrettyTable(
1416 'operational status',
1421 if ns_name
== ns
['name']:
1422 nsopdata
= ctx
.obj
.ns
.get_opdata(ns
['id'])
1423 scaling_records
= nsopdata
['nsr:nsr']['scaling-group-record']
1424 for record
in scaling_records
:
1425 if 'instance' in record
:
1426 instances
= record
['instance']
1427 for inst
in instances
:
1429 [record
['scaling-group-name-ref'],
1430 inst
['instance-id'],
1432 time
.strftime('%Y-%m-%d %H:%M:%S',
1434 inst
['create-time'])),
1440 @cli.command(name
='ns-scale')
1441 @click.argument('ns_name')
1442 @click.option('--ns_scale_group', prompt
=True)
1443 @click.option('--index', prompt
=True)
1445 def ns_scale(ctx
, ns_name
, ns_scale_group
, index
):
1448 NS_NAME: name of the NS instance to be scaled
1451 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1452 ctx
.obj
.ns
.scale(ns_name
, ns_scale_group
, index
)
1453 except ClientException
as inst
:
1454 print((inst
.message
))
1458 @cli.command(name
='config-agent-list')
1460 def config_agent_list(ctx
):
1461 '''list config agents'''
1463 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1464 except ClientException
as inst
:
1465 print((inst
.message
))
1467 table
= PrettyTable(['name', 'account-type', 'details'])
1468 for account
in ctx
.obj
.vca
.list():
1471 account
['account-type'],
1477 @cli.command(name
='config-agent-delete')
1478 @click.argument('name')
1480 def config_agent_delete(ctx
, name
):
1481 '''deletes a config agent
1483 NAME: name of the config agent to be deleted
1486 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1487 ctx
.obj
.vca
.delete(name
)
1488 except ClientException
as inst
:
1489 print((inst
.message
))
1493 @cli.command(name
='config-agent-add')
1494 @click.option('--name',
1496 @click.option('--account_type',
1498 @click.option('--server',
1500 @click.option('--user',
1502 @click.option('--secret',
1505 confirmation_prompt
=True)
1507 def config_agent_add(ctx
, name
, account_type
, server
, user
, secret
):
1508 '''adds a config agent'''
1510 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1511 ctx
.obj
.vca
.create(name
, account_type
, server
, user
, secret
)
1512 except ClientException
as inst
:
1513 print((inst
.message
))
1516 @cli.command(name
='ro-dump')
1519 '''shows RO agent information'''
1520 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1521 resp
= ctx
.obj
.vim
.get_resource_orchestrator()
1522 table
= PrettyTable(['key', 'attribute'])
1523 for k
, v
in list(resp
.items()):
1524 table
.add_row([k
, json
.dumps(v
, indent
=2)])
1529 @cli.command(name
='vcs-list')
1532 check_client_version(ctx
.obj
, ctx
.command
.name
, 'v1')
1533 resp
= ctx
.obj
.utils
.get_vcs_info()
1534 table
= PrettyTable(['component name', 'state'])
1535 for component
in resp
:
1536 table
.add_row([component
['component_name'], component
['state']])
1541 @cli.command(name
='ns-action')
1542 @click.argument('ns_name')
1543 @click.option('--vnf_name', default
=None)
1544 @click.option('--action_name', prompt
=True)
1545 @click.option('--params', prompt
=True)
1552 '''executes an action/primitive over a NS instance
1554 NS_NAME: name or ID of the NS instance
1557 check_client_version(ctx
.obj
, ctx
.command
.name
)
1560 op_data
['vnf_member_index'] = vnf_name
1561 op_data
['primitive'] = action_name
1562 op_data
['primitive_params'] = yaml
.load(params
)
1563 ctx
.obj
.ns
.exec_op(ns_name
, op_name
='action', op_data
=op_data
)
1565 except ClientException
as inst
:
1566 print((inst
.message
))
1570 @cli.command(name
='vnf-scale')
1571 @click.argument('ns_name')
1572 @click.argument('vnf_name')
1573 @click.option('--scaling-group', prompt
=True, help="scaling-group-descriptor name to use")
1574 @click.option('--scale-in', default
=False, is_flag
=True, help="performs a scale in operation")
1575 @click.option('--scale-out', default
=False, is_flag
=True, help="performs a scale out operation (by default)")
1583 '''executes a VNF scale (adding/removing VDUs)
1586 NS_NAME: name or ID of the NS instance.
1587 VNF_NAME: member-vnf-index in the NS to be scaled.
1590 check_client_version(ctx
.obj
, ctx
.command
.name
)
1591 if not scale_in
and not scale_out
:
1593 ctx
.obj
.ns
.scale_vnf(ns_name
, vnf_name
, scaling_group
, scale_in
, scale_out
)
1594 except ClientException
as inst
:
1595 print((inst
.message
))
1599 if __name__
== '__main__':
1602 except pycurl
.error
as e
:
1604 print('Maybe "--hostname" option or OSM_HOSTNAME' +
1605 'environment variable needs to be specified')