| ####################################################################################### |
| # Copyright ETSI Contributors and Others. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| # implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| ####################################################################################### |
| |
| import logging |
| import click |
| import yaml |
| from osmclient.cli_commands import common, utils |
| from osmclient.common.exceptions import ClientException |
| from osmclient.common import print_output |
| |
| logger = logging.getLogger("osmclient") |
| |
| |
| def get_oka_id(ctx, oka_name): |
| """Get the ID of an OKA by name or ID""" |
| logger.debug("") |
| resp = ctx.obj.oka.get(oka_name) |
| logger.debug("OKA obtained: %s", resp) |
| if "_id" in resp: |
| return resp["_id"] |
| else: |
| raise ClientException("Unexpected failure when reading the OKA") |
| |
| |
| def get_profile_id(ctx, profile, profile_type): |
| """Get the ID of a profile of a specifc profile_type by name or ID""" |
| logger.debug("") |
| get_function = { |
| "infra-controller-profile": ctx.obj.infra_controller_profile.get, |
| "infra-config-profile": ctx.obj.infra_config_profile.get, |
| "app-profile": ctx.obj.app_profile.get, |
| "resource-profile": ctx.obj.resource_profile.get, |
| } |
| resp = get_function[profile_type](profile) |
| logger.debug("Profile obtained: %s", resp) |
| if "_id" in resp: |
| return resp["_id"] |
| else: |
| raise ClientException("Unexpected failure when reading the profile") |
| |
| |
| @click.command(name="app-create", short_help="creates an App Instance") |
| @utils.require_hostname |
| @click.argument("name") |
| @click.option("--description", default="", help="human readable description") |
| @click.option( |
| "--oka", |
| default="", |
| help="name or ID of the OKA that the App Instance will be based on", |
| ) |
| @click.option( |
| "--sw-catalog-path", |
| default="", |
| help="folder in the SW catalog (git repo) that the App Instance will be based on", |
| ) |
| @click.option( |
| "--profile", |
| default="", |
| help="name or ID of the profile the App Instance will belong to", |
| ) |
| @click.option( |
| "--profile-type", |
| type=click.Choice( |
| [ |
| "infra-controller-profile", |
| "infra-config-profile", |
| "app-profile", |
| "resource-profile", |
| ] |
| ), |
| default="app-profile", |
| help="type of profile. Default: app-profile", |
| ) |
| @click.option( |
| "--model", |
| default=None, |
| help="specific yaml file with App Instance model file (to be merged with App blueprint model file)", |
| ) |
| @click.option( |
| "--params", |
| default=None, |
| help="specific yaml file with clear params for the App Instance", |
| ) |
| @click.option( |
| "--secret-params", |
| default=None, |
| help="specific yaml file with secret params for the App Instance", |
| ) |
| @click.pass_context |
| def app_create( |
| ctx, |
| name, |
| description, |
| oka, |
| sw_catalog_path, |
| profile, |
| profile_type, |
| model, |
| params, |
| secret_params, |
| ): |
| """creates an App Instance |
| |
| NAME: name of the App Instance to be created |
| """ |
| logger.debug("") |
| profile_type_mapping = { |
| "infra-controller-profile": "infra_controller_profiles", |
| "infra-config-profile": "infra_config_profiles", |
| "app-profile": "app_profiles", |
| "resource-profile": "resource_profiles", |
| } |
| app = {} |
| app["name"] = name |
| if description: |
| app["description"] = description |
| if oka and sw_catalog_path: |
| raise ClientException( |
| '"--oka" option is incompatible with "--sw-catalog-path" option' |
| ) |
| if oka: |
| app["oka"] = get_oka_id(ctx, oka) |
| if sw_catalog_path: |
| app["sw_catalog_path"] = sw_catalog_path |
| app["profile_type"] = profile_type_mapping[profile_type] |
| app["profile"] = get_profile_id(ctx, profile, profile_type) |
| if model: |
| with open(model, "r", encoding="utf-8") as cf: |
| model_data = cf.read() |
| try: |
| app["model"] = yaml.safe_load(model_data) |
| except yaml.YAMLError as e: |
| raise ClientException(f"Error parsing YAML configuration: {e}") from e |
| if params: |
| with open(params, "r", encoding="utf-8") as cf: |
| params_data = cf.read() |
| try: |
| app["params"] = yaml.safe_load(params_data) |
| except yaml.YAMLError as e: |
| raise ClientException(f"Error parsing YAML configuration: {e}") from e |
| if secret_params: |
| with open(secret_params, "r", encoding="utf-8") as cf: |
| secret_params_data = cf.read() |
| try: |
| app["secret_params"] = yaml.safe_load(secret_params_data) |
| except yaml.YAMLError as e: |
| raise ClientException(f"Error parsing YAML configuration: {e}") from e |
| ctx.obj.app.create(name, content_dict=app) |
| |
| |
| @click.command(name="app-delete", short_help="deletes an App Instance cluster") |
| @utils.require_hostname |
| @click.argument("name") |
| @click.option( |
| "--force", is_flag=True, help="forces the deletion from the DB (not recommended)" |
| ) |
| @click.pass_context |
| def app_delete(ctx, name, force): |
| """deletes an App Instance |
| |
| NAME: name or ID of the App Instance to be deleted |
| """ |
| logger.debug("") |
| ctx.obj.app.delete(name, force=force) |
| |
| |
| @click.command(name="app-list") |
| @utils.require_hostname |
| @click.option( |
| "--filter", |
| default=None, |
| multiple=True, |
| help="restricts the list to the items matching the filter", |
| ) |
| @print_output.output_option |
| @click.pass_context |
| def app_list(ctx, filter, output): |
| """list all App instances""" |
| logger.debug("") |
| common.generic_list(callback=ctx.obj.app.list, filter=filter, format=output) |
| |
| |
| @click.command(name="app-show", short_help="shows the details of an app instance") |
| @utils.require_hostname |
| @click.argument("name") |
| @print_output.output_option |
| @click.pass_context |
| def app_show(ctx, name, output): |
| """shows the details of an App instance |
| |
| NAME: name or ID of the App instance to be shown |
| """ |
| logger.debug("") |
| common.generic_show(callback=ctx.obj.app.get, name=name, format=output) |
| |
| |
| @click.command( |
| name="app-edit", short_help="updates name or description of an App Instance" |
| ) |
| @utils.require_hostname |
| @click.argument("name") |
| @click.option("--newname", help="New name for the App Instance") |
| @click.option("--description", help="human readable description") |
| @click.pass_context |
| def app_edit(ctx, name, newname, description, **kwargs): |
| """updates the name or description of an App Instance |
| |
| NAME: name or ID of the App Instance to be updated |
| """ |
| logger.debug("") |
| app_changes = common.generic_update(newname, description, kwargs) |
| ctx.obj.app.update(name, changes_dict=app_changes) |
| |
| |
| @click.command(name="app-update", short_help="updates an App Instance") |
| @utils.require_hostname |
| @click.argument("name") |
| @click.option( |
| "--model", |
| default=None, |
| help="specific yaml file with App Instance model file (to be merged with App blueprint model file)", |
| ) |
| @click.option( |
| "--params", |
| default=None, |
| help="specific yaml file with clear params for the App Instance", |
| ) |
| @click.option( |
| "--secret-params", |
| default=None, |
| help="specific yaml file with secret params for the App Instance", |
| ) |
| @click.pass_context |
| def app_update( |
| ctx, |
| name, |
| model, |
| params, |
| secret_params, |
| ): |
| """updates an App Instance |
| |
| NAME: name or ID of the App Instance to be updated |
| """ |
| logger.debug("") |
| app_changes = {} |
| if model: |
| with open(model, "r", encoding="utf-8") as cf: |
| model_data = cf.read() |
| try: |
| app_changes["model"] = yaml.safe_load(model_data) |
| except yaml.YAMLError as e: |
| raise ClientException(f"Error parsing YAML configuration: {e}") from e |
| if params: |
| with open(params, "r", encoding="utf-8") as cf: |
| params_data = cf.read() |
| try: |
| app_changes["params"] = yaml.safe_load(params_data) |
| except yaml.YAMLError as e: |
| raise ClientException(f"Error parsing YAML configuration: {e}") from e |
| if secret_params: |
| with open(secret_params, "r", encoding="utf-8") as cf: |
| secret_params_data = cf.read() |
| try: |
| app_changes["secret_params"] = yaml.safe_load(secret_params_data) |
| except yaml.YAMLError as e: |
| raise ClientException(f"Error parsing YAML configuration: {e}") from e |
| ctx.obj.app.fullupdate(name, app_changes) |