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 |
1 |
import click |
17 |
1 |
from osmclient.common.exceptions import NotFound |
18 |
1 |
from osmclient.cli_commands import utils |
19 |
1 |
from prettytable import PrettyTable |
20 |
1 |
import yaml |
21 |
1 |
import json |
22 |
1 |
import logging |
23 |
|
|
24 |
1 |
logger = logging.getLogger("osmclient") |
25 |
|
|
26 |
|
|
27 |
1 |
@click.command(name="repo-add", short_help="adds a repo to OSM") |
28 |
1 |
@click.argument("name") |
29 |
1 |
@click.argument("uri") |
30 |
1 |
@click.option( |
31 |
|
"--type", |
32 |
|
type=click.Choice(["helm-chart", "juju-bundle", "osm"]), |
33 |
|
default="osm", |
34 |
|
help="type of repo (helm-chart for Helm Charts, juju-bundle for Juju Bundles, osm for OSM Repositories)", |
35 |
|
) |
36 |
1 |
@click.option("--description", default=None, help="human readable description") |
37 |
1 |
@click.option( |
38 |
|
"--user", default=None, help="OSM repository: The username of the OSM repository" |
39 |
|
) |
40 |
1 |
@click.option( |
41 |
|
"--password", |
42 |
|
default=None, |
43 |
|
help="OSM repository: The password of the OSM repository", |
44 |
|
) |
45 |
1 |
@click.pass_context |
46 |
1 |
def repo_add(ctx, **kwargs): |
47 |
|
"""adds a repo to OSM |
48 |
|
|
49 |
|
NAME: name of the repo |
50 |
|
URI: URI of the repo |
51 |
|
""" |
52 |
0 |
kwargs = {k: v for k, v in kwargs.items() if v is not None} |
53 |
0 |
repo = kwargs |
54 |
0 |
repo["url"] = repo.pop("uri") |
55 |
0 |
if repo["type"] in ["helm-chart", "juju-bundle"]: |
56 |
0 |
ctx.obj.repo.create(repo["name"], repo) |
57 |
|
else: |
58 |
0 |
ctx.obj.osmrepo.create(repo["name"], repo) |
59 |
|
|
60 |
|
|
61 |
1 |
@click.command(name="repo-update", short_help="updates a repo in OSM") |
62 |
1 |
@click.argument("name") |
63 |
1 |
@click.option("--newname", help="New name for the repo") |
64 |
1 |
@click.option("--uri", help="URI of the repo") |
65 |
1 |
@click.option("--description", help="human readable description") |
66 |
1 |
@click.pass_context |
67 |
1 |
def repo_update(ctx, name, newname, uri, description): |
68 |
|
"""updates a repo in OSM |
69 |
|
|
70 |
|
NAME: name of the repo |
71 |
|
""" |
72 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
73 |
0 |
repo = {} |
74 |
0 |
if newname: |
75 |
0 |
repo["name"] = newname |
76 |
0 |
if uri: |
77 |
0 |
repo["uri"] = uri |
78 |
0 |
if description: |
79 |
0 |
repo["description"] = description |
80 |
0 |
try: |
81 |
0 |
ctx.obj.repo.update(name, repo) |
82 |
0 |
except NotFound: |
83 |
0 |
ctx.obj.osmrepo.update(name, repo) |
84 |
|
|
85 |
|
|
86 |
1 |
@click.command( |
87 |
|
name="repo-index", short_help="Index a repository from a folder with artifacts" |
88 |
|
) |
89 |
1 |
@click.option( |
90 |
|
"--origin", default=".", help="origin path where the artifacts are located" |
91 |
|
) |
92 |
1 |
@click.option( |
93 |
|
"--destination", default=".", help="destination path where the index is deployed" |
94 |
|
) |
95 |
1 |
@click.pass_context |
96 |
1 |
def repo_index(ctx, origin, destination): |
97 |
|
"""Index a repository |
98 |
|
|
99 |
|
NAME: name or ID of the repo to be deleted |
100 |
|
""" |
101 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
102 |
0 |
ctx.obj.osmrepo.repo_index(origin, destination) |
103 |
|
|
104 |
|
|
105 |
1 |
@click.command(name="repo-delete", short_help="deletes a repo") |
106 |
1 |
@click.argument("name") |
107 |
1 |
@click.option( |
108 |
|
"--force", is_flag=True, help="forces the deletion from the DB (not recommended)" |
109 |
|
) |
110 |
1 |
@click.pass_context |
111 |
1 |
def repo_delete(ctx, name, force): |
112 |
|
"""deletes a repo |
113 |
|
|
114 |
|
NAME: name or ID of the repo to be deleted |
115 |
|
""" |
116 |
0 |
logger.debug("") |
117 |
0 |
try: |
118 |
0 |
ctx.obj.repo.delete(name, force=force) |
119 |
0 |
except NotFound: |
120 |
0 |
ctx.obj.osmrepo.delete(name, force=force) |
121 |
|
|
122 |
|
|
123 |
1 |
@click.command(name="repo-list") |
124 |
1 |
@click.option( |
125 |
|
"--filter", |
126 |
|
default=None, |
127 |
|
multiple=True, |
128 |
|
help="restricts the list to the repos matching the filter", |
129 |
|
) |
130 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
131 |
1 |
@click.pass_context |
132 |
1 |
def repo_list(ctx, filter, literal): |
133 |
|
"""list all repos""" |
134 |
|
# K8s Repositories |
135 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
136 |
0 |
if filter: |
137 |
0 |
filter = "&".join(filter) |
138 |
0 |
resp = ctx.obj.repo.list(filter) |
139 |
0 |
resp += ctx.obj.osmrepo.list(filter) |
140 |
0 |
if literal: |
141 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
142 |
0 |
return |
143 |
0 |
table = PrettyTable(["Name", "Id", "Type", "URI", "Description"]) |
144 |
0 |
for repo in resp: |
145 |
|
# cluster['k8s-nets'] = json.dumps(yaml.safe_load(cluster['k8s-nets'])) |
146 |
0 |
table.add_row( |
147 |
|
[ |
148 |
|
repo["name"], |
149 |
|
repo["_id"], |
150 |
|
repo["type"], |
151 |
|
repo["url"], |
152 |
|
utils.trunc_text(repo.get("description") or "", 40), |
153 |
|
] |
154 |
|
) |
155 |
0 |
table.align = "l" |
156 |
0 |
print(table) |
157 |
|
|
158 |
|
|
159 |
1 |
@click.command(name="repo-show", short_help="shows the details of a repo") |
160 |
1 |
@click.argument("name") |
161 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
162 |
1 |
@click.pass_context |
163 |
1 |
def repo_show(ctx, name, literal): |
164 |
|
"""shows the details of a repo |
165 |
|
|
166 |
|
NAME: name or ID of the repo |
167 |
|
""" |
168 |
0 |
try: |
169 |
0 |
resp = ctx.obj.repo.get(name) |
170 |
0 |
except NotFound: |
171 |
0 |
resp = ctx.obj.osmrepo.get(name) |
172 |
|
|
173 |
0 |
if literal: |
174 |
0 |
if resp: |
175 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
176 |
0 |
return |
177 |
0 |
table = PrettyTable(["key", "attribute"]) |
178 |
0 |
if resp: |
179 |
0 |
for k, v in list(resp.items()): |
180 |
0 |
table.add_row([k, json.dumps(v, indent=2)]) |
181 |
|
|
182 |
0 |
table.align = "l" |
183 |
0 |
print(table) |
184 |
|
|
185 |
|
|
186 |
|
######################## |
187 |
|
# Catalogue commands |
188 |
|
######################## |
189 |
|
|
190 |
|
|
191 |
1 |
def pkg_repo_list(ctx, pkgtype, filter, repo, long): |
192 |
0 |
resp = ctx.obj.osmrepo.pkg_list(pkgtype, filter, repo) |
193 |
0 |
if long: |
194 |
0 |
table = PrettyTable( |
195 |
|
["nfpkg name", "vendor", "version", "latest", "description", "repository"] |
196 |
|
) |
197 |
|
else: |
198 |
0 |
table = PrettyTable(["nfpkg name", "repository"]) |
199 |
0 |
for vnfd in resp: |
200 |
0 |
name = vnfd.get("id", vnfd.get("name", "-")) |
201 |
0 |
repository = vnfd.get("repository") |
202 |
0 |
if long: |
203 |
0 |
vendor = vnfd.get("provider", vnfd.get("vendor")) |
204 |
0 |
version = vnfd.get("version") |
205 |
0 |
description = vnfd.get("description") |
206 |
0 |
latest = vnfd.get("latest") |
207 |
0 |
table.add_row([name, vendor, version, latest, description, repository]) |
208 |
|
else: |
209 |
0 |
table.add_row([name, repository]) |
210 |
0 |
table.align = "l" |
211 |
0 |
print(table) |
212 |
|
|
213 |
|
|
214 |
1 |
def pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal): |
215 |
0 |
logger.debug("") |
216 |
0 |
if filter: |
217 |
0 |
filter = "&".join(filter) |
218 |
0 |
resp = ctx.obj.osmrepo.pkg_get(pkgtype, name, repo, version, filter) |
219 |
|
|
220 |
0 |
if literal: |
221 |
0 |
print(yaml.safe_dump(resp, indent=4, default_flow_style=False)) |
222 |
0 |
return |
223 |
0 |
pkgtype += "d" |
224 |
0 |
catalog = pkgtype + "-catalog" |
225 |
0 |
full_catalog = pkgtype + ":" + catalog |
226 |
0 |
if resp.get(catalog): |
227 |
0 |
resp = resp.pop(catalog)[pkgtype][0] |
228 |
0 |
elif resp.get(full_catalog): |
229 |
0 |
resp = resp.pop(full_catalog)[pkgtype][0] |
230 |
|
|
231 |
0 |
table = PrettyTable(["field", "value"]) |
232 |
0 |
for k, v in list(resp.items()): |
233 |
0 |
table.add_row([k, utils.wrap_text(text=json.dumps(v, indent=2), width=100)]) |
234 |
0 |
table.align = "l" |
235 |
0 |
print(table) |
236 |
|
|
237 |
|
|
238 |
1 |
@click.command(name="vnfpkg-repo-list", short_help="list all xNF from OSM repositories") |
239 |
1 |
@click.option( |
240 |
|
"--filter", |
241 |
|
default=None, |
242 |
|
multiple=True, |
243 |
|
help="restricts the list to the NFpkg matching the filter", |
244 |
|
) |
245 |
1 |
@click.option( |
246 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
247 |
|
) |
248 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
249 |
1 |
@click.pass_context |
250 |
1 |
def nfpkg_repo_list1(ctx, filter, repo, long): |
251 |
|
"""list xNF packages from OSM repositories""" |
252 |
0 |
pkgtype = "vnf" |
253 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
254 |
|
|
255 |
|
|
256 |
1 |
@click.command(name="nfpkg-repo-list", short_help="list all xNF from OSM repositories") |
257 |
1 |
@click.option( |
258 |
|
"--filter", |
259 |
|
default=None, |
260 |
|
multiple=True, |
261 |
|
help="restricts the list to the NFpkg matching the filter", |
262 |
|
) |
263 |
1 |
@click.option( |
264 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
265 |
|
) |
266 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
267 |
1 |
@click.pass_context |
268 |
1 |
def nfpkg_repo_list2(ctx, filter, repo, long): |
269 |
|
"""list xNF packages from OSM repositories""" |
270 |
0 |
pkgtype = "vnf" |
271 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
272 |
|
|
273 |
|
|
274 |
1 |
@click.command(name="nsd-repo-list", short_help="list all NS from OSM repositories") |
275 |
1 |
@click.option( |
276 |
|
"--filter", |
277 |
|
default=None, |
278 |
|
multiple=True, |
279 |
|
help="restricts the list to the NS matching the filter", |
280 |
|
) |
281 |
1 |
@click.option( |
282 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
283 |
|
) |
284 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
285 |
1 |
@click.pass_context |
286 |
1 |
def nspkg_repo_list(ctx, filter, repo, long): |
287 |
|
"""list xNF packages from OSM repositories""" |
288 |
0 |
pkgtype = "ns" |
289 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
290 |
|
|
291 |
|
|
292 |
1 |
@click.command(name="nspkg-repo-list", short_help="list all NS from OSM repositories") |
293 |
1 |
@click.option( |
294 |
|
"--filter", |
295 |
|
default=None, |
296 |
|
multiple=True, |
297 |
|
help="restricts the list to the NS matching the filter", |
298 |
|
) |
299 |
1 |
@click.option( |
300 |
|
"--repo", default=None, help="restricts the list to a particular OSM repository" |
301 |
|
) |
302 |
1 |
@click.option("--long", is_flag=True, help="get more details") |
303 |
1 |
@click.pass_context |
304 |
1 |
def nspkg_repo_list2(ctx, filter, repo, long): |
305 |
|
"""list xNF packages from OSM repositories""" |
306 |
0 |
pkgtype = "ns" |
307 |
0 |
pkg_repo_list(ctx, pkgtype, filter, repo, long) |
308 |
|
|
309 |
|
|
310 |
1 |
@click.command( |
311 |
|
name="vnfpkg-repo-show", |
312 |
|
short_help="shows the details of a NF package in an OSM repository", |
313 |
|
) |
314 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
315 |
1 |
@click.option("--repo", required=True, help="Repository name") |
316 |
1 |
@click.argument("name") |
317 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
318 |
1 |
@click.option("--version", default="latest", help="package version") |
319 |
1 |
@click.pass_context |
320 |
1 |
def vnfd_show1(ctx, name, repo, version, literal=None, filter=None): |
321 |
|
"""shows the content of a VNFD in a repository |
322 |
|
|
323 |
|
NAME: name or ID of the VNFD/VNFpkg |
324 |
|
""" |
325 |
0 |
pkgtype = "vnf" |
326 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
327 |
|
|
328 |
|
|
329 |
1 |
@click.command( |
330 |
|
name="nsd-repo-show", |
331 |
|
short_help="shows the details of a NS package in an OSM repository", |
332 |
|
) |
333 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
334 |
1 |
@click.option("--repo", required=True, help="Repository name") |
335 |
1 |
@click.argument("name") |
336 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
337 |
1 |
@click.option("--version", default="latest", help="package version") |
338 |
1 |
@click.pass_context |
339 |
1 |
def nsd_repo_show(ctx, name, repo, version, literal=None, filter=None): |
340 |
|
"""shows the content of a VNFD in a repository |
341 |
|
|
342 |
|
NAME: name or ID of the VNFD/VNFpkg |
343 |
|
""" |
344 |
0 |
pkgtype = "ns" |
345 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
346 |
|
|
347 |
|
|
348 |
1 |
@click.command( |
349 |
|
name="nspkg-repo-show", |
350 |
|
short_help="shows the details of a NS package in an OSM repository", |
351 |
|
) |
352 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
353 |
1 |
@click.option("--repo", required=True, help="Repository name") |
354 |
1 |
@click.argument("name") |
355 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
356 |
1 |
@click.option("--version", default="latest", help="package version") |
357 |
1 |
@click.pass_context |
358 |
1 |
def nsd_repo_show2(ctx, name, repo, version, literal=None, filter=None): |
359 |
|
"""shows the content of a VNFD in a repository |
360 |
|
|
361 |
|
NAME: name or ID of the VNFD/VNFpkg |
362 |
|
""" |
363 |
0 |
pkgtype = "ns" |
364 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |
365 |
|
|
366 |
|
|
367 |
1 |
@click.command( |
368 |
|
name="nfpkg-repo-show", |
369 |
|
short_help="shows the details of a NF package in an OSM repository", |
370 |
|
) |
371 |
1 |
@click.option("--literal", is_flag=True, help="print literally, no pretty table") |
372 |
1 |
@click.option("--repo", required=True, help="Repository name") |
373 |
1 |
@click.argument("name") |
374 |
1 |
@click.option("--filter", default=None, multiple=True, help="filter by fields") |
375 |
1 |
@click.option("--version", default="latest", help="package version") |
376 |
1 |
@click.pass_context |
377 |
1 |
def vnfd_show2(ctx, name, repo, version, literal=None, filter=None): |
378 |
|
"""shows the content of a VNFD in a repository |
379 |
|
|
380 |
|
NAME: name or ID of the VNFD/VNFpkg |
381 |
|
""" |
382 |
0 |
pkgtype = "vnf" |
383 |
0 |
pkg_repo_show(ctx, pkgtype, name, repo, version, filter, literal) |