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.cli_commands import utils |
18 |
1 |
from prettytable import PrettyTable |
19 |
1 |
import logging |
20 |
|
|
21 |
1 |
logger = logging.getLogger("osmclient") |
22 |
|
|
23 |
|
|
24 |
1 |
@click.command( |
25 |
|
name="package-create", short_help="Create empty VNF or NS package structure" |
26 |
|
) |
27 |
1 |
@click.argument("package-type") |
28 |
1 |
@click.argument("package-name") |
29 |
1 |
@click.option( |
30 |
|
"--base-directory", |
31 |
|
default=".", |
32 |
|
help=('(NS/VNF/NST) Set the location for package creation. Default: "."'), |
33 |
|
) |
34 |
1 |
@click.option( |
35 |
|
"--image", |
36 |
|
default="image-name", |
37 |
|
help='(VNF) Set the name of the vdu image. Default "image-name"', |
38 |
|
) |
39 |
1 |
@click.option( |
40 |
|
"--vdus", default=1, help="(VNF) Set the number of vdus in a VNF. Default 1" |
41 |
|
) |
42 |
1 |
@click.option( |
43 |
|
"--vcpu", default=1, help="(VNF) Set the number of virtual CPUs in a vdu. Default 1" |
44 |
|
) |
45 |
1 |
@click.option( |
46 |
|
"--memory", |
47 |
|
default=1024, |
48 |
|
help="(VNF) Set the memory size (MB) of the vdu. Default 1024", |
49 |
|
) |
50 |
1 |
@click.option( |
51 |
|
"--storage", default=10, help="(VNF) Set the disk size (GB) of the vdu. Default 10" |
52 |
|
) |
53 |
1 |
@click.option( |
54 |
|
"--interfaces", |
55 |
|
default=0, |
56 |
|
help="(VNF) Set the number of additional interfaces apart from the management interface. Default 0", |
57 |
|
) |
58 |
1 |
@click.option( |
59 |
|
"--vendor", default="OSM", help='(NS/VNF) Set the descriptor vendor. Default "OSM"' |
60 |
|
) |
61 |
1 |
@click.option( |
62 |
|
"--override", |
63 |
|
default=False, |
64 |
|
is_flag=True, |
65 |
|
help="(NS/VNF/NST) Flag for overriding the package if exists.", |
66 |
|
) |
67 |
1 |
@click.option( |
68 |
|
"--detailed", |
69 |
|
is_flag=True, |
70 |
|
default=False, |
71 |
|
help="(NS/VNF/NST) Flag for generating descriptor .yaml with all possible commented options", |
72 |
|
) |
73 |
1 |
@click.option( |
74 |
|
"--netslice-subnets", default=1, help="(NST) Number of netslice subnets. Default 1" |
75 |
|
) |
76 |
1 |
@click.option( |
77 |
|
"--netslice-vlds", default=1, help="(NST) Number of netslice vlds. Default 1" |
78 |
|
) |
79 |
1 |
@click.option( |
80 |
|
"--old", |
81 |
|
default=False, |
82 |
|
is_flag=True, |
83 |
|
help="Flag to create a descriptor using the previous OSM format (pre SOL006, OSM<9)", |
84 |
|
) |
85 |
1 |
@click.pass_context |
86 |
1 |
def package_create( |
87 |
|
ctx, |
88 |
|
package_type, |
89 |
|
base_directory, |
90 |
|
package_name, |
91 |
|
override, |
92 |
|
image, |
93 |
|
vdus, |
94 |
|
vcpu, |
95 |
|
memory, |
96 |
|
storage, |
97 |
|
interfaces, |
98 |
|
vendor, |
99 |
|
detailed, |
100 |
|
netslice_subnets, |
101 |
|
netslice_vlds, |
102 |
|
old, |
103 |
|
): |
104 |
|
""" |
105 |
|
Creates an OSM NS, VNF, NST package |
106 |
|
|
107 |
|
\b |
108 |
|
PACKAGE_TYPE: Package to be created: NS, VNF or NST. |
109 |
|
PACKAGE_NAME: Name of the package to create the folder with the content. |
110 |
|
""" |
111 |
|
|
112 |
0 |
logger.debug("") |
113 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
114 |
0 |
print( |
115 |
|
"Creating the {} structure: {}/{}".format( |
116 |
|
package_type.upper(), base_directory, package_name |
117 |
|
) |
118 |
|
) |
119 |
0 |
resp = ctx.obj.package_tool.create( |
120 |
|
package_type, |
121 |
|
base_directory, |
122 |
|
package_name, |
123 |
|
override=override, |
124 |
|
image=image, |
125 |
|
vdus=vdus, |
126 |
|
vcpu=vcpu, |
127 |
|
memory=memory, |
128 |
|
storage=storage, |
129 |
|
interfaces=interfaces, |
130 |
|
vendor=vendor, |
131 |
|
detailed=detailed, |
132 |
|
netslice_subnets=netslice_subnets, |
133 |
|
netslice_vlds=netslice_vlds, |
134 |
|
old=old, |
135 |
|
) |
136 |
0 |
print(resp) |
137 |
|
|
138 |
|
|
139 |
1 |
@click.command( |
140 |
|
name="package-validate", short_help="Validate descriptors given a base directory" |
141 |
|
) |
142 |
1 |
@click.argument("base-directory", default=".", required=False) |
143 |
1 |
@click.option( |
144 |
|
"--recursive/--no-recursive", |
145 |
|
default=True, |
146 |
|
help="The activated recursive option will validate the yaml files" |
147 |
|
" within the indicated directory and in its subdirectories", |
148 |
|
) |
149 |
1 |
@click.option( |
150 |
|
"--old", |
151 |
|
is_flag=True, |
152 |
|
default=False, |
153 |
|
help="Validates also the descriptors using the previous OSM format (pre SOL006)", |
154 |
|
) |
155 |
1 |
@click.pass_context |
156 |
1 |
def package_validate(ctx, base_directory, recursive, old): |
157 |
|
""" |
158 |
|
Validate descriptors given a base directory. |
159 |
|
|
160 |
|
\b |
161 |
|
BASE_DIRECTORY: Base folder for NS, VNF or NST package. |
162 |
|
""" |
163 |
0 |
logger.debug("") |
164 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
165 |
0 |
results = ctx.obj.package_tool.validate(base_directory, recursive, old) |
166 |
0 |
table = PrettyTable() |
167 |
0 |
table.field_names = ["TYPE", "PATH", "VALID", "ERROR"] |
168 |
|
# Print the dictionary generated by the validation function |
169 |
0 |
for result in results: |
170 |
0 |
table.add_row( |
171 |
|
[result["type"], result["path"], result["valid"], result["error"]] |
172 |
|
) |
173 |
0 |
table.sortby = "VALID" |
174 |
0 |
table.align["PATH"] = "l" |
175 |
0 |
table.align["TYPE"] = "l" |
176 |
0 |
table.align["ERROR"] = "l" |
177 |
0 |
print(table) |
178 |
|
|
179 |
|
|
180 |
1 |
@click.command( |
181 |
|
name="package-translate", short_help="Translate descriptors given a base directory" |
182 |
|
) |
183 |
1 |
@click.argument("base-directory", default=".", required=False) |
184 |
1 |
@click.option( |
185 |
|
"--recursive/--no-recursive", |
186 |
|
default=True, |
187 |
|
help="The activated recursive option will translate the yaml files" |
188 |
|
" within the indicated directory and in its subdirectories", |
189 |
|
) |
190 |
1 |
@click.option( |
191 |
|
"--dryrun", |
192 |
|
is_flag=True, |
193 |
|
default=False, |
194 |
|
help="Do not translate yet, only make a dry-run to test translation", |
195 |
|
) |
196 |
1 |
@click.pass_context |
197 |
1 |
def package_translate(ctx, base_directory, recursive, dryrun): |
198 |
|
""" |
199 |
|
Translate descriptors given a base directory. |
200 |
|
|
201 |
|
\b |
202 |
|
BASE_DIRECTORY: Stub folder for NS, VNF or NST package. |
203 |
|
""" |
204 |
0 |
logger.debug("") |
205 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
206 |
0 |
results = ctx.obj.package_tool.translate(base_directory, recursive, dryrun) |
207 |
0 |
table = PrettyTable() |
208 |
0 |
table.field_names = [ |
209 |
|
"CURRENT TYPE", |
210 |
|
"NEW TYPE", |
211 |
|
"PATH", |
212 |
|
"VALID", |
213 |
|
"TRANSLATED", |
214 |
|
"ERROR", |
215 |
|
] |
216 |
|
# Print the dictionary generated by the validation function |
217 |
0 |
for result in results: |
218 |
0 |
table.add_row( |
219 |
|
[ |
220 |
|
result["current type"], |
221 |
|
result["new type"], |
222 |
|
result["path"], |
223 |
|
result["valid"], |
224 |
|
result["translated"], |
225 |
|
result["error"], |
226 |
|
] |
227 |
|
) |
228 |
0 |
table.sortby = "TRANSLATED" |
229 |
0 |
table.align["PATH"] = "l" |
230 |
0 |
table.align["TYPE"] = "l" |
231 |
0 |
table.align["ERROR"] = "l" |
232 |
0 |
print(table) |
233 |
|
|
234 |
|
|
235 |
1 |
@click.command(name="package-build", short_help="Build the tar.gz of the package") |
236 |
1 |
@click.argument("package-folder") |
237 |
1 |
@click.option( |
238 |
|
"--skip-validation", default=False, is_flag=True, help="skip package validation" |
239 |
|
) |
240 |
1 |
@click.option( |
241 |
|
"--skip-charm-build", |
242 |
|
default=False, |
243 |
|
is_flag=True, |
244 |
|
help="the charm will not be compiled, it is assumed to already exist", |
245 |
|
) |
246 |
1 |
@click.pass_context |
247 |
1 |
def package_build(ctx, package_folder, skip_validation, skip_charm_build): |
248 |
|
""" |
249 |
|
Build the package NS, VNF given the package_folder. |
250 |
|
|
251 |
|
\b |
252 |
|
PACKAGE_FOLDER: Folder of the NS, VNF or NST to be packaged |
253 |
|
""" |
254 |
0 |
logger.debug("") |
255 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
256 |
0 |
results = ctx.obj.package_tool.build( |
257 |
|
package_folder, |
258 |
|
skip_validation=skip_validation, |
259 |
|
skip_charm_build=skip_charm_build, |
260 |
|
) |
261 |
0 |
print(results) |
262 |
|
|
263 |
|
|
264 |
1 |
@click.command( |
265 |
|
name="descriptor-translate", |
266 |
|
short_help="Translate input descriptor file from Rel EIGHT OSM descriptors to SOL006 and prints in standard output", |
267 |
|
) |
268 |
1 |
@click.argument("descriptor-file", required=True) |
269 |
1 |
@click.pass_context |
270 |
1 |
def descriptor_translate(ctx, descriptor_file): |
271 |
|
""" |
272 |
|
Translate input descriptor. |
273 |
|
|
274 |
|
\b |
275 |
|
DESCRIPTOR_FILE: Descriptor file for NS, VNF or Network Slice. |
276 |
|
""" |
277 |
0 |
logger.debug("") |
278 |
0 |
utils.check_client_version(ctx.obj, ctx.command.name) |
279 |
0 |
result = ctx.obj.package_tool.descriptor_translate(descriptor_file) |
280 |
0 |
print(result) |
281 |
|
|
282 |
|
|
283 |
|
# TODO: check if this command should be here. It is more related to nspkg and nfpkg |
284 |
1 |
@click.command(name="upload-package", short_help="uploads a VNF package or NS package") |
285 |
1 |
@click.argument("filename") |
286 |
1 |
@click.option( |
287 |
|
"--skip-charm-build", |
288 |
|
default=False, |
289 |
|
is_flag=True, |
290 |
|
help="the charm will not be compiled, it is assumed to already exist", |
291 |
|
) |
292 |
1 |
@click.pass_context |
293 |
1 |
def upload_package(ctx, filename, skip_charm_build): |
294 |
|
"""uploads a vnf package or ns package |
295 |
|
|
296 |
|
filename: vnf or ns package folder, or vnf or ns package file (tar.gz) |
297 |
|
""" |
298 |
0 |
logger.debug("") |
299 |
0 |
ctx.obj.package.upload(filename, skip_charm_build=skip_charm_build) |
300 |
0 |
fullclassname = ctx.obj.__module__ + "." + ctx.obj.__class__.__name__ |
301 |
0 |
if fullclassname != "osmclient.sol005.client.Client": |
302 |
0 |
ctx.obj.package.wait_for_upload(filename) |