X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=osmclient%2Fscripts%2Fosm.py;h=2182346d9d968d442b5a029c7c77f67bbd91373f;hb=refs%2Fchanges%2F18%2F11518%2F4;hp=feb8c2f9e03f47ce5ea8bf43dd5a781a24bc7a57;hpb=54a2a65cf3c784ceeb41e2351140ce216a21dd4d;p=osm%2Fosmclient.git diff --git a/osmclient/scripts/osm.py b/osmclient/scripts/osm.py index feb8c2f..2182346 100755 --- a/osmclient/scripts/osm.py +++ b/osmclient/scripts/osm.py @@ -94,6 +94,26 @@ def get_vim_name(vim_list, vim_id): return vim_name +def create_config(config_file, json_string): + ''' + Combines a YAML or JSON file with a JSON string into a Python3 structure + It loads the YAML or JSON file 'cfile' into a first dictionary. + It loads the JSON string into a second dictionary. + Then it updates the first dictionary with the info in the second dictionary. + If the field is present in both cfile and cdict, the field in cdict prevails. + If both cfile and cdict are None, it returns an empty dict (i.e. {}) + ''' + config = {} + if config_file: + with open(config_file, "r") as cf: + config = yaml.safe_load(cf.read()) + if json_string: + cdict = yaml.safe_load(json_string) + for k, v in cdict.items(): + config[k] = v + return config + + @click.group( context_settings=dict(help_option_names=["-h", "--help"], max_content_width=160) ) @@ -2564,13 +2584,15 @@ def nsi_create2( @click.option("--description", help="human readable description") @click.option( "--vim_account", - help="list of VIM accounts (in the same VIM) that can reach this PDU", + help="list of VIM accounts (in the same VIM) that can reach this PDU\n" + + "The format for multiple VIMs is --vim_account " + + "--vim_account ... --vim_account ", multiple=True, ) @click.option( "--descriptor_file", default=None, - help="PDU descriptor file (as an alternative to using the other arguments", + help="PDU descriptor file (as an alternative to using the other arguments)", ) @click.pass_context def pdu_create( @@ -2578,26 +2600,90 @@ def pdu_create( ): """creates a new Physical Deployment Unit (PDU)""" logger.debug("") - # try: + check_client_version(ctx.obj, ctx.command.name) + + pdu = create_pdu_dictionary( + name, pdu_type, interface, description, vim_account, descriptor_file + ) + ctx.obj.pdu.create(pdu) + + +######################## +# UPDATE PDU operation # +######################## + + +@cli_osm.command( + name="pdu-update", short_help="updates a Physical Deployment Unit to the catalog" +) +@click.argument("name") +@click.option("--newname", help="New name for the Physical Deployment Unit") +@click.option("--pdu_type", help="type of PDU (e.g. router, firewall, FW001)") +@click.option( + "--interface", + help="interface(s) of the PDU: name=,mgmt=,ip-address=" + + "[,type=][,mac-address=][,vim-network-name=]", + multiple=True, +) +@click.option("--description", help="human readable description") +@click.option( + "--vim_account", + help="list of VIM accounts (in the same VIM) that can reach this PDU\n" + + "The format for multiple VIMs is --vim_account " + + "--vim_account ... --vim_account ", + multiple=True, +) +@click.option( + "--descriptor_file", + default=None, + help="PDU descriptor file (as an alternative to using the other arguments)", +) +@click.pass_context +def pdu_update( + ctx, name, newname, pdu_type, interface, description, vim_account, descriptor_file +): + """Updates a new Physical Deployment Unit (PDU)""" + logger.debug("") + + check_client_version(ctx.obj, ctx.command.name) + + update = True + + if not newname: + newname = name + + pdu = create_pdu_dictionary( + newname, pdu_type, interface, description, vim_account, descriptor_file, update + ) + ctx.obj.pdu.update(name, pdu) + + +def create_pdu_dictionary( + name, pdu_type, interface, description, vim_account, descriptor_file, update=False +): + + logger.debug("") pdu = {} + if not descriptor_file: - if not name: - raise ClientException( - 'in absence of descriptor file, option "--name" is mandatory' - ) - if not pdu_type: - 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)' - ) + if not update: + if not name: + raise ClientException( + 'in absence of descriptor file, option "--name" is mandatory' + ) + if not pdu_type: + 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.safe_load(df.read()) @@ -2616,10 +2702,7 @@ def pdu_create( 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 e: - # print(str(e)) - # exit(1) + return pdu #################### @@ -3039,18 +3122,13 @@ def pdu_delete(ctx, name, force): @cli_osm.command(name="vim-create", short_help="creates a new VIM account") -@click.option("--name", prompt=True, help="Name to create datacenter") -@click.option("--user", prompt=True, help="VIM username") -@click.option( - "--password", - prompt=True, - hide_input=True, - confirmation_prompt=True, - help="VIM password", -) -@click.option("--auth_url", prompt=True, help="VIM url") -@click.option("--tenant", prompt=True, help="VIM tenant name") +@click.option("--name", required=True, help="Name to create datacenter") +@click.option("--user", default=None, help="VIM username") +@click.option("--password", default=None, help="VIM password") +@click.option("--auth_url", default=None, help="VIM url") +@click.option("--tenant", "--project", "tenant", default=None, help="VIM tenant/project name") @click.option("--config", default=None, help="VIM specific config parameters") +@click.option("--config_file", default=None, help="VIM specific config parameters in YAML or JSON file") @click.option("--account_type", default="openstack", help="VIM type") @click.option("--description", default=None, help="human readable description") @click.option( @@ -3072,6 +3150,7 @@ def pdu_delete(ctx, name, force): "until the operation is completed, or timeout", ) @click.option("--vca", default=None, help="VCA to be used in this VIM account") +@click.option("--creds", default=None, help="credentials file (only applycable for GCP VIM type)") @click.pass_context def vim_create( ctx, @@ -3081,12 +3160,14 @@ def vim_create( auth_url, tenant, config, + config_file, account_type, description, sdn_controller, sdn_port_mapping, wait, vca, + creds, ): """creates a new VIM account""" logger.debug("") @@ -3102,13 +3183,13 @@ def vim_create( vim["vim-tenant-name"] = tenant vim["vim-type"] = account_type vim["description"] = description - vim["config"] = config if vca: vim["vca"] = vca - if sdn_controller or sdn_port_mapping: - ctx.obj.vim.create(name, vim, sdn_controller, sdn_port_mapping, wait=wait) - else: - ctx.obj.vim.create(name, vim, wait=wait) + vim_config = create_config(config_file, config) + if creds: + with open(creds, "r") as cf: + vim_config["credentials"] = yaml.safe_load(cf.read()) + ctx.obj.vim.create(name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait) # except ClientException as e: # print(str(e)) # exit(1) @@ -3122,6 +3203,7 @@ def vim_create( @click.option("--auth_url", help="VIM url") @click.option("--tenant", help="VIM tenant name") @click.option("--config", help="VIM specific config parameters") +@click.option("--config_file", default=None, help="VIM specific config parameters in YAML or JSON file") @click.option("--account_type", help="VIM type") @click.option("--description", help="human readable description") @click.option( @@ -3143,6 +3225,7 @@ def vim_create( help="do not return the control immediately, but keep it " "until the operation is completed, or timeout", ) +@click.option("--creds", default=None, help="credentials file (only applycable for GCP VIM type)") @click.pass_context def vim_update( ctx, @@ -3153,11 +3236,13 @@ def vim_update( auth_url, tenant, config, + config_file, account_type, description, sdn_controller, sdn_port_mapping, wait, + creds, ): """updates a VIM account @@ -3181,9 +3266,14 @@ def vim_update( 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) + vim_config = None + if config or config_file: + vim_config = create_config(config_file, config) + if creds: + with open(creds, "r") as cf: + vim_config["credentials"] = yaml.safe_load(cf.read()) + logger.info(f"VIM: {vim}, VIM config: {vim_config}") + ctx.obj.vim.update(name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait) # except ClientException as e: # print(str(e)) # exit(1) @@ -3260,6 +3350,8 @@ def vim_list(ctx, filter, long): if long: if "vim_password" in vim: vim["vim_password"] = "********" + if "config" in vim and "credentials" in vim["config"]: + vim["config"]["credentials"] = "********" logger.debug("VIM details: {}".format(yaml.safe_dump(vim))) vim_state = vim["_admin"].get("operationalState", "-") error_details = "N/A" @@ -3292,8 +3384,9 @@ def vim_list(ctx, filter, long): multiple=True, help="restricts the information to the fields in the filter", ) +@click.option("--literal", is_flag=True, help="print literally, no pretty table") @click.pass_context -def vim_show(ctx, name, filter): +def vim_show(ctx, name, filter, literal): """shows the details of a VIM account NAME: name or ID of the VIM account @@ -3303,10 +3396,15 @@ def vim_show(ctx, name, filter): resp = ctx.obj.vim.get(name) if "vim_password" in resp: resp["vim_password"] = "********" + if "config" in resp and "credentials" in resp["config"]: + resp["config"]["credentials"] = "********" # except ClientException as e: # print(str(e)) # exit(1) + if literal: + print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) + return table = PrettyTable(["key", "attribute"]) for k, v in list(resp.items()): if not filter or k in filter: @@ -3770,6 +3868,14 @@ def sdnc_show(ctx, name): default="kube-system", help="namespace to be used for its operation, defaults to `kube-system`", ) +@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.option( "--cni", default=None, @@ -3783,7 +3889,7 @@ def sdnc_show(ctx, name): # 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 + ctx, name, creds, version, vim, k8s_nets, description, namespace, wait, cni ): """adds a K8s cluster to OSM @@ -3804,7 +3910,7 @@ def k8scluster_add( cluster["namespace"] = namespace if cni: cluster["cni"] = yaml.safe_load(cni) - ctx.obj.k8scluster.create(name, cluster) + ctx.obj.k8scluster.create(name, cluster, wait) # except ClientException as e: # print(str(e)) # exit(1) @@ -3826,12 +3932,20 @@ def k8scluster_add( "--namespace", help="namespace to be used for its operation, defaults to `kube-system`", ) +@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.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 + ctx, name, newname, creds, version, vim, k8s_nets, description, namespace, wait, cni ): """updates a K8s cluster @@ -3857,7 +3971,7 @@ def k8scluster_update( cluster["namespace"] = namespace if cni: cluster["cni"] = yaml.safe_load(cni) - ctx.obj.k8scluster.update(name, cluster) + ctx.obj.k8scluster.update(name, cluster, wait) # except ClientException as e: # print(str(e)) # exit(1) @@ -3868,18 +3982,23 @@ def k8scluster_update( @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.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 k8scluster_delete(ctx, name, force): +def k8scluster_delete(ctx, name, force, wait): """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) + ctx.obj.k8scluster.delete(name, force, wait) # except ClientException as e: # print(str(e)) # exit(1) @@ -5695,6 +5814,12 @@ def role_show(ctx, name): @click.option( "--netslice-vlds", default=1, help="(NST) Number of netslice vlds. Default 1" ) +@click.option( + "--old", + default=False, + is_flag=True, + help="Flag to create a descriptor using the previous OSM format (pre SOL006, OSM<9)", +) @click.pass_context def package_create( ctx, @@ -5712,6 +5837,7 @@ def package_create( detailed, netslice_subnets, netslice_vlds, + old, ): """ Creates an OSM NS, VNF, NST package @@ -5744,6 +5870,7 @@ def package_create( detailed=detailed, netslice_subnets=netslice_subnets, netslice_vlds=netslice_vlds, + old=old, ) print(resp) # except ClientException as inst: