Feature 10955: Osmclient changes related to VIM configuration with a Prometheus TSDB...
[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.cli_commands import utils
18 from prettytable import PrettyTable
19 import yaml
20 import json
21 import logging
22
23 logger = logging.getLogger("osmclient")
24
25
26 def _check_ca_cert(vim_config: dict) -> None:
27 """
28 Checks if the VIM has a CA certificate.
29 In that case, reads the content and add it to the config
30 : param vim_config: configuration provided with the VIM creation
31 : return: None
32 """
33
34 if vim_config.get("ca_cert"):
35 with open(vim_config["ca_cert"], "r") as cert_f:
36 vim_config["ca_cert_content"] = str(cert_f.read())
37 del vim_config["ca_cert"]
38
39
40 @click.command(name="vim-create", short_help="creates a new VIM account")
41 @click.option("--name", required=True, help="Name to create datacenter")
42 @click.option("--user", default=None, help="VIM username")
43 @click.option("--password", default=None, help="VIM password")
44 @click.option("--auth_url", default=None, help="VIM url")
45 @click.option(
46 "--tenant", "--project", "tenant", default=None, help="VIM tenant/project name"
47 )
48 @click.option("--config", default=None, help="VIM specific config parameters")
49 @click.option(
50 "--config_file",
51 default=None,
52 help="VIM specific config parameters in YAML or JSON file",
53 )
54 @click.option("--account_type", default="openstack", help="VIM type")
55 @click.option("--description", default=None, help="human readable description")
56 @click.option(
57 "--sdn_controller",
58 default=None,
59 help="Name or id of the SDN controller associated to this VIM account",
60 )
61 @click.option(
62 "--sdn_port_mapping",
63 default=None,
64 help="File describing the port mapping between compute nodes' ports and switch ports",
65 )
66 @click.option(
67 "--wait",
68 required=False,
69 default=False,
70 is_flag=True,
71 help="do not return the control immediately, but keep it "
72 "until the operation is completed, or timeout",
73 )
74 @click.option("--vca", default=None, help="VCA to be used in this VIM account")
75 @click.option(
76 "--creds", default=None, help="credentials file (only applicable for GCP VIM type)"
77 )
78 @click.option(
79 "--prometheus_url",
80 default=None,
81 help="PrometheusTSBD URL to get VIM data",
82 )
83 @click.option(
84 "--prometheus_map",
85 default=None,
86 help="PrometheusTSBD metrics mapping for VIM data",
87 )
88 @click.option(
89 "--prometheus_config_file",
90 default=None,
91 help="Prometheus configuration to get VIM data",
92 )
93 @click.pass_context
94 def vim_create(
95 ctx,
96 name,
97 user,
98 password,
99 auth_url,
100 tenant,
101 config,
102 config_file,
103 account_type,
104 description,
105 sdn_controller,
106 sdn_port_mapping,
107 wait,
108 vca,
109 creds,
110 prometheus_url,
111 prometheus_map,
112 prometheus_config_file,
113 ):
114 """creates a new VIM account"""
115 logger.debug("")
116 if sdn_controller:
117 utils.check_client_version(ctx.obj, "--sdn_controller")
118 if sdn_port_mapping:
119 utils.check_client_version(ctx.obj, "--sdn_port_mapping")
120 vim = {}
121 prometheus_config = {}
122 if prometheus_url:
123 prometheus_config["prometheus-url"] = prometheus_url
124 if prometheus_map:
125 prometheus_config["prometheus-map"] = prometheus_map
126 if prometheus_config_file:
127 with open(prometheus_config_file) as prometheus_file:
128 prometheus_config_dict = json.load(prometheus_file)
129 prometheus_config.update(prometheus_config_dict)
130 if prometheus_config:
131 vim["prometheus-config"] = prometheus_config
132 vim["vim-username"] = user
133 vim["vim-password"] = password
134 vim["vim-url"] = auth_url
135 vim["vim-tenant-name"] = tenant
136 vim["vim-type"] = account_type
137 vim["description"] = description
138 if vca:
139 vim["vca"] = vca
140 vim_config = utils.create_config(config_file, config)
141 _check_ca_cert(vim_config)
142 if creds:
143 with open(creds, "r") as cf:
144 vim_config["credentials"] = yaml.safe_load(cf.read())
145 ctx.obj.vim.create(
146 name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait
147 )
148
149
150 @click.command(name="vim-update", short_help="updates a VIM account")
151 @click.argument("name")
152 @click.option("--newname", help="New name for the VIM account")
153 @click.option("--user", help="VIM username")
154 @click.option("--password", help="VIM password")
155 @click.option("--auth_url", help="VIM url")
156 @click.option("--tenant", help="VIM tenant name")
157 @click.option("--config", help="VIM specific config parameters")
158 @click.option(
159 "--config_file",
160 default=None,
161 help="VIM specific config parameters in YAML or JSON file",
162 )
163 @click.option("--account_type", help="VIM type")
164 @click.option("--description", help="human readable description")
165 @click.option(
166 "--sdn_controller",
167 default=None,
168 help="Name or id of the SDN controller to be associated with this VIM"
169 "account. Use empty string to disassociate",
170 )
171 @click.option(
172 "--sdn_port_mapping",
173 default=None,
174 help="File describing the port mapping between compute nodes' ports and switch ports",
175 )
176 @click.option(
177 "--wait",
178 required=False,
179 default=False,
180 is_flag=True,
181 help="do not return the control immediately, but keep it "
182 "until the operation is completed, or timeout",
183 )
184 @click.option(
185 "--creds", default=None, help="credentials file (only applicable for GCP VIM type)"
186 )
187 @click.option(
188 "--prometheus_url",
189 default=None,
190 help="PrometheusTSBD URL to get VIM data",
191 )
192 @click.option(
193 "--prometheus_map",
194 default=None,
195 help="PrometheusTSBD metrics mapping for VIM data",
196 )
197 @click.option(
198 "--prometheus_config_file",
199 default=None,
200 help="Prometheus configuration to get VIM data",
201 )
202 @click.pass_context
203 def vim_update(
204 ctx,
205 name,
206 newname,
207 user,
208 password,
209 auth_url,
210 tenant,
211 config,
212 config_file,
213 account_type,
214 description,
215 sdn_controller,
216 sdn_port_mapping,
217 wait,
218 creds,
219 prometheus_url,
220 prometheus_map,
221 prometheus_config_file,
222 ):
223 """updates a VIM account
224
225 NAME: name or ID of the VIM account
226 """
227 logger.debug("")
228 utils.check_client_version(ctx.obj, ctx.command.name)
229 vim = {}
230 if newname:
231 vim["name"] = newname
232 if user:
233 vim["vim_user"] = user
234 if password:
235 vim["vim_password"] = password
236 if auth_url:
237 vim["vim_url"] = auth_url
238 if tenant:
239 vim["vim-tenant-name"] = tenant
240 if account_type:
241 vim["vim_type"] = account_type
242 if description:
243 vim["description"] = description
244 vim_config = None
245 if config or config_file:
246 vim_config = utils.create_config(config_file, config)
247 _check_ca_cert(vim_config)
248 if creds:
249 with open(creds, "r") as cf:
250 vim_config["credentials"] = yaml.safe_load(cf.read())
251 prometheus_config = {}
252 if prometheus_url:
253 prometheus_config["prometheus-url"] = prometheus_url
254 if prometheus_map:
255 prometheus_config["prometheus-map"] = prometheus_map
256 if prometheus_config_file:
257 with open(prometheus_config_file) as prometheus_file:
258 prometheus_config_dict = json.load(prometheus_file)
259 prometheus_config.update(prometheus_config_dict)
260 if prometheus_config:
261 vim["prometheus-config"] = prometheus_config
262 ctx.obj.vim.update(
263 name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait
264 )
265
266
267 @click.command(name="vim-delete", short_help="deletes a VIM account")
268 @click.argument("name")
269 @click.option(
270 "--force", is_flag=True, help="forces the deletion bypassing pre-conditions"
271 )
272 @click.option(
273 "--wait",
274 required=False,
275 default=False,
276 is_flag=True,
277 help="do not return the control immediately, but keep it "
278 "until the operation is completed, or timeout",
279 )
280 @click.pass_context
281 def vim_delete(ctx, name, force, wait):
282 """deletes a VIM account
283
284 NAME: name or ID of the VIM account to be deleted
285 """
286 logger.debug("")
287 if not force:
288 ctx.obj.vim.delete(name, wait=wait)
289 else:
290 utils.check_client_version(ctx.obj, "--force")
291 ctx.obj.vim.delete(name, force, wait=wait)
292
293
294 @click.command(name="vim-list", short_help="list all VIM accounts")
295 @click.option(
296 "--filter",
297 default=None,
298 multiple=True,
299 help="restricts the list to the VIM accounts matching the filter",
300 )
301 @click.option(
302 "--long",
303 is_flag=True,
304 help="get more details of the NS (project, vim, deployment status, configuration status.",
305 )
306 @click.pass_context
307 def vim_list(ctx, filter, long):
308 """list all VIM accounts"""
309 logger.debug("")
310 if filter:
311 filter = "&".join(filter)
312 utils.check_client_version(ctx.obj, "--filter")
313 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
314 if fullclassname == "osmclient.sol005.client.Client":
315 resp = ctx.obj.vim.list(filter)
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 )
350 table.align = "l"
351 print(table)
352
353
354 @click.command(name="vim-show", short_help="shows the details of a VIM account")
355 @click.argument("name")
356 @click.option(
357 "--filter",
358 multiple=True,
359 help="restricts the information to the fields in the filter",
360 )
361 @click.option("--literal", is_flag=True, help="print literally, no pretty table")
362 @click.pass_context
363 def vim_show(ctx, name, filter, literal):
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)])
382 table.align = "l"
383 print(table)