+ """
+ logger.debug("")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ vim = {}
+ if newname: vim['name'] = newname
+ if user: vim['vim_user'] = user
+ if password: vim['vim_password'] = password
+ if auth_url: vim['vim_url'] = auth_url
+ if tenant: vim['vim-tenant-name'] = tenant
+ if account_type: vim['vim_type'] = account_type
+ if description: vim['description'] = description
+ if config: vim['config'] = config
+ ctx.obj.vim.update(name, vim, sdn_controller, sdn_port_mapping, wait=wait)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='vim-delete', short_help='deletes a VIM account')
+@click.argument('name')
+@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
+@click.option('--wait',
+ required=False,
+ default=False,
+ is_flag=True,
+ help='do not return the control immediately, but keep it '
+ 'until the operation is completed, or timeout')
+@click.pass_context
+def vim_delete(ctx, name, force, wait):
+ """deletes a VIM account
+
+ NAME: name or ID of the VIM account to be deleted
+ """
+ logger.debug("")
+ # try:
+ if not force:
+ ctx.obj.vim.delete(name, wait=wait)
+ else:
+ check_client_version(ctx.obj, '--force')
+ ctx.obj.vim.delete(name, force, wait=wait)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='vim-list', short_help='list all VIM accounts')
+#@click.option('--ro_update/--no_ro_update',
+# default=False,
+# help='update list from RO')
+@click.option('--filter', default=None, multiple=True,
+ help='restricts the list to the VIM accounts matching the filter')
+@click.option('--long', is_flag=True,
+ help='get more details of the NS (project, vim, deployment status, configuration status.')
+@click.pass_context
+def vim_list(ctx, filter, long):
+ """list all VIM accounts"""
+ logger.debug("")
+ if filter:
+ filter='&'.join(filter)
+ check_client_version(ctx.obj, '--filter')
+# if ro_update:
+# check_client_version(ctx.obj, '--ro_update', 'v1')
+ fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
+ if fullclassname == 'osmclient.sol005.client.Client':
+ resp = ctx.obj.vim.list(filter)
+# else:
+# resp = ctx.obj.vim.list(ro_update)
+ if long:
+ table = PrettyTable(['vim name', 'uuid', 'project', 'operational state', 'error details'])
+ project_list = ctx.obj.project.list()
+ else:
+ table = PrettyTable(['vim name', 'uuid', 'operational state'])
+ for vim in resp:
+ if long:
+ if 'vim_password' in vim:
+ vim['vim_password']='********'
+ logger.debug('VIM details: {}'.format(yaml.safe_dump(vim)))
+ vim_state = vim['_admin'].get('operationalState', '-')
+ error_details = 'N/A'
+ if vim_state == 'ERROR':
+ error_details = vim['_admin'].get('detailed-status', 'Not found')
+ project_id, project_name = get_project(project_list, vim)
+ #project_info = '{} ({})'.format(project_name, project_id)
+ project_info = project_name
+ table.add_row([vim['name'], vim['uuid'], project_info,
+ vim_state, wrap_text(text=error_details, width=80)])
+ else:
+ table.add_row([vim['name'], vim['uuid'], vim['_admin'].get('operationalState', '-')])
+ table.align = 'l'
+ print(table)
+
+
+@cli_osm.command(name='vim-show', short_help='shows the details of a VIM account')
+@click.argument('name')
+@click.option('--filter', multiple=True,
+ help='restricts the information to the fields in the filter')
+@click.pass_context
+def vim_show(ctx, name, filter):
+ """shows the details of a VIM account
+
+ NAME: name or ID of the VIM account
+ """
+ logger.debug("")
+ # try:
+ resp = ctx.obj.vim.get(name)
+ if 'vim_password' in resp:
+ resp['vim_password']='********'
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+ table = PrettyTable(['key', 'attribute'])
+ for k, v in list(resp.items()):
+ if not filter or k in filter:
+ table.add_row([k, wrap_text(text=json.dumps(v, indent=2),width=100)])
+ table.align = 'l'
+ print(table)
+
+
+####################
+# WIM operations
+####################
+
+@cli_osm.command(name='wim-create', short_help='creates a new WIM account')
+@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=None,
+ 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.option('--wait',
+ required=False,
+ default=False,
+ is_flag=True,
+ help='do not return the control immediately, but keep it '
+ 'until the operation is completed, or timeout')
+@click.pass_context
+def wim_create(ctx,
+ name,
+ user,
+ password,
+ url,
+ # tenant,
+ config,
+ wim_type,
+ description,
+ wim_port_mapping,
+ wait):
+ """creates a new WIM account"""
+ logger.debug("")
+ # 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, wait=wait)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.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.option('--wait',
+ required=False,
+ default=False,
+ is_flag=True,
+ help='do not return the control immediately, but keep it until the operation is completed, or timeout')
+@click.pass_context
+def wim_update(ctx,
+ name,
+ newname,
+ user,
+ password,
+ url,
+ config,
+ wim_type,
+ description,
+ wim_port_mapping,
+ wait):
+ """updates a WIM account
+
+ NAME: name or ID of the WIM account
+ """
+ logger.debug("")
+ # 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, wait=wait)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='wim-delete', short_help='deletes a WIM account')
+@click.argument('name')
+@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
+@click.option('--wait',
+ required=False,
+ default=False,
+ is_flag=True,
+ help='do not return the control immediately, but keep it until the operation is completed, or timeout')
+@click.pass_context
+def wim_delete(ctx, name, force, wait):
+ """deletes a WIM account
+
+ NAME: name or ID of the WIM account to be deleted
+ """
+ logger.debug("")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.wim.delete(name, force, wait=wait)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='wim-list', short_help='list all WIM accounts')
+@click.option('--filter', default=None, multiple=True,
+ help='restricts the list to the WIM accounts matching the filter')
+@click.pass_context
+def wim_list(ctx, filter):
+ """list all WIM accounts"""
+ logger.debug("")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ if filter:
+ filter='&'.join(filter)
+ 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 e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='wim-show', short_help='shows the details of a WIM account')
+@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
+ """
+ logger.debug("")
+ # 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 e:
+ # print(str(e))
+ # 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
+####################
+
+@cli_osm.command(name='sdnc-create', short_help='creates a new SDN controller')
+@click.option('--name',
+ prompt=True,
+ help='Name to create sdn controller')
+@click.option('--type',
+ prompt=True,
+ help='SDN controller type')
+@click.option('--sdn_controller_version', # hidden=True,
+ help='Deprecated. Use --config {version: sdn_controller_version}')
+@click.option('--url',
+ help='URL in format http[s]://HOST:IP/')
+@click.option('--ip_address', # hidden=True,
+ help='Deprecated. Use --url')
+@click.option('--port', # hidden=True,
+ help='Deprecated. Use --url')
+@click.option('--switch_dpid', # hidden=True,
+ help='Deprecated. Use --config {switch_id: DPID}')
+@click.option('--config',
+ help='Extra information for SDN in yaml format, as {switch_id: identity used for the plugin (e.g. DPID: '
+ 'Openflow Datapath ID), version: version}')
+@click.option('--user',
+ help='SDN controller username')
+@click.option('--password',
+ hide_input=True,
+ confirmation_prompt=True,
+ help='SDN controller password')
+@click.option('--description', default=None, help='human readable description')
+@click.option('--wait',
+ required=False,
+ default=False,
+ is_flag=True,
+ help="do not return the control immediately, but keep it until the operation is completed, or timeout")
+@click.pass_context
+def sdnc_create(ctx, **kwargs):
+ """creates a new SDN controller"""
+ logger.debug("")
+ sdncontroller = {x: kwargs[x] for x in kwargs if kwargs[x] and
+ x not in ("wait", "ip_address", "port", "switch_dpid")}
+ if kwargs.get("port"):
+ print("option '--port' is deprecated, use '--url' instead")
+ sdncontroller["port"] = int(kwargs["port"])
+ if kwargs.get("ip_address"):
+ print("option '--ip_address' is deprecated, use '--url' instead")
+ sdncontroller["ip"] = kwargs["ip_address"]
+ if kwargs.get("switch_dpid"):
+ print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
+ sdncontroller["dpid"] = kwargs["switch_dpid"]
+ if kwargs.get("sdn_controller_version"):
+ print("option '--sdn_controller_version' is deprecated, use '--config={version: SDN_CONTROLLER_VERSION}'"
+ " instead")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.sdnc.create(kwargs["name"], sdncontroller, wait=kwargs["wait"])
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+@cli_osm.command(name='sdnc-update', short_help='updates an SDN controller')
+@click.argument('name')
+@click.option('--newname', help='New name for the SDN controller')
+@click.option('--description', default=None, help='human readable description')
+@click.option('--type', help='SDN controller type')
+@click.option('--url', help='URL in format http[s]://HOST:IP/')
+@click.option('--config', help='Extra information for SDN in yaml format, as '
+ '{switch_id: identity used for the plugin (e.g. DPID: '
+ 'Openflow Datapath ID), version: version}')
+@click.option('--user', help='SDN controller username')
+@click.option('--password', help='SDN controller password')
+@click.option('--ip_address', help='Deprecated. Use --url') # hidden=True
+@click.option('--port', help='Deprecated. Use --url') # hidden=True
+@click.option('--switch_dpid', help='Deprecated. Use --config {switch_dpid: DPID}') # hidden=True
+@click.option('--sdn_controller_version', help='Deprecated. Use --config {version: VERSION}') # hidden=True
+@click.option('--wait', required=False, default=False, is_flag=True,
+ help='do not return the control immediately, but keep it until the operation is completed, or timeout')
+@click.pass_context
+def sdnc_update(ctx, **kwargs):
+ """updates an SDN controller
+
+ NAME: name or ID of the SDN controller
+ """
+ logger.debug("")
+ sdncontroller = {x: kwargs[x] for x in kwargs if kwargs[x] and
+ x not in ("wait", "ip_address", "port", "switch_dpid", "new_name")}
+ if kwargs.get("newname"):
+ sdncontroller["name"] = kwargs["newname"]
+ if kwargs.get("port"):
+ print("option '--port' is deprecated, use '--url' instead")
+ sdncontroller["port"] = int(kwargs["port"])
+ if kwargs.get("ip_address"):
+ print("option '--ip_address' is deprecated, use '--url' instead")
+ sdncontroller["ip"] = kwargs["ip_address"]
+ if kwargs.get("switch_dpid"):
+ print("option '--switch_dpid' is deprecated, use '--config={switch_id: id|DPID}' instead")
+ sdncontroller["dpid"] = kwargs["switch_dpid"]
+ if kwargs.get("sdn_controller_version"):
+ print("option '--sdn_controller_version' is deprecated, use '---config={version: SDN_CONTROLLER_VERSION}'"
+ " instead")
+
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.sdnc.update(kwargs["name"], sdncontroller, wait=kwargs["wait"])
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='sdnc-delete', short_help='deletes an SDN controller')
+@click.argument('name')
+@click.option('--force', is_flag=True, help='forces the deletion bypassing pre-conditions')
+@click.option('--wait', required=False, default=False, is_flag=True,
+ help='do not return the control immediately, but keep it until the operation is completed, or timeout')
+@click.pass_context
+def sdnc_delete(ctx, name, force, wait):
+ """deletes an SDN controller
+
+ NAME: name or ID of the SDN controller to be deleted
+ """
+ logger.debug("")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.sdnc.delete(name, force, wait=wait)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='sdnc-list', short_help='list all SDN controllers')
+@click.option('--filter', default=None, multiple=True,
+ help="restricts the list to the SDN controllers matching the filter with format: 'k[.k..]=v[&k[.k]=v2]'")
+@click.pass_context
+def sdnc_list(ctx, filter):
+ """list all SDN controllers"""
+ logger.debug("")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ if filter:
+ filter='&'.join(filter)
+ resp = ctx.obj.sdnc.list(filter)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+ table = PrettyTable(['sdnc name', 'id'])
+ for sdnc in resp:
+ table.add_row([sdnc['name'], sdnc['_id']])
+ table.align = 'l'
+ print(table)
+
+
+@cli_osm.command(name='sdnc-show', short_help='shows the details of an SDN controller')
+@click.argument('name')
+@click.pass_context
+def sdnc_show(ctx, name):
+ """shows the details of an SDN controller
+
+ NAME: name or ID of the SDN controller
+ """
+ logger.debug("")
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ resp = ctx.obj.sdnc.get(name)
+ # except ClientException as e:
+ # print(str(e))
+ # 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)
+
+
+###########################
+# K8s cluster operations
+###########################
+
+@cli_osm.command(name='k8scluster-add', short_help='adds a K8s cluster to OSM')
+@click.argument('name')
+@click.option('--creds',
+ prompt=True,
+ help='credentials file, i.e. a valid `.kube/config` file')
+@click.option('--version',
+ prompt=True,
+ help='Kubernetes version')
+@click.option('--vim',
+ prompt=True,
+ help='VIM target, the VIM where the cluster resides')
+@click.option('--k8s-nets',
+ prompt=True,
+ help='list of VIM networks, in JSON inline format, where the cluster is accessible via L3 routing, e.g. "{(k8s_net1:vim_network1) [,(k8s_net2:vim_network2) ...]}"')
+@click.option('--description',
+ default=None,
+ help='human readable description')
+@click.option('--namespace',
+ default='kube-system',
+ help='namespace to be used for its operation, defaults to `kube-system`')
+@click.option('--cni',
+ default=None,
+ help='list of CNI plugins, in JSON inline format, used in the cluster')
+#@click.option('--skip-init',
+# is_flag=True,
+# help='If set, K8s cluster is assumed to be ready for its use with OSM')
+#@click.option('--wait',
+# is_flag=True,
+# help='do not return the control immediately, but keep it until the operation is completed, or timeout')
+@click.pass_context
+def k8scluster_add(ctx,
+ name,
+ creds,
+ version,
+ vim,
+ k8s_nets,
+ description,
+ namespace,
+ cni):
+ """adds a K8s cluster to OSM
+
+ NAME: name of the K8s cluster
+ """
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ cluster = {}
+ cluster['name'] = name
+ with open(creds, 'r') as cf:
+ cluster['credentials'] = yaml.safe_load(cf.read())
+ cluster['k8s_version'] = version
+ cluster['vim_account'] = vim
+ cluster['nets'] = yaml.safe_load(k8s_nets)
+ if description:
+ cluster['description'] = description
+ if namespace: cluster['namespace'] = namespace
+ if cni: cluster['cni'] = yaml.safe_load(cni)
+ ctx.obj.k8scluster.create(name, cluster)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='k8scluster-update', short_help='updates a K8s cluster')
+@click.argument('name')
+@click.option('--newname', help='New name for the K8s cluster')
+@click.option('--creds', help='credentials file, i.e. a valid `.kube/config` file')
+@click.option('--version', help='Kubernetes version')
+@click.option('--vim', help='VIM target, the VIM where the cluster resides')
+@click.option('--k8s-nets', help='list of VIM networks, in JSON inline format, where the cluster is accessible via L3 routing, e.g. "{(k8s_net1:vim_network1) [,(k8s_net2:vim_network2) ...]}"')
+@click.option('--description', help='human readable description')
+@click.option('--namespace', help='namespace to be used for its operation, defaults to `kube-system`')
+@click.option('--cni', help='list of CNI plugins, in JSON inline format, used in the cluster')
+@click.pass_context
+def k8scluster_update(ctx,
+ name,
+ newname,
+ creds,
+ version,
+ vim,
+ k8s_nets,
+ description,
+ namespace,
+ cni):
+ """updates a K8s cluster
+
+ NAME: name or ID of the K8s cluster
+ """
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ cluster = {}
+ if newname: cluster['name'] = newname
+ if creds:
+ with open(creds, 'r') as cf:
+ cluster['credentials'] = yaml.safe_load(cf.read())
+ if version: cluster['k8s_version'] = version
+ if vim: cluster['vim_account'] = vim
+ if k8s_nets: cluster['nets'] = yaml.safe_load(k8s_nets)
+ if description: cluster['description'] = description
+ if namespace: cluster['namespace'] = namespace
+ if cni: cluster['cni'] = yaml.safe_load(cni)
+ ctx.obj.k8scluster.update(name, cluster)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='k8scluster-delete', short_help='deletes a K8s cluster')
+@click.argument('name')
+@click.option('--force', is_flag=True, help='forces the deletion from the DB (not recommended)')
+#@click.option('--wait',
+# is_flag=True,
+# help='do not return the control immediately, but keep it until the operation is completed, or timeout')
+@click.pass_context
+def k8scluster_delete(ctx, name, force):
+ """deletes a K8s cluster
+
+ NAME: name or ID of the K8s cluster to be deleted
+ """
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ ctx.obj.k8scluster.delete(name, force=force)
+ # except ClientException as e:
+ # print(str(e))
+ # exit(1)
+
+
+@cli_osm.command(name='k8scluster-list')
+@click.option('--filter', default=None, multiple=True,
+ help='restricts the list to the K8s clusters matching the filter')
+@click.option('--literal', is_flag=True,
+ help='print literally, no pretty table')
+@click.option('--long', is_flag=True, help='get more details')
+@click.pass_context
+def k8scluster_list(ctx, filter, literal, long):
+ """list all K8s clusters"""
+ # try:
+ check_client_version(ctx.obj, ctx.command.name)
+ if filter:
+ filter='&'.join(filter)
+ resp = ctx.obj.k8scluster.list(filter)
+ if literal:
+ print(yaml.safe_dump(resp, indent=4, default_flow_style=False))
+ return
+ if long:
+ table = PrettyTable(['Name', 'Id', 'Project', 'Version', 'VIM', 'K8s-nets',
+ 'Operational State', 'Op. state (details)', 'Description', 'Detailed status'])
+ project_list = ctx.obj.project.list()
+ else:
+ table = PrettyTable(['Name', 'Id', 'VIM', 'Operational State', 'Op. state details'])