Refactor -o option to simplify code
[osm/osmclient.git] / osmclient / cli_commands / vim.py
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
17 from osmclient.common import print_output
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(
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(
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,
111 prometheus_url,
112 prometheus_map,
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 = {}
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
127 if prometheus_config_file:
128 with open(prometheus_config_file) as prometheus_file:
129 prometheus_config_dict = json.load(prometheus_file)
130 prometheus_config.update(prometheus_config_dict)
131 if prometheus_config:
132 vim["prometheus-config"] = prometheus_config
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(
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(
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,
220 prometheus_url,
221 prometheus_map,
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())
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
257 if prometheus_config_file:
258 with open(prometheus_config_file) as prometheus_file:
259 prometheus_config_dict = json.load(prometheus_file)
260 prometheus_config.update(prometheus_config_dict)
261 if prometheus_config:
262 vim["prometheus-config"] = prometheus_config
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 )
307 @print_output.output_option
308 @click.pass_context
309 def vim_list(ctx, filter, long, output):
310 """list all VIM accounts"""
311 logger.debug("")
312 if filter:
313 filter = "&".join(filter)
314 utils.check_client_version(ctx.obj, "--filter")
315 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
316 if fullclassname == "osmclient.sol005.client.Client":
317 resp = ctx.obj.vim.list(filter)
318 if long:
319 table = PrettyTable(
320 ["vim name", "uuid", "project", "operational state", "error details"]
321 )
322 project_list = ctx.obj.project.list()
323 else:
324 table = PrettyTable(["vim name", "uuid", "operational state"])
325 for vim in resp:
326 if long:
327 if "vim_password" in vim:
328 vim["vim_password"] = "********"
329 if "config" in vim and "credentials" in vim["config"]:
330 vim["config"]["credentials"] = "********"
331 logger.debug("VIM details: {}".format(yaml.safe_dump(vim)))
332 vim_state = vim["_admin"].get("operationalState", "-")
333 error_details = "N/A"
334 if vim_state == "ERROR":
335 error_details = vim["_admin"].get("detailed-status", "Not found")
336 project_id, project_name = utils.get_project(project_list, vim)
337 # project_info = '{} ({})'.format(project_name, project_id)
338 project_info = project_name
339 table.add_row(
340 [
341 vim["name"],
342 vim["uuid"],
343 project_info,
344 vim_state,
345 utils.wrap_text(text=error_details, width=80),
346 ]
347 )
348 else:
349 table.add_row(
350 [vim["name"], vim["uuid"], vim["_admin"].get("operationalState", "-")]
351 )
352 print_output.print_output(output, table.field_names, table._rows)
353
354
355 @click.command(name="vim-show", short_help="shows the details of a VIM account")
356 @click.argument("name")
357 @click.option(
358 "--filter",
359 multiple=True,
360 help="restricts the information to the fields in the filter",
361 )
362 @click.option("--literal", is_flag=True, help="print literally, no pretty table")
363 @print_output.output_option
364 @click.pass_context
365 def vim_show(ctx, name, filter, literal, output):
366 """shows the details of a VIM account
367
368 NAME: name or ID of the VIM account
369 """
370 logger.debug("")
371 resp = ctx.obj.vim.get(name)
372 if "vim_password" in resp:
373 resp["vim_password"] = "********"
374 if "config" in resp and "credentials" in resp["config"]:
375 resp["config"]["credentials"] = "********"
376
377 if literal:
378 print(yaml.safe_dump(resp, indent=4, default_flow_style=False))
379 return
380 table = PrettyTable(["key", "attribute"])
381 for k, v in list(resp.items()):
382 if not filter or k in filter:
383 table.add_row([k, utils.wrap_text(text=json.dumps(v, indent=2), width=100)])
384 print_output.print_output(output, table.field_names, table._rows)