nsd_list(ctx,filter)
-def vnfd_list(ctx, filter):
- if filter:
+def vnfd_list(ctx, nf_type, filter):
+ if nf_type:
+ check_client_version(ctx.obj, '--nf_type')
+ elif filter:
check_client_version(ctx.obj, '--filter')
+ if nf_type:
+ if nf_type == "vnf":
+ nf_filter = "_admin.type=vnfd"
+ elif nf_type == "pnf":
+ nf_filter = "_admin.type=pnfd"
+ elif nf_type == "hnf":
+ nf_filter = "_admin.type=hnfd"
+ else:
+ raise ClientException('wrong value for "--nf_type" option, allowed values: vnf, pnf, hnf')
+ if filter:
+ filter = '{}&{}'.format(nf_filter, filter)
+ else:
+ filter = nf_filter
+ if filter:
resp = ctx.obj.vnfd.list(filter)
else:
resp = ctx.obj.vnfd.list()
#print yaml.safe_dump(resp)
- table = PrettyTable(['vnfd name', 'id'])
+ table = PrettyTable(['nfpkg name', 'id'])
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
if fullclassname == 'osmclient.sol005.client.Client':
for vnfd in resp:
@cli.command(name='vnfd-list')
+@click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
@click.option('--filter', default=None,
- help='restricts the list to the VNFD/VNFpkg matching the filter')
+ help='restricts the list to the NFpkg matching the filter')
@click.pass_context
-def vnfd_list1(ctx, filter):
+def vnfd_list1(ctx, nf_type, filter):
'''list all VNFD/VNFpkg in the system'''
- vnfd_list(ctx,filter)
+ vnfd_list(ctx, nf_type, filter)
@cli.command(name='vnfpkg-list')
+@click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
@click.option('--filter', default=None,
- help='restricts the list to the VNFD/VNFpkg matching the filter')
+ help='restricts the list to the NFpkg matching the filter')
@click.pass_context
-def vnfd_list2(ctx, filter):
+def vnfd_list2(ctx, nf_type, filter):
'''list all VNFD/VNFpkg in the system'''
- vnfd_list(ctx,filter)
+ vnfd_list(ctx, nf_type, filter)
-@cli.command(name='vnf-list')
-@click.option('--ns', default=None, help='NS instance id or name to restrict the VNF list')
+@cli.command(name='nfpkg-list')
+@click.option('--nf_type', help='type of NF (vnf, pnf, hnf)')
@click.option('--filter', default=None,
- help='restricts the list to the VNF instances matching the filter.')
+ help='restricts the list to the NFpkg matching the filter')
@click.pass_context
-def vnf_list(ctx, ns, filter):
- '''list all VNF instances
-
- \b
- Options:
- --ns TEXT NS instance id or name to restrict the VNF list
- --filter filterExpr Restricts the list to the VNF instances matching the filter
-
- \b
- filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
- concatenated using the "&" character:
-
- \b
- filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
- simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
- op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
- attrName := string
- value := scalar value
-
- \b
- where:
- * zero or more occurrences
- ? zero or one occurrence
- [] grouping of expressions to be used with ? and *
- "" quotation marks for marking string constants
- <> name separator
+def nfpkg_list(ctx, nf_type, filter):
+ '''list all NFpkg (VNFpkg, PNFpkg, HNFpkg) in the system'''
+ try:
+ check_client_version(ctx.obj, ctx.command.name)
+ vnfd_list(ctx,nf_type,filter)
+ except ClientException as inst:
+ print((inst.message))
+ exit(1)
- \b
- "AttrName" is the name of one attribute in the data type that defines the representation
- of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
- <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
- "Op" stands for the comparison operator. If the expression has concatenated <attrName>
- entries, it means that the operator "op" is applied to the attribute addressed by the last
- <attrName> entry included in the concatenation. All simple filter expressions are combined
- by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
- the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
- concatenation of all "attrName" entries except the leaf attribute is called the "attribute
- prefix". If an attribute referenced in an expression is an array, an object that contains a
- corresponding array shall be considered to match the expression if any of the elements in the
- array matches all expressions that have the same attribute prefix.
- \b
- Filter examples:
- --filter vim-account-id=<VIM_ACCOUNT_ID>
- --filter vnfd-ref=<VNFD_NAME>
- --filter vdur.ip-address=<IP_ADDRESS>
- --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
- '''
+def vnf_list(ctx, ns, filter):
try:
if ns or filter:
if ns:
table.align = 'l'
print(table)
+
+@cli.command(name='vnf-list')
+@click.option('--ns', default=None, help='NS instance id or name to restrict the NF list')
+@click.option('--filter', default=None,
+ help='restricts the list to the NF instances matching the filter.')
+@click.pass_context
+def vnf_list1(ctx, ns, filter):
+ '''list all NF instances'''
+ vnf_list(ctx, ns, filter)
+
+
+@cli.command(name='nf-list')
+@click.option('--ns', default=None, help='NS instance id or name to restrict the NF list')
+@click.option('--filter', default=None,
+ help='restricts the list to the NF instances matching the filter.')
+@click.pass_context
+def nf_list(ctx, ns, filter):
+ '''list all NF instances
+
+ \b
+ Options:
+ --ns TEXT NS instance id or name to restrict the VNF list
+ --filter filterExpr Restricts the list to the VNF instances matching the filter
+
+ \b
+ filterExpr consists of one or more strings formatted according to "simpleFilterExpr",
+ concatenated using the "&" character:
+
+ \b
+ filterExpr := <simpleFilterExpr>["&"<simpleFilterExpr>]*
+ simpleFilterExpr := <attrName>["."<attrName>]*["."<op>]"="<value>[","<value>]*
+ op := "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "cont" | "ncont"
+ attrName := string
+ value := scalar value
+
+ \b
+ where:
+ * zero or more occurrences
+ ? zero or one occurrence
+ [] grouping of expressions to be used with ? and *
+ "" quotation marks for marking string constants
+ <> name separator
+
+ \b
+ "AttrName" is the name of one attribute in the data type that defines the representation
+ of the resource. The dot (".") character in "simpleFilterExpr" allows concatenation of
+ <attrName> entries to filter by attributes deeper in the hierarchy of a structured document.
+ "Op" stands for the comparison operator. If the expression has concatenated <attrName>
+ entries, it means that the operator "op" is applied to the attribute addressed by the last
+ <attrName> entry included in the concatenation. All simple filter expressions are combined
+ by the "AND" logical operator. In a concatenation of <attrName> entries in a <simpleFilterExpr>,
+ the rightmost "attrName" entry in a "simpleFilterExpr" is called "leaf attribute". The
+ concatenation of all "attrName" entries except the leaf attribute is called the "attribute
+ prefix". If an attribute referenced in an expression is an array, an object that contains a
+ corresponding array shall be considered to match the expression if any of the elements in the
+ array matches all expressions that have the same attribute prefix.
+
+ \b
+ Filter examples:
+ --filter vim-account-id=<VIM_ACCOUNT_ID>
+ --filter vnfd-ref=<VNFD_NAME>
+ --filter vdur.ip-address=<IP_ADDRESS>
+ --filter vnfd-ref=<VNFD_NAME>,vdur.ip-address=<IP_ADDRESS>
+ '''
+ vnf_list(ctx, ns, filter)
+
+
@cli.command(name='ns-op-list')
@click.argument('name')
@click.pass_context
['pdu name',
'id',
'type',
- 'shared',
'mgmt ip address'])
for pdu in resp:
pdu_name = pdu['name']
pdu_id = pdu['_id']
pdu_type = pdu['type']
- pdu_shared = pdu['shared']
pdu_ipaddress = "None"
for iface in pdu['interfaces']:
if iface['mgmt']:
[pdu_name,
pdu_id,
pdu_type,
- pdu_shared,
pdu_ipaddress])
table.align = 'l'
print(table)
vnfd_show(ctx, name, literal)
+@cli.command(name='nfpkg-show', short_help='shows the content of a NF Descriptor')
+@click.option('--literal', is_flag=True,
+ help='print literally, no pretty table')
+@click.argument('name')
+@click.pass_context
+def nfpkg_show(ctx, name, literal):
+ '''shows the content of a NF Descriptor
+
+ NAME: name or ID of the NFpkg
+ '''
+ vnfd_show(ctx, name, literal)
+
+
@cli.command(name='ns-show', short_help='shows the info of a NS instance')
@click.argument('name')
@click.option('--literal', is_flag=True,
vnfd_create(ctx, filename, overwrite)
+@cli.command(name='nfpkg-create', short_help='creates a new NFpkg')
+@click.argument('filename')
+@click.option('--overwrite', default=None,
+ help='overwrites some fields in NFD')
+@click.pass_context
+def nfpkg_create(ctx, filename, overwrite):
+ '''creates a new NFpkg
+
+ FILENAME: NF Descriptor yaml file or NFpkg tar.gz file
+ '''
+ vnfd_create(ctx, filename, overwrite)
+
+
@cli.command(name='ns-create', short_help='creates a new Network Service instance')
@click.option('--ns_name',
prompt=True, help='name of the NS instance')
prompt=True, help='name of the NS descriptor')
@click.option('--vim_account',
prompt=True, help='default VIM account id or name for the deployment')
+@click.option('--wim_account',
+ default=None, help='default WIM account for intersite connectivity. False to not use a WIM')
@click.option('--admin_status',
default='ENABLED',
help='administration status')
nsd_name,
ns_name,
vim_account,
+ wim_account,
admin_status,
ssh_keys,
config,
ns_name,
config=config,
ssh_keys=ssh_keys,
- account=vim_account)
+ account=vim_account,
+ wim_account=wim_account)
except ClientException as inst:
print((inst.message))
exit(1)
with open(config_file, 'r') as cf:
config=cf.read()
ctx.obj.nsi.create(nst_name, nsi_name, config=config, ssh_keys=ssh_keys,
- account=vim_account)
+ account=vim_account)
except ClientException as inst:
- print((inst.message))
+ print(inst.message)
exit(1)
'netslice_subnet: [\n'
'id: TEXT, vim_account: TEXT,\n'
'vnf: [member-vnf-index: TEXT, vim_account: TEXT]\n'
- 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
+ 'vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]\n'
+ 'additionalParamsForNsi: {param: value, ...}\n'
+ 'additionalParamsForsubnet: [{id: SUBNET_ID, additionalParamsForNs: {}, additionalParamsForVnf: {}}]\n'
'],\n'
'netslice-vld: [name: TEXT, vim-network-name: TEXT or DICT with vim_account, vim_net entries]'
)
'[,type=<overlay|underlay>][,mac-address=<MAC_ADDRESS>][,vim-network-name=<VIM_NET_NAME>]',
multiple=True)
@click.option('--description', help='human readable description')
-@click.option('--shared', is_flag=True, help='flag to indicate if the PDU is shared')
-@click.option('--vimAccounts', help='list of VIM accounts where this PDU is physically connected')
+@click.option('--vim_account', help='list of VIM accounts (in the same VIM) that can reach this PDU', multiple=True)
@click.option('--descriptor_file', default=None, help='PDU descriptor file (as an alternative to using the other arguments')
@click.pass_context
-#TODO
-def pdu_create(ctx, name, pdu_type, interface, description, shared, vimAccounts, descriptor_file):
+def pdu_create(ctx, name, pdu_type, interface, description, vim_account, descriptor_file):
'''creates a new Physical Deployment Unit (PDU)'''
try:
check_client_version(ctx.obj, ctx.command.name)
raise ClientException('in absence of descriptor file, option "--pdu_type" is mandatory')
if not interface:
raise ClientException('in absence of descriptor file, option "--interface" is mandatory (at least once)')
+ if not vim_account:
+ raise ClientException('in absence of descriptor file, option "--vim_account" is mandatory (at least once)')
else:
with open(descriptor_file, 'r') as df:
pdu = yaml.load(df.read())
if name: pdu["name"] = name
if pdu_type: pdu["type"] = pdu_type
if description: pdu["description"] = description
- if shared: pdu["shared"] = shared
- if vimAccounts: pdu["vim_accounts"] = yaml.load(vimAccounts)
+ if vim_account: pdu["vim_accounts"] = vim_account
if interface:
ifaces_list = []
for iface in interface:
- ifaces_list.append({k:v for k,v in [i.split('=') for i in iface.split(',')]})
+ new_iface={k:v for k,v in [i.split('=') for i in iface.split(',')]}
+ new_iface["mgmt"] = (new_iface.get("mgmt","false").lower() == "true")
+ ifaces_list.append(new_iface)
pdu["interfaces"] = ifaces_list
ctx.obj.pdu.create(pdu)
except ClientException as inst:
vnfd_update(ctx, name, content)
+@cli.command(name='nfpkg-update', short_help='updates a NFpkg')
+@click.argument('name')
+@click.option('--content', default=None,
+ help='filename with the NFpkg replacing the current one')
+@click.pass_context
+def nfpkg_update(ctx, name, content):
+ '''updates a NFpkg
+
+ NAME: NF Descriptor yaml file or NFpkg tar.gz file
+ '''
+ vnfd_update(ctx, name, content)
+
+
def nst_update(ctx, name, content):
try:
check_client_version(ctx.obj, ctx.command.name)
vnfd_delete(ctx, name, force)
+@cli.command(name='nfpkg-delete', short_help='deletes a NFpkg')
+@click.argument('name')
+@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
+@click.pass_context
+def nfpkg_delete(ctx, name, force):
+ '''deletes a NFpkg
+
+ NAME: name or ID of the NFpkg to be deleted
+ '''
+ vnfd_delete(ctx, name, force)
+
+
@cli.command(name='ns-delete', short_help='deletes a NS instance')
@click.argument('name')
@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
print(table)
+####################
+# WIM operations
+####################
+
+@cli.command(name='wim-create')
+@click.option('--name',
+ prompt=True,
+ help='Name for the WIM account')
+@click.option('--user',
+ help='WIM username')
+@click.option('--password',
+ help='WIM password')
+@click.option('--url',
+ prompt=True,
+ help='WIM url')
+# @click.option('--tenant',
+# help='wIM tenant name')
+@click.option('--config',
+ default=None,
+ help='WIM specific config parameters')
+@click.option('--wim_type',
+ help='WIM type')
+@click.option('--description',
+ default='no description',
+ help='human readable description')
+@click.option('--wim_port_mapping', default=None, help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge (WAN service endpoint id and info)")
+@click.pass_context
+def wim_create(ctx,
+ name,
+ user,
+ password,
+ url,
+ # tenant,
+ config,
+ wim_type,
+ description,
+ wim_port_mapping):
+ '''creates a new WIM account
+ '''
+ try:
+ check_client_version(ctx.obj, ctx.command.name)
+ # if sdn_controller:
+ # check_client_version(ctx.obj, '--sdn_controller')
+ # if sdn_port_mapping:
+ # check_client_version(ctx.obj, '--sdn_port_mapping')
+ wim = {}
+ if user: wim['user'] = user
+ if password: wim['password'] = password
+ if url: wim['wim_url'] = url
+ # if tenant: wim['tenant'] = tenant
+ wim['wim_type'] = wim_type
+ if description: wim['description'] = description
+ if config: wim['config'] = config
+ ctx.obj.wim.create(name, wim, wim_port_mapping)
+ except ClientException as inst:
+ print((inst.message))
+ exit(1)
+
+
+@cli.command(name='wim-update', short_help='updates a WIM account')
+@click.argument('name')
+@click.option('--newname', help='New name for the WIM account')
+@click.option('--user', help='WIM username')
+@click.option('--password', help='WIM password')
+@click.option('--url', help='WIM url')
+@click.option('--config', help='WIM specific config parameters')
+@click.option('--wim_type', help='WIM type')
+@click.option('--description', help='human readable description')
+@click.option('--wim_port_mapping', default=None, help="File describing the port mapping between DC edge (datacenters, switches, ports) and WAN edge (WAN service endpoint id and info)")
+@click.pass_context
+def wim_update(ctx,
+ name,
+ newname,
+ user,
+ password,
+ url,
+ config,
+ wim_type,
+ description,
+ wim_port_mapping):
+ '''updates a WIM account
+
+ NAME: name or ID of the WIM account
+ '''
+ try:
+ check_client_version(ctx.obj, ctx.command.name)
+ wim = {}
+ if newname: wim['name'] = newname
+ if user: wim['user'] = user
+ if password: wim['password'] = password
+ if url: wim['url'] = url
+ # if tenant: wim['tenant'] = tenant
+ if wim_type: wim['wim_type'] = wim_type
+ if description: wim['description'] = description
+ if config: wim['config'] = config
+ ctx.obj.wim.update(name, wim, wim_port_mapping)
+ except ClientException as inst:
+ print((inst.message))
+ exit(1)
+
+
+@cli.command(name='wim-delete')
+@click.argument('name')
+@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
+@click.pass_context
+def wim_delete(ctx, name, force):
+ '''deletes a WIM account
+
+ NAME: name or ID of the WIM account to be deleted
+ '''
+ try:
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.wim.delete(name, force)
+ except ClientException as inst:
+ print((inst.message))
+ exit(1)
+
+
+@cli.command(name='wim-list')
+@click.option('--filter', default=None,
+ help='restricts the list to the WIM accounts matching the filter')
+@click.pass_context
+def wim_list(ctx, filter):
+ '''list all WIM accounts'''
+ try:
+ check_client_version(ctx.obj, ctx.command.name)
+ resp = ctx.obj.wim.list(filter)
+ table = PrettyTable(['wim name', 'uuid'])
+ for wim in resp:
+ table.add_row([wim['name'], wim['uuid']])
+ table.align = 'l'
+ print(table)
+ except ClientException as inst:
+ print((inst.message))
+ exit(1)
+
+
+@cli.command(name='wim-show')
+@click.argument('name')
+@click.pass_context
+def wim_show(ctx, name):
+ '''shows the details of a WIM account
+
+ NAME: name or ID of the WIM account
+ '''
+ try:
+ check_client_version(ctx.obj, ctx.command.name)
+ resp = ctx.obj.wim.get(name)
+ if 'password' in resp:
+ resp['wim_password']='********'
+ except ClientException as inst:
+ print((inst.message))
+ exit(1)
+
+ table = PrettyTable(['key', 'attribute'])
+ for k, v in list(resp.items()):
+ table.add_row([k, json.dumps(v, indent=2)])
+ table.align = 'l'
+ print(table)
+
+
####################
# SDN controller operations
####################
confirmation_prompt=True,
help='user password')
@click.option('--projects',
- default=None,
+ prompt="Comma separate list of projects",
+ multiple=True,
+ callback=lambda ctx, param, value: ''.join(value).split(',') if all(len(x)==1 for x in value) else value,
help='list of project ids that the user belongs to')
#@click.option('--description',
# default='no description',
exit(1)
table = PrettyTable(['name', 'id'])
for user in resp:
- table.add_row([user['name'], user['_id']])
+ table.add_row([user['username'], user['_id']])
table.align = 'l'
print(table)