| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 1 | # Copyright ETSI Contributors and Others. |
| 2 | # All Rights Reserved. |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 5 | # not use this file except in compliance with the License. You may obtain |
| 6 | # a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 | # License for the specific language governing permissions and limitations |
| 14 | # under the License. |
| 15 | |
| 16 | import click |
| hernandezchu | 9ba58bd | 2023-06-14 17:20:28 +0200 | [diff] [blame] | 17 | from osmclient.common import print_output |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 18 | from osmclient.cli_commands import utils |
| 19 | from prettytable import PrettyTable |
| 20 | import yaml |
| 21 | import json |
| 22 | import logging |
| 23 | |
| 24 | logger = logging.getLogger("osmclient") |
| 25 | |
| 26 | |
| 27 | def _check_ca_cert(vim_config: dict) -> None: |
| 28 | """ |
| 29 | Checks if the VIM has a CA certificate. |
| 30 | In that case, reads the content and add it to the config |
| 31 | : param vim_config: configuration provided with the VIM creation |
| 32 | : return: None |
| 33 | """ |
| 34 | |
| 35 | if vim_config.get("ca_cert"): |
| 36 | with open(vim_config["ca_cert"], "r") as cert_f: |
| 37 | vim_config["ca_cert_content"] = str(cert_f.read()) |
| 38 | del vim_config["ca_cert"] |
| 39 | |
| 40 | |
| 41 | @click.command(name="vim-create", short_help="creates a new VIM account") |
| 42 | @click.option("--name", required=True, help="Name to create datacenter") |
| 43 | @click.option("--user", default=None, help="VIM username") |
| 44 | @click.option("--password", default=None, help="VIM password") |
| 45 | @click.option("--auth_url", default=None, help="VIM url") |
| 46 | @click.option( |
| 47 | "--tenant", "--project", "tenant", default=None, help="VIM tenant/project name" |
| 48 | ) |
| 49 | @click.option("--config", default=None, help="VIM specific config parameters") |
| 50 | @click.option( |
| 51 | "--config_file", |
| 52 | default=None, |
| 53 | help="VIM specific config parameters in YAML or JSON file", |
| 54 | ) |
| 55 | @click.option("--account_type", default="openstack", help="VIM type") |
| 56 | @click.option("--description", default=None, help="human readable description") |
| 57 | @click.option( |
| 58 | "--sdn_controller", |
| 59 | default=None, |
| 60 | help="Name or id of the SDN controller associated to this VIM account", |
| 61 | ) |
| 62 | @click.option( |
| 63 | "--sdn_port_mapping", |
| 64 | default=None, |
| 65 | help="File describing the port mapping between compute nodes' ports and switch ports", |
| 66 | ) |
| 67 | @click.option( |
| 68 | "--wait", |
| 69 | required=False, |
| 70 | default=False, |
| 71 | is_flag=True, |
| 72 | help="do not return the control immediately, but keep it " |
| 73 | "until the operation is completed, or timeout", |
| 74 | ) |
| 75 | @click.option("--vca", default=None, help="VCA to be used in this VIM account") |
| 76 | @click.option( |
| 77 | "--creds", default=None, help="credentials file (only applicable for GCP VIM type)" |
| 78 | ) |
| 79 | @click.option( |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 80 | "--prometheus_url", |
| 81 | default=None, |
| 82 | help="PrometheusTSBD URL to get VIM data", |
| 83 | ) |
| 84 | @click.option( |
| 85 | "--prometheus_map", |
| 86 | default=None, |
| 87 | help="PrometheusTSBD metrics mapping for VIM data", |
| 88 | ) |
| 89 | @click.option( |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 90 | "--prometheus_config_file", |
| 91 | default=None, |
| 92 | help="Prometheus configuration to get VIM data", |
| 93 | ) |
| 94 | @click.pass_context |
| 95 | def vim_create( |
| 96 | ctx, |
| 97 | name, |
| 98 | user, |
| 99 | password, |
| 100 | auth_url, |
| 101 | tenant, |
| 102 | config, |
| 103 | config_file, |
| 104 | account_type, |
| 105 | description, |
| 106 | sdn_controller, |
| 107 | sdn_port_mapping, |
| 108 | wait, |
| 109 | vca, |
| 110 | creds, |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 111 | prometheus_url, |
| 112 | prometheus_map, |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 113 | prometheus_config_file, |
| 114 | ): |
| 115 | """creates a new VIM account""" |
| 116 | logger.debug("") |
| 117 | if sdn_controller: |
| 118 | utils.check_client_version(ctx.obj, "--sdn_controller") |
| 119 | if sdn_port_mapping: |
| 120 | utils.check_client_version(ctx.obj, "--sdn_port_mapping") |
| 121 | vim = {} |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 122 | prometheus_config = {} |
| 123 | if prometheus_url: |
| 124 | prometheus_config["prometheus-url"] = prometheus_url |
| 125 | if prometheus_map: |
| 126 | prometheus_config["prometheus-map"] = prometheus_map |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 127 | if prometheus_config_file: |
| 128 | with open(prometheus_config_file) as prometheus_file: |
| 129 | prometheus_config_dict = json.load(prometheus_file) |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 130 | prometheus_config.update(prometheus_config_dict) |
| 131 | if prometheus_config: |
| 132 | vim["prometheus-config"] = prometheus_config |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 133 | vim["vim-username"] = user |
| 134 | vim["vim-password"] = password |
| 135 | vim["vim-url"] = auth_url |
| 136 | vim["vim-tenant-name"] = tenant |
| 137 | vim["vim-type"] = account_type |
| 138 | vim["description"] = description |
| 139 | if vca: |
| 140 | vim["vca"] = vca |
| 141 | vim_config = utils.create_config(config_file, config) |
| 142 | _check_ca_cert(vim_config) |
| 143 | if creds: |
| 144 | with open(creds, "r") as cf: |
| 145 | vim_config["credentials"] = yaml.safe_load(cf.read()) |
| 146 | ctx.obj.vim.create( |
| 147 | name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait |
| 148 | ) |
| 149 | |
| 150 | |
| 151 | @click.command(name="vim-update", short_help="updates a VIM account") |
| 152 | @click.argument("name") |
| 153 | @click.option("--newname", help="New name for the VIM account") |
| 154 | @click.option("--user", help="VIM username") |
| 155 | @click.option("--password", help="VIM password") |
| 156 | @click.option("--auth_url", help="VIM url") |
| 157 | @click.option("--tenant", help="VIM tenant name") |
| 158 | @click.option("--config", help="VIM specific config parameters") |
| 159 | @click.option( |
| 160 | "--config_file", |
| 161 | default=None, |
| 162 | help="VIM specific config parameters in YAML or JSON file", |
| 163 | ) |
| 164 | @click.option("--account_type", help="VIM type") |
| 165 | @click.option("--description", help="human readable description") |
| 166 | @click.option( |
| 167 | "--sdn_controller", |
| 168 | default=None, |
| 169 | help="Name or id of the SDN controller to be associated with this VIM" |
| 170 | "account. Use empty string to disassociate", |
| 171 | ) |
| 172 | @click.option( |
| 173 | "--sdn_port_mapping", |
| 174 | default=None, |
| 175 | help="File describing the port mapping between compute nodes' ports and switch ports", |
| 176 | ) |
| 177 | @click.option( |
| 178 | "--wait", |
| 179 | required=False, |
| 180 | default=False, |
| 181 | is_flag=True, |
| 182 | help="do not return the control immediately, but keep it " |
| 183 | "until the operation is completed, or timeout", |
| 184 | ) |
| 185 | @click.option( |
| 186 | "--creds", default=None, help="credentials file (only applicable for GCP VIM type)" |
| 187 | ) |
| 188 | @click.option( |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 189 | "--prometheus_url", |
| 190 | default=None, |
| 191 | help="PrometheusTSBD URL to get VIM data", |
| 192 | ) |
| 193 | @click.option( |
| 194 | "--prometheus_map", |
| 195 | default=None, |
| 196 | help="PrometheusTSBD metrics mapping for VIM data", |
| 197 | ) |
| 198 | @click.option( |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 199 | "--prometheus_config_file", |
| 200 | default=None, |
| 201 | help="Prometheus configuration to get VIM data", |
| 202 | ) |
| 203 | @click.pass_context |
| 204 | def vim_update( |
| 205 | ctx, |
| 206 | name, |
| 207 | newname, |
| 208 | user, |
| 209 | password, |
| 210 | auth_url, |
| 211 | tenant, |
| 212 | config, |
| 213 | config_file, |
| 214 | account_type, |
| 215 | description, |
| 216 | sdn_controller, |
| 217 | sdn_port_mapping, |
| 218 | wait, |
| 219 | creds, |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 220 | prometheus_url, |
| 221 | prometheus_map, |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 222 | prometheus_config_file, |
| 223 | ): |
| 224 | """updates a VIM account |
| 225 | |
| 226 | NAME: name or ID of the VIM account |
| 227 | """ |
| 228 | logger.debug("") |
| 229 | utils.check_client_version(ctx.obj, ctx.command.name) |
| 230 | vim = {} |
| 231 | if newname: |
| 232 | vim["name"] = newname |
| 233 | if user: |
| 234 | vim["vim_user"] = user |
| 235 | if password: |
| 236 | vim["vim_password"] = password |
| 237 | if auth_url: |
| 238 | vim["vim_url"] = auth_url |
| 239 | if tenant: |
| 240 | vim["vim-tenant-name"] = tenant |
| 241 | if account_type: |
| 242 | vim["vim_type"] = account_type |
| 243 | if description: |
| 244 | vim["description"] = description |
| 245 | vim_config = None |
| 246 | if config or config_file: |
| 247 | vim_config = utils.create_config(config_file, config) |
| 248 | _check_ca_cert(vim_config) |
| 249 | if creds: |
| 250 | with open(creds, "r") as cf: |
| 251 | vim_config["credentials"] = yaml.safe_load(cf.read()) |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 252 | prometheus_config = {} |
| 253 | if prometheus_url: |
| 254 | prometheus_config["prometheus-url"] = prometheus_url |
| 255 | if prometheus_map: |
| 256 | prometheus_config["prometheus-map"] = prometheus_map |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 257 | if prometheus_config_file: |
| 258 | with open(prometheus_config_file) as prometheus_file: |
| 259 | prometheus_config_dict = json.load(prometheus_file) |
| Luis Vega | 166f7b0 | 2022-11-25 14:52:25 +0000 | [diff] [blame] | 260 | prometheus_config.update(prometheus_config_dict) |
| 261 | if prometheus_config: |
| 262 | vim["prometheus-config"] = prometheus_config |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 263 | ctx.obj.vim.update( |
| 264 | name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait |
| 265 | ) |
| 266 | |
| 267 | |
| 268 | @click.command(name="vim-delete", short_help="deletes a VIM account") |
| 269 | @click.argument("name") |
| 270 | @click.option( |
| 271 | "--force", is_flag=True, help="forces the deletion bypassing pre-conditions" |
| 272 | ) |
| 273 | @click.option( |
| 274 | "--wait", |
| 275 | required=False, |
| 276 | default=False, |
| 277 | is_flag=True, |
| 278 | help="do not return the control immediately, but keep it " |
| 279 | "until the operation is completed, or timeout", |
| 280 | ) |
| 281 | @click.pass_context |
| 282 | def vim_delete(ctx, name, force, wait): |
| 283 | """deletes a VIM account |
| 284 | |
| 285 | NAME: name or ID of the VIM account to be deleted |
| 286 | """ |
| 287 | logger.debug("") |
| 288 | if not force: |
| 289 | ctx.obj.vim.delete(name, wait=wait) |
| 290 | else: |
| 291 | utils.check_client_version(ctx.obj, "--force") |
| 292 | ctx.obj.vim.delete(name, force, wait=wait) |
| 293 | |
| 294 | |
| 295 | @click.command(name="vim-list", short_help="list all VIM accounts") |
| 296 | @click.option( |
| 297 | "--filter", |
| 298 | default=None, |
| 299 | multiple=True, |
| 300 | help="restricts the list to the VIM accounts matching the filter", |
| 301 | ) |
| 302 | @click.option( |
| 303 | "--long", |
| 304 | is_flag=True, |
| 305 | help="get more details of the NS (project, vim, deployment status, configuration status.", |
| 306 | ) |
| garciadeblas | cd7cd5e | 2023-06-26 17:41:46 +0200 | [diff] [blame] | 307 | @print_output.output_option |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 308 | @click.pass_context |
| garciadeblas | cd7cd5e | 2023-06-26 17:41:46 +0200 | [diff] [blame] | 309 | def vim_list(ctx, filter, long, output): |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 310 | """list all VIM accounts""" |
| 311 | logger.debug("") |
| 312 | if filter: |
| 313 | filter = "&".join(filter) |
| 314 | utils.check_client_version(ctx.obj, "--filter") |
| garciadeblas | 23cc10b | 2023-06-26 18:34:45 +0200 | [diff] [blame] | 315 | resp = ctx.obj.vim.list(filter) |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 316 | if long: |
| 317 | table = PrettyTable( |
| 318 | ["vim name", "uuid", "project", "operational state", "error details"] |
| 319 | ) |
| 320 | project_list = ctx.obj.project.list() |
| 321 | else: |
| 322 | table = PrettyTable(["vim name", "uuid", "operational state"]) |
| 323 | for vim in resp: |
| 324 | if long: |
| 325 | if "vim_password" in vim: |
| 326 | vim["vim_password"] = "********" |
| 327 | if "config" in vim and "credentials" in vim["config"]: |
| 328 | vim["config"]["credentials"] = "********" |
| 329 | logger.debug("VIM details: {}".format(yaml.safe_dump(vim))) |
| 330 | vim_state = vim["_admin"].get("operationalState", "-") |
| 331 | error_details = "N/A" |
| 332 | if vim_state == "ERROR": |
| 333 | error_details = vim["_admin"].get("detailed-status", "Not found") |
| 334 | project_id, project_name = utils.get_project(project_list, vim) |
| 335 | # project_info = '{} ({})'.format(project_name, project_id) |
| 336 | project_info = project_name |
| 337 | table.add_row( |
| 338 | [ |
| 339 | vim["name"], |
| 340 | vim["uuid"], |
| 341 | project_info, |
| 342 | vim_state, |
| 343 | utils.wrap_text(text=error_details, width=80), |
| 344 | ] |
| 345 | ) |
| 346 | else: |
| 347 | table.add_row( |
| 348 | [vim["name"], vim["uuid"], vim["_admin"].get("operationalState", "-")] |
| 349 | ) |
| garciadeblas | cd7cd5e | 2023-06-26 17:41:46 +0200 | [diff] [blame] | 350 | print_output.print_output(output, table.field_names, table._rows) |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 351 | |
| 352 | |
| 353 | @click.command(name="vim-show", short_help="shows the details of a VIM account") |
| 354 | @click.argument("name") |
| 355 | @click.option( |
| 356 | "--filter", |
| 357 | multiple=True, |
| 358 | help="restricts the information to the fields in the filter", |
| 359 | ) |
| 360 | @click.option("--literal", is_flag=True, help="print literally, no pretty table") |
| garciadeblas | cd7cd5e | 2023-06-26 17:41:46 +0200 | [diff] [blame] | 361 | @print_output.output_option |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 362 | @click.pass_context |
| garciadeblas | cd7cd5e | 2023-06-26 17:41:46 +0200 | [diff] [blame] | 363 | def vim_show(ctx, name, filter, literal, output): |
| garciadeblas | 00bc035 | 2022-03-29 00:11:30 +0200 | [diff] [blame] | 364 | """shows the details of a VIM account |
| 365 | |
| 366 | NAME: name or ID of the VIM account |
| 367 | """ |
| 368 | logger.debug("") |
| 369 | resp = ctx.obj.vim.get(name) |
| 370 | if "vim_password" in resp: |
| 371 | resp["vim_password"] = "********" |
| 372 | if "config" in resp and "credentials" in resp["config"]: |
| 373 | resp["config"]["credentials"] = "********" |
| 374 | |
| 375 | if literal: |
| 376 | print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
| 377 | return |
| 378 | table = PrettyTable(["key", "attribute"]) |
| 379 | for k, v in list(resp.items()): |
| 380 | if not filter or k in filter: |
| 381 | table.add_row([k, utils.wrap_text(text=json.dumps(v, indent=2), width=100)]) |
| garciadeblas | cd7cd5e | 2023-06-26 17:41:46 +0200 | [diff] [blame] | 382 | print_output.print_output(output, table.field_names, table._rows) |