Feature 10962 Refactoring of osmclient commands
[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_config_file",
80 default=None,
81 help="Prometheus configuration to get VIM data",
82 )
83 @click.pass_context
84 def vim_create(
85 ctx,
86 name,
87 user,
88 password,
89 auth_url,
90 tenant,
91 config,
92 config_file,
93 account_type,
94 description,
95 sdn_controller,
96 sdn_port_mapping,
97 wait,
98 vca,
99 creds,
100 prometheus_config_file,
101 ):
102 """creates a new VIM account"""
103 logger.debug("")
104 if sdn_controller:
105 utils.check_client_version(ctx.obj, "--sdn_controller")
106 if sdn_port_mapping:
107 utils.check_client_version(ctx.obj, "--sdn_port_mapping")
108 vim = {}
109 if prometheus_config_file:
110 with open(prometheus_config_file) as prometheus_file:
111 prometheus_config_dict = json.load(prometheus_file)
112 vim["prometheus-config"] = prometheus_config_dict
113
114 vim["vim-username"] = user
115 vim["vim-password"] = password
116 vim["vim-url"] = auth_url
117 vim["vim-tenant-name"] = tenant
118 vim["vim-type"] = account_type
119 vim["description"] = description
120 if vca:
121 vim["vca"] = vca
122 vim_config = utils.create_config(config_file, config)
123 _check_ca_cert(vim_config)
124 if creds:
125 with open(creds, "r") as cf:
126 vim_config["credentials"] = yaml.safe_load(cf.read())
127 ctx.obj.vim.create(
128 name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait
129 )
130
131
132 @click.command(name="vim-update", short_help="updates a VIM account")
133 @click.argument("name")
134 @click.option("--newname", help="New name for the VIM account")
135 @click.option("--user", help="VIM username")
136 @click.option("--password", help="VIM password")
137 @click.option("--auth_url", help="VIM url")
138 @click.option("--tenant", help="VIM tenant name")
139 @click.option("--config", help="VIM specific config parameters")
140 @click.option(
141 "--config_file",
142 default=None,
143 help="VIM specific config parameters in YAML or JSON file",
144 )
145 @click.option("--account_type", help="VIM type")
146 @click.option("--description", help="human readable description")
147 @click.option(
148 "--sdn_controller",
149 default=None,
150 help="Name or id of the SDN controller to be associated with this VIM"
151 "account. Use empty string to disassociate",
152 )
153 @click.option(
154 "--sdn_port_mapping",
155 default=None,
156 help="File describing the port mapping between compute nodes' ports and switch ports",
157 )
158 @click.option(
159 "--wait",
160 required=False,
161 default=False,
162 is_flag=True,
163 help="do not return the control immediately, but keep it "
164 "until the operation is completed, or timeout",
165 )
166 @click.option(
167 "--creds", default=None, help="credentials file (only applicable for GCP VIM type)"
168 )
169 @click.option(
170 "--prometheus_config_file",
171 default=None,
172 help="Prometheus configuration to get VIM data",
173 )
174 @click.pass_context
175 def vim_update(
176 ctx,
177 name,
178 newname,
179 user,
180 password,
181 auth_url,
182 tenant,
183 config,
184 config_file,
185 account_type,
186 description,
187 sdn_controller,
188 sdn_port_mapping,
189 wait,
190 creds,
191 prometheus_config_file,
192 ):
193 """updates a VIM account
194
195 NAME: name or ID of the VIM account
196 """
197 logger.debug("")
198 utils.check_client_version(ctx.obj, ctx.command.name)
199 vim = {}
200 if newname:
201 vim["name"] = newname
202 if user:
203 vim["vim_user"] = user
204 if password:
205 vim["vim_password"] = password
206 if auth_url:
207 vim["vim_url"] = auth_url
208 if tenant:
209 vim["vim-tenant-name"] = tenant
210 if account_type:
211 vim["vim_type"] = account_type
212 if description:
213 vim["description"] = description
214 vim_config = None
215 if config or config_file:
216 vim_config = utils.create_config(config_file, config)
217 _check_ca_cert(vim_config)
218 if creds:
219 with open(creds, "r") as cf:
220 vim_config["credentials"] = yaml.safe_load(cf.read())
221 if prometheus_config_file:
222 with open(prometheus_config_file) as prometheus_file:
223 prometheus_config_dict = json.load(prometheus_file)
224 vim["prometheus-config"] = prometheus_config_dict
225 logger.info(f"VIM: {vim}, VIM config: {vim_config}")
226 ctx.obj.vim.update(
227 name, vim, vim_config, sdn_controller, sdn_port_mapping, wait=wait
228 )
229
230
231 @click.command(name="vim-delete", short_help="deletes a VIM account")
232 @click.argument("name")
233 @click.option(
234 "--force", is_flag=True, help="forces the deletion bypassing pre-conditions"
235 )
236 @click.option(
237 "--wait",
238 required=False,
239 default=False,
240 is_flag=True,
241 help="do not return the control immediately, but keep it "
242 "until the operation is completed, or timeout",
243 )
244 @click.pass_context
245 def vim_delete(ctx, name, force, wait):
246 """deletes a VIM account
247
248 NAME: name or ID of the VIM account to be deleted
249 """
250 logger.debug("")
251 if not force:
252 ctx.obj.vim.delete(name, wait=wait)
253 else:
254 utils.check_client_version(ctx.obj, "--force")
255 ctx.obj.vim.delete(name, force, wait=wait)
256
257
258 @click.command(name="vim-list", short_help="list all VIM accounts")
259 @click.option(
260 "--filter",
261 default=None,
262 multiple=True,
263 help="restricts the list to the VIM accounts matching the filter",
264 )
265 @click.option(
266 "--long",
267 is_flag=True,
268 help="get more details of the NS (project, vim, deployment status, configuration status.",
269 )
270 @click.pass_context
271 def vim_list(ctx, filter, long):
272 """list all VIM accounts"""
273 logger.debug("")
274 if filter:
275 filter = "&".join(filter)
276 utils.check_client_version(ctx.obj, "--filter")
277 fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__
278 if fullclassname == "osmclient.sol005.client.Client":
279 resp = ctx.obj.vim.list(filter)
280 if long:
281 table = PrettyTable(
282 ["vim name", "uuid", "project", "operational state", "error details"]
283 )
284 project_list = ctx.obj.project.list()
285 else:
286 table = PrettyTable(["vim name", "uuid", "operational state"])
287 for vim in resp:
288 if long:
289 if "vim_password" in vim:
290 vim["vim_password"] = "********"
291 if "config" in vim and "credentials" in vim["config"]:
292 vim["config"]["credentials"] = "********"
293 logger.debug("VIM details: {}".format(yaml.safe_dump(vim)))
294 vim_state = vim["_admin"].get("operationalState", "-")
295 error_details = "N/A"
296 if vim_state == "ERROR":
297 error_details = vim["_admin"].get("detailed-status", "Not found")
298 project_id, project_name = utils.get_project(project_list, vim)
299 # project_info = '{} ({})'.format(project_name, project_id)
300 project_info = project_name
301 table.add_row(
302 [
303 vim["name"],
304 vim["uuid"],
305 project_info,
306 vim_state,
307 utils.wrap_text(text=error_details, width=80),
308 ]
309 )
310 else:
311 table.add_row(
312 [vim["name"], vim["uuid"], vim["_admin"].get("operationalState", "-")]
313 )
314 table.align = "l"
315 print(table)
316
317
318 @click.command(name="vim-show", short_help="shows the details of a VIM account")
319 @click.argument("name")
320 @click.option(
321 "--filter",
322 multiple=True,
323 help="restricts the information to the fields in the filter",
324 )
325 @click.option("--literal", is_flag=True, help="print literally, no pretty table")
326 @click.pass_context
327 def vim_show(ctx, name, filter, literal):
328 """shows the details of a VIM account
329
330 NAME: name or ID of the VIM account
331 """
332 logger.debug("")
333 resp = ctx.obj.vim.get(name)
334 if "vim_password" in resp:
335 resp["vim_password"] = "********"
336 if "config" in resp and "credentials" in resp["config"]:
337 resp["config"]["credentials"] = "********"
338
339 if literal:
340 print(yaml.safe_dump(resp, indent=4, default_flow_style=False))
341 return
342 table = PrettyTable(["key", "attribute"])
343 for k, v in list(resp.items()):
344 if not filter or k in filter:
345 table.add_row([k, utils.wrap_text(text=json.dumps(v, indent=2), width=100)])
346 table.align = "l"
347 print(table)